1. 为什么需要从Flannel迁移到Calico很多刚开始接触Kubernetes的同学都会选择Flannel作为默认网络插件因为它简单易用开箱即用。我在早期搭建测试环境时也经常用Flannel毕竟一条kubectl apply -f kube-flannel.yml命令就能搞定整个集群的网络连通。但随着业务规模扩大特别是需要实现多租户隔离时Flannel的局限性就逐渐暴露出来了。Flannel最大的问题是缺乏细粒度的网络策略控制。它就像小区里的公共走廊所有住户Pod都可以自由串门。这在生产环境是极其危险的想象一下你的数据库Pod可以被任意业务Pod访问甚至被恶意攻击者利用漏洞入侵。我曾经就遇到过因为Flannel默认全通策略导致的数据库被误删事故从那以后就开始研究更安全的网络方案。Calico则像给每个房间装了智能门锁你可以精确控制谁能进谁不能进。它通过Linux内核的iptables/ebtables实现网络策略性能损耗几乎可以忽略不计。实测下来在相同硬件环境下Calico的网络延迟比Flannel低15%-20%这对于高频交易类应用非常关键。另一个重要区别是网络模型。Flannel使用Overlay网络默认VXLAN模式所有数据包都要经过封装/解封装而Calico默认是纯三层路由BGP模式就像快递直接按门牌号送货不需要额外包装。这带来的性能优势在大流量场景下尤为明显我们有个视频处理集群在切换到Calico后网络吞吐量直接提升了30%。2. 迁移前的准备工作2.1 环境检查与兼容性验证在动手迁移前建议先用kubectl get nodes -o wide检查所有节点状态确保没有NotReady节点。我遇到过因为节点磁盘压力导致网络插件安装失败的情况后来通过kubectl describe node发现是磁盘空间不足。关键检查项Kubernetes版本建议1.16节点操作系统Calico对内核版本有要求现有Pod的网络连接状态关键业务服务的Endpoint是否正常2.2 安全清理Flannel残留配置直接删除Flannel可能会导致网络中断正确的操作顺序应该是# 先删除DaemonSet kubectl delete -f kube-flannel.yml # 清理CNI配置所有节点执行 mv /etc/cni/net.d/10-flannel.conflist /tmp/ # 检查iptables规则可选 iptables-save | grep flannel特别注意如果有Pod正在使用Flannel创建的虚拟网卡强制删除可能导致这些Pod网络异常。建议在业务低峰期操作或者先通过kubectl drain排空节点。3. Calico的安装与核心配置3.1 两种部署模式详解从官网下载的calico.yaml默认使用IPIP模式这对新手最友好。但生产环境我更推荐BGP模式它需要额外的路由配置# 修改calico.yaml关键参数 - name: CALICO_IPV4POOL_IPIP value: Never # 禁用IPIP - name: CALICO_IPV4POOL_CIDR value: 10.244.0.0/16 # 需与kube-controller-manager的--cluster-cidr一致如果集群跨多个子网比如不同可用区还需要配置BGP对等cat EOF | kubectl apply -f - apiVersion: projectcalico.org/v3 kind: BGPPeer metadata: name: peer-to-route-reflector spec: nodeSelector: !has(i-am-route-reflector) peerSelector: has(i-am-route-reflector) EOF3.2 关键组件解析安装完成后用kubectl get pods -n kube-system会看到这些核心组件Felix每个节点上的守护进程负责配置路由和ACL规则。出问题时可以查看它的日志kubectl logs -n kube-system -l k8s-appcalico-node -c calico-nodeBIRDBGP路由守护进程。通过calicoctl node status可以查看路由分发状态# 需要先安装calicoctl curl -L https://github.com/projectcalico/calico/releases/download/v3.21.4/calicoctl-linux-amd64 -o calicoctl chmod x calicoctl ./calicoctl node statusTypha大规模集群中用于降低API Server负载的组件。当节点超过50个时建议启用。4. 网络策略实战进阶4.1 基础隔离禁止所有入站流量安全的第一原则是最小化开放权限。这个策略会阻止所有入站连接相当于给Pod上了默认锁apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: default-deny-all spec: podSelector: {} policyTypes: - Ingress应用后测试方法# 启动测试Pod kubectl run tester --imagealpine -- sleep 3600 # 尝试ping其他Pod应该失败 kubectl exec tester -- ping target-pod-ip4.2 精确控制基于标签的访问给前端Pod开放数据库访问权限的典型场景apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: allow-frontend-to-db spec: podSelector: matchLabels: app: mysql ingress: - from: - podSelector: matchLabels: tier: frontend ports: - protocol: TCP port: 3306常见踩坑点标签选择器是AND逻辑。如果Pod有多个标签必须在matchLabels中全部指定才能匹配。4.3 跨命名空间隔离财务系统的Namespace需要特殊保护apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: deny-cross-ns namespace: finance spec: podSelector: {} ingress: - from: - namespaceSelector: matchLabels: role: trusted配合Namespace标签使用kubectl label ns finance roletrusted4.4 出口流量控制防止数据泄露的重要策略apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: restrict-egress spec: podSelector: matchLabels: sensitive: true egress: - to: - ipBlock: cidr: 10.244.0.0/16 # 只允许访问集群内IP - ports: - protocol: UDP port: 53 # 放行DNS5. 生产环境调优经验5.1 性能优化参数在calico-node的DaemonSet中添加这些环境变量env: - name: FELIX_IPTABLESREFRESHINTERVAL value: 60s # 降低iptables刷新频率 - name: FELIX_IPV6SUPPORT value: false # 禁用IPv6减少规则数量 - name: FELIX_LOGSEVERITYSCREEN value: error # 减少日志量5.2 监控与排错推荐使用这些Prometheus指标felix_active_local_endpoints节点上健康的Pod数量felix_ipset_calls规则更新频率bgp_session_upBGP会话状态关键日志分析命令# 查看拒绝的连接 kubectl logs -n kube-system -l k8s-appcalico-node | grep Dropped packet5.3 高可用部署对于关键业务集群建议部署Route Reflectorkubectl label node k8s-master-1 i-am-route-reflectortrue calicoctl patch node k8s-master-1 -p {spec:{routeReflectorClusterID:224.0.0.1}}6. 迁移后的验证清单基础连通性测试kubectl run test-nginx --imagenginx kubectl run test-client --imagebusybox --command -- /bin/sh -c while true; do wget -q -O- http://test-nginx; sleep 1; done网络策略生效验证# 应该被拒绝 kubectl exec test-client -- ping db-pod-ip # 应该成功 kubectl exec test-client -- wget -q -O- http://frontend-service性能基准测试# 安装qperf工具 kubectl run qperf-server --imagearjanschaaf/qperf kubectl run qperf-client --imagearjanschaaf/qperf --command -- /bin/sh -c sleep 10; qperf server-ip tcp_bw tcp_lat迁移完成后建议持续监控网络延迟和丢包率至少24小时。我们曾经遇到过BGP路由收敛慢导致的间歇性连接问题后来通过调整BGP_KEEPALIVETIME参数解决。