Kubernetes的“厨房”:架构是菜谱,组件是厨具,资源对象是食材(上)
Kubernetes的“厨房”:架构是菜谱,组件是厨具,资源对象是食材(下)
Kubernetes基础资源对象和架构组件的关系
- 基础资源对象是用户定义集群状态的工具,而架构组件则负责实现和维持这些状态,两者共同构成了Kubernetes的自动化管理和编排能力。
基础资源对象
- 定义:基础资源对象是Kubernetes API中的持久化实体,用于表示集群的状态,如Pod、Service、Deployment等。
- 作用:描述系统中部署的应用、工作负载、网络和存储资源等,是用户与Kubernetes系统进行交互的基本单元。
架构组件
- 定义:架构组件是Kubernetes系统中负责具体功能的模块,如API Server、Scheduler、Controller Manager、etcd、Kubelet和Kube-proxy等。
- 作用:负责处理基础资源对象的创建、更新、删除等操作,维护集群的实际状态与期望状态一致。
关系
- API Server:所有基础资源对象的增删改查操作都通过API Server进行,API Server负责将这些对象存储在etcd中,并通知其他组件。
- etcd:作为Kubernetes的后端存储,保存所有基础资源对象的状态信息,确保数据的一致性和可靠性。
- Controller Manager:包含多个控制器,如Deployment控制器、ReplicaSet控制器等,它们监控基础资源对象的状态,并根据需要调整集群资源,确保实际状态与期望状态一致。
- Scheduler:根据基础资源对象(如Pod)的资源需求和调度策略,将它们调度到合适的节点上。
- Kubelet:在节点上根据基础资源对象的定义创建和管理容器,确保Pod等对象按预期运行。
- Kube-proxy:负责实现Service的负载均衡和网络代理,确保基础资源对象(如Service)的网络功能正常工作。
在 Kubernetes 中,Service 是一种抽象概念,但它也是一个真实存在的 API 对象(实体)。让我们从两个角度来理解这个问题:
✅ 1. Service 是一个真实的 Kubernetes 资源对象(API 实体)
Kubernetes 中的 Service 是通过 API 定义的一种资源类型,它存在于集群的 etcd 存储中,并且可以通过 kubectl
命令或 Kubernetes API 来创建、查询、更新和删除。
例如:
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
selector:
app: MyApp
ports:
- protocol: TCP
port: 80
targetPort: 9376
这个 YAML 文件定义了一个名为 my-service
的 Service,它是一个实际存在于 Kubernetes 集群中的对象。
✅ 2. Service 是对 Pod 集合的逻辑抽象(逻辑实体)
虽然 Service 是一个真实存在的资源对象,但它的主要作用是提供一种稳定的网络端点,将请求路由到一组符合条件的 Pod 上。它本身并不运行任何服务代码,也不直接处理流量,而是由 Kubernetes 的网络组件(如 kube-proxy 和 iptables/IPVS)来实现其功能。
Service 的作用包括:
- 为一组 Pod 提供统一的访问入口;
- 实现负载均衡;
- 提供稳定的 IP 和 DNS 名称(如
my-service.namespace.svc.cluster.local
); - 支持多种访问方式:ClusterIP、NodePort、LoadBalancer、ExternalName 等。
🔍 总结
角度 | 是否“真实存在” | 说明 |
---|---|---|
API 层面 | ✅ 是 | Service 是 Kubernetes 中的一个资源对象,有对应的 API 和持久化存储 |
功能层面 | ❌ 否(抽象) | 它不运行任何程序,只是一个逻辑抽象,依赖其他组件实现功能 |
🧠 类比理解
你可以把 Service 想象成一个“虚拟 IP + 路由规则”的定义文件。它自己不是进程,但通过 kube-proxy 在每个节点上配置 iptables 或 IPVS 规则,实现了类似负载均衡器的功能。
Kubernetes 中的 Service:一个“虚拟 IP + 路由规则”的定义文件
在 Kubernetes 中,Service 是一个 API 对象,它本身不是进程,但通过 kube-proxy
在每个节点上配置 iptables
或 IPVS
规则,实现了类似负载均衡器的功能。
🎯 场景说明
我们部署了一个 Web 应用,包含三个 Pod:
apiVersion: v1
kind: Pod
metadata:
name: web-pod-1
labels:
app: web
spec:
containers:
- name: nginx
image: nginx
这三个 Pod 的 IP 分别是:
Pod 名称 | IP 地址 |
---|---|
web-pod-1 | 10.244.1.10 |
web-pod-2 | 10.244.2.20 |
web-pod-3 | 10.244.3.30 |
现在我们希望其他服务能够访问这些 Pod。
📦 创建一个 Service
创建如下 Service:
apiVersion: v1
kind: Service
metadata:
name: web-service
spec:
selector:
app: web
ports:
- protocol: TCP
port: 80
targetPort: 80
这个 Service 会:
- 匹配所有标签为
app=web
的 Pod; - 暴露端口 80,并转发到 Pod 的 80 端口;
- 自动分配 ClusterIP(例如:
10.96.1.100
)。
⚙️ kube-proxy 的工作原理(以 iptables 为例)
当你创建这个 Service 后,Kubernetes 中的 kube-proxy
组件会在每个节点上自动做以下事情。
1. 创建 Endpoints 对象
运行命令查看对应的 Endpoints:
kubectl get endpoints web-service
输出:
NAME ENDPOINTS
web-service 10.244.1.10:80,10.244.2.20:80,10.244.3.30:80
2. 配置 iptables 规则(简化示例)
在每个节点上,kube-proxy
会写入一些 iptables 规则,大致如下:
# 所有发往 10.96.1.100:80 的流量
-A KUBE-SERVICES ! -s 10.0.0.0/8 -d 10.96.1.100/32 -p tcp --dport 80 -j KUBE-MARK-MASQ
-A KUBE-SERVICES -d 10.96.1.100/32 -p tcp --dport 80 -j KUBE-SVC-XXXXXX
# 随机选择后端 Pod
-A KUBE-SVC-XXXXXX -m statistic --mode random --probability 0.33333333343 -j KUBE-SEP-AAA
-A KUBE-SVC-XXXXXX -m statistic --mode random --probability 0.50000000000 -j KUBE-SEP-BBB
-A KUBE-SVC-XXXXXX -j KUBE-SEP-CCC
# 具体转发到某个 Pod
-A KUBE-SEP-AAA -j DNAT --to-destination 10.244.1.10:80
-A KUBE-SEP-BBB -j DNAT --to-destination 10.244.2.20:80
-A KUBE-SEP-CCC -j DNAT --to-destination 10.244.3.30:80
这段规则的作用是:
- 当访问
10.96.1.100:80
时,kube-proxy 使用 iptables 将请求随机转发给其中一个 Pod; - 这个过程不需要额外的代理程序,完全由内核级的 iptables 实现;
- 如果某个 Pod 被删除或宕机,Endpoints 会更新,iptables 规则也会随之更新,实现动态负载均衡。
🧠 总结:Service 到底是什么?
你可以把 Service 想象成一个“虚拟 IP + 路由规则”的定义文件。
在这个例子中:
内容 | 对应解释 |
---|---|
虚拟 IP(ClusterIP) | 10.96.1.100 ,是一个逻辑地址,不绑定任何具体 Pod |
路由规则 | kube-proxy 生成的 iptables/IPVS 规则,决定流量如何分发 |
定义文件 | YAML 文件中的 Service 定义,告诉 Kubernetes 如何配置网络 |
负载均衡功能 | kube-proxy 动态维护 iptables 规则,实现类似 L4 负载均衡器的效果 |
🧩 补充说明:IPVS vs iptables
特性 | iptables | IPVS |
---|---|---|
性能 | 规则多时性能下降明显 | 更高效,支持连接跟踪和调度算法 |
调度算法 | 只能随机选择 | 支持 RR、LC、SH 等多种算法 |
可扩展性 | 不适合大规模集群 | 更适合大规模集群 |
默认启用 | ✅ | ❌(需要手动启用) |
如果你还想进一步了解 Service 的底层 iptables/IPVS 规则、Service 与 Ingress 的区别,或者实际调试方法,我可以继续为你深入讲解 😊
好的,我们进入更深入、技术层面的讲解。以下是关于 Kubernetes 中 Service 的详细解析内容,包括其定义、工作原理、类型、实现机制和相关组件。
🧾 一、Service 是什么?
在 Kubernetes 中,Service 是一个抽象的 API 资源对象(Resource Object),用于为一组具有相同标签(Label)的 Pod 提供统一的网络访问入口。
它通过以下方式实现服务发现与负载均衡:
- 提供稳定的 IP 地址(ClusterIP);
- 提供 DNS 名称(如
my-service.namespace.svc.cluster.local
); - 将请求转发到后端符合条件的 Pod;
- 支持多种暴露方式(ClusterIP、NodePort、LoadBalancer、ExternalName)。
📐 二、Service 的核心字段
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
selector:
app: MyApp
ports:
- protocol: TCP
port: 80
targetPort: 9376
type: ClusterIP | NodePort | LoadBalancer | ExternalName
🔍 关键字段说明:
字段 | 含义 |
---|---|
selector | 选择器,用来筛选哪些 Pod 属于这个 Service |
ports | 指定 Service 暴露的端口以及转发到 Pod 的哪个端口 |
type | Service 类型,决定其如何被访问 |
⚙️ 三、Service 的工作原理
Kubernetes 中的 Service 并不直接处理流量,而是由以下几个组件协同工作来实现其功能:
1. kube-proxy
- 运行在每个节点上的守护进程;
- 监听 Kubernetes API Server 中 Service 和 Endpoint 的变化;
- 根据这些信息,在节点上配置 iptables 或 IPVS 规则,将流量转发到正确的 Pod。
默认使用 iptables,但也可以切换为 IPVS(性能更好,支持更复杂的调度策略)。
2. Endpoints
- 当你创建一个 Service 时,Kubernetes 会自动创建一个同名的 Endpoints 对象;
- 它保存了当前所有匹配 selector 的 Pod 的 IP 和端口;
- kube-proxy 会根据这些 Endpoints 来配置转发规则。
示例:
kubectl get endpoints my-service
输出可能是:
NAME ENDPOINTS
my-service 10.244.1.3:8080,10.244.2.5:8080
3. DNS 插件(如 CoreDNS)
- 自动为每个 Service 创建 DNS 记录;
- 例如:
my-service.namespace.svc.cluster.local
; - 应用可以通过 DNS 名称访问 Service,而不需要硬编码 IP。
📦 四、Service 的类型(Type)
1. ClusterIP(默认)
- 只在集群内部可见;
- 提供一个虚拟 IP(ClusterIP),仅用于集群内通信;
- 最常用于微服务之间互相调用。
2. NodePort
- 在 ClusterIP 基础上,把 Service 暴露到每个节点的某个端口(NodePort);
- 外部可以通过任意节点的 IP + NodePort 访问;
- 适用于测试或简单部署场景。
示例:
spec:
type: NodePort
ports:
- port: 80
targetPort: 8080
nodePort: 30080 # 可选,默认随机分配(30000-32767)
3. LoadBalancer
- 在 NodePort 基础上,由云厂商自动创建外部负载均衡器(如 AWS ELB、GCP Load Balancer);
- 外部可通过 LB 的 IP 访问 Service;
- 适用于生产环境对外暴露服务。
4. ExternalName
- 不代理任何 Pod,而是返回一个 CNAME 记录;
- 用于将集群外的服务映射为集群内的 Service;
- 示例:将数据库
db.example.com
映射为my-db.namespace.svc.cluster.local
。
🔄 五、Service 的生命周期管理
Service 本身是静态资源,不会随着 Pod 的变化而删除,除非手动删除 Service 或者对应的 Namespace。
当 Pod 发生变动(新增/删除/重启)时:
- Endpoints 会动态更新;
- kube-proxy 会重新配置 iptables/IPVS;
- Service 的 IP 不变,但背后的 Pod 可能变化。
🧩 六、Headless Service(无头服务)
当不想分配 ClusterIP 时,可以设置 clusterIP: None
,这种 Service 称为 Headless Service。
它的用途包括:
- 直接返回 Pod 的 IP 列表(而不是 ClusterIP);
- 配合 StatefulSet 使用,提供稳定网络标识;
- 用于自定义服务发现逻辑。
示例:
spec:
clusterIP: None
ports:
- port: 80
🔐 七、安全性考虑
- 默认情况下,Service 是集群内部可访问的;
- 如果使用 NodePort 或 LoadBalancer,需注意暴露的端口安全;
- 可以结合 NetworkPolicy 控制流量;
- 使用 TLS 终止或 Ingress Controller 实现加密访问。
🧱 八、Service 与其他资源的关系
资源 | 作用 |
---|---|
Pod | 提供实际运行的应用容器 |
Selector | 确定哪些 Pod 属于该 Service |
Endpoints | 存储 Pod 的实际地址列表 |
kube-proxy | 实现网络转发规则(iptables/IPVS) |
CoreDNS | 提供 Service 的 DNS 解析 |
Ingress | 提供基于 HTTP 的路由规则,通常配合 Service 使用 |
✅ 总结
特性 | 说明 |
---|---|
是否真实存在 | 是,是一个 Kubernetes API 对象 |
作用 | 抽象一组 Pod,提供稳定的网络访问入口 |
实现机制 | kube-proxy + iptables/IPVS + Endpoints + DNS |
类型 | ClusterIP(默认)、NodePort、LoadBalancer、ExternalName |
适用场景 | 内部服务通信、外部访问、跨集群服务引用等 |