k8s通过CNI接口接入其他插件来实现网络通讯。目前比较流行的插件有flannel,calico等。CNI插件存放位置:# cat /etc/cni/net.d/10-flannel.conflist
插件使用的解决方案如下:
- 虚拟网桥,虚拟网卡,多个容器共用一个虚拟网卡进行通信。
- 多路复用:MacVLAN,多个容器共用一个物理网卡进行通信。
- 硬件交换:SR-LOV,一个物理网卡可以虚拟出多个接口,这个性能最好。
Flannel是CoreOS团队针对Kubernetes设计的一个网络规划服务,简单来说,它的功能是让集群中的不同节点主机创建的Docker容器都具有全集群唯一的虚拟IP地址。
在默认的Docker配置中,每个节点上的Docker服务会分别负责所在节点容器的IP分配。这样导致的一个问题是,不同节点上容器可能获得相同的内外IP地址。并使这些容器之间能够之间通过IP地址相互找到,也就是相互ping通。
Flannel的设计目的就是为集群中的所有节点重新规划IP地址的使用规则,从而使得不同节点上的容器能够获得“同属一个内网”且”不重复的”IP地址,并让属于不同节点上的容器能够直接通过内网IP通信。
flannel支持多种后端:
[root@server3 ~]# yum install -y bridge-utils
[root@server3 ~]# brctl show
[root@server3 ~]# ip addr
server2用cni0进行通信,server3和server4利用flannel进行通信
bridge fdb:查看主机ip对应的MAC地址
server3对应的MAC地址为f6:5a:8b:dc:8a:b6
[root@server2 ingress]# kubectl -n kube-system get cm
[root@server2 ingress]# kubectl -n kube-system edit cm kube-flannel-cfg ##修改
configmap/kube-flannel-cfg edited
"Type": "host-gw"
删除重建会自动更新
[root@server2 ingress]# kubectl get pod -n kube-system | grep kube-flannel | awk '{system("kubectl delete pod "$1" -n kube-system")}'
查看各个节点网关(server4为关闭状态,所以未改变)
flannel实现的是网络通信,calico的特性是在pod之间的隔离。
通过BGP路由,但大规模端点的拓扑计算和收敛往往需要一定的时间和计算资源。
纯三层的转发,中间没有任何的NAT和overlay,转发效率最好。
Calico 仅依赖三层路由可达。Calico 较少的依赖性使它能适配所有 VM、Container、白盒或者混合环境场景。
网络架构:
真实主机获取calico.yaml和calico的压缩包,然后将压缩包发送给server1,将calico.yaml发送到server2的/root/calico目录下
从官方获取文档
[root@server2 service]# mkdir calico
[root@server2 service]# cd calico/
[root@server2 calico]# wget https://docs.projectcalico.org/manifests/calico.yaml --no-check-certificate
[root@server2 calico]# vim calico.yaml 查看image镜像文件
拉取所需镜像并上传至仓库
[root@server1 ~]# docker pull calico/cni:v3.22.1
[root@server1 ~]# docker pull calico/pod2daemon-flexvol:v3.22.1
[root@server1 ~]# docker pull calico/node:v3.22.1
[root@server1 ~]# docker pull calico/kube-controllers:v3.22.1
[root@server1 ~]# docker images | grep calico | awk '{system("docker tag "$1":"$2" reg.westos.org/"$1":"$2"")}'
[root@server1 ~]# docker images | grep reg.westos.org/calico | awk '{system("docker push "$1":"$2"")}'
[root@server2 calico]# vim calico.yaml ##修改镜像下载地址,与仓库保持一致
注意:在执行前需要删除flannel,否则有冲突
每个节点都要删除10-flannel.conflist
[root@server2 calico]# kubectl apply -f calico.yaml
查看节点
切换完成之后,测试一下
server2进入calico目录下编辑deny-nginx.yaml配置文件
[root@server2 calico]# vim deny-nginx.yml
[root@server2 calico]# cat deny-nginx.yml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-nginx
spec:
podSelector:
matchLabels:
app: myapp
要进行限制访问的是标签为myapp的pod容器
删除depoly相关的配置文件
[root@server2 ~]# cd pod/
[root@server2 pod]# kubectl delete -f depoly.yml
应用下列yml配置文件,查看服务,看到ip,对这两个地址测试访问,发现
[root@server2 pod]# kubectl apply -f depoly.yml
deployment.apps/deployment-myapp created
[root@server2 pod]# cd
[root@server2 ~]# cd service/calico/
[root@server2 calico]# ls
calico.yaml deny-nginx.yml
[root@server2 calico]# kubectl apply -f deny-nginx.yml
对这两个地址测试访问,发现web1访问失败,web2访问成功
因为web1的pod的标签都是myapp,已经设置了限制访问
使用nginx镜像拉起一个新的容器,名为demo
查看demo容器所在节点地址,测试访问,看到可以成功访问
使用busyboxplus镜像拉起一个新容器,标签为test,然后进入该容器去访问demo,可以看到访问成功,再去访问myapp的节点地址,发现能访问
编辑deny-nginx.yaml配置文件,配置可以访问myapp服务的容器,这里是test
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-myapp
spec:
podSelector:
matchLabels:
app: myapp
---
kind: NetworkPolicy
metadata:
name: access-myapp
spec:
podSelector:
matchLabels:
app: myapp
ingress:
- from:
- podSelector:
matchLabels:
app: test
编辑完成后应用配置,查看网络策略,可以看到配置好的策略
连接test容器,访问myapp服务,现在可以正常访问了