K8S Calico网络插件之IPIP模式

注:本文基于Calico v3.20.1版本编写

1 关于Calico

flannel是overlay网络, 主要工作在L2(VXLAN),calico主要是L3,通过BGP路由协议在机器之间传送报文。

2 安装Calico(IPIP模式)

因为之前有安装flannel,因此需要先删除,

kubectl delete -f kube-flannel.yml

同时需要删除flannel.1和cni0这两个网络设备,

ip link delete cni0
ip link delete flannel.1

之后就可以根据官网安装了,

curl https://docs.projectcalico.org/manifests/calico.yaml -O
kubectl apply -f calico.yaml

是的,就是这么简单,然后就可以在机器上看到新生成的网络设备,

cali00dc074ce54: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1480
...
tunl0: flags=193<UP,RUNNING,NOARP>  mtu 1480

因为默认情况下,calico使用的是ipip隧道模式,这一点我们可以从calico的日志里看出,

2021-10-02 05:04:26.657 [INFO][9] startup/startup.go 651: CALICO_IPV4POOL_NAT_OUTGOING is true (defaulted) through environment variable
2021-10-02 05:04:26.657 [INFO][9] startup/startup.go 992: Ensure default IPv4 pool is created. IPIP mode: Always, VXLAN mode: Never
2021-10-02 05:04:26.718 [INFO][9] startup/startup.go 1002: Created default IPv4 pool (10.244.0.0/16) with NAT outgoing true. IPIP mode: Always, VXLAN mode: Never

所以多了一个tunl0设备,

[root@master home]# ip -d link show tunl0
9: tunl0@NONE: <NOARP,UP,LOWER_UP> mtu 1480 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1
    link/ipip 0.0.0.0 brd 0.0.0.0 promiscuity 0 
    ipip ...

与此同时,host上也多了两条通往node的路由记录,

[root@master calico]# route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         192.168.0.1     0.0.0.0         UG    0      0        0 ens33
10.244.104.0    192.168.0.112   255.255.255.192 UG    0      0        0 tunl0
10.244.166.128  192.168.0.111   255.255.255.192 UG    0      0        0 tunl0
...

3 Calico ipip模式工作原理

所谓ipip,也就是IP in IP,即在IP报文的基础上,又封装了一个IP头,和overlay网络相似。
在这里插入图片描述

我们以两个node上的两个容器为例,说一下报文的流动过程。

报文从Pod A发出,根据路由发往容器中的网关169.254.1.1,

[root@centos-bc2sm /]# route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         169.254.1.1     0.0.0.0         UG    0      0        0 eth0
169.254.1.1     0.0.0.0         255.255.255.255 UH    0      0        0 eth0

但是你会发现,host上并没有这设备,这就是calico独特之处。那报文到底是如何发送出去的呢?

我们先看下网关通向的二层地址,即mac地址,

[root@centos-bc2sm /]# arp -n
Address                  HWtype  HWaddress           Flags Mask            Iface
169.254.1.1              ether   ee:ee:ee:ee:ee:ee   C                     eth0

可以看到,容器中网关的arp地址是ee:ee:ee:ee:ee:ee,所以现在的问题就变成,哪个网卡的mac地址是这个。

我们在host上查看所有网卡,会发现,cali的所有网卡的mac地址都是ee:ee:ee:ee:ee:ee

[root@node2 ~]# ifconfig | grep -E "flags|ether"
cali0a4fde325ea: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1480
        ether ee:ee:ee:ee:ee:ee  txqueuelen 0  (Ethernet)
cali43af9e40d9b: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1480
        ether ee:ee:ee:ee:ee:ee  txqueuelen 0  (Ethernet)
cali61a9554ce92: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1480
...

另外,我们知道容器中的网卡用的是veth的pair虚拟网卡,一端连接到容器,另一端连着宿主机。所以我们需要查看下容器里网卡编号,

[root@centos-bc2sm /]# ethtool -S eth0
NIC statistics:
     peer_ifindex: 14

然后host中编号为14的即为另一端,

