一、下载配置calico yaml文件
curl https://docs.projectcalico.org/manifests/calico-etcd.yaml -o calico.yaml
二、修改文件
1、修改etcd的证书
[root@k8s-master ~]# cat /opt/etcd/ssl/ca.pem |base64 -w 0 [root@k8s-master ~]# cat /opt/etcd/ssl/server.pem |base64 -w 0 [root@k8s-master ~]# cat /opt/etcd/ssl/server-key.pem |base64 -w 0 将对应的都添进去,将注释去掉: # etcd-key: null 将对应ssl下的证书转换成base64编码放进来,并去掉注释 # etcd-cert: null # etcd-ca: null
2、要读取secret落地到容器中位置,直接将注释去掉就可以了
etcd_ca: "/calico-secrets/etcd-ca" etcd_cert: "/calico-secrets/etcd-cert" etcd_key: "/calico-secrets/etcd-key"
3、连接etcd的字符串,这与k8s连接API的字符串是一样的
这个是在[root@k8s-master1 ~]# cat /opt/kubernetes/cfg/kube-apiserver.conf 这个目录下,因为每个集群都是自己部署的,位置可能不一样
etcd_endpoints: "https://192.168.124.61:2379,https://192.168.124.62:2379,https://192.168.124.63:2379"
将这个证书放进放进calico配置中
4、根据实际网络规划修改Pod CIDR
默认的地址,需要改成自己的 - name: CALICO_IPV4POOL_CIDR value: "192.168.0.0/16"
[root@k8s-master ~]# cat /opt/kubernetes/cfg/kube-controller-manager.conf --cluster-cidr=10.244.0.0/16 在配置中改成这个 - name: CALICO_IPV4POOL_CIDR value: "10.244.0.0/16"
5、选择工作模式
IPIP # Enable IPIP - name: CALICO_IPV4POOL_IPIP value: "Always"
这个变量问你要不要开启IPIP,因为有两种模式,第一种就是IPIP,第二种就是BGP
其实它应用最多就是BGP,将这个Always改成Never,就是将它关闭的意思
二、删除flannel网络
1、删除yaml文件
[root@k8s-master k8s]# kubectl delete -f kube-flannel.yaml
2、删除路由
每个节点都要删除路由表和网桥,这是之前部署flannel留下的,也是避免和calico冲突。
[root@k8s-node1 ~]# ip route #查看路由 [root@k8s-node1 ~]# ip link delete cni0 [root@k8s-node1 ~]# ip link delete flannel.1 [root@k8s-node1 ~]# ip route delete 10.244.0.0/24 via 192.168.124.61 dev eth0 [root@k8s-node1 ~]# ip route delete 10.244.1.0/24 via 192.168.124.61 dev eth0
三、部署calico网络
[root@k8s-master calico]# kubectl create -f calico.yaml [root@master metrics_server]# kubectl get pod -o wide -n kube-system NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES calico-kube-controllers-d58dbc6bd-nczw8 1/1 Running 0 16h 192.168.124.61 k8s-master1 <none> <none> calico-node-fqdvd 1/1 Running 0 16h 192.168.124.63 k8s-node2 <none> <none> calico-node-kzwwf 1/1 Running 0 16h 192.168.124.61 k8s-master1 <none> <none> calico-node-s5cf8 1/1 Running 0 16h 192.168.124.62 k8s-node1 <none> <none> coredns-5ffbfd976d-9gb8c 1/1 Running 0 55m 10.244.36.64 k8s-node1 <none> <none> metrics-server-6dd556ccd4-57zdw 1/1 Running 0 54m 10.244.36.65 k8s-node1 <none> <none>
目前为止去查看网络,会发现不到calico的路由表,因为目前的pod没有使用当前的calico的网络,需要重建才会应用到,所以这也是会受到一些影响的,这个需要提前做好准备
重建这些pod之后,网络就会根据calico的规则生成路由表,你会发现之前的pod,使用flannel部署的pod已经无法互通了,所以切换网络也是一个比较大的事情,需要注意安排时间去做这件事
测试一下:
[root@master ~]# kubectl create deployment web --image=nginx [root@master ~]# kubectl scale deployment web --replicas=3 [root@master ~]# ip route default via 192.168.124.1 dev ens33 proto static metric 100 10.244.36.64/26 via 192.168.124.62 dev ens33 proto bird 10.244.169.128/26 via 192.168.124.63 dev ens33 proto bird blackhole 10.244.219.64/26 proto bird 172.17.0.0/16 dev docker0 proto kernel scope link src 172.17.0.1 192.168.124.0/24 dev ens33 proto kernel scope link src 192.168.124.61 metric 100
四、calico 管理工具
curl -O -L https://github.com/projectcalico/calicoctl/releases/download/v3.16.4/calicoctl mv calicoctl /usr/local/bin/ chmod +x /usr/local/bin/calicoctl
安装好这个管理工具之后就可以查看当前节点BGP的节点状态
[root@master ~]# calicoctl node status Calico process is running. IPv4 BGP status +----------------+-------------------+-------+----------+-------------+ | PEER ADDRESS | PEER TYPE | STATE | SINCE | INFO | +----------------+-------------------+-------+----------+-------------+ | 192.168.124.62 | node-to-node mesh | up | 01:35:46 | Established | | 192.168.124.63 | node-to-node mesh | up | 01:35:46 | Established | +----------------+-------------------+-------+----------+-------------+ IPv6 BGP status No IPv6 peers found.
这个工具主要也是往etcd里去操作,主要再etcd去获得,这个表只不过是帮你从etcd中拿出来格式化输出
可以通过这个命令可以看出,进行长链接输出出来
[root@master ~]# netstat -anpt |grep bird tcp 0 0 0.0.0.0:179 0.0.0.0:* LISTEN 79898/bird tcp 0 0 192.168.124.61:179 192.168.124.63:50255 ESTABLISHED 79898/bird tcp 0 0 192.168.124.61:179 192.168.124.62:60507 ESTABLISHED 79898/bird
如果想使用calicoctl get node,就需要指定配置文件了,默认在/etc/calico/calicoctl.cfg下
主要修改etcd的路径,还有它连接的证书,它主要操作etcd
mkdir /etc/calico vim /etc/calico/calicoctl.cfg apiVersion: projectcalico.org/v3 kind: CalicoAPIConfig metadata: spec: datastoreType: "etcdv3" etcdEndpoints: "https://192.168.124.61:2379,https://192.168.124.62:2379,https://192.168.124.63:2379" etcdKeyFile: "/opt/etcd/ssl/server-key.pem" etcdCertFile: "/opt/etcd/ssl/server.pem" etcdCACertFile: "/opt/etcd/ssl/ca.pem"
这样的话就能使用calicocatl get node了,这样的话就是在etcd中去拿的数据了
[root@master ~]# calicoctl get nodes NAME k8s-node1 k8s-node2 master
查看 IPAM的IP地址池:
[root@master ~]# calicoctl get ippool -o wide NAME CIDR NAT IPIPMODE VXLANMODE DISABLED SELECTOR default-ipv4-ippool 10.244.0.0/16 true Never Never false all()
Route Reflector 模式(RR)(路由反射)
https://docs.projectcalico.org/master/networking/bgp
1、关闭 node-to-node BGP网格
添加 default BGP配置,调整 nodeToNodeMeshEnabled和asNumber:
[root@k8s-master1 calico]# cat bgp.yaml apiVersion: projectcalico.org/v3 kind: BGPConfiguration metadata: name: default spec: logSeverityScreen: Info nodeToNodeMeshEnabled: false asNumber: 63400
直接应用一下,当我们禁用node-to-node mesh的时候,网络立马就会断,所以断的话要提前做好影响的范围,也就是切换这个网络是需要断网的,使用node-to-node BGP这种也是建议100个节点以下,当超过100台节点一定要使用路由反射RR模式
[root@k8s-master1 calico]# calicoctl apply -f bgp.yaml Successfully applied 1 'BGPConfiguration' resource(s)
查看bgp网络配置情况,false为关闭
[root@k8s-master1 calico]# calicoctl get bgpconfig NAME LOGSEVERITY MESHENABLED ASNUMBER default Info false 63400
去查看pod的网络测试已经断开了,这里是因为我们使用caclico的配置禁用了node-to-node mesh了
[root@k8s-master1 calico]# ping 10.244.245.2 PING 10.244.245.2 (10.244.245.2) 56(84) bytes of data
ASN号可以通过获取 # calicoctl get nodes --output=wide
这里有个编号,ASN64300,一个编号就是一个自治系统
[root@k8s-master1 calico]# calicoctl get nodes --output=wide NAME ASN IPV4 IPV6 k8s-master1 (63400) 10.4.7.11/24 k8s-node1 (63400) 10.4.7.12/24 k8s-node2 (63400) 10.4.7.21/24
2、配置指定节点充当路由反射器
为方便让BGPPeer轻松选择节点,通过标签选择器匹配,也就是可以去调用k8s里面的标签进行关联,我们可以给哪个节点作为路由发射器打个标签
给路由器反射器节点打标签,我这将node1打上标签
[root@k8s-master1 calico]# kubectl label node k8s-node1 route-reflector=true
查看node BJP的节点状态,因为禁用了网格,所以这里都关闭了,所以也就不通了。
[root@k8s-master1 calico]# calicoctl node status Calico process is running. IPv4 BGP status No IPv4 peers found. IPv6 BGP status No IPv6 peers found.
然后配置路由器反射器节点routeReflectorClusterID,增加一个集群节点的ID
下面的可以通过-o yaml输出出来
[root@k8s-master1 calico]# calicoctl get node k8s-node2 -o yaml > node.yaml apiVersion: projectcalico.org/v3 kind: Node metadata: annotations: projectcalico.org/kube-labels: '{"beta.kubernetes.io/arch":"amd64","beta.kubernetes.io/os":"linux","kubernetes.io/arch":"amd64","kubernetes.io/hostname":"k8s-node2","kubernetes.io/os":"linux"}' creationTimestamp: "2020-11-05T01:34:20Z" labels: beta.kubernetes.io/arch: amd64 beta.kubernetes.io/os: linux kubernetes.io/arch: amd64 kubernetes.io/hostname: k8s-node2 kubernetes.io/os: linux name: k8s-node2 resourceVersion: "208633" uid: 82582f30-602c-452c-b3ed-6e77d72200d7 spec: bgp: ipv4Address: 192.168.124.63/24 routeReflectorClusterID: 244.0.0.1 orchRefs: - nodeName: k8s-node2 orchestrator: k8s status: {}
routeReflectorClusterID: 244.0.0.1 唯一网络
执行:
[root@k8s-master1 calico]# calicoctl apply -f node.yaml
将其他的节点去连接这个k8s-node1打标签的路由发射器
[root@k8s-master1 calico]# cat bgp1.yaml apiVersion: projectcalico.org/v3 kind: BGPPeer metadata: name: peer-with-route-reflectors spec: nodeSelector: all() #所有的节点 peerSelector: route-reflector == 'true'
查看节点的BGP规则与连接状态,这样的话就显示一个路由反射器的节点
[root@k8s-master1 calico]# calicoctl apply -f bgp1.yaml Successfully applied 1 'BGPPeer' resource(s) [root@k8s-master1 calico]# calicoctl get bgppeer NAME PEERIP NODE ASN peer-with-route-reflectors all() 0 [root@k8s-master1 calico]# calicoctl node status Calico process is running. IPv4 BGP status +--------------+---------------+-------+----------+-------------+ | PEER ADDRESS | PEER TYPE | STATE | SINCE | INFO | +--------------+---------------+-------+----------+-------------+ | 192.168.124.63 | node specific | up | 08:22:22 | Established | +--------------+---------------+-------+----------+-------------+ IPv6 BGP status No IPv6 peers found.
测试与容器连接
添加多个路由反射器
现在进行对路由反射器添加多个,100个节点以内建议2-3个路由反射器
1、进行对集群节点打标签
[root@k8s-master1 calico]# kubectl label node k8s-node2 route-reflector=true node/k8s-node2 labeled
2、对k8s-node2添加然后配置路由器反射器节点
[root@k8s-master1 calico]# calicoctl get node k8s-node2 -o yaml > node2.yaml [root@k8s-master1 calico]# vim node2.yaml 增加 routeReflectorClusterID: 244.0.0.1 [root@k8s-master1 calico]# calicoctl apply -f node2.yaml
3、查看节点状态
[root@k8s-master1 calico]# calicoctl node status Calico process is running. IPv4 BGP status +--------------+---------------+-------+----------+-------------+ | PEER ADDRESS | PEER TYPE | STATE | SINCE | INFO | +--------------+---------------+-------+----------+-------------+ | 192.168.124.62 | node specific | up | 08:22:22 | Established | | 192.168.124.63 | node specific | up | 08:44:44 | Established | +--------------+---------------+-------+----------+-------------+
4、试网络连通性
IPIP模式
ipip模式与flannel的vxlan模式类似,这个也是对数据包的一个封装
Flannel host-gw 模式最主要的限制,就是要求集群宿主机之间是二层连通的。而这个限制对于 Calico 来说,也同样存在,也是不能跨vlan的,主要局限就是数据包主要封装的是容器,源IP和目的IP,因为它们工作都是使用的二层,所以二层它不会考虑容器之间进行数据包转发的,但如果添加路由表,将目的的IP通过静态路由的方式也能实现,不同vlan的数据的通信,不过这种方式目前没有测试。
另外还有一个弊端,会发现calico的路由表比flannel的多一些,因为它里面还要加一些传入过来的到设备的路由表信息,就是每个pod都加一个路由表,所以它的路由表的量也比flannel大不少。
1、修改为IPIP模式:
[root@master ~]# calicoctl get ippool -o yaml > ipip.yaml [root@master ~]# vi ipip.yaml apiVersion: projectcalico.org/v3 kind: IPPool metadata: name: default-ipv4-ippool spec: blockSize: 26 cidr: 10.244.0.0/16 ipipMode: Always natOutgoing: true [root@master ~]# calicoctl apply -f ipip.yaml
2、创建好之后查看详细信息,已经开启ippool
[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()
3、查看网络设备会增加一个tunl0,增加了一个隧道的网卡
tunl0@NONE: <NOARP,UP,LOWER_UP> mtu 1440 qdisc noqueue state UNKNOWN group default qlen 1000 link/ipip 0.0.0.0 brd 0.0.0.0 inet 10.244.113.131/32 brd 10.244.113.131 scope global tunl0 valid_lft forever preferred_lft forever
4、测试网络
CNI 网络方案优缺点及最终选择
先考虑几个问题:
需要细粒度网络访问控制?这个flannel是不支持的,calico支持,所以做多租户网络方面的控制ACL,那么要选择calico
追求网络性能?这两个方案无疑是flannel和calico的路由方案是最高的,也就是flannel的host-gw和calico的BGP。
服务器之前是否可以跑BGP协议?很多的公有云是不支持跑BGP协议的,那么使用calico的BGP模式自然是不行的。
集群规模多大?如果规模不大,100节点以下维护起来比较方面之间可以使用flannel就可以
是否有维护能力?calico的路由表很多,而且走BGP协议,一旦出现问题排查起来也比较困难,上百台的,路由表去排查也是很麻烦,这个具体的需求也是跟自己饿的情况而定。