一、下载模板wget https://docs.projectcalico.org/v3.1/getting-started/kubernetes/installation/hosted/kubeadm/1.7/calico.yaml
node
能够获得一份calico官方提供的v3.1版本calico的部署模板(基于kubeadm)。固然里面都是社区的镜像,咱们能够替换成本地镜像.建议到网易云的景象中心下载,不少其余的国内镜像仓库都不作维护了。后端
二、启/禁用 ip-ip网络
目前官方提供的模板里,默认打开了ip-ip功能,该功能会在node上建立一个设备:tunl0,容器的网络数据会通过该设备被封装一个ip头再转发。这里,calico.yaml中经过修改calico-node的环境变量:CALICO_IPV4POOL_IPIP来实现ipip功能的开关:默认是Always,表示开启;Off表示关闭ipip; cross-subnet表示开启并支持跨子网,目前用不到这种类型。sed -i "s#Always#Off#g" calico.yaml
并发
三、部署:app
注意:部署前,要配置一个参数,让calico-node组件可以识别node的IP,node上可能有多块网卡,官方提供的yaml文件中,ip识别策略(IPDETECTMETHOD)没有配置,即默认为first-found,这会致使一个网络异常的ip做为nodeIP被注册,从而影响node-to-node mesh。咱们能够修改为can-reach的策略,尝试链接某一个Ready的node的IP,以此选择出正确的IP。tcp
为了方便,下面的脚本里,我以任意一个node的ip地址为reach 地址ide
connective_ip=`kubectl get node -o wide |grep Ready |head -n1 |awk '{print $6}'` sed -i -rn 'p;/name: IP/,/autodetect/H;/autodetect/{g;s/^\n//;p}' calico.yaml sed -i '1,/name: IP/{s/name: IP/name: IP_AUTODETECTION_METHOD/}' calico.yaml sed -i '1,/\"autodetect\"/{s/\"autodetect\"/can-reach=__ONE_CONNECTIVE_ENDPOINT__/}' calico.yaml sed -i "s#__ONE_CONNECTIVE_ENDPOINT__#$connective_ip#g" calico.yaml
执行:kubectl apply -f calico.yaml
spa
四、calico使用过程当中的一些其余点3d
wget https://docs.projectcalico.org/v3.1/getting-started/kubernetes/installation/hosted/kubernetes-datastore/calico-networking/1.7/calico.yaml wget https://docs.projectcalico.org/v3.1/getting-started/kubernetes/installation/hosted/rbac-kdd.yaml kubectl apply -f rbac-kdd.yaml kubectl apply -f calico.yaml
此处下载的calico.yaml 仍能够参照上文的部署方式进行ipip、ip pool等的定制化。
经过bgp方式部署好calico后,咱们在集群中建立几个pod:code
root@k8s-calico1:~# pods NAMESPACE NAME READY STATUS RESTARTS AGE IP NODE huang1 huangtest-69d9fddd97-cbzbm 1/1 Running 0 20m 192.168.211.1 k8s-calico4 huang1 huangtest-69d9fddd97-pbvvw 1/1 Running 0 3m 192.168.210.194 k8s-calico3 huang2 hhh-6897d64fcd-4zph4 1/1 Running 0 1d 192.168.97.2 k8s-calico2
咱们在k8s-calico2这个node上来看。执行ip r, 在这个node的路由中,须要咱们关注的有:
192.168.97.2 dev calic285cddbb40 scope link blackhole 192.168.97.0/26 proto bird 192.168.210.192/26 via 10.173.32.26 dev eth0 proto bird 192.168.211.0/26 via 10.173.32.25 dev eth0 proto bird
192.168.97.2 dev calic285cddbb40 scope link
这条路由将通向容器ip的请求导向veth:calic285cddbb40 ,进而让请求直达容器内的网卡。blackhole 192.168.97.0/26 proto bird
表示发往192.168.97.0/26
网段的报文都会被丢弃且不会回复源端。配置这条路由的缘由是:这台机器上的calico网络可分配的cidr是192.168.97.0/26
,容器里访问同网段的其余IP时,配置该路由以免报文被发到外部。
最后两条,分别记录了:要访问calico网络中的某个网段,须要以对应的node IP为网关,经过eth0发包。也就是说经过这两条路由,能够将部分网段(目的IP)的包经由eth0发送到正确的地方。
咱们能够这么理解:pod hhh-6897d64fcd-4zph4
中ping huangtest-69d9fddd97-pbvvw
时,流量是这么走的:
0、数据包封装完成,srcip:192.168.97.2 , destip:192.168.210.194
一、容器中只有eth0网卡,容器里ip r 看到的是default **** dev eth0
,因此流量经过容器的eth0发送。
二、容器网卡的配置是经过vethpair作的,也就是说,容器里网卡发的包,在宿主机上都会被calic285cddbb40
设备发出。
三、经过第2步,网络报文就在宿主机的网络中,受宿主机路由影响,192.168.210.192/26 via 10.173.32.26 dev eth0 proto bird
这条路由会将数据从eth0转发,并发给路由中记录的网关:10.173.32.26(这个ip,就是pod huangtest-69d9fddd97-pbvvw
所在的node:k8s-calico3 的ip)
四、10.173.32.26是node:k8s-calico3上eth0的ip,收到包后,在机器自身的路由表中寻找合理的路由,固然这个地方也会有路由:192.168.210.194 dev calif6874dae1d2 scope link
,因而包顺利被对端接收
咱们经过ip-ip模式部署calico,而后将原有的pod所有删掉重建,以下:
root@k8s-calico1:~# pods NAMESPACE NAME READY STATUS RESTARTS AGE IP NODE huang1 huangtest-69d9fddd97-2b8hr 1/1 Running 0 1m 192.168.97.1 k8s-calico2 huang1 huangtest-69d9fddd97-npwzw 1/1 Running 0 1m 192.168.210.65 k8s-calico4 huang2 hhh-6897d64fcd-kqsj4 1/1 Running 0 10s 192.168.210.129 k8s-calico3
咱们再去看看k8s-calico2这个node 上的路由,一样的须要咱们关注的路由有下面的几条:
root@k8s-calico2:~# ip r |grep bird 192.168.97.1 dev cali3683f65394b scope link blackhole 192.168.97.0/26 proto bird 192.168.110.64/26 via 10.173.32.24 dev tunl0 proto bird onlink 192.168.210.64/26 via 10.173.32.25 dev tunl0 proto bird onlink 192.168.210.128/26 via 10.173.32.26 dev tunl0 proto bird onlink
前两条再也不赘述,咱们看到最后三条路由,其实他们描述的逻辑与BGP的那两条没有差异,只不过网卡换成了tunl0.
咱们以一个例子来解释清楚:pod huangtest-69d9fddd97-2b8hr
ping hhh-6897d64fcd-kqsj4
0、封装报文,SRCIP:192.168.97.1 DESTIP:192.168.210.129
一、容器中只有eth0网卡,容器里ip r 看到的是default **** dev eth0
,因此流量经过容器的eth0发送。
二、容器网卡的配置是经过vethpair作的,也就是说,容器里网卡发的包,在宿主机上都会被calic285cddbb40
设备发出。
三、经过第2步,网络报文就在宿主机的网络中,受宿主机路由影响,192.168.210.128/26 via 10.173.32.26 dev tunl0 proto bird onlink
识别到匹配的对端IP,将报文从tunl0发出到10.173.32.26。这里,tunl0会对报文进行封装,在原有的ip报文之上封装了一个ip头部,新的头部中,srcip是宿主机自身的ip:10.173.32.23, destip是对端的ip地址:10.173.32.26。
咱们能够经过tcpdump抓包看到这个步骤:
封装前:
封装后(注意到输出内容结尾有ipip-proto-4
):
四、因为宿主机上只有一个eth的物理机网卡,因此流量终究仍是从eth0向外发出到10.173.32.26。10.173.32.26这个节点的eth0网卡,收到了报文后,发现带有ipip协议的标记(第3步中tcpdump抓包看到的ipip-proto-4
),将ipip头部解开,因而处理到了真实的报文。
五、宿主机上192.168.210.129 dev cali5ce61eb6bc2 scope link
这个路由将包发给vethpair,从而被容器内的eth0接收。
六、icmp响应包的走向与上述的走向逻辑上相同。