参考文档:https://github.com/containernetworking/cni
Pod网络插件,为了实现Pod网络而需要的插件、组件。由于Kubernetes通过开放的CNI接口来允许插件的接入,所以它又称之为CNI网络插件。
为了解决跨主机容器间通信问题,市面上存在很多解决方案,为了兼容和规范这些解决方案,Kubernetes仅设计了网络模型,并将Pod网络的实现交给了CNI网络插件,并允许网络插件通过标准的CNI(Container Network Interface,容器网络接口)连接到容器管理系统。
CNI网络插件主要解决的就是容器跨主机通信问题而存在的,并使跨主机间运行的Pod位于同一个网络平面,其大致解决步骤通常有两步:分配设置自定义容器网络(PodIP在集群中全局唯一性)和实现容器网络通信(处理方法通常有路由、覆盖网络{Vxlan、IPIP}等等)。
每个Pod都会创建一个名叫"pause"的根容器,其他运行的业务容器都是复制该容器的网络,这个容器就是Kubernetes为了自定义网络等特殊功能而存在的。
CNI网络插件分为以下四种:
MAIN,主要的,创建接口,主要网络的实现。如:bridge、ipvlan、loopback、macvlan、ptp、vlan、host-device。
Windows,特用于Windows的MAIN插件。如:win-bridge、win-overlay。
IPAM,仅提供IP地址分配功能。如:dhcp、host-local、static。
META,其他插件,通过调用第三方插件来实现网络功能。如:tuning、portmap、bandwidth、sbr、firewall、flannel。
光单独靠一种CNI网络插件是无法实现完整的Pod网络通信和更高级的网络策略功能的,第三方组织可以灵活的组合这些CNI插件实现基本Pod网络功能和更高级功能,所以市面上流行出来很多解决方案。
在现今,比较常用的流行的Pod网络解决方案有Flannel和Calico(支持网络策略功能)、Canal(由Flannel实现网络通信+Calico提供网络策略)。
参考文档:https://projectcalico.docs.tigera.io/
Calico是一款广泛采用、久经考验的开源网络和网络安全解决方案,适用于Kubernetes、虚拟机和裸机工作负载。与Flannel对比,Calico除了支持基本网络功能的实现之外,它还支持全套Kubernetes网络策略功能,以及在其之上扩展网络策略。
Calico主要由以下组件组成:
CNI网络插件,Calico通过CNI网络插件与kubelet关联,从而实现Pod网络。
Calico节点代理是运行在每个节点上的代理程序,负责管理节点路由信息、策略规则和创建Calico虚拟网络设备。
Calico Node主要由以下子模块程序组成:

Calico网络策略控制器。允许创建"NetworkPolicy"资源对象,并根据资源对象里面对网络策略定义,在对应节点主机上创建针对于Pod流出或流入流量的IPtables规则。
Typha是Calico的一个扩展组件,用于Calico通过Typha直接与Etcd通信,而不是通过kube-apiserver。通常当K8S的规模超过50个节点的时候推荐启用它,以降低kube-apiserver的负载。每个Pod/calico-typha可承载100~200个Calico节点的连接请求,最多不要超过200个。
Calico支持两种类型网络工作模式(后端机制):
如果物理主机在同一2层网络中,则建议采用使用BGP动态路由通信方式;如果物理主机是跨子网通信的话,可能由于到达目标主机的跳数太多导致性能下降,所以建议使用覆盖网络模式。
采用BGP动态路由协议自动学习来自其他AS自治系统上的路由条目,即其他节点主机上的路由条目。
类似于Flannel的Host-GW模式,不过它没有不能跨子网的限制。
想要更多了解BGP动态路由技术,可以参考其他网络资料,这里就不过多的阐述了。
采用IPIP或VXLAN协议封装底层网络,然后通过上层物理覆盖网络通信。
将底层的Pod网络源目IP+数据封装到上层物理网络源目IP的数据包中,由同一个网络的物理主机通过直连路由完成数据包的传输和解封装,以实现底层Pod网络通信。
Calico对于覆盖网络的工作模式有:

