Appearance
K8s 网络:Service / Ingress / CNI / DNS
一、要解决的三个问题(网络模型)
K8s 网络模型有三个基本要求:
- 每个 Pod 有独立 IP(集群内可直连,无需 NAT)。
- 所有 Pod 间可互通(跨节点也直连)。
- 节点上的 agent(kubelet)能与本节点所有 Pod 通信。
实现这些要靠 CNI 插件。另一个关键需求是:Pod 会重建、IP 会变——所以需要稳定的服务访问入口,这就是 Service。
二、Service —— 稳定访问入口 + 负载均衡
为什么需要:Pod IP 不稳定(重建就变),Service 提供固定虚拟 IP(ClusterIP)+ DNS 名,把流量负载均衡到后端 Pod。
核心机制:
- Service 通过 label selector 选一组 Pod。
- 对应的端点记录在 Endpoints / EndpointSlice 对象里(就绪才加入)。
- kube-proxy 在每个节点上维护转发规则,把访问
ClusterIP:port的流量 DNAT 到某个后端 Pod。
四种类型:
| 类型 | 作用 |
|---|---|
| ClusterIP(默认) | 仅集群内可达的虚拟 IP,用于内部服务互访 |
| NodePort | 在每个节点开一个高端口(30000-32767),外部可经 节点IP:端口 访问 |
| LoadBalancer | 借云厂商 LB 暴露对外(有公网 IP),是 NodePort 的云上封装 |
| ExternalName | 不做转发,直接映射到外部 DNS 名(CNAME) |
无头 Service(Headless,clusterIP: None):不做 VIP 负载均衡,DNS 直接返回所有后端 Pod IP,客户端自己选——StatefulSet 靠它做稳定寻址。
三、kube-proxy 的两种实现
- iptables 模式(传统,默认):为每个 Service/Endpoint 写入大量 iptables 规则,随机 DNAT。规则多时性能下降(线性匹配)。
- IPVS 模式:用内核 IPVS 做 L4 负载均衡,支持多种调度算法(rr/wrr/lc…),大规模下性能更好。
- 更新(较新版本):nftables 模式、或部分 CNI 自带的 eBPF 数据面(Cilium)直接绕过 kube-proxy。
一句话:kube-proxy 不是真的"代理进程转发流量",而是在节点上写转发规则,真正转发由内核 netfilter/IPVS 完成(除 eBPF 方案)。
四、Ingress —— 七层入口
- 问题:NodePort/LoadBalancer 是 L4,暴露多个服务要多个端口/IP,且无 HTTP 路由能力。
- Ingress:七层(HTTP/HTTPS)路由规则,按 host/path 把请求转发到不同 Service,支持 TLS 终止。
- Ingress Controller:Ingress 只是规则对象,需要有控制器去实现它(nginx-ingress、Traefik、HAProxy、云厂商实现)。没有 Controller,Ingress 不生效。
- Ingress vs Service:Service 是 L4 服务发现/负载均衡;Ingress 是 L7 HTTP 入口。
新趋势:Gateway API 正在取代 Ingress,能力更强(面向角色、支持更多协议)。
五、CNI(容器网络接口)
- CNI 插件负责给 Pod 分配 IP、配置 veth/路由,实现 Pod 互通。
- 常见插件:
- Flannel:简单,overlay(VXLAN)为主,功能少。
- Calico:主流,支持 BGP 路由(无 overlay)+ NetworkPolicy,性能好。
- Cilium:基于 eBPF,高性能,支持 L7 策略、可观测性、替代 kube-proxy。
- NetworkPolicy:Pod 级防火墙,控制进出流量(需 CNI 支持,Flannel 原生不支持)。
六、DNS 与服务发现
- 集群内置 CoreDNS,为 Service/Pod 提供 DNS 解析。
- Service 的 DNS 形如:
<service>.<namespace>.svc.cluster.local。 - 服务发现方式:环境变量(老,启动时注入)或 DNS(推荐)。
- Headless Service 的 DNS 返回多个 A 记录(各 Pod IP)。
七、高频速答
Q:Service 的 ClusterIP 是真实存在的 IP 吗? A:是虚拟 IP,不在任何网卡上;由 kube-proxy 规则拦截并 DNAT 到真实 Pod IP。
Q:Service 如何做到负载均衡? A:kube-proxy 在节点写 iptables/IPVS 规则,把到 VIP 的连接分派到 Endpoints 里的某个 Pod。
Q:Pod 之间跨节点怎么通? A:靠 CNI 插件建立的路由/overlay 网络,保证 Pod IP 全局可达。
Q:Ingress 和 LoadBalancer Service 区别? A:后者是 L4 暴露单个服务(消耗一个云 LB);Ingress 是 L7 统一入口,用一个入口按 host/path 路由多个服务。
Q:为什么需要 Headless Service? A:给 StatefulSet 等需要"直接寻址每个 Pod"的场景稳定 DNS + 拿到全部 Pod IP,避开 VIP 负载均衡。
Q:K8s 默认能做服务网格式的加密/治理吗? A:不能,需 Service Mesh(Istio/Linkerd)注入 sidecar 或 eBPF 方案提供 mTLS、流量治理、可观测性。