在 Kubernetes 集群中,Pod 是动态、短暂的工作载体,会频繁重建、销毁与重启,导致 Pod IP 始终处于动态变化状态,无法直接对外提供稳定访问入口。Service 是 Kubernetes 用于解决 Pod 动态访问、流量代理与负载均衡的核心资源,可以固定访问入口,持续跟踪后端 Pod 变化,保障服务访问的稳定性与高可用。本文将全面拆解 Service 核心原理、kube-proxy 三大代理模式、四大 Service 类型及完整实操案例。
一、Service 核心作用
Service 通过标签(Label)与选择器(Label Selector)关联后端 Pod,实时监听 Pod 状态变化,自动更新 Endpoints 端点列表,实现对 Pod IP 的动态跟踪,彻底解决 Pod 动态重建导致的访问不稳定问题。核心能力总结如下:
- 统一访问入口:为客户端提供固定的服务访问地址,屏蔽后端 Pod 细节
- 动态感知 Pod 变化:依托标签机制,自动识别 Pod 新增、销毁、IP 变更
- 防止服务失联:自动更新端点列表,剔除异常 Pod、纳入健康 Pod
- 定义访问策略:规范集群内外服务的访问规则与流量调度逻辑
- 四层负载均衡:基于 TCP/UDP 协议实现后端 Pod 流量分发
- 底层代理调度:由 kube-proxy 提供三种代理模式(userspace/iptables/ipvs),支撑流量转发
二、kube-proxy 三大代理模式
Kubernetes 集群网络分为两类:一类是真实网络(Node Network、Pod Network),分配真实物理 IP;一类是虚拟网络(Cluster Network/Service Network),仅集群内部生效的虚拟 IP。
kube-proxy 运行在每个集群节点上,持续监控 kube-apiserver 的 Service、Endpoints 资源变动,实时同步节点流量转发规则,是 Service 流量调度的核心组件。其迭代了三种代理模式,性能与功能逐级优化。
2.1 Userspace 模式(第一代)
该模式从 Kubernetes v1.0 版本开始支持,是最早的代理模式,目前已被淘汰,不推荐使用。
工作原理:kube-proxy 为每个 Service 随机监听一个代理端口,通过 iptables 将 Service 流量重定向到该端口。所有流量需要从内核态转入用户态,由 kube-proxy 完成后端 Pod 选择,支持轮询(默认)、会话亲和力调度。
核心缺点:流量需要在内核空间与用户空间来回切换,产生大量性能损耗,转发效率极低,仅适用于测试环境。
2.2 iptables 模式(第二代)
该模式从 v1.1 版本支持,v1.2 版本后成为默认模式,是经典的流量转发方案。
工作原理:kube-proxy 仅作为控制器,通过 Informer 机制监听 Service 和 Endpoints 变更,自动同步更新节点 iptables 规则。真正的流量转发由内核 netfilter 模块完成,无需经过用户态。
优缺点
- 优点:完全基于内核转发,相比 userspace 模式性能大幅提升,规则灵活、功能全面
- 缺点:iptables 为线性遍历规则,集群规模大、Service 数量多时,规则数量激增,匹配时延升高,性能急剧下降
2.3 IPVS 模式(第三代)
IPVS(IP Virtual Server)是 Kubernetes 新一代四层负载均衡方案,v1.8 版本引入,v1.11 版本正式稳定可用,是生产环境首选模式。
核心原理:IPVS 是 Linux 内核原生的四层负载均衡模块,依托 ipset 存储 IP/端口集合,配合 iptables 完成包过滤、地址伪装、SNAT 等辅助功能。不同于 iptables 线性规则,ipset 是带索引的数据结构,规则匹配效率极高。
核心优势
- 高性能、高可扩展性:适配大规模集群,规则数量不影响转发效率
- 调度算法丰富:支持轮询(rr)、加权轮询(wrr)、最少连接(lc)、IP 哈希等多种策略
- 自带健康检查与连接重试能力,服务容错性更强
局限性:依赖高版本 Linux 内核,需 4.0 及以上内核版本,低版本内核无法兼容。
2.4 iptables 与 IPVS 核心对比
对比维度 | iptables 模式 | IPVS 模式 |
|---|---|---|
运行层级 | 内核空间 | 内核空间 |
核心优点 | 规则灵活、功能全面,适配小集群 | 转发效率高、算法丰富、适配大规模集群 |
核心缺点 | 规则线性遍历,大集群性能衰减严重 | 依赖高版本内核,低版本系统无法使用 |
适用场景 | K8s 1.10 及以下版本、小规模集群 | K8s 1.11+ 版本、生产大规模集群(默认优选) |
版本适配规则:1.1 版本前默认 userspace;1.2-1.10 版本默认 iptables;1.11 版本后默认 IPVS,若 IPVS 模块未加载,自动降级为 iptables。
三、Service 四大类型与核心参数
Kubernetes 根据访问场景定义了四种 Service 类型,适配集群内部访问、节点端口访问、公网负载均衡、外部服务接入等不同需求。
3.1 四大 Service 类型
- ClusterIP(默认):分配集群内部虚拟 IP,仅集群内 Pod、节点可访问,用于内部服务通信
- NodePort:在所有集群节点开放固定端口(30000-32767),外部可通过「节点IP:端口」访问服务
- LoadBalancer:依托云厂商 LB 或自建负载均衡组件(MetalLB),提供公网/局域网统一入口,适配生产对外服务
- ExternalName:将集群外部域名服务映射到集群内部,实现集群内外服务通信,不分配 IP 和端口
3.2 Service 核心端口参数
- port:Service 自身监听的端口,集群内通过「ClusterIP:port」访问服务
- targetPort:后端 Pod 容器的业务端口,流量最终转发到该端口
- nodePort:NodePort 类型专属,节点对外暴露端口,固定区间 30000-32767
四、各类 Service 完整实操案例
4.1 ClusterIP 类型(集群内部访问)
ClusterIP 分为普通 Service 和 Headless Service(无头服务),普通服务提供负载均衡,无头服务直接解析后端 Pod IP。
4.1.1 普通 ClusterIP 服务创建与测试
支持命令行和 YAML 清单两种创建方式,实操如下:
1. 编写 Deployment 资源清单
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-server1
spec:
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: c1
image: nginx:1.15-alpine
imagePullPolicy: IfNotPresent
ports:
- containerPort: 802. 应用资源清单
kubectl apply -f 01_create_deployment_app_nginx.yaml3. 命令行快速创建 Service
kubectl expose deployment.apps nginx-server1 --type=ClusterIP --target-port=80 --port=804. YAML 方式创建 Service(推荐)
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-server1
spec:
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx-smart
image: nginx:1.15-alpine
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: nginx-svc
spec:
type: ClusterIP
ports:
- protocol: TCP
port: 80
targetPort: 80
selector:
app: nginx5. 资源验证
# 查看服务
kubectl get service
# 查看端点
kubectl get endpoints
# 查看后端Pod
kubectl get pods -l app=nginx6. 负载均衡测试
修改两个 Pod 主页区分流量分发效果:
# 第一个Pod修改页面
kubectl exec -it nginx-server1-77d4c485d8-gsrmq -- /bin/bash
echo web1 > /usr/share/nginx/html/index.html
exit
# 第二个Pod修改页面
kubectl exec -it nginx-server1-77d4c485d8-mmc52 -- /bin/bash
echo web2 > /usr/share/nginx/html/index.html
exit
# 循环访问测试负载均衡
while true;do curl 10.101.153.50;sleep 1; done4.1.2 Headless 无头服务
核心特性:不分配 ClusterIP、不经过 kube-proxy 代理,DNS 直接解析为后端所有 Pod IP,适用于需要直接感知后端节点的场景(如数据库集群、微服务注册发现)。
1. 无头服务 YAML 配置
apiVersion: v1
kind: Service
metadata:
name: headless-service
namespace: default
spec:
type: ClusterIP
clusterIP: None # 关键配置:设置为None即为无头服务
ports:
- port: 80
protocol: TCP
targetPort: 80
selector:
app: nginx2. 应用并验证
kubectl apply -f 04_headless-service.yml
kubectl get svc3. DNS 解析测试
# 查看集群DNS服务IP
kubectl get svc -n kube-system
# 解析无头服务域名
dig -t A headless-service.default.svc.cluster.local. @10.96.0.2解析结果会直接返回后端所有 Pod IP,实现精准的后端节点寻址。
4.2 NodePort 类型(节点端口对外访问)
通过在所有节点开放固定端口,实现集群外部通过「任意节点IP:nodePort」访问内部服务,端口范围严格限制 30000-32767。
1. 完整资源清单
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-app
labels:
app: nginx-app
spec:
replicas: 2
selector:
matchLabels:
app: nginx-app
template:
metadata:
labels:
app: nginx-app
spec:
containers:
- name: c1
image: nginx:1.15-alpine
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: nginx-app
spec:
type: NodePort
selector:
app: nginx-app
ports:
- protocol: TCP
nodePort: 30001
port: 8060
targetPort: 802. 部署与验证
kubectl apply -f 05_create_nodeport_service_app.yaml
kubectl get deployment,svc,endpoints3. 外部访问测试
同一网络主机通过任意节点 IP+30001 端口均可访问服务,实现节点级高可用:
curl http://192.168.10.12:30001
curl http://192.168.10.13:300014.3 LoadBalancer 类型(负载均衡对外服务)
云厂商集群可直接使用自带 LB 能力,自建 Kubernetes 集群需部署 MetalLB 组件实现 LoadBalancer 功能,为服务分配固定局域网/公网 IP。
4.3.1 MetalLB 部署与配置
MetalLB 是自建集群专属负载均衡组件,核心能力:IP 地址分配、路由通告(Layer2/BGP 模式)。
1. 部署 MetalLB 资源清单
kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.12.1/manifests/namespace.yaml
kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.12.1/manifests/metallb.yaml2. 配置 IP 地址池(与节点同网段)
apiVersion: v1
kind: ConfigMap
metadata:
namespace: metallb-system
name: config
data:
config: |
address-pools:
- name: default
protocol: layer2
addresses:
- 192.168.10.90-192.168.10.100kubectl apply -f metallb-conf.yaml4.3.2 部署 LoadBalancer 类型服务
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-metallb
spec:
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx-metallb1
image: nginx:1.15-alpine
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: nginx-metallb
spec:
ports:
- port: 8090
protocol: TCP
targetPort: 80
selector:
app: nginx
type: LoadBalancer3. 验证与访问
kubectl get svc
curl http://192.168.10.90:8090关键注意事项:IPVS 模式下,K8s v1.14.2+ 版本必须开启 strictARP 模式,否则 MetalLB 无法正常工作:
kubectl edit configmap -n kube-system kube-proxy
# 新增配置
ipvs:
strictARP: true4.4 ExternalName 类型(外部服务映射)
核心作用:将集群外部域名服务映射为集群内部 Service 域名,实现集群 Pod 无感访问外部服务,支持跨命名空间服务互通。
1. 映射公网域名案例
apiVersion: v1
kind: Service
metadata:
name: my-externalname
namespace: default
spec:
type: ExternalName
externalName: www.baidu.comkubectl apply -f externelname.yml
# 解析测试
dig -t A my-externalname.default.svc.cluster.local. @10.96.0.2集群内部解析该 Service 域名,会自动跳转解析百度公网 IP,实现外部服务内部化访问。
2. 跨命名空间服务互通:可通过 ExternalName 将 ns1/ns2 命名空间的服务互相映射,实现跨命名空间无感访问,且 Pod IP 变更不影响访问稳定性。
五、SessionAffinity 会话粘附
默认情况下 Service 采用轮询负载均衡,同一客户端多次请求会分发到不同 Pod。会话粘附可以实现同一客户端 IP 始终访问同一后端 Pod,适配需要会话保持的业务场景(登录态、缓存业务)。
1. 开启会话粘附
kubectl patch svc nginx-svc -p '{"spec":{"sessionAffinity":"ClientIP"}}'开启后,同一客户端 IP 多次访问会固定分发到同一个 Pod。
2. 关闭会话粘附(恢复轮询)
kubectl patch svc nginx-svc -p '{"spec":{"sessionAffinity":"None"}}'六、拓展:kube-proxy 切换 IPVS 调度模式
6.1 前置准备:升级 Linux 内核
CentOS7 默认 3.10 内核不支持 IPVS,需升级至 4.0+ 或 5.0+ 内核,所有集群节点执行:
# 安装依赖
yum -y install perl
# 导入密钥
rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org
# 安装内核源
yum -y install https://www.elrepo.org/elrepo-release-7.0-4.el7.elrepo.noarch.rpm
# 安装5.0以上内核
yum --enablerepo="elrepo-kernel" -y install kernel-ml.x86_64
# 设置默认内核启动
grub2-set-default 0
grub2-mkconfig -o /boot/grub2/grub.cfg
# 重启生效
reboot6.2 修改 kube-proxy 配置开启 IPVS
# 编辑kube-proxy配置
kubectl edit configmap kube-proxy -n kube-system
# 修改核心参数
mode: "ipvs" # 开启ipvs模式
ipvs:
strictARP: true
scheduler: "" # 可指定调度算法,默认rr轮询6.3 重启 kube-proxy 生效
删除所有 kube-proxy Pod,让集群自动重建,加载新配置:
kubectl delete pod -n kube-system $(kubectl get pods -n kube-system | grep kube-proxy | awk '{print $1}')6.4 验证 IPVS 模式生效
# 查看pod日志,出现Using ipvs Proxier即为生效
kubectl logs -n kube-system $(kubectl get pods -n kube-system | grep kube-proxy | head -1 | awk '{print $1}')七、总结
- Service 是 K8s 服务稳定访问的核心,通过标签关联 Pod,自动实现端点更新与负载均衡,彻底解决 Pod 动态 IP 问题;
- kube-proxy 三大模式迭代升级,生产环境优先使用 IPVS 模式,兼顾性能与功能,小集群可沿用 iptables;
- 四大 Service 类型覆盖全场景:ClusterIP 内部通信、NodePort 简单对外、LoadBalancer 生产高可用、ExternalName 内外服务互通;
- IPVS 模式需依赖高版本内核,搭配 MetalLB 可完美实现自建集群的生产级负载均衡能力。
