Kubernetes 网络模型详解
Kubernetes 网络模型详解
Kubernetes 网络原则
Kubernetes 网络模型遵循以下核心原则:
- 每个 Pod 有唯一的 IP 地址
- 所有 Pod 可以直接通信,无需 NAT
- 节点上的 Agent 可以与该节点上所有 Pod 通信
- Pod 看到的自身 IP 与其他 Pod 看到的一致
网络通信类型
Pod 间通信
同一节点上的 Pod 通信:
# 查看 Pod IP
kubectl get pods -o wide
# 进入 Pod 测试连通性
kubectl exec -it <pod-name> -- ping <other-pod-ip>
跨节点 Pod 通信:
Node A Node B
┌─────────────┐ ┌─────────────┐
│ Pod A │ │ Pod B │
│ 10.244.0.5 │◄──────────────►│ 10.244.1.8 │
└─────────────┘ └─────────────┘
│ │
└──────────────────────────────┘
物理网络
Pod 与 Service 通信
# 通过 ClusterIP 访问
kubectl exec -it <pod-name> -- curl http://my-service
# 通过 DNS 访问
kubectl exec -it <pod-name> -- curl http://my-service.default.svc.cluster.local
外部与 Service 通信
# NodePort
curl http://<node-ip>:<node-port>
# LoadBalancer
curl http://<external-ip>
# Ingress
curl -H "Host: myapp.example.com" http://<ingress-ip>
CNI 插件
常见 CNI 插件
# 查看已安装的 CNI 插件
kubectl get pods -n kube-system | grep cni
# 常见 CNI 插件
# - Calico: 支持网络策略,性能优秀
# - Flannel: 简单易用,适合小规模集群
# - Cilium: 基于 eBPF,功能强大
# - Weave: 支持加密通信
Calico 配置示例
apiVersion: projectcalico.org/v3
kind: NetworkPolicy
metadata:
name: allow-ssh
namespace: default
spec:
selector: role == 'ssh-server'
ingress:
- action: Allow
protocol: TCP
source:
selector: role == 'ssh-client'
destination:
ports:
- 22
网络策略
基本 NetworkPolicy
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-ingress
namespace: default
spec:
podSelector: {}
policyTypes:
- Ingress
允许特定流量
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-web
spec:
podSelector:
matchLabels:
app: web
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
app: api
ports:
- protocol: TCP
port: 8080
禁止所有出口流量
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-egress
spec:
podSelector: {}
policyTypes:
- Egress
网络诊断
检查 Pod 网络
# 查看 Pod IP 和网络命名空间
kubectl exec -it <pod-name> -- ip addr
# 查看路由
kubectl exec -it <pod-name> -- ip route
# 测试 DNS 解析
kubectl exec -it <pod-name> -- nslookup kubernetes
# 测试网络连通性
kubectl exec -it <pod-name> -- curl -s http://kubernetes
检查 Service 网络
# 查看 Service Endpoints
kubectl get endpoints my-service
# 查看 kube-proxy 规则
kubectl exec -it <kube-proxy-pod> -- iptables -t nat -L
网络调试工具
# 部署网络调试 Pod
kubectl run netshoot --image=nicolaka/netshoot --rm -it -- /bin/bash
# 在 netshoot 中测试
ping <pod-ip>
curl http://my-service:80
nslookup my-service
实践案例
部署带网络策略的应用
# 部署 Web 应用
apiVersion: apps/v1
kind: Deployment
metadata:
name: web
spec:
replicas: 3
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
spec:
containers:
- name: web
image: nginx
ports:
- containerPort: 80
---
# 创建 Service
apiVersion: v1
kind: Service
metadata:
name: web-service
spec:
selector:
app: web
ports:
- port: 80
---
# 创建 NetworkPolicy
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: web-policy
spec:
podSelector:
matchLabels:
app: web
policyTypes:
- Ingress
- Egress
ingress:
- from:
- podSelector:
matchLabels:
app: api
egress:
- to:
- podSelector:
matchLabels:
app: database
常见问题
Pod 无法访问 Service
# 检查 Service Endpoints
kubectl get endpoints my-service
# 检查 DNS 解析
kubectl exec -it <pod-name> -- nslookup my-service
# 检查网络策略
kubectl get networkpolicy
跨节点 Pod 无法通信
# 检查 CNI 插件状态
kubectl get pods -n kube-system
# 检查节点网络
kubectl exec -it <pod-name> -- ping <other-node-ip>
最佳实践
- 使用 NetworkPolicy 限制 Pod 间通信
- 合理规划 Pod 网络 CIDR
- 选择适合的 CNI 插件
- 定期监控网络性能
- 使用网络调试工具排查问题
总结
Kubernetes 网络模型提供了灵活的网络通信机制。理解 Pod 间通信、Service 网络和网络策略是部署和管理 Kubernetes 集群的基础。