CIDR,Classless Inter-Domain Routing,无类别域间路由,在Kubernetes中指基于CIDR的网络划分方案,为Pod分配的子网范围(如:10.244.0.0/12)。
通常默认情况下,PodIP地址范围(--pod-network-cidr)为10.244.0.0/16,它拥有16^2=256*256=65536个地址(包括网络地址+广播地址)可拆分成独立子网。
Calico为每个节点都会创建一个独立子网,即从CIDR大的地址池中划分较小范围的地址池给到每个节点。
Calico可以通过修改配置blockSize块大小来设置每个节点分配的独立子网的范围池大小。这边默认值IPV4=26,IPV6=122。
二进制掩码26(11111111 11111111 11111111 11000000)转换成十进制掩码即=255.255.255.192,即每个节点的子网可以有64个IP地址,减去广播地址和网络地址,可为Pod分配的有效IP地址有62个。
Calico使用IPtables实现网络策略功能,在Kubernetes中可以创建"NetworkPolicy"资源对象传给Calico的控制器,由Calico Node根据NetworkPolicy定义的规则在相关节点上创建对应的IPtables规则,以实现对Pod出入口网络流量的安全策略限制。
Calico有两种安装方式:
参考文档:https://projectcalico.docs.tigera.io/archive/v3.14/getting-started/kubernetes/quickstart
当前主机环境:
镜像加速由阿里云"容器加速器"提供。
由于安装清单中所使用的镜像来源于国外站点,所以需要配置为国内镜像源才能正常下载镜像到国内主机。
创建配置文件"/etc/docker/daemon.json",并写入以下内容:
[root@localhost ~]# mkdir -p /etc/docker [root@localhost ~]# cat /etc/docker/daemon.json <<EOF{ "registry-mirrors": [ "https://7mimmp7p.mirror.aliyuncs.com", "https://registry.docker-cn.com", "http://hub-mirror.c.163.com", "https://docker.mirrors.ustc.edu.cn" ], "exec-opts": ["native.cgroupdriver=systemd"], "log-driver": "json-file", "log-opts": { "max-size": "100m" }, "storage-driver": "overlay2", "storage-opts": [ "overlay2.override_kernel_check=true" ]}EOF重启docker服务即可:
[root@localhost ~]# sudo systemctl daemon-reload[root@localhost ~]# sudo systemctl restart docker如果主机系统使用NetworkManager来管理网络的话,则需要配置NetworkManager,以允许Calico管理接口。
NetworkManger操作默认网络命名空间接口的路由表,这可能会干扰Calico代理正确路由的能力。
在所有主机上操作:
[root@k8s-master01 ~]# cat > /etc/NetworkManager/conf.d/calico.conf <<EOF[keyfile]unmanaged-devices=interface-name:cali*;interface-name:tunl*;interface-name:vxlan.calico;interface-name:wireguard.caliEOF[root@k8s-master01 ~]# wget https://docs.projectcalico.org/v3.23/manifests/calico.yaml --no-check-certificate由于默认的Calico清单文件中所使用的镜像来源于docker.io国外镜像源,上面我们配置了Docker镜像加速,应删除docker.io前缀以使镜像从国内镜像加速站点下载。
[root@k8s-master01 ~]# cat calico.yaml |grep 'image:' image: docker.io/calico/cni:v3.23.0 image: docker.io/calico/cni:v3.23.0 image: docker.io/calico/node:v3.23.0 image: docker.io/calico/kube-controllers:v3.23.0[root@k8s-master01 ~]# sed -i 's#docker.io/##g' calico.yaml[root@k8s-master01 ~]# cat calico.yaml |grep 'image:' image: calico/cni:v3.23.0 image: calico/cni:v3.23.0 image: calico/node:v3.23.0 image: calico/kube-controllers:v3.23.0[root@k8s-master01 ~]# kubectl apply -f calico.yamlPod-Calico在"kube-system"名称空间下创建并运行起来:
[root@k8s-master01 ~]# kubectl get pod -n kube-system |grep calicocalico-kube-controllers-77d9858799-c267f 1/1 Running 0 92scalico-node-6jw5q 1/1 Running 0 92scalico-node-krrn6 1/1 Running 0 92scalico-node-mgk2g 1/1 Running 0 92scalico-node-wr2pv 1/1 Running 0 92s这种是官方文档最新指导的安装方式。
Tigera Calico Operator通常会安装最新版本的Calico版本,并使用最新的功能。
如果主机系统使用NetworkManager来管理网络的话,则需要配置NetworkManager,以允许Calico管理接口。
NetworkManger操作默认网络命名空间接口的路由表,这可能会干扰Calico代理正确路由的能力。
在所有主机上操作:
[root@k8s-master01 ~]# cat > /etc/NetworkManager/conf.d/calico.conf <<EOF[keyfile]unmanaged-devices=interface-name:cali*;interface-name:tunl*;interface-name:vxlan.calico;interface-name:wireguard.caliEOF参考文档:https://github.com/tigera/operator
tigera-operator.yaml清单文件用于安装Tigera Calico operator。
operator的镜像来源于quay.io。
[root@k8s-master01 ~]# wget https://projectcalico.docs.tigera.io/manifests/tigera-operator.yaml -O calico-tigera-operator.yaml --no-check-certificate[root@k8s-master01 ~]# cat calico-tigera-operator.yaml |grep 'image:' image: quay.io/tigera/operator:v1.27.0[root@k8s-master01 ~]# kubectl apply -f calico-tigera-operator.yaml [root@k8s-master01 ~]# kubectl get pod -n tigera-operator -o wideNAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATEStigera-operator-566769dc67-mrnhs 1/1 Running 0 5m39s 192.168.124.132 k8s-node01 <none> <none>custom-resources.yaml用于自定义通过Tigera Calico operator安装和配置Calico,它会创建由operator实现的Installation资源对象。
在自定义Calico之前可以通过"https://projectcalico.docs.tigera.io/reference/installation/api#operator.tigera.io/v1.Installation"先了解安装配置。
注:这边需要修改一下Pod分配子网范围(CIDR),该地址需要与kubeadm初始化集群时的"podSubnet"字段或"--pod-network-cidr"参数中填写的值相同。
[root@k8s-master01 ~]# wget https://projectcalico.docs.tigera.io/manifests/custom-resources.yaml -O calico-custom-resources.yaml --no-check-certificate[root@k8s-master01 ~]# vim calico-custom-resources.yamlapiVersion: operator.tigera.io/v1kind: Installationmetadata: name: defaultspec: # Configures Calico networking. calicoNetwork: # Note: The ipPools section cannot be modified post-install. ipPools: - blockSize: 26 cidr: 10.244.0.0/16 encapsulation: VXLANCrossSubnet natOutgoing: Enabled nodeSelector: all()[root@k8s-master01 ~]# kubectl apply -f calico-custom-resources.yaml Tigera Calico Operator会自动创建一个名叫"calico-system"的名称空间来运行Calico。
[root@k8s-master01 ~]# kubectl get namespace NAME STATUS AGEcalico-system Active 3m10sdefault Active 5m55skube-node-lease Active 5m57skube-public Active 5m57skube-system Active 5m57stigera-operator Active 3m20s[root@k8s-master01 ~]# kubectl get pod -n calico-systemNAME READY STATUS RESTARTS AGEcalico-kube-controllers-7dfc6fb85-ktww2 0/1 Pending 0 8m33scalico-node-2t4dp 0/1 Init:ImagePullBackOff 0 8m34scalico-node-mmflx 0/1 Init:ImagePullBackOff 0 8m34scalico-node-r94tt 0/1 Init:ImagePullBackOff 0 8m34scalico-node-w7plh 0/1 Init:ImagePullBackOff 0 7m36scalico-typha-5fb57458cc-g89qp 0/1 ImagePullBackOff 0 8m34scalico-typha-5fb57458cc-t5xcm 0/1 ImagePullBackOff 0 8m28s[root@k8s-master01 ~]# kubectl describe pod calico-kube-controllers-7dfc6fb85-ktww2 -n calico-system Normal BackOff 69s (x2 over 3m41s) kubelet Back-off pulling image "docker.io/calico/pod2daemon-flexvol:v3.23.0" Warning Failed 69s (x2 over 3m41s) kubelet Error: ImagePullBackOff可以看到所有Calico相关的Pod由于在国内环境下都无法正常下载由docker.io提供的镜像:
[root@k8s-master01 ~]# kubectl describe pod -n calico-system |grep 'Events' -A 10 |grep -Eo '"docker.io/calico/.*"' |sort |uniq"docker.io/calico/cni:v3.23.0""docker.io/calico/kube-controllers:v3.23.0""docker.io/calico/node:v3.23.0""docker.io/calico/pod2daemon-flexvol:v3.23.0""docker.io/calico/typha:v3.23.0"尝试手动从quay.io下载镜像。quay.io是一个公共镜像仓库。
所有主机上操作:
[root@k8s-master01 ~]# docker pull quay.io/calico/cni:v3.23.0[root@k8s-master01 ~]# docker pull quay.io/calico/kube-controllers:v3.23.0[root@k8s-master01 ~]# docker pull quay.io/calico/node:v3.23.0[root@k8s-master01 ~]# docker pull quay.io/calico/pod2daemon-flexvol:v3.23.0[root@k8s-master01 ~]# docker pull quay.io/calico/typha:v3.23.0这个时候发现Calico相关Pod都已正常运行了:
[root@k8s-master01 ~]# kubectl get pod -n calico-systemNAME READY STATUS RESTARTS AGEcalico-kube-controllers-7dfc6fb85-vbn6q 1/1 Running 0 64mcalico-node-29h89 1/1 Running 0 64mcalico-node-9c54r 1/1 Running 1 (10m ago) 64mcalico-node-ntzvt 1/1 Running 0 64mcalico-node-s5bz9 1/1 Running 0 64mcalico-typha-5dd57768f4-79clk 1/1 Running 1 (10m ago) 27mcalico-typha-5dd57768f4-dk9ph 1/1 Running 0 64m参考文档:https://docs.projectcalico.org/archive/v3.14/getting-started/kubernetes/installation/config-options#other-configuration-options
calico.yaml清单文件主要用于运行calico-node和calico-kube-controllers服务,其清单安装以下Kubernetes资源:
在calico.yaml清单文件中,Calico默认的工作模式是IPIP。
在安装Calico之前配置Calico通常有以下项:
要更改用于Pod的默认IP范围,请修改calico.yaml清单文件中"CALICO_IPV4POOL_CIDR"部分。
kind: DaemonSetapiVersion: apps/v1metadata: name: calico-node namespace: kube-system labels: k8s-app: calico-nodespec: template: spec: containers: - name: calico-node image: calico/node:v3.14.2 env: ... # - name: CALICO_IPV4POOL_CIDR # value: "192.168.0.0/16" ...设置PodIP范围。
此项用于设置安装Calico时要创建的默认IPv4池,PodIP将从该范围中选择。
Calico安装完成后修改此值将再无效。
默认情况下calico.yaml中"CALICO_IPV4POOL_CIDR"是注释的,如果kube-controller-manager的"--cluster-cidr"不存在任何值的话,则通常取默认值"192.168.0.0/16,172.16.0.0/16,..,172.31.0.0/16"。
当使用kubeadm时,PodIP的范围应该与kubeadm init的清单文件中的"podSubnet"字段或者"--pod-network-cidr"选项填写的值相同。
默认情况下,清单启用跨子网所使用的封装协议是IPIP。
当集群的节点都处于同一个2层网络中时,我们期望修改Calico的工作模式为BGP或其他时,可以设置"CALICO_IPV4POOL_IPIP"的"value: Never"以禁用IPIP。默认IPIP是启用的"value: Always"。
kind: DaemonSetapiVersion: apps/v1metadata: name: calico-node namespace: kube-system labels: k8s-app: calico-nodespec: template: spec: containers: - name: calico-node image: calico/node:v3.14.2 env: ... # Enable IPIP - name: CALICO_IPV4POOL_IPIP value: "Always" ...设置Calico覆盖网络IPV4池所要使用的封装协议为IPIP。
可设置的值:
Always,永久启用。
CrossSubnet,当物理主机是跨子网通信的话才启用,如果物理主机在同一2层网络中则使用BGP动态路由通信方式。
Never,从不启用,即禁用。
如果该项的值设置为"Never"以外的值,则不应设置"CALICO_IPV4POOL_VXLAN"。
Calico覆盖网络支持IPIP、VXLAN两种协议,仅能启用其中一种。
VXLAN协议禁止启用由"CALICO_IPV4POOL_VXLAN"项控制。
默认情况下,Calico清单启用IPIP封装。如果你期望Calico使用VXLAN封装模式,则需要在安装时候做以下操作:
1、将"CALICO_IPV4POOL_IPIP "设置为"Never",将"CALICO_IPV4POOL_VXLAN"设置为"Always".
kind: DaemonSetapiVersion: apps/v1metadata: name: calico-node namespace: kube-system labels: k8s-app: calico-nodespec: template: spec: containers: - name: calico-node image: calico/node:v3.14.2 env: ... # Enable IPIP - name: CALICO_IPV4POOL_IPIP value: "Never" - name: CALICO_IPV4POOL_VXLAN value: "Always" ...2、如果你只想集群仅使用基于VXLAN协议的覆盖网络模式,用不到BGP动态路由模式的话,即为了节省一点资源,可以选择完全禁用Calico基于BGP的网络:
livenessProbe: exec: command: - /bin/calico-node - -felix-live # - -bird-live readinessProbe: exec: command: - /bin/calico-node # - -bird-ready - -felix-ready设置Calico覆盖网络IPV4池所要使用的封装协议为VXLAN。
可设置的值:
在清单文件的开始有ConfigMap描述Calico的配置内容,其重要的配置项解读如下:
kind: ConfigMapapiVersion: v1metadata: name: calico-config namespace: kube-systemdata: typha_service_name: "none" calico_backend: "bird" veth_mtu: "1440" cni_network_config: |- { "name": "k8s-pod-network", "cniVersion": "0.3.1", "plugins": [ { "type": "calico", "log_level": "info", "datastore_type": "kubernetes", "nodename": "__KUBERNETES_NODE_NAME__", "mtu": __CNI_MTU__, "ipam": { "type": "calico-ipam" }, "policy": { "type": "k8s" }, "kubernetes": { "kubeconfig": "__KUBECONFIG_FILEPATH__" } }, { "type": "portmap", "snat": true, "capabilities": {"portMappings": true} }, { "type": "bandwidth", "capabilities": {"bandwidth": true} } ] }Typha是Calico的一个扩展组件,用于Calico通过Typha直接与Etcd通信,而不是通过kube-apiserver。通常当K8S的规模超过50个节点的时候推荐启用它,以降低kube-apiserver的负载。
支持值:
设置Calico使用的后端机制。支持值:
bird,开启BIRD功能,根据Calico-Node的配置来决定主机的网络实现是采用BGP路由模式还是IPIP、VXLAN覆盖网络模式。
vxlan,纯VXLAN模式,仅能够使用VXLAN协议的覆盖网络模式。
设置虚拟接口"calicoxxxxx"的MTU值,默认情况下MTU是自动检测的,不需要显示的设置此字段。
可以通过提供一个非零值来设置它。
MTU,Maximum Transmission Unit,最大传输单元,网络设备一次发送数据包大小,单位为Byte,MTU值约小则传输速率约高,此值应由系统设置的最合理的值,通常不需要我们手动设置,最大值为1500。
在每个节点上都要安装的CNI网络插件配置。保持默认就好。
custom-resources.yaml清单文件通过Tigera Calico Operator安装Calico的自定义清单文件。
在安装Calico之前,我们可以通过修改该清单的内容自定义配置Calico。
参考文档:https://projectcalico.docs.tigera.io/reference/installation/api
# This section includes base Calico installation configuration.# For more information, see: https://projectcalico.docs.tigera.io/v3.23/reference/installation/api#operator.tigera.io/v1.InstallationapiVersion: operator.tigera.io/v1kind: Installationmetadata: name: defaultspec: # Configures Calico networking. calicoNetwork: # Note: The ipPools section cannot be modified post-install. ipPools: - blockSize: 26 cidr: 10.244.0.0/16 encapsulation: VXLANCrossSubnet natOutgoing: Enabled nodeSelector: all()---# This section configures the Calico API server.# For more information, see: https://projectcalico.docs.tigera.io/v3.23/reference/installation/api#operator.tigera.io/v1.APIServerapiVersion: operator.tigera.io/v1kind: APIServermetadata: name: defaultspec: {}配置Calico网络。
开启或禁用BGP路由功能。支持值:Enabled, Disabled。
IPPool,为由节点筛选器指定节点上创建Pod分配的单个或多个地址池,以及要使用的Pod网络的实现方法。
块大小,子网划分技术,指从CIDR(如:10.244.0.0/16)里面为每个节点拆分一个独立的子网块范围大小(如:10.244.32.128/26)。默认IPV4=26,IPV6=122。二进制掩码26转换成十进制掩码即=255.255.255.192,即每个节点的子网可以有64个IP地址,减去广播地址和网络地址,可为Pod分配的有效IP地址有62个。
Pod网络IP范围。
设置Pod网络要使用的封装协议类型,支持:
NAT传出,对传出的流量启用或禁用NAT功能。支持值:Enabled, Disabled。
节点选择器,使用它选择该IPPool池会影响那些节点的Pod。默认值为"all()",保持默认就好。
任一台Master上操作:
[root@k8s-master01 ~]# kubectl delete -f calico.yaml如果使用了IPIP覆盖网络模式,则Calico会在每台主机上创建一块名叫tunl0的虚拟网卡设备。
在所有主机上操作:
[root@k8s-master01 ~]# modprobe -r ipip在所有主机上操作:
[root@k8s-master01 ~]# rm -rf /var/lib/cni/ && rm -rf /etc/cni/net.d/*在所有主机上操作:
[root@k8s-master01 ~]# systemctl restart kubelet