Skip to main content
Documents
Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Back to homepage

Kubernetes Service

Service 是 Kubernetes 中稳定访问后端 Pod 的抽象,通过 标签选择器 + 集群网络 为 Pod 提供:

  • 固定虚拟 IP(ClusterIP)
  • 负载均衡(kube-proxy / eBPF)
  • 稳定 DNS 名称
  • 跨节点透明访问能力(无 NAT 或带 NAT,视 CNI 和 kube-proxy 模式决定)

1. Service 为什么存在?

Pod 会不断变化:

  • Pod 删除重建
  • Pod 重启
  • Pod IP 会变化

Service 解决两个关键问题:

问题 Service 提供的解决方案
如何稳定访问 Pod? 创建 固定 IP:ClusterIP
多个 Pod 怎么负载均衡? kube-proxy / CNI eBPF

2. Service 由什么组成?

核心组件

  • Selector:选择 Pod
  • Endpoints / EndpointSlice:存储被选中的 Pod 列表
  • ClusterIP/NodePort/LoadBalancer 类型
  • kube-proxy / CNI(例如 Calico eBPF):负责流量转发

流程图

Service -> Selector -> Label 匹配 -> EndpointSlice -> kube-proxy/eBPF -> Pod

3. Service 的类型(最重要部分)

🟩 3.1 ClusterIP(默认)

仅集群内部可访问。

特点:

  • 创建一个 虚拟 IP(VIP)
  • kube-proxy(或 eBPF)监听流量并将请求转发到后端 Pod

最佳用途:

  • 微服务内部调用
  • API、内部接口

🔶 3.2 NodePort

在每个 Node 上开放统一端口(30000–32767)。

访问方式:

http://<NodeIP>:<NodePort>

常用于:

  • 暴露服务给云 LB 之前
  • 调试访问服务
  • 内部集群外访问

⚠️ 注意:

  • NodePort 会占用节点端口
  • 不能同时指定多个 NodePort

🟦 3.3 LoadBalancer(云原生环境)

云提供商层面的 L4 负载均衡器(如 ALB、ELB、SLB)。

流程:

用户 -> 云 LB -> NodePort -> kube-proxy -> Pod

适用于:

  • 对外提供服务
  • 生产级访问入口

🟧 3.4 ExternalName

将 Service 映射到外部 DNS:

示例:

externalName: mysql.example.com

用途:

  • 使用 Kubernetes DNS 访问外部数据库、服务

⚠️ 无负载均衡,不是网络代理,只是 DNS CNAME。

🟥 3.5 Headless Service(无 ClusterIP)

clusterIP: None

特点:

  • 不分配 VIP
  • 直接将 Pod IP 返回给客户端(通过 DNS SRV / A 记录)
  • 无 kube-proxy 参与

用途:

  • StatefulSet(MySQL 主从、Kafka、ZooKeeper)
  • 应用自己实现负载均衡或发现机制

4. Service 流量路径(流量如何被转发?)

根据 proxy 实现不同有三类:

⭐ 1. kube-proxy: iptables (默认旧模式)

流量流程:

client -> ClusterIP -> iptables -> Pod

特性:

  • DNAT
  • 规则数量多会变慢
  • 稳定但性能一般

⭐⭐ 2. kube-proxy: IPVS(推荐)

client -> ClusterIP -> IPVS(LVS 内核模块) -> Pod

优点:

  • 高性能(百万级连接)
  • 支持高级调度算法
  • rr(轮询)
  • wrr(加权轮询)
  • lc(最少连接)
  • sh(源地址哈希)

适用:

  • 高并发业务

⭐⭐⭐ 3. eBPF (Calico eBPF / Cilium BPF)

完全绕过 kube-proxy!

流量:

client -> eBPF -> Pod     (无 NAT)

优点:

  • 更低延迟(无内核链路跳转)
  • 更高吞吐
  • 更多可观测性
  • 更智能的负载均衡

适用于:

  • 高 QPS
  • 云原生高性能场景

5. Service 与 Endpoints / EndpointSlice

Endpoints(旧)

不适合大规模,100+Pod 时性能下降。

EndpointSlice(新,>= 1.21 默认)

优势:

  • 可扩展(每个 slice 100 个 Pod)
  • 更快的更新速度
  • 减少控制面压力

调试命令:

kubectl get endpoints
kubectl get endpointslices

6. Service DNS 解析规则

在 pod 内解析:

<service>.<namespace>.svc.cluster.local

示例:

nginx.default.svc.cluster.local

短名访问规则(带搜索域):

nginx
nginx.default

查看 DNS:

kubectl exec -it pod -- cat /etc/resolv.conf

7. Service 负载均衡策略

kube-proxy + iptables

  • conntrack 轮询
  • 单个流量保持 Session Stickiness

kube-proxy + ipvs

支持多种高级算法:

  • rr
  • wrr
  • lc
  • sh(源地址一致性)

eBPF(Calico/Cilium)

  • 最佳性能
  • 可选择 L4 + 自定义调度
  • 无 NAT 模式

8️⃣ Service 常见问题 & 排查

❗1. ClusterIP 无法访问

原因可能是:

  • kube-proxy 异常
  • iptables/ipvs 缺失
  • Overlay 网络断开
  • EndpointSlice 为空

排查:

kubectl get endpoints -A
kubectl get endpointslices -A
kubectl get pods -o wide
systemctl status kube-proxy

❗2. NodePort 无法访问

排查:

iptables -L -n | grep NodePort

检查网络策略(NetworkPolicy)是否阻断。

❗3. LoadBalancer Pending

原因:

  • 没用云环境
  • 未安装 MetalLB

❗4. Service 访问慢、丢包

可能是:

  • conntrack 满了
  • kube-proxy 规则过多
  • NAT 链路过长

解决:

sysctl -w net.netfilter.nf_conntrack_max=2621440

9. Service YAML 示例(完整)

ClusterIP

apiVersion: v1
kind: Service
metadata:
  name: backend
spec:
  selector:
    app: backend
  ports:
    - port: 80
      targetPort: 8080

NodePort

spec:
  type: NodePort
  ports:
    - port: 80
      nodePort: 30080

LoadBalancer

spec:
  type: LoadBalancer

Headless Service

spec:
  clusterIP: None

10. Kubernetes Service 最佳实践(1.33)

推荐使用 eBPF 模式(Calico eBPF / Cilium)

性能更高,延迟更低。

大规模集群使用 EndpointSlice

Pod > 1000 时改善显著。

NodePort 尽量避免暴露公网

建议配合 Ingress / LB。

对外服务:LoadBalancer + Ingress

强烈推荐 Nginx / Traefik / HAProxy。

内部微服务统一使用 ClusterIP

调大 conntrack

生产调优:

net.netfilter.nf_conntrack_max = 2621440

kube-proxy 使用 IPVS

性能比 iptables 高很多:

mode: ipvs