K8s网络组件之Calico:IPIP工作模式
CNI存在的意义
为了对接第三方的网络组件,提供一种接口,实现接口逻辑的松耦合
K8s网络组件之Calico
Calico是一个纯三层(基于路由的)的数据中心网络方案,Calico支持广泛的平台,包括Kubernetes、OpenStack等。
Calico 在每一个计算节点利用 Linux Kernel 实现了一个高效的虚拟路由器( vRouter) 来负责数据转发,而每个 vRouter 通过 BGP 协议负责把自己上运行的 workl oad 的路由信息向整个 Calico 网络内传播。(工作的时候在每个节点跑代理程序来负责该节点的路由规则和网络配置,也会将这个节点当作虚拟路由器看待,实现跨界点的数据包的转发)此外,Calico 项目还实现了 Kubernetes 网络策略,提供ACL功能。
实际上,Calico项目提供的网络解决方案,与Flannel的host-gw模式几乎一样。也就是说,Calico也是基于路由表实现容器数据包转发,但不同于Flannel使用flanneld进程来维护路由信息的做法,而Calico项目使用BGP协议来自动维护整个集群的路由信息。
BGP英文全称是Border Gateway Protocol,即边界网关协议,它是一种自治系统间的动态路由发现协议,与其他 BGP 系统交换网络可达信息
Calico最核心的设计思想是把负责的主机当作路由器,直接是路由的转发
路由器的路由表是由BGP去负责,相互的学习和同步的,同时也支持网络策略,提供pod的acl
K8s网络组件之Calico:BGP介绍
在这里你可以理解为两个公司,这两个公司的网络是没有任何来往的,要让as1中的机器访问as2中的机器,显然是无法通信的
有了bgp将两个公司路由器通过BGP协议去打通,相互学习对方的路由表添加到自己的里面,这样就可以将两个公司的网络连接起来
现在192.168.1.10要访问172.17.1.20,现在上层的路由器配置了BGP协议,那么就会交换双方的路由信息,将对方学到的路由信息写到自己里面
上面黄色部分就是学到的路由表,目标172.17.1.20在路由表显示的是router2,在真实路由表里面是这个路由器的IP,这里就是下一跳,然后从B口出去到达router2的路由器,router2又有路由表,目标172.17.1.20是从A口出去,然后到达二层交换机通过ARP协议获取mac地址去通信,最终到达172.17.1.20机器
BGP边界网关,BGP多线连接着多条线路
BGP实现了路由共享的协议,BGP在calico这里取代了flannel通过进程维护的功能,BGP针对于大规模网络的协议可靠性扩展性远比flannel强的多
BGP用于在大规模的网络当中实现的路由共享的协议,BGP协议在calico这里取代了flanneld进程维护的那种功能。
在了解了 BGP 之后,Calico 项目的架构就非常容易理解了。
Calico主要由三个部分组成
在了解了 BGP 之后,Calico 项目的架构就非常容易理解了。
• Felix:以DaemonSet方式部署,运行在每一个Node节点上,主要负责维护宿主机上路由规则以及ACL规则。(从别的节点学习路由表的信息)
• BGP Client(BIRD):主要负责把 Felix 写入 Kernel 的路由信息分发到集群 Calico 网络。(新启动了一个节点加入集群,会新启动一个agent,agent里面就包括了felix还有bgp client,会从其他的集群网路当中以BPG协议获取除本节点集群涉及到的网络,都将其学习过来,通过BPG clicent写到宿主机上面)
• Etcd:分布式键值存储,保存Calico的策略和网络配置状态。
• calicoctl:命令行管理Calico。
Calico存储有两种方式
• 数据存储在etcd
https://docs.projectcalico.org/v3.9/manifests/calico-etcd.yaml
• 数据存储在Kubernetes API Datastore服务中
https://docs.projectcalico.org/manifests/calico.yaml
数据存储在etcd中还需要修改yaml:
• 配置连接etcd地址,如果使用https,还需要配置证书。(ConfigMap和Secret位置)
• 根据实际网络规划修改Pod CIDR(CALICOIPV4POOLCIDR)
部署:
# kubectl apply -f calico.yaml
# kubectl get pods -n kube-system
K8s节点大于100台,建议数据存储在etcd当中,注意pod的网段,要与实际规划的网络保持一致
[root@k8s-master manifests]# vim kube-controller-manager.yaml
[root@k8s-master manifests]# pwd
/etc/kubernetes/manifests
- --allocate-node-cidrs=true
- --authentication-kubeconfig=/etc/kubernetes/controller-manager.conf
- --authorization-kubeconfig=/etc/kubernetes/controller-manager.conf
- --bind-address=127.0.0.1
- --client-ca-file=/etc/kubernetes/pki/ca.crt
- --cluster-cidr=10.244.0.0/16
要想存储在外部的etcd当作
etcd_ca: "" # "/calico-secrets/etcd-ca"
etcd_cert: "" # "/calico-secrets/etcd-cert"
etcd_key: "" # "/calico-secrets/etcd-key"
写上etcd的私钥,数字证书,CA,配置连接集群的字符串
etcd_endpoints: "http://<ETCD_IP>:<ETCD_PORT>"
修改网段和你规划的保持一致,yml文件里面只需要修改这个
- name: CALICO_IPV4POOL_CIDR
value: "10.244.0.0/16"
K8s网络组件之Calico:管理工具
calicoctl工具用于管理calico,可通过命令行读取、创建、更新和删除 Calico 的存储对象。
项目地址:https://github.com/projectcalico/calicoctl
calicoctl 在使用过程中,需要从配置文件中读取 Calico 对象存储地址等信息。默认配置文件路径 /etc/calico/calicoctl.cfg
二进制程序
[root@k8s-master ~]# chmod o+x calicoctl
[root@k8s-master ~]# mv calicoctl /usr/bin/
[root@k8s-master ~]# mkdir -p /etc/calico/
[root@k8s-master ~]# cd /etc/calico/
[root@k8s-master calico]# cat calicoctl.cfg
apiVersion: projectcalico.org/v3
kind: CalicoAPIConfig
metadata:
spec:
datastoreType: "kubernetes"
kubeconfig: "/root/.kube/config"
如果你使用kubeadm部署的话,这就是一个默认路径。如果使用的是二进制部署的话kube config是需要手动生成
查看Calico状态:
可以查看calico bgp的一个网格,这里会显示除了自己之外的其他的节点,这个网络连接就是为了同步路由信息走的是BGP协议
[root@k8s-master ~]# calicoctl get node
NAME
k8s-master
k8s-node1
k8s-node2
[root@k8s-master ~]# calicoctl get node -o wide
NAME ASN IPV4 IPV6
k8s-master (64512) 192.168.179.102/24
k8s-node1 (64512) 192.168.179.103/24
k8s-node2 (64512) 192.168.179.104/24
[root@k8s-master ~]# calicoctl node status
Calico process is running.
IPv4 BGP status
+-----------------+-------------------+-------+----------+-------------+
| PEER ADDRESS | PEER TYPE | STATE | SINCE | INFO |
+-----------------+-------------------+-------+----------+-------------+
| 192.168.179.103 | node-to-node mesh | up | 09:57:38 | Established |
| 192.168.179.104 | node-to-node mesh | up | 09:56:54 | Established |
+-----------------+-------------------+-------+----------+-------------+
IPv6 BGP status
No IPv6 peers found.
查看当前网段
[root@k8s-master ~]# calicoctl get ippool
NAME CIDR SELECTOR
default-ipv4-ippool 10.244.0.0/16 all()
[root@k8s-master ~]# calicoctl get ippool -o wide
NAME CIDR NAT IPIPMODE VXLANMODE DISABLED SELECTOR
default-ipv4-ippool 10.244.0.0/16 true Always Never false all()
K8s网络组件之Calico:工作模式
Calico工作模式:
• IPIP:Overlay Network方案,源数据包封装在宿主机网络包里进行转发和通信。(默认)
• BGP:基于路由转发,每个节点通过BGP协议同步路由表,写到宿主机。 (值设置Never)
• CrossSubnet:同时支持BGP和IPIP,即根据子网选择转发方式。(折中方案,集群当中是有两个网段,又想使用路由的高性能)
通过调整参数改变工作模式:
- name: CALICO_IPV4POOL_IPIP
value: "Always"
K8s网络组件之Calico:IPIP工作模式
和flannel的vxlan实现的原理类似,都是一种网络虚拟化技术,将原始的数据包封装在书主机网络数据包里面转发
IPIP模式:采用Linux IPIP隧道技术实现的数据包封装与转发。
IP 隧道(IP tunneling)是将一个IP报文封装在另一个IP报文的技术,Linux系统内核实现的
IP隧道技术主要有三种:IPIP、GRE、SIT。
当容器发出数据包就会到达宿主机上面,也是通过veth的设备对一端放在容器当中,另外一端放在宿主机上面,实现从容器当中的数据到达到宿主机上面的网络命名空间,宿主机上面的网络命名空间根据路由表信息转发
[root@k8s-master ~]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-6799fc88d8-drb2s 1/1 Running 3 78d 10.244.169.137 k8s-node2 <none> <none>
[root@k8s-master ~]# ip route
default via 192.168.179.2 dev ens32 proto static metric 100
10.244.36.64/26 via 192.168.179.103 dev tunl0 proto bird onlink
10.244.169.128/26 via 192.168.179.104 dev tunl0 proto bird onlink
10.244.169.128/26 via 192.168.179.104 dev tunl0 proto bird onlink
从tunl0这个虚拟的隧道设备进行出去
这个就是calio ipip隧道模式先创建的一个设备,这个设备和flannel的flannel.1这个设备非常类似,完成数据包的封装,将源容器的数据包封装好之后通过宿主机发出去,收到看到是tunl0封装,需要解开。
这里网桥用的是cali
在这里可以看到像flannel一样使用cni网卡做网桥,tunl0通过数据包引到容器的veth这里
[root@k8s-node1 ~]# ip route
default via 192.168.179.2 dev ens32 proto static metric 100
blackhole 10.244.36.64/26 proto bird
10.244.36.73 dev calib98307d9f10 scope link
10.244.36.74 dev califb92f94764a scope link
10.244.36.75 dev cali10e5fc0b45a scope link
10.244.36.76 dev calid4dc2dc6ef3 scope link
在这个节点上有多少个pod,就有多少个路由表,这样会导致有大量的路由表产生,会给网络造成复杂程度
两个节点两个机房,不在一个局域网,主要宿主机的网络打通就行,因为数据包最后还是走宿主机,二层数据包还是走三层网络
Pod 1 访问 Pod 2 大致流程如下:
目录 返回
首页