Kubernetes学习目录
1、基础知识
1.1、简介
Calico是一个开源的虚拟化网络方案,用于为云原生应用实现互联及策略控制.相较于 Flannel 来
说,Calico 的优势是对网络策略(network policy),它允许用户动态定义 ACL 规则控制进出容器的数据
报文,实现为 Pod 间的通信按需施加安全策略.不仅如此,Calico 还可以整合进大多数具备编排能力的环
境,可以为 虚机和容器提供多主机间通信的功能。
Calico 本身是一个三层的虚拟网络方案,它将每个节点都当作路由器,将每个节点的容器都当作是节点
路由器的一个终端并为其分配一个 IP 地址,各节点路由器通过 BGP(Border Gateway Protocol)学习
生成路由规则,从而将不同节点上的容器连接起来.因此,Calico 方案其实是一个纯三层的解决方案,通过每
个节点协议栈的三层(网络层)确保容器之间的连通性,这摆脱了 flannel host-gw 类型的所有节点必须
位于同一二层网络的限制,从而极大地扩展了网络规模和网络边界。
1.2、官网文档地址
官方地址:https://www.tigera.io/project-calico/
项目地址:https://github.com/projectcalico/calico
当前版本:3.26.0
1.3、网络模型
Calico为了实现更广层次的虚拟网络的应用场景,它支持多种网络模型来满足需求。
underlay network - BGP
overlay network - IPIP、VXLAN
1.4、设计思想
Calico不使用隧道或者NAT来实现转发,而是巧妙的把所有二三层流量转换成三层流量,并通过host上路由配置完成跨host转发。
2、模型简介
2.1、BGP
2.1.1、BGP-简介
BGP(Border Gateway Protocol - 边界网关协议) ,这是一种三层虚拟网络解决方案,也是Calico广为人知的一种网络模型。
它是互联网上一个核心的去中心化自治路由协议。
- 每个工作节点都是一个网络主机边缘节点。
由一个虚拟路由(vrouter)和一系列其他节点组成的一个自治系统(AS)。
- 各个节点上的vrouter基于BGP协议,通过互相学习的方式,动态生成路由规则,实现各节点之间的网络互通性。
BGP不使用传统的内部网关协议(IGP)的指标,而使用基于路径、网络策略或规则集来决定路由规则
它属于矢量路由协议。
这也是很多人从flannel切换到Calico之上的一个重要的考虑因素,VGP是一种纯粹的三层路由解决方案,并没有叠加,而是一种承载网络。
它有点类似于flannel的host-gw模型,但是与host-gw的区别在于,host-gw是由flanneld通过
kube-apiserver来操作etct内部的各种网络配置,进而实时更新到当前节点上的路由表中。
BGP方案中,各节点上的vRouter通过BGP协议学习生成路由表,基于路径、网络策略或规则集来动态生成路由规则
2.1.2、BGP模型划分
BGP模型根据主机容量来划分,可以分层两种网络模型:
小规模网络:BGP peer,以一对多(N-1)的方式,彼此更新网络信息,主机量多的时候,性能不好。因为每个节点都要进行(N-1)的网络信息更新,形成了mesh(网格)的效果
大规模网络:BGP Reflector,他以中央反射器的方式收集所有节点主机的信息,然后将收集后的信息,发布给所有节点,从而减轻集群中的路由同步的报文效率。但是我们需要对中央BGP反射器进行冗余处理。
简单来说,BGP就是通过动态生成的路由表的方式,以类似flannel的host-gw方式,来完成pod之间报文的直接路由,通信效率较高。
它要求所有的节点处于一个二层网络中,同时所有的主机也需要支持BGP协议。
2.1.3、BGP流程图
注意:如果节点是跨网段的话,会因为目标地址找不到,而无法发送数据包

2.2、IPIP
通过把一个IP数据包又套在一个IP包里,即把IP层封装到IP层的一个 tunnel,实现跨网段效果
2.3、VXLAN
2.3.1、vxlan简介
把数据包封装在UDP中,并使用物理网络的IP/MAC作为outer-header进行封装标识,然后在物理IP网上传输,"根据标识"到达目的地后由隧道终结点解封并将数据发送给目标虚拟机。
BGP要求所有的节点处于一个二层网络中,同时所有的主机也需要支持BGP协议。但是一旦我们要构建大
规模的网络集群,比如是一个B类网站,放了很多的节点主机,这个时候,由于网络报文无法被隔离,所以一
旦安全措施做的不到位的话,就会导致广播风暴,对我们产生很大的影响。所以,正常情况下,我们一般不推
荐在一个子网内创建大量的节点主机。所以一旦跨子网,BGP就不支持了。
所以VXLAN就实现了这样一种类似于 flannel的 VXLAN with directrouting的机制,演变出了一种 Vxlan With BGP的效果。
- 如果是同一网段,就使用BGP
- 如果不是同一网段,就用VXLAN机制
2.3.2、vxlan流程图
注意:calico默认的配置清单中,使用的是 IPIP方式,因为它默认节点中不支持BGP协议。

