1. 为什么选择Calico作为内网Kubernetes的CNI插件
去年我们团队需要在内网环境部署一套生产级Kubernetes集群,网络方案选型时经过多轮技术评估,最终选择了Calico。这个决定主要基于以下几个实际考量:
首先是性能需求。我们业务涉及大量微服务间通信,测试发现Flannel的VXLAN模式在吞吐量上无法满足要求。而Calico的纯三层路由方案,通过BGP协议直接路由Pod流量,避免了额外的封包解包开销。实测在相同硬件条件下,Calico的TCP吞吐量比Flannel高出约40%。
其次是网络策略的精细度。我们的安全合规要求必须实现Pod级别的访问控制。Calico内置的NetworkPolicy支持L3-L4层的规则,还能通过GlobalNetworkPolicy实现集群级策略。相比之下,Flannel需要额外安装插件才能支持基础策略功能。
最后是架构简洁性。在内网环境中,Calico不需要依赖etcd集群,可以直接使用Kubernetes的API Server作为数据存储。这大大降低了运维复杂度,也减少了潜在故障点。我们通过calico-node的DaemonSet部署模式,每个节点只需运行一个Pod就能完成所有网络功能。
关键提示:在内网环境中部署时,Calico的BGP模式需要关闭默认的Node-to-Node Mesh,改为通过Route Reflector集中管理路由。否则随着节点增加,全连接拓扑会导致路由同步效率急剧下降。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 内网环境下的特殊准备工作
2.1 离线镜像打包方案
由于目标环境是完全离线的内网,我们提前准备了以下Docker镜像(以Calico v3.24.1为例):
code复制docker pull calico/node:v3.24.1
docker pull calico/cni:v3.24.1
docker pull calico/kube-controllers:v3.24.1
docker pull calico/typha:v3.24.1
使用docker save命令打包后,通过内网仓库分发。这里有个细节需要注意:Calico的cni插件二进制文件需要手动拷贝到每个节点的/opt/cni/bin目录,我们编写了Ansible playbook自动完成这个步骤。
2.2 内核参数调优
Calico对Linux内核有特定要求,我们在内网节点上预先配置了以下参数:
bash复制# /etc/sysctl.d/10-calico.conf
net.ipv4.ip_forward = 1
net.ipv4.conf.all.rp_filter = 0
net.ipv4.conf.default.rp_filter = 0
这些配置必须在部署前生效,否则Pod网络会出现异常。我们遇到过一个典型案例:某节点Pod间通信时断时续,排查发现是rp_filter参数未正确设置导致的反向路径校验失败。
2.3 证书信任链处理
内网CA签发的证书需要被Calico组件信任。我们修改了calico-node的DaemonSet配置,在initContainer中添加证书注入逻辑:
yaml复制initContainers:
- name: install-ca-cert
image: busybox
command: ["sh", "-c", "cp /etc/ssl/certs/internal-ca.crt /usr/local/share/ca-certificates/ && update-ca-certificates"]
volumeMounts:
- mountPath: /etc/ssl/certs/internal-ca.crt
name: ssl-certs
subPath: internal-ca.crt
3. 集群部署实战记录
3.1 管理节点初始化
我们使用kubeadm初始化第一个管理节点:
bash复制kubeadm init --pod-network-cidr=192.168.0.0/16 \
--apiserver-advertise-address=10.1.1.100 \
--control-plane-endpoint=cluster-control.internal
关键参数解析:
pod-network-cidr必须与后续Calico配置的IP池范围一致apiserver-advertise-address指定内网管理IPcontrol-plane-endpoint指向内部DNS记录
初始化完成后,遇到第一个坑:kube-proxy默认使用iptables模式,与Calico的felix组件在某些内核版本上存在竞争。解决方案是在kubeadm-config中显式指定ipvs模式:
yaml复制apiVersion: kubeadm.k8s.io/v1beta3
kind: ClusterConfiguration
networking:
podSubnet: "192.168.0.0/16"
---
apiVersion: kubeproxy.config.k8s.io/v1alpha1
kind: KubeProxyConfiguration
mode: "ipvs"
3.2 Calico定制化安装
标准安装方式是从官网下载manifest直接应用:
bash复制kubectl apply -f https://docs.projectcalico.org/manifests/calico.yaml
但在内网环境需要做多处调整:
- 修改IP池配置(calico.yaml中搜索IP_AUTODETECTION_METHOD):
yaml复制- name: IP_AUTODETECTION_METHOD
value: "interface=eth.*"
- 关闭Node-to-Node Mesh:
yaml复制- name: CALICO_IPV4POOL_IPIP
value: "Never"
- name: CALICO_ROUTER_ID
value: "hash"
- 配置内网镜像地址:
yaml复制containers:
- name: calico-node
image: registry.internal/calico/node:v3.24.1
3.3 工作节点加入集群
工作节点加入时需要特别注意两点:
- 必须确保
/var/lib/kubelet目录干净,特别是之前部署过其他CNI插件时:
bash复制rm -rf /var/lib/kubelet/*
- 加入命令需要添加
--ignore-preflight-errors=NumCPU参数,因为我们的测试环境worker节点只有2核:
bash复制kubeadm join cluster-control.internal:6443 \
--token xxxx \
--discovery-token-ca-cert-hash sha256:xxxx \
--ignore-preflight-errors=NumCPU
4. 网络连通性验证与排错
4.1 基础测试方案
部署完成后,我们通过以下步骤验证网络功能:
- 创建测试Pod:
bash复制kubectl run test-nginx --image=registry.internal/nginx:alpine
- 检查IP分配:
bash复制kubectl get pod test-nginx -o wide
# 确认分配的IP在192.168.0.0/16范围内
- 跨节点通信测试:
bash复制kubectl exec test-nginx -- ping 192.168.1.5
4.2 典型问题排查记录
案例1:Pod无法跨节点通信
现象:同一节点Pod互通正常,跨节点不通
排查步骤:
- 检查calico-node日志发现BGP连接失败
- 确认节点间6443端口未开放
- 解决方案:修改Calico配置使用IPIP模式作为过渡
yaml复制- name: CALICO_IPV4POOL_IPIP
value: "Always"
案例2:DNS解析异常
现象:Pod内无法解析Service名称
根本原因:CoreDNS Pod被错误网络策略隔离
修复方法:创建基线网络策略允许DNS流量:
yaml复制apiVersion: projectcalico.org/v3
kind: GlobalNetworkPolicy
metadata:
name: allow-dns
spec:
selector: all()
egress:
- action: Allow
protocol: UDP
destination:
ports: [53]
5. 生产级优化实践
5.1 启用Typha提高扩展性
当集群规模超过50节点时,建议部署Typha作为Calico的数据平面代理。我们的配置方案:
yaml复制apiVersion: apps/v1
kind: Deployment
metadata:
name: calico-typha
spec:
replicas: 3
template:
spec:
containers:
- name: calico-typha
resources:
limits:
memory: "500Mi"
requests:
cpu: "250m"
memory: "100Mi"
5.2 BGP路由优化
与内网核心交换机建立BGP Peer:
yaml复制apiVersion: projectcalico.org/v3
kind: BGPPeer
metadata:
name: peer-to-core-switch
spec:
peerIP: 10.1.0.1
asNumber: 64512
5.3 网络策略最佳实践
我们采用的策略编写原则:
- 默认拒绝所有流量
- 按应用分层定义策略
- 使用命名空间标签组织策略
示例策略:
yaml复制apiVersion: projectcalico.org/v3
kind: NetworkPolicy
metadata:
name: frontend-to-backend
spec:
selector: role == 'frontend'
egress:
- action: Allow
protocol: TCP
destination:
selector: role == 'backend'
ports: [8080]
在内网环境部署Calico确实会遇到各种特殊场景,经过这次实践我们总结出几点关键经验:离线镜像要提前验证兼容性、内核参数必须统一配置、BGP拓扑需要根据实际网络结构调整。现在这套集群已经稳定运行8个月,期间通过Calico的监控接口采集的流量数据,还帮助我们发现了多个微服务间的异常调用模式。