[root@node2 ~]# ip link show
...
14: cali0a4fde325ea@if4: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1480 qdisc noqueue state UP mode DEFAULT 
    link/ether ee:ee:ee:ee:ee:ee brd ff:ff:ff:ff:ff:ff link-netnsid 4

因此,容器中的报文就通过cali0a4fde325ea到达宿主机。

然后根据宿主机的路由,报文发往tunl0

10.244.166.128  192.168.0.111   255.255.255.192 UG    0      0        0 tunl0

报文到达tunl0时,会再次封装一层ip报文头,把目标node的ip作为目的ip,然后通过ens33将报文发出。

对端node收到报文后,解开外层ip报文头,发现是ipip报文,会转交给tunl0, tunl0把内层ip报文头解开,查找路由,就发送给cali7dadcb96356,

10.244.166.140  0.0.0.0         255.255.255.255 UH    0      0        0 cali7dadcb96356

而这个cali7dadcb96356正是目标容器的veth pair网络设备的另一端。

[root@node1 ~]# ip link show cali7dadcb96356
14: cali7dadcb96356@if4: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1480 qdisc noqueue state UP mode DEFAULT 
    link/ether ee:ee:ee:ee:ee:ee brd ff:ff:ff:ff:ff:ff link-netnsid 0

[root@centos-t854j /]# ethtool -S eth0
NIC statistics:
     peer_ifindex: 14

最终报文到达目标pod。

对于封装后的报文,我们可以通过tcpcump看下报文信息,
在这里插入图片描述而对于同个node的情况,就不需要经过tunl0设备了,因为报文到达host上时,直接根据路由规则就可以转发到对应的cali设备。

4 几个疑问

4.1 容器内网关为169.254.1.1,为什么报文会到宿主机cali网络设备

我们通过arp命令查询mac缓存是逆推而来,而实际上,在发送报文时,会先通过arp广播报文,查询网关的mac地址,由于cali网络设备都开启了arp代理,因此在接收到arp请求时,就会响应该请求,把自己的mac地址回复给ARP广播请求发送者,这样报文就会发往该cali网络设备,同时也就有了这条arp缓存记录。

[root@node2 ~]# cat /proc/sys/net/ipv4/conf/cali0a4fde325ea/proxy_arp
1

所以,理论上容器内的网关设置为什么并不重要,最终由于arp代理,报文到会发送到宿主机的cali设备上。

4.2 为什么cali网络设备mac地址都为ee:ee:ee:ee:ee:ee

因为有一些系统无法在启动时给网络设备分配好mac地址,并且cali的mac地址并不会在实际的链路层报文中使用,因此calico将所有cali网络设备的mac地址都设置为全e,便于管理。

4.3 calico的cali网络设备和flannel的docker0网桥设备有和不同

flannel中所有容器都连接到docker0上,意味着所有容器都可以互通。而对于cali网络设备,每个容器连接到不同的host cali设备中,就能通过网络策略规则实现容器间的隔离,这就为多租户的场景提供了可能。

4.4 每个host是如何获取其他host的路由信息

这是通过BGP协议获取的,calico会在每个host上运行felix和bird进程,

[root@node2 ~]# ps aux | grep -iE "felix|bird"
root       4204  0.0  0.0   4236   400 ?        Ss   Oct08   0:00 runsv felix
root       4207  0.0  0.0   4236   400 ?        Ss   Oct08   0:00 runsv bird
root       4208  0.0  0.0   4236   400 ?        Ss   Oct08   0:00 runsv bird6
root       4213  4.7  2.4 1510880 45552 ?       Sl   Oct08 105:50 calico-node -felix
root       4412  0.0  0.0   1712   516 ?        S    Oct08   1:45 bird6 -R -s /var/run/calico/bird6.ctl -d -c /etc/calico/confd/config/bird6.cfg
root       4414  0.0  0.0   1828   780 ?        S    Oct08   1:51 bird -R -s /var/run/calico/bird.ctl -d -c /etc/calico/confd/config/bird.cfg

其中,felix进程负责监听etcd事件,获取路由、ARP 管理、ACL 管理和同步、状态上报等;而bird进程则负责把felix注入的路由信息通过BGP协议发送给其他机器,这样整个集群中都能获取到相关node的路由信息。