3、工作模型
3.1、前提
如果我们要使用calico的时候,必须要提前将 flannel 功能禁用,然后再安装calico。因为对于k8s来说,cni配置的是谁,他就用谁。
如删除flannel
kubectl delete -f flannel/kube-flannel.yml
3.1、软件架构
3.1.1、安装方式
calico支持的模式很多,但是默认情况下,calico不知道我们的节点是否支持 BGP,所以,默认情况下,
我们在安装calico的时候,它采用的模式是 IPIP模式。如果我们非要使用BGP模型的话,需要自己修改配置
清单文件或者选择适合我们自己的BGP配置。
参考资料: https://docs.projectcalico.org/getting-started/kubernetes/quickstart
3.1.2、Calico-架构图

3.1.3、架构说明
注意:以下三点不是calico的组成部分。
1、每个黑色的背景就是一个边缘自治节点,里面有很多工作中的pod对象
2、每个pod对象不像flannel通过一对虚拟网卡连接到cni0,而是直接连接到内核中。
3、借助于内核中的iptables 和 routers(路由表)来完成转发的功能
3.1.4、关键组件
组件 解析
Felix 每个节点都有,负责配置路由、ACL、向etcd宣告状态等
BIRD 每个节点都有,负责把 Felix 写入Kernel的路由信息 分发到整个Calico网络,确保workload 连通
etcd 存储calico自己的状态数据,可以结合kube-apiserver来工作
RouteReflector 路由反射器,用于集中式的动态生成所有主机的路由表,非必须选项
Calico 编排系统插件 实现更广范围的虚拟网络解决方案。
参考资料:https://docs.projectcalico.org/reference/architecture/overview
3.2、组件解析
由于Calico是一种纯三层的实现,因此可以避免与二层方案相关的数据包封装的操作,中间没有任何的NAT,
没有任何的overlay,所以它的转发效率可能是所有方案中最高的,因为它的包直接走原生TCP/IP的协议
栈,它的隔离也因为这个栈而变得好做。因为TCP/IP的协议栈提供了一整套的防火墙的规则,所以它可以通过IPTABLES的规则达到比较复杂的隔离逻辑。
3.2.1、Calico网络模型主要工作组件 - Felix
运行在每一台host的agent进程,主要负责网络接口管理和监听、路由规划、ARP管理、ACL管理和同步、状
态报告等。Felix会监听Etcd中心的存储,从它获取事件,比如说用户在这台机器上加了一个IP,或者是创
建了一个容器等,用户创建Pod后,Felix负责将其网卡、IP、MAC都设置好,然后在内核的路由表里面写一
条,注明这个IP应该到这张网卡。同样,用户如果制定了隔离策略,Felix同样会将该策略创建到ACL中,以实现隔离。
注意:这里的策略规则是通过内核的iptables方式实现的
3.2.2、Calico网络模型主要工作组件 - Etcd
分布式键值存储,主要负责网络元数据一致性,确保Calico网络状态的准确性,可以与Kubernetes共用。
简单来说:ETCD是所有calico节点的通信总线,也是calico对接到到其他编排系统的通信总线。
官方推荐;
< 50节点,可以结合 kube-apiserver 来实现数据的存储
> 50节点,推荐使用独立的ETCD集群来进行处理。
参考资料:https://docs.projectcalico.org/getting-started/kubernetes/self-managedonprem/onpremises
3.2.3、Calico网络模型主要工作组件 - BIRD
Calico为每一台host部署一个BGP Client,使用BIRD实现,BIRD是一个单独的持续发展的项目,实现了
众多动态路由协议比如:BGP、OSPF、RIP等。在Calico的角色是监听Host上由Felix注入的路由信息,然
后通过BGP协议广播告诉剩余Host节点,从而实现网络互通。BIRD是一个标准的路由程序,它会从内核里面
获取哪一些IP的路由发生了变化,然后通过标准BGP的路由协议扩散到整个其他的宿主机上,让外界都知道这
个IP在这里,你们路由的时候得到这里来。
3.2.4、Calico网络模型主要工作组件 - Route Reflector
在大型网络规模中,如果仅仅使用BGP Client形成mesh全网互联的方案就会导致规模限制,因为所有节点之
间两两互连,需要N^2个连接,为了解决这个规模问题,可以采用BGP的Route Reflector的方法,使所有
BGP Client仅与特定RR节点互连并做路由同步,从而大大减少连接数。
4、软件部署
4.1、准备工作
4.1.1、部署解析
对于calico在k8s集群上的部署来说,为了完成上面四个组件的部署,这里会涉及到两个部署组件
组件名 组件作用
calico-node 需要部署到所有集群节点上的代理守护进程,提供封装好的Felix和BIRD
calico-kube-controller 专用于k8s上对calico所有节点管理的中央控制器。负责calico与k8s集群的协同及calico核心功能实现。
4.1.2、部署步骤
1、获取资源配置文件
从calico官网获取相关的配置信息
2、定制CIDR配置
定制calico自身对于pod网段的配置信息,并且清理无关的网络其他插件
3、定制pod的manifest文件分配网络配置
默认的k8s集群在启动的时候,会有一个cidr的配置,有可能与calico进行冲突,那么我们需要修改一下
4、应用资源配置文件
4.1.3、注意事项
对于calico来说,它自己会生成自己的路由表,如果路由表中存在响应的记录,默认情况下会直接使
用,而不是覆盖掉当前主机的路由表
所以如果我们在部署calico之前,曾经使用过flannel,尤其是flannel的host-gw模式的话,一定
要注意,在使用calico之前,将之前所有的路由表信息清空,否则无法看到calico的tunl的封装效果。
4.2、环境部署
4.2.1、删除之前布署的flannel
kubectl delete -f flannel/kube-flannel.yml
# 为了确保不受flannel之前多余的路由影响,建议重启一下节点,确保cni0、flannel、flannel.1接口是不存在。
4.2.2、获取资源配置清单
# 建议单独下载
https://github.com/projectcalico/calico/blob/master/manifests/calico.yaml
4.2.3、准备本地镜像
# 查看需要的镜像
]# grep docker.io calico/calico.yaml | uniq
image: docker.io/calico/cni:master
image: docker.io/calico/node:master
image: docker.io/calico/kube-controllers:master
# 准备离线镜像
# 1)、下载node:master
docker pull calico/node:master
docker tag calico/node:master 192.168.10.33:80/k8s/calico/node:master
docker push 192.168.10.33:80/k8s/calico/node:master
# 2)、下载kube-controllers:master
docker pull kube-controllers:master
docker tag calico/kube-controllers:master 192.168.10.33:80/k8s/calico/kube-controllers:master
docker push 192.168.10.33:80/k8s/calico/kube-controllers:master
# 3)、下载cni:master
docker pull cni:master
docker tag calico/cni:master 192.168.10.33:80/k8s/calico/cni:master
docker push 192.168.10.33:80/k8s/calico/cni:master
# 修改下载镜像地址
sed -i 's#docker.io/calico#192.168.10.33:80/k8s/calico#g' calico.yaml
# 修改成功
master1 calico]# grep 'k8s/calico' calico.yaml
image: 192.168.10.33:80/k8s/calico/cni:master
image: 192.168.10.33:80/k8s/calico/cni:master
image: 192.168.10.33:80/k8s/calico/node:master
image: 192.168.10.33:80/k8s/calico/node:master
image: 192.168.10.33:80/k8s/calico/kube-controllers:master
4.2.4、配置CIDR
# 开放默认注释的 CALICO_IPV4POOL_CIDR 变量,然后定制我们当前的pod的网段范围即可
master1 calico]# vi calico.yaml
4800 - name: CALICO_IPV4POOL_CIDR
4801 value: "10.244.0.0/16"
4.2.5、定制pod的manifest文件分配网络配置
# 这里我们直接让calico使用kube-controller-manager为节点分配的网段信
master1 calico]# vi calico.yaml
71 "ipam": {
72 "type": "host-local",
73 "subnet": "usePodCidr"
74 },
4.2.6、应用资源配置清单
kubectl apply -f calico/calico.yaml
4.2.7、检查pod状态
master1 ~]# kubectl -n kube-system get pod -o wide| grep calico
calico-kube-controllers-74846594dd-tt6t8 1/1 Running 0 2m21s 10.244.3.3 node1 <none> <none>
calico-node-2gxlc 1/1 Running 0 2m21s 192.168.10.28 master3 <none> <none>
calico-node-8bjxx 1/1 Running 0 2m21s 192.168.10.27 master2 <none> <none>
calico-node-8gfbc 1/1 Running 0 2m21s 192.168.10.29 node1 <none> <none>
calico-node-dx8zx 1/1 Running 0 2m21s 192.168.10.30 node2 <none> <none>
calico-node-jhshc 1/1 Running 0 2m21s 192.168.10.26 master1 <none> <none>
4.2.8、查看节点主机的进程
node2 ~]# ps -ef | grep calico
root 79038 79036 0 17:27 ? 00:00:00 calico-node -confd
root 79039 79037 0 17:27 ? 00:00:00 calico-node -monitor-token
root 79040 79032 0 17:27 ? 00:00:00 calico-node -allocate-tunnel-addrs
root 79041 79033 0 17:27 ? 00:00:00 calico-node -status-reporter
root 79044 79031 0 17:27 ? 00:00:00 calico-node -monitor-addresses
root 79045 79030 0 17:27 ? 00:00:02 calico-node -felix
root 79477 79035 0 17:27 ? 00:00:00 bird6 -R -s /var/run/calico/bird6.ctl -d -c /etc/calico/confd/config/bird6.cfg
root 79478 79034 0 17:27 ? 00:00:00 bird -R -s /var/run/calico/bird.ctl -d -c /etc/calico/confd/config/bird.cfg
4.2.9、创建pod,验证calico是否生效
]# kubectl create deployment pod-dept --replicas=3 --image=192.168.10.33:80/k8s/pod_test:v0.1
]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod-dept-75cb4f74c8-888kd 1/1 Running 0 10s 10.244.4.5 node2 <none> <none>
pod-dept-75cb4f74c8-bklxw 1/1 Running 0 10s 10.244.3.5 node1 <none> <none>
pod-dept-75cb4f74c8-xpd6t 1/1 Running 0 10s 10.244.4.4 node2 <none> <none>
# 暴露一个service
]# kubectl expose deployment pod-dept --port=80 --target-port=80
# 访问测试
]# curl 10.111.204.254
kubernetes pod-test v0.1!! ClientIP: 10.244.137.64, ServerName: pod-dept-75cb4f74c8-888kd, ServerIP: 10.244.4.5!
]# curl 10.111.204.254
kubernetes pod-test v0.1!! ClientIP: 10.244.137.64, ServerName: pod-dept-75cb4f74c8-xpd6t, ServerIP: 10.244.4.4!
]# curl 10.111.204.254
kubernetes pod-test v0.1!! ClientIP: 10.244.137.64, ServerName: pod-dept-75cb4f74c8-bklxw, ServerIP: 10.244.3.5!
5、calico-网络解析
5.1、自动生成一个api版本信息
]# kubectl api-versions | grep crd
crd.projectcalico.org/v1
5.2、自动生成很多api资源
5.2.1、查询生成的资源
]# kubectl api-resources | grep crd.pro
bgpconfigurations crd.projectcalico.org/v1 false BGPConfiguration
bgpfilters crd.projectcalico.org/v1 false BGPFilter
bgppeers crd.projectcalico.org/v1 false BGPPeer
blockaffinities crd.projectcalico.org/v1 false BlockAffinity
caliconodestatuses crd.projectcalico.org/v1 false CalicoNodeStatus
clusterinformations crd.projectcalico.org/v1 false ClusterInformation
felixconfigurations crd.projectcalico.org/v1 false FelixConfiguration
globalnetworkpolicies crd.projectcalico.org/v1 false GlobalNetworkPolicy
globalnetworksets crd.projectcalico.org/v1 false GlobalNetworkSet
hostendpoints crd.projectcalico.org/v1 false HostEndpoint
ipamblocks crd.projectcalico.org/v1 false IPAMBlock
ipamconfigs crd.projectcalico.org/v1 false IPAMConfig
ipamhandles crd.projectcalico.org/v1 false IPAMHandle
ippools crd.projectcalico.org/v1 false IPPool
ipreservations crd.projectcalico.org/v1 false IPReservation
kubecontrollersconfigurations crd.projectcalico.org/v1 false KubeControllersConfiguration
networkpolicies crd.projectcalico.org/v1 true NetworkPolicy
networksets crd.projectcalico.org/v1 true NetworkSet
5.2.2、测试查询ippools资源
]# kubectl get ippools
NAME AGE
default-ipv4-ippool 178m
5.3、查询网络的模型
5.3.1、默认是ipip模型
]# kubectl describe ippools default-ipv4-ippool
Name: default-ipv4-ippool
Namespace:
Labels: <none>
Annotations: projectcalico.org/metadata: {"uid":"1d92a905-4c11-4d84-a53d-4999a4d64666","creationTimestamp":"2023-04-02T09:27:06Z"}
API Version: crd.projectcalico.org/v1
Kind: IPPool
Metadata:
Creation Timestamp: 2023-04-02T09:27:06Z
Generation: 1
Managed Fields:
API Version: crd.projectcalico.org/v1
Fields Type: FieldsV1
fieldsV1:
f:metadata:
f:annotations:
.:
f:projectcalico.org/metadata:
f:spec:
.:
f:allowedUses:
f:blockSize:
f:cidr:
f:ipipMode:
f:natOutgoing:
f:nodeSelector:
f:vxlanMode:
Manager: Go-http-client
Operation: Update
Time: 2023-04-02T09:27:06Z
Resource Version: 1194008
UID: ef561fbc-59df-4aae-8d39-21f83dac43da
Spec:
Allowed Uses:
Workload
Tunnel
Block Size: 26
Cidr: 10.244.0.0/16
Ipip Mode: Always
Nat Outgoing: true
Node Selector: all()
Vxlan Mode: Never
Events: <none>
5.3.2、说明
这里的calico采用的模型就是ipip模型,分配的网段是使我们定制的cidr网段,而且子网段也是我们定制的16位掩码。
5.4、查看calico启动后,节点网口的情况
]# ifconfig
tunl0: flags=193<UP,RUNNING,NOARP> mtu 1480
inet 10.244.136.0 netmask 255.255.255.255
master3 ]# route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 192.168.10.2 0.0.0.0 UG 100 0 0 ens33
10.244.3.2 192.168.10.29 255.255.255.255 UGH 0 0 0 tunl0
10.244.3.3 192.168.10.29 255.255.255.255 UGH 0 0 0 tunl0
10.244.3.4 192.168.10.29 255.255.255.255 UGH 0 0 0 tunl0
10.244.3.5 192.168.10.29 255.255.255.255 UGH 0 0 0 tunl0
10.244.4.2 192.168.10.30 255.255.255.255 UGH 0 0 0 tunl0
10.244.4.3 192.168.10.30 255.255.255.255 UGH 0 0 0 tunl0
10.244.4.4 192.168.10.30 255.255.255.255 UGH 0 0 0 tunl0
10.244.4.5 192.168.10.30 255.255.255.255 UGH 0 0 0 tunl0
10.244.104.0 192.168.10.30 255.255.255.192 UG 0 0 0 tunl0
10.244.136.0 0.0.0.0 255.255.255.192 U 0 0 0 *
10.244.137.64 192.168.10.26 255.255.255.192 UG 0 0 0 tunl0
10.244.166.128 192.168.10.29 255.255.255.192 UG 0 0 0 tunl0
10.244.180.0 192.168.10.27 255.255.255.192 UG 0 0 0 tunl0
172.17.0.0 0.0.0.0 255.255.0.0 U 0 0 0 docker0
192.168.10.0 0.0.0.0 255.255.255.0 U 100 0 0 ens33
环境创建完毕后,会生成一个tunl0的网卡,所有的流量会走这个tunl0网卡
5.5、捉包分析ipip网络模式
5.5.1、node2节点的pod发出一个icmp包
# node2节点的pod发出一个icmp包
master1 ~]# kubectl exec -it pod-dept-75cb4f74c8-888kd -- /bin/sh
[root@pod-dept-75cb4f74c8-888kd /]# ping -c 1 10.244.3.5
5.5.2、分析总结-捉到的包
# 192.168.10.29、192.168.10.30 是node1和node2的物理IP地址
node1 ~]# tcpdump -i ens33 -nn ip host 192.168.10.29 and host 192.168.10.30
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on ens33, link-type EN10MB (Ethernet), capture size 262144 bytes
20:43:44.424164 IP 192.168.10.30 > 192.168.10.29: IP 10.244.4.5 > 10.244.3.5: ICMP echo request, id 8704, seq 0, length 64 (ipip-proto-4)
20:43:44.424271 IP 192.168.10.29 > 192.168.10.30: IP 10.244.3.5 > 10.244.4.5: ICMP echo reply, id 8704, seq 0, length 64 (ipip-proto-4)
每个数据包都是基于双层ip嵌套的方式来进行传输,而且协议是 ipip-proto-4
结合路由的分发详情,可以看到具体的操作效果。
具体效果:10.244.4.5 -> 192.168.10.30 -> 192.168.10.29 -> 10.244.4.5
6、Calico-BGP网络
6.1、简单介绍
calico本身是一个复杂的系统,复杂到它自己提供一个非常重要的Restful接口,结合calicoctl命
令来管理自身的相关属性信息,calicoctl可以直接与etcd进行操作,也可以通过kube-apiserver的方式
与etcd来进行操作。默认情况下,它与kube-apiserver通信的认证方式与kubectl的命令使用同一个
context。但是我们还是推荐,使用手工定制的一个配置文件。
calicoctl 是运行在集群之外的,用于管理集群功能的一个重要的组件。calicoctl 的安装方式很
多,常见的方式有:单主机方式、kubectl命令插件方式、pod方式、主机容器方式。我们需要自己选择一种适合自己的方式
参考资料:https://docs.projectcalico.org/gettingstarted/clis/calicoctl/install
6.2、calicoctl
6.2.1、安装calicoctl
curl -o /usr/local/bin/calicoctl -O -L https://github.com/projectcalico/calico/releases/download/v3.25.1/calicoctl-linux-amd64
chmod +x /usr/local/bin/calicoctl
# 测试
]# calicoctl ipam show --allow-version-mismatch
+----------+---------------+-----------+------------+--------------+
| GROUPING | CIDR | IPS TOTAL | IPS IN USE | IPS FREE |
+----------+---------------+-----------+------------+--------------+
| IP Pool | 10.244.0.0/16 | 65536 | 5 (0%) | 65531 (100%) |
+----------+---------------+-----------+------------+--------------+
6.2.2、关联kube-apiserver
mkdir /etc/calico
cat >/etc/calico/calicoctl.cfg<<'EOF'
apiVersion: projectcalico.org/v3
kind: CalicoAPIConfig
metadata:
spec:
datastoreType: "kubernetes"
kubeconfig: "/etc/kubernetes/admin.conf"
EOF
master1 ~]# calicoctl get nodes --allow-version-mismatch
NAME
master1
master2
master3
node1
node2
我们可以通过 calicoctl 来操作kubectl操作的资源了,只不过显式的格式稍微有一点点的区别.
6.2.3、命令操作
]# calicoctl ipam show --allow-version-mismatch
+----------+---------------+-----------+------------+--------------+
| GROUPING | CIDR | IPS TOTAL | IPS IN USE | IPS FREE |
+----------+---------------+-----------+------------+--------------+
| IP Pool | 10.244.0.0/16 | 65536 | 5 (0%) | 65531 (100%) |
+----------+---------------+-----------+------------+--------------+
]# calicoctl ipam show --show-configuration --allow-version-mismatch
+--------------------+-------+
| PROPERTY | VALUE |
+--------------------+-------+
| StrictAffinity | false |
| AutoAllocateBlocks | true |
| MaxBlocksPerHost | 0 |
+--------------------+-------+
6.2.4、定制kubectl 插件子命令
cp -p /usr/local/bin/calicoctl /usr/local/bin/kubectl-calico
]# kubectl calico node status --allow-version-mismatch
Calico process is running.
IPv4 BGP status
+---------------+-------------------+-------+----------+-------------+
| PEER ADDRESS | PEER TYPE | STATE | SINCE | INFO |
+---------------+-------------------+-------+----------+-------------+
| 192.168.10.27 | node-to-node mesh | up | 01:31:06 | Established |
| 192.168.10.29 | node-to-node mesh | up | 01:31:06 | Established |
| 192.168.10.30 | node-to-node mesh | up | 01:31:06 | Established |
| 192.168.10.28 | node-to-node mesh | up | 01:31:13 | Established |
+---------------+-------------------+-------+----------+-------------+
IPv6 BGP status
No IPv6 peers found.
6.3、配置BGP网络
6.3.1、修改配置
# 查看ipv4 ippool资源
]# kubectl calico --allow-version-mismatch get ipPools
NAME CIDR SELECTOR
default-ipv4-ippool 10.244.0.0/16 all()
# 导出资源配置文件
]# kubectl calico --allow-version-mismatch get ipPools default-ipv4-ippool -o yaml >calico/default-ipv4-ippool.yml
# 修改资源配置清单
]# cat default-ipv4-ippool.yml
apiVersion: projectcalico.org/v3
kind: IPPool
metadata:
name: default-ipv4-ippool
spec:
allowedUses:
- Workload
- Tunnel
blockSize: 26
cidr: 10.244.0.0/16
ipipMode: CrossSubnet
natOutgoing: true
nodeSelector: all()
vxlanMode: Never
主要修改如下:
1、pipMode: Always 修改为 ipipMode: CrossSubnet
这样子就可以实现所谓的 BGP with vxlan的效果
6.3.2、应用资源配置清单
]# kubectl calico --allow-version-mismatch apply -f default-ipv4-ippool.yml
Successfully applied 1 'IPPool' resource(s)
6.3.3、分析节点路由变化
]# ip route list
default via 192.168.10.2 dev ens33 proto static metric 100
blackhole 10.244.0.0/26 proto bird
10.244.1.2 via 192.168.10.27 dev ens33 proto bird
10.244.1.3 via 192.168.10.27 dev ens33 proto bird
10.244.1.4 via 192.168.10.27 dev ens33 proto bird
10.244.2.0/26 via 192.168.10.28 dev ens33 proto bird
10.244.3.0/26 via 192.168.10.29 dev ens33 proto bird
10.244.4.0/26 via 192.168.10.30 dev ens33 proto bird
10.244.180.0/26 via 192.168.10.27 dev ens33 proto bird
172.17.0.0/16 dev docker0 proto kernel scope link src 172.17.0.1
192.168.10.0/24 dev ens33 proto kernel scope link src 192.168.10.26 metric 100
# 更新完毕配置后,动态路由的信息就发生改变了,不再完全是 tunl0 网卡了,而是变成了通过具体的,物理网卡ens33 转发出去了。
6.4、捉包验证
6.4.1、开启deployment控制器 3个pod
master1 ~]# kubectl create deployment dp-test --replicas=3 --image=192.168.10.33:/k8s/pod_test:v0.1
6.4.2、node开启捉包并且发出icmp包验证
master1 ~]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
dp-test-55b67b496-c79hd 1/1 Running 0 110m 10.244.3.4 node1 <none> <none>
dp-test-55b67b496-kst8x 1/1 Running 0 110m 10.244.3.5 node1 <none> <none>
dp-test-55b67b496-stffx 1/1 Running 0 110m 10.244.4.3 node2 <none> <none>
master1 ~]# kubectl exec -it dp-test-55b67b496-stffx -- /bin/sh
[root@dp-test-55b67b496-stffx /]# ping -c 1 10.244.3.4
64 bytes from 10.244.3.4: seq=0 ttl=62 time=0.385 ms
# Node1开启捉包
node1 ~]# tcpdump -i ens33 -nn ip host 10.244.3.4
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on ens33, link-type EN10MB (Ethernet), capture size 262144 bytes
14:11:14.063730 IP 10.244.4.3 > 10.244.3.4: ICMP echo request, id 5888, seq 0, length 64
14:11:14.063837 IP 10.244.3.4 > 10.244.4.3: ICMP echo reply, id 5888, seq 0, length 64
# 可以实现正常的通信效果,没有再次使用ipip的方式了。
7、BGP reflecter-进阶
7.1、基础知识
7.1.1、查询当前节点的网络情况
master1 ~]# kubectl calico node status
Calico process is running.
IPv4 BGP status
+---------------+-------------------+-------+----------+-------------+
| PEER ADDRESS | PEER TYPE | STATE | SINCE | INFO |
+---------------+-------------------+-------+----------+-------------+
| 192.168.10.27 | node-to-node mesh | up | 01:31:06 | Established |
| 192.168.10.29 | node-to-node mesh | up | 01:31:06 | Established |
| 192.168.10.30 | node-to-node mesh | up | 01:31:06 | Established |
| 192.168.10.28 | node-to-node mesh | up | 01:31:13 | Established |
+---------------+-------------------+-------+----------+-------------+
IPv6 BGP status
No IPv6 peers found.
当前的calico节点的网络状态是 BGP peer 的模型效果,也就是说 每个节点上都要维护 n-1 个路
由配置信息,整个集群中需要维护 n*(n-1) 个路由效果,这在节点量非常多的场景中,不是我们想要的。
所以我们需要实现一种 BGP reflecter 的效果。
7.1.2、反射器方案
一个集群中,至少需要一个反射器角色。
如果我们要做 BGP reflecter 效果的话,需要对反射器角色做冗余,如果我们的集群是一个多主集群
的话,可以将集群的master节点作为bgp的reflecter角色,从而实现反射器的冗余。
7.1.3、操作步骤
1、定制反射器角色
2、后端节点使用反射器
3、关闭默认的网格效果
7.2、设置为BGP reflecter模型
7.2.1、创建反射器角色
# 定义calico资源配置清单
kubectl calico --allow-version-mismatch apply -f - <<EOF
apiVersion: projectcalico.org/v3
kind: Node
metadata:
labels:
route-reflector: "true"
name: master1
spec:
bgp:
ipv4Address: 192.168.10.26/24
ipv4IPIPTunnelAddr: 10.244.0.1
routeReflectorClusterID: 1.1.1.1
EOF
# Successfully applied 1 'Node' resource(s)
属性解析;
metadata.labels 是非常重要的,因为它需要被后面的节点来进行获取
metadata.name 是通过 calicoctl get nodes 获取到的节点名称。
spec.bgp.ipv4Address 是指定节点的IP地址
spec.bgp.ipv4IPIPTunnelAddr 是指定节点上tunl0的IP地址
spec.bgp.routeReflectorClusterID 是BGP网络中的唯一标识,所以这里的集群标识只要唯一就可以了
7.2.2、将节点的网络模型更换为 reflecter模型
kubectl calico --allow-version-mismatch apply -f - <<EOF
kind: BGPPeer
apiVersion: projectcalico.org/v3
metadata:
name: bgppeer-demo
spec:
nodeSelector: all()
peerSelector: route-reflector=="true"
EOF
属性解析;
spec.nodeSelector 指定的所有后端节点
spec.peerSelector 指定的是反射器的标签,标识所有的后端节点与这个反射器进行数据交流
master1 ~]# kubectl calico get BGPPeer --allow-version-mismatch
NAME PEERIP NODE ASN
bgppeer-demo all() 0
master1 ~]# kubectl calico node status
IPv4 BGP status
+---------------+---------------+-------+----------+-------------+
| PEER ADDRESS | PEER TYPE | STATE | SINCE | INFO |
+---------------+---------------+-------+----------+-------------+
| 192.168.10.27 | node specific | up | 07:00:30 | Established |
| 192.168.10.28 | node specific | up | 07:00:30 | Established |
| 192.168.10.29 | node specific | up | 07:00:30 | Established |
| 192.168.10.30 | node specific | up | 07:00:30 | Established |
+---------------+---------------+-------+----------+-------------+
这个时候,节点的状态发生了改变,原来是PEER TYPE:node-to-node mesh 现在变成 PEER TYPE: node specific
7.2.3、关闭默认的网格效果
注意:
我使用的版本是Calico Cluster Version: 3.26.0,默认自动会做如下操作
如果node-to-node mesh与node specific并存的时候,请做如下操作:
kubectl calico --allow-version-mismatch apply -f - <<EOF
apiVersion: projectcalico.org/v3
kind: BGPConfiguration
metadata:
name: default
spec:
logSeverityScreen: Info
nodeToNodeMeshEnabled: false
asNumber: 63400
EOF
# Successfully applied 1 'BGPConfiguration' resource(s)
属性解析;
metadata.name 在这里最好是default,因为我们要对BGP默认的网络效果进行关闭
spec.nodeToNodeMeshEnabled 关闭后端节点的BGP peer默认状态 -- 即点对点通信关闭
spec.asNumber 指定的是后端节点间使用反射器的时候,我们要在一个标志号内,这里随意写一个
# 查看资源运行
master1 ~]# kubectl calico get BGPConfiguration --allow-version-mismatch
NAME LOGSEVERITY MESHENABLED ASNUMBER
default Info false 63400
# 效果如下:
master1 ~]# kubectl calico node status
Calico process is running.
IPv4 BGP status
+---------------+---------------+-------+----------+-------------+
| PEER ADDRESS | PEER TYPE | STATE | SINCE | INFO |
+---------------+---------------+-------+----------+-------------+
| 192.168.10.27 | node specific | up | 07:08:47 | Established |
| 192.168.10.29 | node specific | up | 07:08:47 | Established |
| 192.168.10.30 | node specific | up | 07:08:47 | Established |
| 192.168.10.28 | node specific | up | 07:08:47 | Established |
+---------------+---------------+-------+----------+-------------+
此时点对点已经没有,剩下反射器模式