主题
第一部分 K8s 网络进阶
网络是 Kubernetes 中最复杂的部分之一。本部分深入讲解 CNI 原理、Service 实现细节、CoreDNS 机制、Ingress 控制器和网络策略。
第 1 章 Kubernetes 网络模型与 CNI 原理
1.1 K8s 网络模型要求
K8s 网络模型要求:
- 所有 Pod 可以直接通信,无需 NAT
- 节点上的 Agent 可以与所有 Pod 通信
- Pod 看到的自己的 IP 与其他 Pod 看到的一致
这意味着 Pod IP 必须是可路由的,或者通过 Overlay 网络实现逻辑直连。
1.2 CNI 简介
CNI(Container Network Interface)是容器网络接口标准,定义了容器如何获取网络配置。
CNI 工作流程:
容器运行时(containerd/CRI-O)
|
v
调用 CNI 插件(如 bridge、calico、cilium)
|
v
创建 veth pair,分配 IP,设置路由1.3 常见 CNI 对比
| CNI | 特点 | 适用场景 |
|---|---|---|
| Flannel | 简单,使用 VXLAN 或 host-gw | 中小型集群 |
| Calico | 支持 BGP、NetworkPolicy、WireGuard | 中大型集群,需要网络策略 |
| Cilium | 基于 eBPF,高性能,可观测性强 | 大规模集群,安全要求高 |
| Weave | 易用,自动发现 | 小型集群 |
| Antrea | VMware 出品,基于 OVS | 与 NSX-T 集成 |
1.4 Calico 网络模式
Calico 支持三种数据面:
| 模式 | 说明 |
|---|---|
| BGP | 与物理网络交换路由,Pod IP 可直接路由 |
| VXLAN | Overlay 网络,无需底层网络支持 |
| WireGuard | 加密 Overlay |
bash
# 查看 Calico 节点状态
kubectl get nodes -o wide
kubectl get pods -n calico-system -o wide
# 查看 BGP 对等体
kubectl exec -it calico-node-xxx -n calico-system -- calicoctl node status1.5 Cilium 与 eBPF
Cilium 使用 eBPF 替代 iptables 实现网络、安全和可观测性。
优势:
- 高性能(绕过 netfilter)
- 强大的安全策略(L3/L4/L7)
- 内置 Hubble 可观测性
- 支持 WireGuard 加密
bash
# 安装 Cilium
helm install cilium cilium/cilium --namespace kube-system
# 查看 Cilium 状态
cilium status1.6 本章实验
实验 1-1:查看 Pod 网络命名空间
bash
# 找到 Pod 所在节点和容器 ID
kubectl get pod <POD> -o wide
kubectl describe pod <POD> | grep -i "Container ID"
# 在节点上查看网络命名空间
ls /var/run/netns/
# 使用 nsenter 进入 Pod 网络命名空间
nsenter -t <PID> -n ip addr1.7 本章练习
- 解释 K8s 网络模型的三个要求。
- 比较 Flannel、Calico、Cilium 的优缺点。
- 在实验集群中部署 Calico 或 Cilium。
- 查看一个 Pod 的 veth pair 和路由表。
第 2 章 Service 实现原理深度解析
2.1 Service 的本质
Service 不是真实存在的网络实体,而是一组 iptables/ipvs/eBPF 规则的集合。
2.2 ClusterIP 的 IP 分配
ClusterIP 从 --service-cluster-ip-range 指定的 CIDR 中分配。
bash
# 查看 API Server 配置
ps aux | grep kube-apiserver | grep service-cluster-ip-range
# --service-cluster-ip-range=10.96.0.0/122.3 kube-proxy 的三种模式
| 模式 | 实现 | 特点 |
|---|---|---|
| userspace | kube-proxy 作为用户态代理 | 已废弃 |
| iptables | 使用 iptables DNAT | 稳定,适合中小规模 |
| ipvs | 使用 IPVS | 高性能,适合大规模 |
2.4 iptables 模式详解
访问 ClusterIP 时的数据流:
Pod A (10.244.1.2) -> Service nginx (10.96.123.45:80)
|
v
iptables KUBE-SERVICES 链
|
v
KUBE-SVC-XXX 链(Service 链)
|
v
KUBE-SEP-XXX 链(Endpoint 链)
|
v
DNAT 到 Pod IP: 10.244.2.5:80查看规则:
bash
# 查看 Service 规则
iptables -t nat -L KUBE-SERVICES | grep nginx
# 查看 Endpoint 规则
iptables -t nat -L KUBE-SVC-XXX2.5 ipvs 模式详解
bash
# 查看 ipvs 规则
ipvsadm -Ln
# 输出示例
# TCP 10.96.123.45:80 rr
# -> 10.244.1.5:80 Masq 1 0 0
# -> 10.244.2.7:80 Masq 1 0 0ipvs 支持算法:
- rr:轮询
- lc:最少连接
- dh:目标地址哈希
- sh:源地址哈希
- sed:最短预期延迟
- nq:永不排队
2.6 无头服务(Headless Service)
Headless Service 不分配 ClusterIP,DNS 直接返回后端 Pod IP。
yaml
apiVersion: v1
kind: Service
metadata:
name: nginx-headless
spec:
selector:
app: nginx
clusterIP: None
ports:
- port: 80DNS 解析结果:
bash
nslookup nginx-headless
# 返回所有 Pod IP:10.244.1.5, 10.244.2.7适用于:
- StatefulSet 的服务发现
- 客户端负载均衡
- 需要直接访问 Pod 的场景
2.7 Service 的会话亲和性
yaml
spec:
sessionAffinity: ClientIP
sessionAffinityConfig:
clientIP:
timeoutSeconds: 108002.8 本章实验
实验 2-1:追踪 Service 流量路径
bash
# 1. 创建 Deployment 和 Service
kubectl create deployment nginx --image=nginx:1.25 --replicas=2
kubectl expose deployment nginx --port=80 --target-port=80
# 2. 查看 Service ClusterIP
kubectl get svc nginx
# 3. 查看 Endpoints
kubectl get endpoints nginx
# 4. 切换到 ipvs 模式(如果当前是 iptables)
kubectl edit configmap kube-proxy -n kube-system
# 修改 mode: "ipvs"
kubectl rollout restart daemonset kube-proxy -n kube-system
# 5. 查看 ipvs 规则
ipvsadm -Ln | grep nginx
# 6. 从 Pod 内多次访问 Service,观察流量分发
kubectl run test --image=busybox:1.36 -it --rm --restart=Never -- sh
for i in $(seq 1 10); do wget -qO- http://nginx; done2.9 本章练习
- 解释 iptables 模式和 ipvs 模式的区别。
- 查看你集群中 kube-proxy 的工作模式。
- 创建一个 Headless Service 并观察 DNS 解析结果。
- 配置 Service 的会话亲和性并测试。
第 3 章 CoreDNS 与 K8s DNS
3.1 K8s DNS 架构
Pod 发起 DNS 查询
|
v
/etc/resolv.conf 中的 nameserver: 10.96.0.10
|
v
CoreDNS Service (kube-dns)
|
v
CoreDNS Pod 处理查询
|
v
返回 Service/Pod IP 或转发到上游 DNS3.2 CoreDNS 配置
yaml
# CoreDNS ConfigMap
apiVersion: v1
kind: ConfigMap
metadata:
name: coredns
namespace: kube-system
data:
Corefile: |
.:53 {
errors
health {
lameduck 5s
}
ready
kubernetes cluster.local in-addr.arpa ip6.arpa {
pods insecure
fallthrough in-addr.arpa ip6.arpa
ttl 30
}
prometheus :9153
forward . /etc/resolv.conf
cache 30
loop
reload
loadbalance
}3.3 DNS 解析规则
| 名称 | 解析结果 |
|---|---|
service | 同命名空间 Service 的 ClusterIP |
service.namespace | 其他命名空间 Service 的 ClusterIP |
service.namespace.svc.cluster.local | FQDN 解析 |
pod-ip.namespace.pod.cluster.local | Pod IP |
3.4 CoreDNS 性能调优
- 增加 CoreDNS 副本数
- 使用 NodeLocal DNSCache
- 调整缓存 TTL
- 优化上游 DNS
bash
# 部署 NodeLocal DNSCache
kubectl apply -f https://raw.githubusercontent.com/kubernetes/kubernetes/master/cluster/addons/dns/nodelocaldns/nodelocaldns.yaml3.5 常见 DNS 问题排查
bash
# 测试 DNS
kubectl run -it --rm debug --image=busybox:1.36 -- nslookup kubernetes.default
# 查看 CoreDNS 日志
kubectl logs -n kube-system -l k8s-app=kube-dns
# 查看 /etc/resolv.conf
kubectl run -it --rm debug --image=busybox:1.36 -- cat /etc/resolv.conf3.6 本章练习
- 查看 CoreDNS 的 ConfigMap 配置。
- 测试不同格式的 Service DNS 解析。
- 部署 NodeLocal DNSCache 并观察效果。
- 模拟一个 DNS 解析失败场景并排查。
第 4 章 Ingress 控制器深度解析
4.1 Ingress 控制器种类
| 控制器 | 特点 |
|---|---|
| NGINX Ingress Controller | 最常用,功能全面 |
| Traefik | 云原生,动态配置 |
| HAProxy Ingress | 高性能 |
| Kong | API 网关能力 |
| Istio Ingress Gateway | 服务网格集成 |
| Emissary | 基于 Envoy |
4.2 NGINX Ingress Controller 架构
外部流量
|
v
LoadBalancer/NodePort Service
|
v
NGINX Ingress Controller Pod
|
v
根据 Ingress 规则路由到后端 Service
|
v
后端 Pod4.3 Ingress 高级配置
yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: app-ingress
annotations:
nginx.ingress.kubernetes.io/ssl-redirect: "true"
nginx.ingress.kubernetes.io/proxy-body-size: "50m"
nginx.ingress.kubernetes.io/rate-limit: "100"
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
ingressClassName: nginx
tls:
- hosts:
- app.example.com
secretName: app-tls
rules:
- host: app.example.com
http:
paths:
- path: /api
pathType: Prefix
backend:
service:
name: api-service
port:
number: 80
- path: /
pathType: Prefix
backend:
service:
name: web-service
port:
number: 804.4 IngressClass
IngressClass 用于指定使用哪个 Ingress 控制器。
yaml
apiVersion: networking.k8s.io/v1
kind: IngressClass
metadata:
name: nginx
spec:
controller: k8s.io/ingress-nginx4.5 Gateway API
Gateway API 是 Ingress 的下一代标准,提供更强大的流量管理能力。
yaml
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: example-gateway
spec:
gatewayClassName: example-gateway-class
listeners:
- name: http
protocol: HTTP
port: 804.6 本章练习
- 部署 NGINX Ingress Controller。
- 配置基于路径和域名的路由规则。
- 配置 HTTPS 证书。
- 了解 Gateway API 与 Ingress 的区别。
第 5 章 网络策略(NetworkPolicy)实战
5.1 NetworkPolicy 基础
NetworkPolicy 用于控制 Pod 之间的网络流量。
默认行为:
- 没有 NetworkPolicy 时,所有 Pod 之间允许互通
- 一旦某个 Pod 被 NetworkPolicy 选中,只有策略允许的流量才能通过
5.2 默认拒绝策略
yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-all
namespace: production
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress5.3 允许特定流量
yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-frontend
spec:
podSelector:
matchLabels:
app: backend
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
app: frontend
ports:
- protocol: TCP
port: 80805.4 Cilium 的 L7 策略
Cilium 支持基于 HTTP/HTTP2/gRPC 的 L7 策略:
yaml
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
name: l7-policy
spec:
endpointSelector:
matchLabels:
app: backend
ingress:
- fromEndpoints:
- matchLabels:
app: frontend
toPorts:
- ports:
- port: "8080"
protocol: TCP
rules:
http:
- method: GET
path: "/api/.*"5.5 本章练习
- 在命名空间内实施默认拒绝策略。
- 只允许 frontend Pod 访问 backend Pod 的 8080 端口。
- 使用 Cilium 配置 HTTP 级别的访问控制。
- 测试策略是否生效。
第一部分总结
完成本阶段学习后,你应该能够:
- 理解 K8s 网络模型和 CNI 原理
- 对比不同 CNI 的实现和适用场景
- 深入理解 Service 的 iptables/ipvs 实现
- 排查 CoreDNS 和 DNS 问题
- 部署和配置 Ingress 控制器
- 使用 NetworkPolicy 实现网络隔离
进入第二部分:高级调度与资源管理。