嘿,我是Agnes。今天咱们不聊枯燥的文档,而是像老朋友聊天一样,深入探讨Kubernetes中那个让无数新手(甚至老手)头疼的问题:为什么我的Pod之间明明在同一集群里,却连不上?
很多人以为K8s装完网络就通了,其实不然。网络隔离的误区、CNI插件的选择、底层Linux网桥的工作原理,这三者环环相扣。我将用通俗的语言,结合代码和比喻,带你彻底搞懂这些概念。
一、网络隔离的误区:你以为的“隔离”和真正的“隔离”
误区1:不同Namespace就不通
这是最常见的误解。很多开发者认为,只要把服务放在不同的Namespace里,它们就天然隔离了。
事实是: Kubernetes的默认网络模型是所有Pod都在同一个扁平的网络中,无论它们属于哪个Namespace。Namespace是资源管理(如RBAC、配额)的逻辑隔离,不是网络隔离。
# 创建两个不同Namespace的Pod
kubectl run nginx -n dev --image=nginx
kubectl run redis -n prod --image=redis
# 在nginx Pod里访问redis
kubectl exec -n dev nginx -- wget -qO- redis-svc.prod.svc.cluster.local:6379
# 结果:默认情况下,这是通的!
要真正实现网络隔离,你需要使用NetworkPolicy。
误区2:有NetworkPolicy就绝对安全
NetworkPolicy确实能控制流量,但它的行为取决于你使用的CNI插件。有些CNI插件不完全支持NetworkPolicy,或者只支持特定的规则语法。
# 一个典型的NetworkPolicy示例
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-all
namespace: prod
spec:
podSelector: {}
policyTypes:
- Ingress
# 不指定ingress规则,意味着拒绝所有入站流量
关键点: 如果CNI插件不支持NetworkPolicy,这个YAML文件会被忽略,不会报错,但也不会生效。这是另一个大坑!
误区3:NodePort/LoadBalancer服务在集群内也能访问
NodePort和LoadBalancer是用于集群外部访问服务的。在集群内部,应该使用ClusterIP。虽然很多CNI实现允许在集群内访问NodePort,但这不是标准行为,且依赖具体配置。
二、Linux网桥原理:K8s网络的底层基石
要理解CNI插件,必须先理解Linux网桥(Linux Bridge)。你可以把网桥想象成一个软件交换机。
网桥的工作原理
当数据包进入一个网桥端口时,网桥会检查目标MAC地址:
- 如果知道目标在哪个端口,直接转发到那个端口。
- 如果不知道,向所有其他端口广播(泛洪)。
- 如果目标就是自己,交给上层协议处理。
在Kubernetes中,每个Pod都会被连接到一个虚拟以太网对(veth pair)的一端,另一端连接到网桥(通常是cni0或br0)。
# 查看网桥信息
ip link show cni0
# 输出类似:
# 3: cni0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue state UP
# link/ether 0a:58:0a:81:01:01 brd ff:ff:ff:ff:ff:ff
# 查看网桥上的端口
bridge link show cni0
Pod的网络命名空间
每个Pod都有自己的网络命名空间(network namespace),这是一个独立的网络栈。Pod内的eth0接口通过veth pair与宿主机的网桥相连。
# 进入Pod的网络命名空间
nsenter -t $(pidof pause) -n ip addr
# 你会看到Pod内部有一个eth0接口,IP地址是10.244.1.2(举例)
比喻时间: 把Kubernetes集群想象成一栋公寓楼:
- 网桥(Bridge) = 楼里的走廊,所有房间(Pod)都通向这里。
- veth pair = 每个房间的門,连接房间内部和走廊。
- 网络命名空间 = 每个房间的内部空间,互不相通,除非通过門(veth)和走廊(网桥)。
- CNI插件 = 物业管理系统,负责安装門、维护走廊、制定出入规则(NetworkPolicy)。
三、三大主流CNI方案深度对比
现在,让我们看看最流行的三个CNI插件:Flannel、Calico和Weave。我将从架构、性能、功能、易用性等多个维度进行对比。
1. Flannel:简单至上
核心架构: Flannel是最早流行的CNI插件之一,设计理念是“简单有效”。它主要有两种模式:
- vxlan模式(默认): 在UDP包中封装K8s网络数据包,通过VXLAN隧道实现跨主机通信。
- host-gw模式: 利用宿主机的默认路由,直接将数据包发送给目标主机,性能更高,但要求所有节点在同一二层网络。
优点:
- 部署极其简单,一条命令搞定。
- 资源消耗低,适合小型集群。
- 支持NetworkPolicy(有限支持)。
缺点:
- 性能开销:VXLAN模式需要在每个数据包上加/解封装UDP头部,增加CPU和延迟。
- 功能有限:不支持细粒度的NetworkPolicy,调试困难。
- 不适合大规模集群。
代码示例:安装Flannel
kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
性能数据(参考):
- 吞吐量:约1-2 Gbps(取决于节点硬件)
- 延迟:VXLAN模式下增加约10-20%
2. Calico:企业级首选
核心架构: Calico基于BGP(边界网关协议)实现Pod IP的路由分发。每个节点运行一个BIRD守护进程,负责学习其他节点的Pod子网信息,并通过BGP会话交换路由表。
优点:
- 高性能:基于Iptables或eBPF实现数据平面,无封装开销(除非启用加密)。
- 强大的NetworkPolicy:支持L3/L4策略,可以基于IP、端口、协议进行细粒度控制。
- 可扩展性:支持数千个节点和数万个Pod。
- 透明调试:Pod IP是真实的路由可达IP,便于网络诊断。
缺点:
- 部署较复杂,需要配置BGP路由。
- 资源消耗较高(每个节点需要运行BIRD进程)。
- 对网络环境有要求(节点间需要BGP端口可达)。
代码示例:安装Calico
kubectl create -f https://raw.githubusercontent.com/projectcalico/calico/v3.26.1/manifests/tigera-operator.yaml
# 创建自定义资源配置
cat <<EOF | kubectl apply -f -
apiVersion: operator.tigera.io/v1
kind: Installation
metadata:
name: default
spec:
calicoNetwork:
bgp: Disabled # 禁用BGP,使用IPIP封装
ipPools:
- blockSize: 24
cidr: 10.244.0.0/16
encapsulation: IPIP
natOutgoing: Enabled
nodeSelector: all()
EOF
NetworkPolicy示例(Calico专属):
apiVersion: projectcalico.org/v3
kind: NetworkPolicy
metadata:
name: allow-redis
namespace: prod
spec:
selector: app == 'redis'
types:
- Ingress
ingress:
- action: Allow
protocol: TCP
source:
selector: app == 'nginx'
destination:
ports: [6379]
性能数据(参考):
- 吞吐量:可达10+ Gbps
- 延迟:接近裸机性能,仅增加约5%
3. Weave:跨云友好
核心架构: Weave使用一种独特的分布式网络协议,通过加密的TCP连接建立Overlay网络。它特别强调跨云和混合云场景的支持。
优点:
- 跨云支持好:天然支持跨AWS、Azure、GCP等云服务商的Pod通信。
- 加密:默认启用mTLS加密,数据平面安全。
- 简单易用:一键安装,自动发现对端节点。
缺点:
- 性能较差:每个数据包都需要加密/解密,CPU开销大。
- 吞吐量低:不适合高性能要求的场景。
- 社区活跃度下降:近年来更新缓慢,官方支持减弱。
代码示例:安装Weave
kubectl apply -f "https://cloud.weave.works/k8s/net?k8s-version=$(kubectl version | base64 | tr -d '\n')"
性能数据(参考):
- 吞吐量:约500 Mbps - 1 Gbps
- 延迟:高,加密开销显著
对比总结表
| 特性 | Flannel | Calico | Weave |
|---|---|---|---|
| 架构 | VXLAN/Host-GW | BGP/IPTABLES/eBPF | Overlay/TCP |
| 性能 | 中等 | 高 | 低 |
| NetworkPolicy | 有限支持 | 完整支持 | 支持 |
| 跨云支持 | 弱 | 中 | 强 |
| 加密 | 无 | 可选 | 默认启用 |
| 部署复杂度 | 低 | 中 | 低 |
| 适用场景 | 小型集群、测试环境 | 生产环境、大规模集群 | 跨云、混合云 |
四、如何选择CNI插件?实战建议
场景1:开发测试环境,集群规模小于10个节点
推荐:Flannel
- 理由:部署简单,资源占用低,足够满足测试需求。
- 配置建议:使用host-gw模式,如果节点不在同一二层网络,再用VXLAN。
# Flannel host-gw模式配置
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: ConfigMap
metadata:
name: flannel-config
namespace: kube-system
data:
cni-conf.json: |
{
"name": "cbr0",
"plugins": [
{
"type": "flannel",
"delegate": {
"hairpinMode": true,
"isDefaultGateway": true
}
},
{
"type": "portmap",
"capabilities": {
"portMappings": true
}
}
]
}
net-conf.json: |
{
"Network": "10.244.0.0/16",
"Backend": {
"Type": "host-gw"
}
}
EOF
场景2:生产环境,规模中等(10-100节点),需要网络隔离
推荐:Calico
- 理由:高性能、完善的NetworkPolicy支持、良好的可扩展性。
- 配置建议:启用eBPF数据平面以获得最佳性能。
# Calico eBPF模式配置
spec:
calicoNetwork:
bgp: Disabled
nodeToNodeMeshEnabled: false
ipPools:
- blockSize: 26
cidr: 10.244.0.0/16
encapsulation: None
natOutgoing: Enabled
nodeSelector: all()
kubernetesProvider: GKE # 或其他云提供商
cni:
type: calico
ipam:
type: calico
bpf:
enabled: true # 启用eBPF
场景3:跨云或混合云部署
推荐:Calico或Weave
- 理由:两者都支持跨云,但Calico性能更好。
- 配置建议:如果性能不是首要考虑,Weave的自动加密可能更省心。
# Weave跨云配置示例(需要在每个云环境安装)
# AWS
kubectl apply -f "https://cloud.weave.works/k8s/net?k8s-version=$(kubectl version | base64 | tr -d '\n')&env.WEAVE_PASSWORD=yourpassword"
# Azure
# 同样命令,但需要配置端点发现
env WEAVE_HTTPS_ENDPOINT=https://weave-cloud-controller:443 kubectl apply -f ...
五、调试网络问题的实用技巧
无论选择哪个CNI,你都可能遇到网络问题。以下是一些实用的调试步骤:
1. 检查Pod网络状态
# 查看Pod的IP地址
kubectl get pods -o wide
# 进入Pod检查网络配置
kubectl exec -it <pod-name> -- ip addr
kubectl exec -it <pod-name> -- ip route
kubectl exec -it <pod-name> -- ping <other-pod-ip>
2. 检查节点网络配置
# 查看网桥和veth接口
ip link show
bridge link show
# 查看路由表
ip route
3. 检查CNI插件状态
# 查看CNI Pod日志
kubectl logs -n kube-system <cni-pod-name>
# 查看CNI配置
cat /etc/cni/net.d/10-calico.conflist
4. 使用tcpdump抓包分析
# 在节点上抓包
tcpdump -i cni0 -nn
# 在Pod内抓包
kubectl exec -it <pod-name> -- tcpdump -i eth0 -nn
5. 检查NetworkPolicy
# 查看NetworkPolicy
kubectl get networkpolicy -A
# 查看Calico策略(如果使用Calico)
calicoctl get policy -o yaml
六、常见网络问题及解决方案
问题1:Pod无法跨节点通信
原因: CNI插件配置错误,或节点间网络不通。 解决:
# 检查节点间Ping
ping <node-ip>
# 检查CNI插件日志
kubectl logs -n kube-system -l k8s-app=calico-node # 或flannel/weave
# 检查BGP会话(Calico)
birdc show protocol all
问题2:Pod可以Ping通IP,但无法访问服务
原因: CoreDNS问题,或NetworkPolicy阻止了流量。 解决:
# 检查DNS解析
kubectl run test --rm -it --image=busybox -- nslookup kubernetes.default
# 检查CoreDNS Pod
kubectl get pods -n kube-system -l k8s-app=kube-dns
kubectl logs -n kube-system <coredns-pod>
# 检查NetworkPolicy
kubectl get networkpolicy -A
问题3:网络策略不生效
原因: CNI插件不支持NetworkPolicy,或策略配置错误。 解决:
# 检查CNI插件是否支持NetworkPolicy
kubectl get pods -n kube-system -l k8s-app=calico-node
# 或
kubectl get pods -n kube-system -l k8s-app=flannel
# 验证NetworkPolicy
kubectl describe networkpolicy <policy-name> -n <namespace>
结语:没有最好的CNI,只有最合适的
Kubernetes的网络模型看似简单,实则复杂。从Linux网桥到CNI插件,每一个环节都可能成为瓶颈。Flannel、Calico、Weave各有优劣,选择时需要考虑集群规模、性能要求、网络隔离需求、跨云支持等因素。
记住:网络问题是Kubernetes中最容易踩坑的地方之一。在部署前,务必充分测试网络连通性,合理规划IP地址空间,配置适当的NetworkPolicy。希望这篇文章能帮助你更好地理解Kubernetes网络,避免常见的误区。
如果你还有具体问题,欢迎在评论区留言,我会尽力解答。毕竟,学习Kubernetes就像解谜,每一步都充满挑战,但也充满乐趣!
