Kubernetes Service 是定义一组 Pod 的访问策略的抽象,它为 Pod 提供稳定的网络端点,即使 Pod 的 IP 地址发生变化,Service 也能保证服务的可访问性。
Service 的作用
-
服务发现:Service 为一组 Pod 提供统一的访问入口,客户端不需要知道具体的 Pod IP 地址。
-
负载均衡:Service 自动将流量分发到后端的多个 Pod,实现负载均衡。
-
稳定的网络标识:Service 拥有固定的 IP 地址和 DNS 名称,即使 Pod 重新创建,Service 的地址也不会改变。
Service 的类型
Kubernetes 支持四种 Service 类型:
-
ClusterIP(默认):
- 在集群内部暴露服务
- 只能从集群内部访问
- 适合内部服务之间的通信
-
NodePort:
- 在每个 Node 上开放一个端口
- 可以通过 NodeIP:Port 从外部访问
- 端口范围:30000-32767
-
LoadBalancer:
- 在云提供商处创建外部负载均衡器
- 自动将流量分发到 NodePort
- 需要云提供商支持
-
ExternalName:
- 将服务映射到外部 DNS 名称
- 不创建代理或负载均衡器
- 适用于访问外部服务
Service 的工作原理
Service 通过 kube-proxy 实现:
-
iptables 模式(默认):
- kube-proxy 监听 API Server 的 Service 和 Endpoint 变化
- 使用 iptables 规则将流量转发到后端 Pod
- 性能较好,但更新规则时会有延迟
-
IPVS 模式:
- 使用 Linux IPVS(IP Virtual Server)实现负载均衡
- 支持多种负载均衡算法(轮询、最少连接等)
- 性能更高,适合大规模集群
Service 的选择器
Service 通过 selector 选择要代理的 Pod:
yamlapiVersion: v1 kind: Service metadata: name: my-service spec: selector: app: my-app ports: - protocol: TCP port: 80 targetPort: 8080
Endpoint
Service 的后端由 Endpoint 对象维护,Endpoint 包含所有匹配 selector 的 Pod 的 IP 地址和端口。
无选择器的 Service
Service 可以不指定 selector,此时需要手动创建 Endpoint 对象,用于:
- 访问集群外部的服务
- 访问其他命名空间的服务
- 访问外部数据库等
最佳实践
-
使用 ClusterIP 作为默认类型:除非需要外部访问,否则使用 ClusterIP 以提高安全性。
-
合理设置 sessionAffinity:对于有状态的应用,可以设置 sessionAffinity 为 ClientIP,实现会话保持。
-
使用 Headless Service:对于需要直接访问 Pod 的场景(如 StatefulSet),可以使用 Headless Service(ClusterIP: None)。
-
监控 Service 的健康状态:定期检查 Endpoint 的状态,确保后端 Pod 正常。
-
使用 Ingress 替代 LoadBalancer:对于 HTTP/HTTPS 服务,使用 Ingress 可以更灵活地管理路由和 SSL。