参考资料:

  1. https://docs.projectcalico.org/getting-started/kubernetes/self-managed-onprem/onpremises
  2. https://docs.projectcalico.org/reference/faq
  3. https://docs.projectcalico.org/reference/architecture/overview
  • 6
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 很高兴回答您的问题。K8sCalico的安装非常简单,首先需要安装Kubernetes集群,然后安装calicoctl工具,最后使用calicoctl命令安装Calico网络组件即可。具体的安装步骤可参考Calico的官方文档。 ### 回答2: Kubernetes(简称K8s)是一个开源的容器编排引擎,而Calico是一个为Kubernetes提供网络和安全策略的解决方案。在安装Kubernetes时,可以选择安装Calico来管理容器之间的网络通信和策略控制。 以下是K8s Calico的详细安装步骤: 1. 首先,需要安装Kubernetes集群。可以使用kubeadm、Minikube或其他Kubernetes集群管理工具进行安装。 2. 在集群中的每个节点上,需要设置网络策略为"ACCEPT",以便Calico可以正常工作。 3. 配置Calico网络插件。可以通过kubectl命令行工具在Kubernetes集群中创建Calico网络插件。 4. 创建Calico的RBAC授权。使用kubectl创建一个Calico的ServiceAccount、ClusterRole和ClusterRoleBinding。 5. 下载Calico的YAML文件。可以从Calico的官方网站或GitHub仓库下载Calico的YAML文件,用于创建Calico的资源和配置。 6. 在Kubernetes集群中使用kubectl来应用Calico的YAML文件。例如,可以运行kubectl apply -f calico.yaml命令来应用Calico的配置。 7. 等待Calico在Kubernetes集群中启动和生效。可以使用kubectl get pods命令来检查Calico的Pod是否正常运行。 8. 验证Calico的安装。可以创建一个简单的Pod,并使用kubectl exec命令进入Pod中,然后尝试与其他Pod进行通信,以验证Calico网络功能。 总的来说,安装K8s Calico需要先安装Kubernetes集群,然后配置Calico网络插件和RBAC授权,最后使用kubectl应用Calico的配置文件。安装完成后,可以验证Calico是否正常工作。这样,Kubernetes集群将能够使用Calico来管理容器之间的网络通信和策略控制。 ### 回答3: Kubernetes是一种容器编排平台,而Calico是一种网络插件,可以为Kubernetes集群提供高性能和高度可扩展的网络解决方案。下面是关于如何安装Kubernetes上的Calico的详细步骤: 1. 在Kubernetes集群中的每个节点上安装和配置Docker和Kubernetes。确保节点之间可以互相通信。 2. 下载最新版本的Calico二进制文件。可以在Calico的官方网站或者GitHub上找到相关的安装包。 3. 使用kubectl在每个节点上安装Calico的Kubernetes自定义资源和自定义控制器。这可以通过运行以下命令来完成: ``` kubectl apply -f calico.yaml ``` 这将安装Kubernetes Calico的必要组件和对象。 4. 等待Calico安装完成并运行。可以使用以下命令来检查Calico的运行状态: ``` kubectl get pods -n kube-system ``` 如果所有的Calico相关的pod都是运行状态,那么表示安装成功。 5. 配置Calico网络策略。可以使用calicoctl命令行工具来创建和管理Calico网络策略。首先,需要在每个节点上安装calicoctl。可以从Calico的官方网站或者GitHub上找到相关的安装包和使用说明。 6. 使用calicoctl创建和配置网络策略。可以创建一些允许或者拒绝特定网络流量的策略。例如,可以限制来自某个IP地址或者标签的流量的访问。具体的使用方法可以查阅Calico的官方文档。 7. 验证Calico网络策略是否生效。可以在Kubernetes集群中的各个容器之间进行通信,并根据配置的策略进行验证。 通过按照上述步骤,您就可以在Kubernetes上安装和配置Calico,以提供高性能和高度可扩展的网络解决方案。请注意,这只是一个简要的概述,并且确切的安装步骤可能会因具体的环境和版本而有所不同。在安装过程中,请始终参考官方文档和最新的安装说明。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值