Kubernetes 网络
网络模型
Kubernetes 的基本假设:
- 每个 Pod 有集群内唯一 IP。
- Pod 可直接与其他 Pod 通信,不依赖应用感知的 NAT。
- 节点代理和 Pod 可以互相通信。
- 同一 Pod 内容器共享 IP、端口空间和
localhost。
具体路由、隧道、eBPF、iptables/IPVS/nftables、IPAM 和 NetworkPolicy 由 CNI/数据面实现。Pod IP 是短暂身份,客户端应通过 Service 或更高层路由访问服务。
Service
apiVersion: v1
kind: Service
metadata:
name: web
namespace: demo
spec:
selector:
app: web
ports:
- name: http
port: 80
targetPort: http
type: ClusterIPService 选择 Ready Pod 并通过 EndpointSlice 发布后端:
kubectl -n demo get service web
kubectl -n demo get endpointslice -l kubernetes.io/service-name=web
kubectl -n demo describe service webtargetPort: http 引用容器命名端口,减少端口修改时的耦合。Service selector 错误、Pod 未 Ready 或标签不匹配都会导致没有端点。
Service 类型
| 类型 | 作用 | 注意事项 |
|---|---|---|
| ClusterIP | 仅集群内部虚拟 IP | 默认选择,仍需 NetworkPolicy |
| Headless | clusterIP: None,DNS 返回 Pod/端点 | 常配 StatefulSet/服务发现 |
| NodePort | 每个节点暴露端口 | 暴露面大,通常作为 LB 的底层机制 |
| LoadBalancer | 请求云/平台负载均衡器 | 成本、配额、源 IP 和健康检查依赖实现 |
| ExternalName | DNS CNAME 指向外部名称 | 无代理和健康检查,注意 DNS/证书语义 |
externalTrafficPolicy: Local 可保留客户端源 IP并避免第二跳,但只有本地有端点的节点能接流量,负载均衡健康检查和容量必须配套。
DNS
同命名空间内:
web
web.demo
web.demo.svc
web.demo.svc.cluster.local集群域名未必是 cluster.local,不要硬编码完整后缀。Pod 的 /etc/resolv.conf 通常含搜索域和 ndots,短名称查询可能产生多次 DNS 请求;外部高 QPS 域名可使用尾点完全限定名并验证应用行为。
kubectl -n demo exec dns-test -- cat /etc/resolv.conf
kubectl -n demo exec dns-test -- nslookup web
kubectl -n kube-system get deployment,pods -l k8s-app=kube-dnsDNS 故障要区分:解析失败、DNS 服务无端点、CoreDNS 上游故障、NetworkPolicy 拦截 UDP/TCP 53、节点 conntrack 或应用缓存。
Ingress
Ingress 是 HTTP(S) 路由 API,必须安装 Ingress Controller 才生效:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: web
namespace: demo
spec:
ingressClassName: internal-nginx
rules:
- host: web.example.internal
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: web
port:
name: http注解、正则、重写、超时和认证多为 Controller 私有能力,迁移前必须核对实现。生产应显式 ingressClassName,配置 TLS、证书自动化、访问日志、超时和请求大小限制。
Ingress Controller 生命周期
Ingress API 仍是 Kubernetes 稳定 API,但具体 Controller 是独立项目。选择实现时核对官方维护状态、安全公告和升级路径,不要把旧教程中的 Controller 注解当作 Kubernetes 标准。
Gateway API
Gateway API 将基础设施与应用路由职责分离,需要安装 CRD 和兼容 Controller:
GatewayClass:基础设施提供者定义的实现类。Gateway:监听器、地址和证书等基础设施入口。HTTPRoute、GRPCRoute等:应用团队定义的路由。ReferenceGrant:显式授权跨命名空间引用。
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: web
namespace: demo
spec:
parentRefs:
- name: internal-gateway
namespace: platform-gateway
hostnames:
- web.example.internal
rules:
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
- name: web
port: 80检查 status.parents[].conditions,对象 Accepted 不代表所有引用均已解析或数据面已就绪。Gateway API 版本与能力取决于 CRD/Controller,不跟 Kubernetes 核心版本自动同步。
NetworkPolicy
NetworkPolicy 只有在 CNI 支持时才生效。策略是加法模型:某方向一旦被策略选中,只允许所有适用策略规则的并集。
先为命名空间建立默认拒绝:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny
namespace: demo
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress再允许 web 接收 gateway 流量并访问 DNS;本例未放通 Kubernetes API 或其他业务出站,须按真实目的端点另加规则:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: web-allow
namespace: demo
spec:
podSelector:
matchLabels:
app: web
policyTypes: [Ingress, Egress]
ingress:
- from:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: platform-gateway
ports:
- protocol: TCP
port: 8080
egress:
- to:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: kube-system
ports:
- protocol: UDP
port: 53
- protocol: TCP
port: 53DNS 规则必须匹配集群实际 DNS Pod/节点实现;某些 CNI 对 ipBlock、hostNetwork、节点和 NAT 前后地址的行为不同。上线默认拒绝前,用测试命名空间和流量清单验证监控、证书、镜像、API、外部依赖全部路径。
双栈、MTU 与源地址
- 双栈 Service 可有 IPv4/IPv6 两个 ClusterIP,应用和依赖必须支持。
- 隧道网络会减少有效 MTU;症状可能是小包成功、大包超时或 TLS 卡住。
- Service、Ingress 和负载均衡可能做 SNAT,应用看到的源 IP取决于数据路径。
- 代理链上的
X-Forwarded-For只有在信任边界正确时可用,不能无条件信任客户端自带头。
网络排障路径
# 1. Pod 是否 Ready、IP 是否分配
kubectl -n demo get pod -l app=web -o wide
# 2. Service selector 与端点
kubectl -n demo get svc web -o yaml
kubectl -n demo get endpointslice -l kubernetes.io/service-name=web -o wide
# 3. 从调用方 Pod 测 DNS、端口和 HTTP
kubectl -n demo exec client -- nslookup web
kubectl -n demo exec client -- wget -S -O- http://web:80/readyz
# 4. 查看策略、路由对象与事件
kubectl -n demo get networkpolicy
kubectl -n demo describe ingress web
kubectl -n demo get httproute web -o yaml按“应用监听 → Pod IP → EndpointSlice → Service → Ingress/Gateway/LB → 外部 DNS”逐层测试,不要一开始就重启 CNI。
生产网络清单
- Pod、Service、节点和 LB 地址段不重叠,容量有告警。
- CNI、kube-proxy/替代数据面、CoreDNS 多副本跨故障域。
- 命名空间默认拒绝并显式放行,策略有自动化连通性测试。
- 入站和出站均有明确边界、证书、超时、重试和限流。
- 避免应用层与网关层重试叠加造成重试风暴。
- DNS、conntrack、丢包、延迟、EndpointSlice 和 LB 健康有监控。
- Controller/CRD 升级与 Kubernetes 升级分开评估兼容性。
补充:端口与会话亲和性
来源:jekyall_blog 的 Kubernetes Services 笔记(2023-11-24);重复的类型、选择器和排障说明已合并到上文。
NodePort 的常见默认范围是 30000–32767,实际范围由集群配置决定。端口冲突应检查具体的 NodePort 分配或外部监听入口;不能据此要求不同 ClusterIP Service 使用互不重复的 port。
Service 可以配置会话亲和性,使同一客户端尽量落到相同后端。它不能代替应用的会话存储,也不能保证 Pod 重建后仍是原实例。排查无流量时,依次核对 selector、Ready、targetPort、网络策略和入口类型,清单先通过 dry-run 验证。
继续阅读
- 命令
- 故障排查
- 故障排查