Calico v3.11.2
Kubernetes v1.16.7
官方文档:
https://docs.projectcalico.org/introduction/
https://github.com/projectcalico/calico
https://docs.projectcalico.org/v3.11/introduction/
各版本:
https://docs.projectcalico.org/releases
日期:20200310
我看的时候v3.13还不能在生产使用,发行说明里面明确说明了还没有准备好生产使用,v3.12也是只有v3.12.0版本.
https://docs.projectcalico.org/v3.13/release-notes/
https://docs.projectcalico.org/v3.12/release-notes/
所以这里来安装v3.11.2版本。生产环境版本应该会更低。
一、calico介绍
calico支持kubernetes的网络策略kind: NetworkPolicy
。flannel不支持,而且,flannel一般是用在集群节点数少的情况下,比如十几个节点。
Calico支持广泛的平台,包括Kubernetes,OpenShift,Docker EE,OpenStack和裸机服务。
Calico有丰富的网络策略,可以在主机网络层和服务层(如果使用Istio&Envoy)上实施相同的策略。
Calico在每一个节点使用linux内核实现一个高效的虚拟路由器(vRouter)来负责数据转发,而每个 vRouter 通过 BGP 协议负责把自己上运行的路由信息向整个 Calico 网络内传播。
可以与路由器建立BGP对等关系,实现跨子网通信,而非封装的方式。
每个节点都当做是一个自治系统。通过BGP连接起来。,
calico有两种网络互连模式, 一种就是BGP, 一种是封装。
BGP模式跟flannel的host-gw差不多,都是更新节点路由信息的方式,只是flannel是由进程自己获取节点信息来维护路由信息,而calico是由BGP协议传播节点路由信息。
封装也有两种方式,一种是默认的IPIP, 一种是VXLAN。
经常问到的问题:
https://docs.projectcalico.org/v3.11/reference/faq#are-the-calico-manifests-compatible-with-coreos
二、安装准备
网络中需要能够运行BGP协议。纯VXLAN模式不需要BGP,可以用于在不支持BGP的公有云环境中运行calico。
1、系统要求
https://docs.projectcalico.org/v3.11/getting-started/kubernetes/requirements
- Linux kernel >= 3.10
- 以下linux发行版有所需内核和一些依赖项:
-
- RedHat Linux 7
-
- CentOS 7
-
- CoreOS Container Linux stable
-
- Ubuntu 16.04
-
- Debian 8
- 关闭 NetworkManager, NetworkManager会操作路由表,可能会干扰calico正确处理路由的功能。
- 关闭防火墙与selinux。
2、存储方面
calico可以使用etcd或k8s集群存储数据,如果使用etcd,需要calico所有组件都可以访问etcd v3集群。
3、特权
calico需要运行在特权容器。
用两种方式:
- apiserver运行参数添加
--allow-privileged
。
pod添加containers.securityContext.privileged: true
参数。calico的yaml文件里已经添加了。 - 添加pod安全策略
kind: PodSecurityPolicy
kubernetes要求
k8s版本
官方对以下版本测试了calico v3.11
- 1.14
- 1.15
- 1.16
cni插件
Calico 作为cni插件安装,kubelet必须通过传递参数--network-plugin=cni
来使用cni网络。
k8s集群中必须只有calico网络方案
目前calico不支持将其他网络方案迁移到Calico网络
不过好像可以从flannel迁移到calico。
支持的kube-proxy模式
Calico支持以下kube-proxy模式:
- iptables (默认)
- ipvs需要Kubernetes> = v1.9.3。有关更多详细信息,请参阅 在
IP池配置
为Pod IP地址选择的IP范围不能与网络中的任何其他IP范围重叠,包括:
- Kubernetes Service 地址范围
- 分配主机IP的范围
应用层策略要求
kube-apiserver需要启用MutatingAdmissionWebhook
准入控制器。k8s 1.9版本以上都默认启用。
Istio v1.0,v1.1,v1.2或v1.3
请注意,Kubernetes 1.16+版需要Istio 1.2版或更高版本。
内核模块
如果是上面的linux发行版,已经支持了。
- nf_conntrack_netlink 子系统
- ip_tables (对于IPv4)
- ip6_tables (对于IPv6)
- ip_set
- xt_set
- ipt_set
- ipt_rpfilter
- ipt_REJECT
- ipip (如果使用Calico联网)
三、安装
https://docs.projectcalico.org/v3.11/getting-started/kubernetes/installation/calico
组件介绍
https://docs.projectcalico.org/v3.11/reference/architecture/
Felix
与Confd
Felix在所有calico节点上运行, 是主要的组件。
负责本节点接口路由,确保各pod之间或是pod与主机之间可以通信。
还有acl规则,以及其他任何可以帮助网络连接的,比如iptables规则,arp代理。
Confd在所有节点,负责使用存储中存在的配置为Felix和Bird生成配置文件。
这两个组件都由calico-node
这个程序提供,而且是在同一个容器里启动的。
calico-node -felix
calico-node -confd
Bird
与Bird6
在所有calico节点运行,是BGP客户端,负责BGP的操作,在主机之间分配IPv4和IPv6路由。
具体是这个样子:
将felix生成的路由通过BGP协议发送到网络中,并且接受其他节点通过BGP发送过来的路由,以生成全局的路由信息。还可以作为BGP路由反射器。
Typha
Typha是一个可选的组件,位于数据存储与Felix之间,通过减少每个节点对数据存储的影响来增加规模。Felix与Confd连接Typha,Typha再连接存储。
当超过50个Calico节点时,使用Typha来避免数据存储中的瓶颈和性能问题。但是etcdv3已经优化过很多客户端的情况,所以在使用etcdv3的情况下不建议使用Typha
。
https://docs.projectcalico.org/v3.11/reference/typha/
kube-controllers
https://docs.projectcalico.org/v3.11/reference/kube-controllers/configuration
属于Orchestrator
插件的范畴,每个主要的云编排平台都有独立的Orchestrator
插件,kubernetes就是kube-controllers
。通过监听kubernetes api来执行一些操作。
准备calico的yaml文件
官方提供了3个安装用的yaml文件。
分别是使用k8s存储少于或等于50个节点:
https://docs.projectcalico.org/v3.11/manifests/calico.yaml
使用k8s存储大于50个节点:
https://docs.projectcalico.org/v3.11/manifests/calico-typha.yaml
使用etcd存储:
https://docs.projectcalico.org/v3.11/manifests/calico-etcd.yaml
这里不搞这么复杂,使用etcd存储,etcdv3环境下不需要使用Typha。
下载calico-etcd.yaml文件以后,有3个地方需要修改一下:
修改calico-etcd.yaml
里的配置
1、连接etcd需要的证书。
把连接etcd的证书,放到secret对应的位置,因为secret里面都是base64编码的,所以使用提示的cat <file> | base64 -w 0
生成,然后放到对应位置就可以了。比如我这里:
[root@k8s-master ~]# cat calico-etcd/cacert.pem | base64 -w 0
LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUZ5ekNDQTdPZ0F3SUJBZ0lKQVBCL0x0d3VkRitJTUEwR0NTcUdTSWIzRFFFQkN3VUFNSHd4Q3pBSkJnTlYKQkFZVEFrTk9NUXN3Q1FZRFZRUUlEQUpDU2pFTE1Ba0dBMVVFQnd3Q1Frb3hFakFRQmdOVkJBb01DV0YwWlhOMApMbkIxWWpFTE1Ba0dBMVVFQ3d3Q2IzQXhGVEFUQmdOVkJBTU1ER05oTG1GMFpYTjBMbkIxWWpFYk1Ca0dDU3FHClNJYjNEUUVKQVJZTWIzQkFZWFJsYzNRdWNIVmlNQjRYRFRJd01ETXdOekF3TURZMU1Gb1hEVE13TURNd05UQXcKTURZMU1Gb3dmREVMTUFrR0ExVUVCaE1DUTA0eEN6QUpCZ05WQkFnTUFrSktNUXN3Q1FZRFZRUUhEQUpDU2pFUwpNQkFHQTFVRUNnd0pZWFJsYzNRdWNIVmlNUXN3Q1FZRFZRUUxEQUp2Y0RFVk1CTUdBMVVFQXd3TVkyRXVZWFJsCmMzUXVjSFZpTVJzd0dRWUpLb1pJaHZjTkFRa0JGZ3h2Y0VCaGRHVnpkQzV3ZFdJd2dnSWlNQTBHQ1NxR1NJYjMKRFFFQkFRVUFBNElDRHdBd2dnSUtBb0lDQVFEUVlPbWsyQXJhaDVOemJ3ZXBEcW5TRThmYUZoT0Z5K1Y3d2JzVgppMVBOL1BSTkdMU25hZGJldlQyUnZwMnRVMU1mVk1zVU05SEQzVnhydWk4bVNaNzh2NjAvMlZqSGorV2hxWDhlCng4U2ZJaU1SMmRLWEhDL1g1L2QvNE12SlYvTWlHV1VpZkxvdTc2a08vZmdzdTNjVjFwbzR2SzRvMmhyWDMzeHIKTEZZMnJwV2N5TTRmNTdwNlcwbGY3TjM5ZWpPdFNNYnNsMHdBdEJOUlQ2QmJwM2hhbW1BaTAwMHNQVHJBSlBmOQpHRGt5WU9EZ2FnNC8rL1VHTFlaMXRHSHlVRnRYSGdsVzNaWXlzd1MxeDlIcVB0ckNoODNzSjRLRjJ5Qy9QcStyClplcWMzQkhDRkZpNk0zMmcwMFlENzJFVU56elk2Rk1ZSmxiVFg2V0MydThwN1FoMlZmbjFtOXFPb3pyQVFSQWUKNG1MbXI2MlFmRU9IYWNRZTVaTnVSVUdwaEd4N1NsRHE2K1BvMmZjVXFqZEVCajlqY0xJSE1MU09kc3hWWFl1dQpIbmdCdkVDaE9aUGNURW4wRlZTbk9ndzhqdVlvSDh5d0s0WlZYeExlZWlheHcwUStkdnpmVjBvaVF3Z3ZjcDhvCmx1WW1mUksrY1hvT01iRFltRDhwWWNGMHhnL21QWHg2TVR2Y3M5WURwcnkrbWszWEMxTXczZHlQMnk3WnlSVU0KN1ZxZ0VnY00wbzZWMUU0YlhSV0cyYWttR0pHSnhzVWVvVXJBUWZhQ2c5WW9STkV3MWYxdVdHaTRvVmROMC9mQQpzUXBiMGkvODRXSFE1L0hDcFM2cnBhdWlWdlVpZ1gvY2NEa0lMSlNyQVJiTm5ISVl5VHhSRG9oQk1Qc1Y1VkxkCjZLd29Id0lEQVFBQm8xQXdUakFkQmdOVkhRNEVGZ1FVaEtMS0RLODVOVlNtWEJ5S0ttWndOM3Zuc1FZd0h3WUQKVlIwakJCZ3dGb0FVaEtMS0RLODVOVlNtWEJ5S0ttWndOM3Zuc1FZd0RBWURWUjBUQkFVd0F3RUIvekFOQmdrcQpoa2lHOXcwQkFRc0ZBQU9DQWdFQWV1cDhQK0lybjlZY3grRWNEY0NnQnlKT2kvNXZxWk1IUm96THk4VEp0c3BICjBwWFRvc2d4dWl1aTlBbnZweEcwMFYxK3RBVWp6NEtEQ3p5RWF4L3JuSHdUSlc4YmZ3bm9rRkNBMXJ2TW9oYWoKa3hYaUZ1cWlIU2xPcklidDFMcFpGRE9aVnBVb0tJNWtybGRicnIyMjJod3VXSjRGQWZBaWM3SEl3YlRwOEduSgpWaVBVSDBrZ3llak9VU2ZVdGkwUDBVa2o1S0U0L0F1M0RQRGVYWldUekdKTUJMMHRiZ0JKK1V4NHVpblhyUis5CldFN2kvaWFtVGJrTHhSRXNmQkJRMTNFZkliUHBxQ2JJS2VTZUtsUllkR3lHeVFlU0ExNHZtYlhoOVJFS3BhN0MKbWxUQm1TZnFLQU1Gd1RtYVlwclhRUkZ4Sm9Wb1RoZFRUOFdoRC9kV1BkQ1pCdzg0bEg3QkRQN0prY2k3V1J5RApkWXdhVExWZzRhRFBBZTFpdnp4d2x3QmFQdWR5SzhramxLcUdsOHdZQnhVZWRuMjNQM1dEOSs5YUNnTmtrUEVYCmdsUmtWc0NOcUxOcnhHL2w1RDB0eXdDc2pPYWV0RnFjdmRRWGlSNTc4U083cUNFQVVleGZxQjl5VTN0Z0JIUUcKa0lpME92eFRla0UxK1BxUWR0NlQ5R2xjS0RkUjhkc2Z4cnQ3T1hxTnJuMlIwOTUveUgwczRhK20xdzZDWld5RQpHaFlKNUV6d1k3ZXF0S0ZsTWR5eTNGdFllZFZyVCtwOTVlcGRmRnpKVDl1dTNGUGlwVk1Wa3loTmtyUjM1L1luCkY4ZWhZWUVORGE3b0phRXBXNGx3clR5RkdGZy9xZVBzL0JmZU5iaDdWOTlFTzVieS9PdDZucWFkUjZnRTFodz0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=
上面是ca证书文件,放到ca.crt位置:
以此类推。
2、连接etcd的地址。
填上etcd的地址,以及把注释的那个etcd证书路径
放到对应的位置。
完了之后是这个样子:
3、修改pods地址范围
CALICO_IPV4POOL_CIDR
这个位置
- name: CALICO_IPV4POOL_CIDR
value: "192.168.0.0/16"
改成你对应的地址范围, 我这里:
- name: CALICO_IPV4POOL_CIDR
value: "10.6.0.0/16"
4、修改calico工作模式
calico工作模式有2模式,一种是BGP对等技术
CALICO_IPV4POOL_IPIP`
- name: CALICO_IPV4POOL_IPIP
value: "Always"
这里的Always
表示使用IPIP
或VXLAN
,如果使用VXLAN
还需要CALICO_IPV4POOL_VXLAN
为Always
,但是没有测试过。
可以设置为: Always, CrossSubnet, Never
CrossSubnet
是IPIP与BGP混合模式。
这里修改CALICO_IPV4POOL_IPIP
为Never
orOff
来使用BGP。
上面的一些要修改的地方以及其他地方的意思:
https://docs.projectcalico.org/v3.11/getting-started/kubernetes/installation/config-options
https://docs.projectcalico.org/v3.11/reference/node/configuration
这样就可以应用了,只是里面的镜像地址是国外的,可能不好下载,如果需要的话可以使用我传到阿里云的地址,这里有介绍:
https://www.yxingxing.net/archives/kubernetes-20200117-inside-image
修改kubelet
参数
如果之前使用过flannel或者其他的cni插件,最好把/etc/cni目录删了,里面包含kubelet使用flannel插件的配置。不然的话就会成这样:
[root@k8s-node2 bin]# ls /etc/cni/net.d
10-calico.conflist 10-flannel.conflist calico-kubeconfig calico-tls
存放插件的那个目录倒是无所谓。
有三个参数:
--network-plugin # 调用的网络插件。写cni。
--cni-bin-dir # cni插件目录
--cni-conf-dir # cni配置目录
--cni-bin-dir
默认位置是/opt/cni/bin/
。
--cni-conf-dir
默认位置是 /etc/cni/net.d
。
这两个参数默认就行, calico安装以后会自动在目录里生成对应的文件。
所以,添加下面这一条就行了,然后重启kubelet。
--network-plugin=cni
重启以后kubelet日志里会报错:
==> kubelet.WARNING <==
E0310 20:35:14.300902 23198 kubelet.go:2187] Container runtime network not ready: NetworkReady=false reason:NetworkPluginNotReady message:docker: network plugin is not ready: cni config uninitialized
W0310 20:35:17.502225 23198 cni.go:237] Unable to update cni config: no networks found in /etc/cni/net.d
节点状态会变成NotReady:
[root@k8s-master ~]# kubectl get nodes
NAME STATUS ROLES AGE VERSION
k8s-node1 NotReady <none> 2d21h v1.16.7
k8s-node2 NotReady <none> 3d7h v1.16.7
k8s-node3 NotReady <none> 5h41m v1.16.7
这个没事, 只是因为kubelet的网络部分报错,下面把calico-etcd.yaml应用一下就好了。
应用yaml文件
[root@k8s-master ~]# kubectl apply -f calico-etcd.yaml
secret/calico-etcd-secrets created
configmap/calico-config created
clusterrole.rbac.authorization.k8s.io/calico-kube-controllers created
clusterrolebinding.rbac.authorization.k8s.io/calico-kube-controllers created
clusterrole.rbac.authorization.k8s.io/calico-node created
clusterrolebinding.rbac.authorization.k8s.io/calico-node created
daemonset.apps/calico-node created
serviceaccount/calico-node created
deployment.apps/calico-kube-controllers created
serviceaccount/calico-kube-controllers created
[root@k8s-master ~]#
[root@k8s-master ~]# kubectl get pods -n kube-system
NAME READY STATUS RESTARTS AGE
calico-kube-controllers-d669f4bdd-7gt25 0/1 ContainerCreating 0 7s
calico-node-65dgj 0/1 Init:0/2 0 8s
calico-node-gbsqt 0/1 Init:0/2 0 8s
calico-node-kxplx 0/1 Init:0/2 0 8s
等待。。。。。
[root@k8s-master ~]# kubectl get pods -n kube-system
NAME READY STATUS RESTARTS AGE
calico-kube-controllers-d669f4bdd-2qjnd 1/1 Running 0 5m25s
calico-node-f4qj4 1/1 Running 0 5m25s
calico-node-jg6zf 1/1 Running 0 5m25s
calico-node-jgwjg 1/1 Running 0 5m25s
[root@k8s-master ~]# kubectl get nodes
NAME STATUS ROLES AGE VERSION
k8s-node1 Ready <none> 2d21h v1.16.7
k8s-node2 Ready <none> 3d7h v1.16.7
k8s-node3 Ready <none> 5h50m v1.16.7
三、后续
calico把所有节点都当做了路由器,所以网络实现有点特殊。
安装完以后,在节点上会发现多了一个类型是dummy
的dummy0
网卡, 但是没有ip。
4: dummy0: <BROADCAST,NOARP> mtu 1500 qdisc noop state DOWN group default qlen 1000
link/ether 12:58:3d:08:0d:21 brd ff:ff:ff:ff:ff:ff
启动pod以后,容器的网卡没有关联到dummy0
上面。
容器的网络命名空间与主机是靠veth peer连接的。一般情况下这一端连在网桥上,比如docker0
,cni0
等, 另一端连接容器网络命名空间。
但是calico有点不一样了,这一端不连接在网桥上,他就是主机上一个独立的网卡。
再查看容器的网络信息,这里使用ip来查看容器的网络信息。
发现容器地址的掩码是32位的,这就表示它自己就是一个网络。所以也不可能会有网关之类的。
[root@k8s-node1 bin]# ip netns exec test1 ip addr show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
3: eth0@if7: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1440 qdisc noqueue state UP group default
link/ether da:c3:29:e5:55:72 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 10.6.36.65/32 scope global eth0
valid_lft forever preferred_lft forever
[root@k8s-node1 bin]# ip netns exec test1 ip route list
default via 169.254.1.1 dev eth0
169.254.1.1 dev eth0 scope link
默认路由就是直接从网卡设备发出,另一端也就到主机了。
通信方式:
pod中有默认路由,但是因为连接的veth网卡没有地址,所以就伪造了一个网关169.254.1.1,然后通过主机的arp代理响应veth网卡的mac。从而可以让pod中的arp请求成功,从而把数据发送到主机上。然后转发走。
有兴趣可以看看这个:
https://www.yxingxing.net/archives/calico-20200311-repeate#%E5%90%8E%E7%BB%AD
节点路由信息中包含所有pod的路由,而不是单单某个网段的路由。 从而知道直接发给哪个容器的网卡。
[root@k8s-node1 bin]# ip route list
default via 172.100.102.1 dev ens192 proto static metric 100
10.6.36.64 dev cali873cacc82fb scope link
blackhole 10.6.36.64/26 proto bird
10.6.36.65 dev cali89c77a2a7a4 scope link
10.6.107.192/26 via 172.100.102.73 dev ens192 proto bird
10.6.169.128/26 via 172.100.102.72 dev ens192 proto bird
172.17.0.0/16 dev docker0 proto kernel scope link src 172.17.0.1
172.100.102.0/24 dev ens192 proto kernel scope link src 172.100.102.71 metric 100
如果只是为了实现通信,把pod的网卡挂到没有地址的网桥上也是一样的,路由就可以写一个网段, 但是calico可能是为了实现网络策略,还有arp proxy,所以特意把pod的网卡单独出来管理。
同节点容器之间交换数据,有网桥那种方式是直接通过网桥交换数据。而calico这种都需要通过主机路由来实现。
容器veph peer网卡mtu是1440,是因为yaml文件里的configmap里的veth_mtu
配置的1440,默认是IPIP的设置。
BGP环境下,其实也无所谓,毕竟容器出来就是主机的3层路由了。主要还是用于隧道环境,这个大小作用于隧道网卡的MTU,因为多了一层IPIP或VXLAN的封装,不能超过物理传输MTU的大小。
一般环境纯BGP的,可以改成1500, IPIP 1480, VXLAN 1450。configmap改完以后需要重启calico-node节点。这个网址有介绍:
https://docs.projectcalico.org/v3.11/networking/mtu
重启calico-node。
kubectl rollout restart daemonset/calico-node -n kube-system
已经存在的容器网卡mtu不会变。
如何监控
https://docs.projectcalico.org/v3.11/maintenance/monitor-component-metrics
故障排除:
https://docs.projectcalico.org/maintenance/troubleshooting#configure-networkmanager