Kubernetes Service
Service 是 Kubernetes 中稳定访问后端 Pod 的抽象,通过 标签选择器 + 集群网络 为 Pod 提供:
- 固定虚拟 IP(ClusterIP)
- 负载均衡(kube-proxy / eBPF)
- 稳定 DNS 名称
- 跨节点透明访问能力(无 NAT 或带 NAT,视 CNI 和 kube-proxy 模式决定)
Pod 会不断变化:
- Pod 删除重建
- Pod 重启
- Pod IP 会变化
Service 解决两个关键问题:
| 问题 | Service 提供的解决方案 |
|---|---|
| 如何稳定访问 Pod? | 创建 固定 IP:ClusterIP |
| 多个 Pod 怎么负载均衡? | kube-proxy / CNI eBPF |
核心组件
- Selector:选择 Pod
- Endpoints / EndpointSlice:存储被选中的 Pod 列表
- ClusterIP/NodePort/LoadBalancer 类型
- kube-proxy / CNI(例如 Calico eBPF):负责流量转发
流程图
Service -> Selector -> Label 匹配 -> EndpointSlice -> kube-proxy/eBPF -> Pod
仅集群内部可访问。
特点:
- 创建一个 虚拟 IP(VIP)
- kube-proxy(或 eBPF)监听流量并将请求转发到后端 Pod
最佳用途:
- 微服务内部调用
- API、内部接口
在每个 Node 上开放统一端口(30000–32767)。
访问方式:
http://<NodeIP>:<NodePort>
常用于:
- 暴露服务给云 LB 之前
- 调试访问服务
- 内部集群外访问
⚠️ 注意:
- NodePort 会占用节点端口
- 不能同时指定多个 NodePort
云提供商层面的 L4 负载均衡器(如 ALB、ELB、SLB)。
流程:
用户 -> 云 LB -> NodePort -> kube-proxy -> Pod
适用于:
- 对外提供服务
- 生产级访问入口
将 Service 映射到外部 DNS:
示例:
externalName: mysql.example.com
用途:
- 使用 Kubernetes DNS 访问外部数据库、服务
⚠️ 无负载均衡,不是网络代理,只是 DNS CNAME。
clusterIP: None
特点:
- 不分配 VIP
- 直接将 Pod IP 返回给客户端(通过 DNS SRV / A 记录)
- 无 kube-proxy 参与
用途:
- StatefulSet(MySQL 主从、Kafka、ZooKeeper)
- 应用自己实现负载均衡或发现机制
根据 proxy 实现不同有三类:
流量流程:
client -> ClusterIP -> iptables -> Pod
特性:
- DNAT
- 规则数量多会变慢
- 稳定但性能一般
client -> ClusterIP -> IPVS(LVS 内核模块) -> Pod
优点:
- 高性能(百万级连接)
- 支持高级调度算法
- rr(轮询)
- wrr(加权轮询)
- lc(最少连接)
- sh(源地址哈希)
适用:
- 高并发业务
完全绕过 kube-proxy!
流量:
client -> eBPF -> Pod (无 NAT)
优点:
- 更低延迟(无内核链路跳转)
- 更高吞吐
- 更多可观测性
- 更智能的负载均衡
适用于:
- 高 QPS
- 云原生高性能场景
不适合大规模,100+Pod 时性能下降。
优势:
- 可扩展(每个 slice 100 个 Pod)
- 更快的更新速度
- 减少控制面压力
调试命令:
kubectl get endpoints
kubectl get endpointslices
在 pod 内解析:
<service>.<namespace>.svc.cluster.local
示例:
nginx.default.svc.cluster.local
短名访问规则(带搜索域):
nginx
nginx.default
查看 DNS:
kubectl exec -it pod -- cat /etc/resolv.conf
- conntrack 轮询
- 单个流量保持 Session Stickiness
支持多种高级算法:
- rr
- wrr
- lc
- sh(源地址一致性)
- 最佳性能
- 可选择 L4 + 自定义调度
- 无 NAT 模式
原因可能是:
- kube-proxy 异常
- iptables/ipvs 缺失
- Overlay 网络断开
- EndpointSlice 为空
排查:
kubectl get endpoints -A
kubectl get endpointslices -A
kubectl get pods -o wide
systemctl status kube-proxy
排查:
iptables -L -n | grep NodePort
检查网络策略(NetworkPolicy)是否阻断。
原因:
- 没用云环境
- 未安装 MetalLB
可能是:
- conntrack 满了
- kube-proxy 规则过多
- NAT 链路过长
解决:
sysctl -w net.netfilter.nf_conntrack_max=2621440
apiVersion: v1
kind: Service
metadata:
name: backend
spec:
selector:
app: backend
ports:
- port: 80
targetPort: 8080
spec:
type: NodePort
ports:
- port: 80
nodePort: 30080
spec:
type: LoadBalancer
spec:
clusterIP: None
性能更高,延迟更低。
Pod > 1000 时改善显著。
建议配合 Ingress / LB。
强烈推荐 Nginx / Traefik / HAProxy。
生产调优:
net.netfilter.nf_conntrack_max = 2621440
性能比 iptables 高很多:
mode: ipvs