Service
Service 为一组 Pod 提供稳定的网络访问入口,实现服务发现和负载均衡。
工作原理
flowchart LR
C[Client] --> S[Service]
S --> P1[Pod 1]
S --> P2[Pod 2]
S --> P3[Pod 3]
Service 类型
| 类型 | 访问范围 | 适用场景 |
|---|---|---|
| ClusterIP | 集群内部 | 内部服务 |
| NodePort | 集群外部 | 开发测试 |
| LoadBalancer | 公网访问 | 生产环境 |
| ExternalName | 外部服务映射 | 映射外部服务到集群内部 |
Service 流量转发机制
ClusterIP 流量转发
工作原理:ClusterIP Service分配一个集群内部虚拟IP,通过iptables或IPVS规则将流量转发到后端Pod。
graph LR
Client[集群内客户端] --> SVC[ClusterIP Service
10.96.0.10:80]
SVC --> EP1[Pod A
10.1.1.10:8080]
SVC --> EP2[Pod B
10.1.1.11:8080]
SVC --> EP3[Pod C
10.1.1.12:8080]
style SVC fill:#e3f2fd
style EP1 fill:#e8f5e8
style EP2 fill:#e8f5e8
style EP3 fill:#e8f5e8
实现方式: kube-proxy监听Service和Endpoints变化,动态更新iptables规则或IPVS条目,实现负载均衡。
NodePort 流量转发
工作原理:在每个节点上开放一个端口,外部通过NodeIP:NodePort访问,流量先到达节点端口,再转发到ClusterIP Service,最后转发到Pod。
graph LR
ExtClient[外部客户端] --> NodePort[NodeIP:30080]
NodePort --> SVC[ClusterIP Service
10.96.0.10:80]
SVC --> EP1[Pod A
10.1.1.10:8080]
SVC --> EP2[Pod B
10.1.1.11:8080]
style NodePort fill:#fff3e0
style SVC fill:#e3f2fd
实现方式: NodePort实际上是ClusterIP的扩展,在每个节点上开放端口,并通过iptables规则将该端口流量重定向到Service的ClusterIP。
LoadBalancer 流量转发
工作原理:在公有云环境中,LoadBalancer会创建云提供商的负载均衡器,并将其路由到节点上的NodePort,再转发到Pod。
graph LR
subgraph "云环境"
ExtClient[外部客户端]
LB[云负载均衡器]
end
subgraph "K8s 集群"
NodePort[NodePort
30080]
SVC[ClusterIP Service
10.96.0.10:80]
EP1[Pod A]
EP2[Pod B]
end
ExtClient --> LB
LB --> NodePort
NodePort --> SVC
SVC --> EP1
SVC --> EP2
实现方式: LoadBalancer依赖于云提供商的控制器,创建外部负载均衡器资源,并配置其将流量导向集群节点。
ExternalName 流量转发
工作原理:ExternalName Service不通过kube-proxy处理,而是直接在集群DNS中创建CNAME记录,将服务名映射到指定的外部域名。
graph LR
App[集群内应用] --> DNS[集群DNS]
DNS -.-> CNAME["CNAME 记录
my-service --> external.example.com"]
App -.-> Ext[外部服务
external.example.com]
style DNS fill:#f3e5f5
style Ext fill:#ffebee
实现方式: 当应用访问Service名称时,集群DNS直接返回CNAME记录,将请求转发到外部域名,不经过kube-proxy或任何Pod。
kube-proxy 工作模式
| 模式 | 实现方式 | 特点 | 性能 |
|---|---|---|---|
| userspace | 在用户空间处理流量转发 | 最早的实现方式,性能较低 | 低 |
| iptables | 使用Linux内核iptables规则 | 目前主流方式,性能好 | 高 |
| IPVS | 使用Linux内核IPVS模块 | 最新方式,支持更多负载均衡算法 | 最高 |
ExternalName 类型详解
ExternalName Service 是一种特殊类型的 Service,它不指向 Pod,而是将服务映射到 DNS 名称。这种类型的 Service 通过返回 CNAME 记录和其映射的值来工作。
flowchart LR
subgraph "K8s Cluster"
App[应用 Pod]
S[ExternalName Service
my-external-service]
end
S -.-> EX[External Service
external.example.com]
App --> S
S --> EX
# 创建 ExternalName 类型的 Service
apiVersion: v1
kind: Service
metadata:
name: my-external-service
spec:
type: ExternalName
externalName: external.example.com
# 使用 kubectl 创建 ExternalName Service
kubectl create service externalname my-external-service --external-name external.example.com
# 验证 ExternalName Service
kubectl get service my-external-service
# 测试 DNS 解析
nslookup my-external-service.default.svc.cluster.local
常用命令
# 暴露 Deployment 为 Service
kubectl expose deployment nginx --port=80 --target-port=80
# 创建 NodePort 类型 Service
kubectl expose deployment nginx --port=80 --type=NodePort
# 查看所有 Service
kubectl get services
# 查看 Endpoints
kubectl get endpoints nginx