当前位置:   article > 正文

Kubenetes(3)--网络通信(2)--flannel和calico_如何查看k8s 集群用 calico 还是flannel

如何查看k8s 集群用 calico 还是flannel

一、flannel

1.1、flannel 插件的基本介绍

        Flannel由CoreOS推出,解决跨主机通信的一种方式;支持3种实现:UDP、VXLAN、host-gw
        udp模式:使用设备flannel.0进行封包解包,不是内核原生支持,上下文切换较大,性能非常差;

        vxlan模式:使用flannel.1进行封包解包,内核原生支持,性能较强;

        host-gw模式:无需flannel.1这样的中间设备,直接宿主机当作子网的下一跳地址,性能最强,host-gw的性能损失大约在10%左右,而其他所有基于VXLAN“隧道”机制的网络方案,性能损失在20%~30%左右

1.2、flannel的跨主机通信模式:VXLAN

1.2.1 、什么是VXLAN

        VXLAN,即Virtual Extensible LAN(虚拟可扩展局域网),是Linux本身支持的一网种网络虚拟化技术。VXLAN可以完全在内核态实现封装和解封装工作,从而通过“隧道”机制,构建出覆盖网络(Overlay Network)

1.2.2 、VXLAN的设计过程

        在现有的三层网络之上,“覆盖”一层虚拟的、由内核VXLAN模块负责维护的二层网络,使得连接在这个VXLAN二nfcu网络上的“主机”(虚拟机或容器都可以),可以像在同一个局域网(LAN)里那样自由通信。
        为了能够在nfcu网络上打通“隧道”,VXLAN会在宿主机上设置一个特殊的网络设备作为“隧道”的两端,叫VTEP:VXLAN Tunnel End Point(虚拟隧道端点)

1.2.3、VXLAN的工作原理

图 1 fannel--vxlan模式解释

图例解释:

        Container:即运行的容器--包含各自的IP;

        Cni0:网桥设备,没创建一个POD都会创建一对veth pair。其中一端是POD中的eth0,另一端是Cni0网桥中的端口(即网卡)

        Flanel.1:TUN设备(虚拟网卡),用来进行VXLAN报文的处理(封装和解封)。不同node之间的pod数居流都是从高overlay设备以隧道模式发送到对端的。

        Flanneld:flannel在每个主机中运行flanneld作为agent,它会为所在主机从集群的网络地址空间中,获取一个小的网段subnet,本主机内所有容器的IP地址都将从中分配。同时Flanneld监听K8s集群数据库,为flannel1设备提供封装数据时必要的mac、ip等网络数据信息。

过程解释:

        1、当要发送数据包时,首先通过veth pair发送到cni网桥,再路由到本机的flannel.1设备进行处理;

        2、VTEP设备之间通过二层数据桢进行通信;源VTEP设备收到原始IP包后,在上面加上一个目的MAC地址,封装成一个导去数据桢,发送给目的VTEP设备(获取 MAC地址需要通过三层IP地址查询,这是ARP表的功能);

        3、对于得到的内部数据帧,并不能在宿主机的二层网络传输,Linux内核还需要把它进一步封装成为宿主机的一个普通的数据桢,好让它带着“内部数据桢”通过宿主机的eth0进行传输,Linux会在内部数据桢前面,加上一个VXLAN头,VXLAN头里有一个重要的标志叫VNI,它是VTEP识别某个数据桢是不是应该归自己处理的重要标识。

        4、当数据伪装完毕则可以通过eth0进行转发,然后到目的主机进行相应的解析即可。

        其中在Flannel中,VNI的默认值是1,这也是为什么宿主机的VTEP设备都叫flannel.1的原因;一个flannel.1设备只知道另一端flannel.1设备的MAC地址,却不知道对应的宿主机地址是什么。
        在linux内核里面,网络设备进行转发的依据,来自FDB的转发数据库,这个flannel.1网桥对应的FDB信息,是由flanneld进程维护的。linux内核再在IP包前面加上二层数据桢头,把Node2的MAC地址填进去。这个MAC地址本身,是Node1的ARP表要学习的,需Flannel维护,这时候Linux封装的“外部数据桢”的格式如下
在这里插入图片描述

图 2 vxlan报文示意图


1.3 host-gw模式和directrouting的设置和测试

1.3.1 host-gw模式

        host-gw是一种纯三层网络的方案,性能最高。

        工作原理:就是将每个Flannel子网的下一跳,设置成了该子网对应的宿主机的IP地址,也就是说,宿主机(host)充当了这条容器通信路径的“网关”(Gateway),这正是host-gw的含义。所有的子网和主机的信息,都保存在Etcd中,flanneld只需要watch这些数据的变化 ,实时更新路由表就行了。
        核心:IP包在封装成桢的时候,使用路由表的“下一跳”设置上的MAC地址,这样可以经过二层网络到达目的宿主机。

  1. ##host-gw模式
  2. [root@server1 fannel]# cp ~/kube-flannel.yml . ##将flannel.yml pod清单复制到当前目录下
  3. [root@server1 fannel]# vim kube-flannel.yml ##编辑kube-flannel.yml文件,将网络类型改为直接路由模式(host-gw)
  4. [root@server1 fannel]# kubectl apply -f kube-flannel.yml
  5. Warning: policy/v1beta1 PodSecurityPolicy is deprecated in v1.21+, unavailable in v1.25+
  6. podsecuritypolicy.policy/psp.flannel.unprivileged created
  7. clusterrole.rbac.authorization.k8s.io/flannel created
  8. clusterrolebinding.rbac.authorization.k8s.io/flannel created
  9. serviceaccount/flannel created
  10. configmap/kube-flannel-cfg created
  11. daemonset.apps/kube-flannel-ds created
  12. [root@server1 fannel]# kubectl get pod -n kube-system ## 查看flannel网络插件应用成功
图 3 编辑配置文件,重启p服务

 

图 4 host-gw模式修改的内容

 

         查看三台Node的IP,发现都存在gw:10.96.0.1/32

图 5查看server1 的IP

 

图 6 查看server2的IP

 

图 7 查看server3 的IP

创建测试用例:

  1. ###创建pod:
  2. [root@server1 network]# vim pod2.yml
  3. 1 Version: apps/v1
  4. 2 kind: Deployment
  5. 3 metadata:
  6. 4 name: deployment-example
  7. 5 spec:
  8. 6 replicas: 4
  9. 7 selector:
  10. 8 matchLabels:
  11. 9 app: myapp
  12. 10 template:
  13. 11 metadata:
  14. 12 labels:
  15. 13 app: myapp
  16. 14 spec:
  17. 15 containers:
  18. 16 - name: myapp
  19. 17 image: nginx
  20. ##创建服务:
  21. 1 nd: Service
  22. 2 apiVersion: v1
  23. 3 metadata:
  24. 4 name: myservice
  25. 5 spec:
  26. 6 ports:
  27. 7 - protocol: TCP
  28. 8 port: 80
  29. 9 targetPort: 80
  30. 10 selector:
  31. 11 app: myapp
  32. 12 type: NodePort

查看节点上的IP:10.224.1.0/24  10.224.2.0/24

通过外部访问:不卡顿,server2 server3 轮循访问

图 8 查看具体服务信息

 

 

图 9 查看访问结果

 

 1.3.2 Flannel——vxlan+Directrouting模式

  1. ##删除之前的模式:
  2. [root@server1 fannel]# kubectl delete -f kube-flannel.yml
  3. ##重新设置配置
  4. [root@server1 fannel]# vim kube-flannel.yml
  5. ##应用新的配置
  6. [root@server1 fannel]# kubectl apply -f kube-flannel.yml
  7. ##查看服务是否启动
  8. [root@server1 fannel]# kubectl get pod -n kube-system
图 10 Directrouting模式的配置文件

 

图 11 查看重启后的服务

使用curl进行访问测试,和host-gw相同,这里不再赘述。

二、calico

        默认当前的通信模式为calico,具体切换方式,请查看文章:

kubernetes---fannel和calico之间的切换

        官方参考:

https://projectcalico.docs.tigera.io/getting-started/kubernetes/self-managed-onprem/onpremises

2.1 基本介绍

        Fannal只解决通信,没有策略,k8s本事有相应的策略,但是需要相应的服务进行支持。

        Calico 就是一种开源网络和网络安全解决方案,适用于容器,虚拟机和基于主机的本机工作负载。Calico 支持广泛的平台,包括 Kubernetes,docker,OpenStack 和裸机服务。Calico 后端支持多种网络模式。

三种模式:

        BGP 模式:将节点做为虚拟路由器通过 BGP 路由协议来实现集群内容器之间的网络访问。

        IPIP 模式:在原有 IP 报文中封装一个新的 IP 报文,新的 IP 报文中将源地址 IP 和目的地址 IP 都修改为对端宿主机 IP。

        cross-subnet:Calico-ipip 模式和 calico-bgp 模式都有对应的局限性,对于一些主机跨子网而又无法使网络设备使用 BGP 的场景可以使用 cross-subnet 模式,实现同子网机器使用 calico-BGP 模式,跨子网机器使用 calico-ipip 模式。

网络架构:

        Felix: 监听ECTD中心的存储获取事件,用户创建pod后,Felix负责将其网卡、IP、MAC都设置好,然后在内核的路由表里面写一条,注明这个IP应该到这张网卡。同样如果用户制定了限离策略,Felix同样会将该策略创建到ACL中,以实现隔离。

        BIRD: 一个标准的路由程序,它会从内核里面获取哪一些IP的路由发生了变化,然后通过标准 BGP的路由协议扩散到整个其他的宿主机上,让外界都知道这个P在这里,路由的时候到这里来。

图 12 calico 的通信模型

2.2 应用和配置

2.2.1 安装和配置

  1. ##安装和配置calico
  2. ##下载配置文件
  3. curl https://projectcalico.docs.tigera.io/manifests/calico.yaml -O
  4. ##根据配置文件,下载相应的镜像
  5. [root@server1 fannel]# docker pull docker.io/calico/cni:v3.22.2
  6. [root@server1 fannel]# docker pull docker.io/calico/pod2daemon-flexvol:v3.22.2
  7. [root@server1 fannel]# docker pull docker.io/calico/node:v3.22.2
  8. [root@server1 fannel]# docker pull docker.io/calico/kube-controllers:v3.22.2
  9. ##编写配置文件的模式,设置IPIP为OFF
  10. ##应用配置文件
  11. [root@server1 calico]# kubectl apply -f calico.yaml
  12. ##查看应用状态
  13. [root@server1 calico]# kubectl get pod -n kube-system
  14. [root@server1 calico]# kubectl get daemonset.apps -n kube-system
  15. ##查看运行的模式
  16. [root@server1 calico]# kubectl describe ippools
图 13 设置指IPIP为off
图14 使fannel网络生效

 

图 15 查看服务是否启动
图 16 查看启动的方式

 2.2.2 基本的通信状态

  1. ##配置pod和svc,查看通信状态
  2. [root@server1 network]# cat pod2.yml
  3. apiVersion: apps/v1
  4. kind: Deployment
  5. metadata:
  6. name: deployment-example
  7. spec:
  8. replicas: 4
  9. selector:
  10. matchLabels:
  11. app: myapp
  12. template:
  13. metadata:
  14. labels:
  15. app: myapp
  16. spec:
  17. containers:
  18. - name: myapp
  19. image: nginx
  20. [root@server1 network]# cat server2.yml
  21. kind: Service
  22. apiVersion: v1
  23. metadata:
  24. name: myservice
  25. spec:
  26. ports:
  27. - protocol: TCP
  28. port: 80
  29. targetPort: 80
  30. selector:
  31. app: myapp
  32. type: NodePort
  33. ##查看路由环,观察通信模式
  34. [root@server1 network]# ip route
图 17 查看路由环

 2.2.3 打开隧道模式,分配固定的pod ip网段

  1. [root@server1 calico]# vim calico.yaml
  2. # Enable IPIP
  3. - name: CALICO_IPV4POOL_IPIP
  4. value: "Always"
  5. - name: CALICO_IPV4POOL_CIDR
  6. value: "192.168.0.0/16"
  7. [root@server1 calico]# kubectl apply -f calico.yaml
图 18 设置ipip模式

 

图 19 开启IP分配

2.3 通过Calico实现网络策略

calico的限制策略都是通过标签来进行匹配,设置相应的主机服务。

官方网址:https://projectcalico.docs.tigera.io/security/

2.3.1 限制访问指定服务

  1. apiVersion: networking.k8s.io/v1
  2. kind: NetworkPolicy
  3. metadata:
  4. name: deny-nginx
  5. spec:
  6. podSelector: ##通过标签选择含有指定label的pod进行通信
  7. matchLabels:
  8. app: nginx

2.3.2 允许指定pod访问

  1. kind: NetworkPolicy
  2. apiVersion: networking.k8s.io/v1
  3. metadata:
  4. name: access-nginx
  5. spec:
  6. podSelector:
  7. matchLabels:
  8. app: nginx
  9. ingress: ##允许通过
  10. - from:
  11. - podSelector: ##选择含有对应的标签的pod
  12. matchLabels:
  13. app: demo

2.3.3 禁止 namespace 中所有 Pod 之间的相互访问

  1. apiVersion: networking.k8s.io/v1
  2. kind: NetworkPolicy
  3. metadata:
  4. name: default-deny
  5. namespace: default
  6. spec:
  7. podSelector: {} ##没有选择任何标签,则为拒绝所有POD

2.3.4 禁止其他 namespace 访问服务

  1. kind: NetworkPolicy
  2. apiVersion: networking.k8s.io/v1
  3. metadata:
  4. name: deny-namespace
  5. spec:
  6. podSelector:
  7. matchLabels:
  8. ingress: ##没有选择其他的namespace,则为禁止其他的namespace
  9. - from:
  10. - podSelector: {}

2.3.5 只允许指定namespace访问服务

  1. kind: NetworkPolicy
  2. apiVersion: networking.k8s.io/v1
  3. metadata:
  4. name: access-namespace
  5. spec:
  6. podSelector:
  7. matchLabels:
  8. app: myapp
  9. ingress:
  10. - from:
  11. - namespaceSelector: ##指定有相应标签的namespace
  12. matchLabels:
  13. role: prod

2.3.6 允许外网访问服务

  1. kind: NetworkPolicy
  2. apiVersion: networking.k8s.io/v1
  3. metadata:
  4. name: web-allow-external
  5. spec:
  6. podSelector:
  7. matchLabels:
  8. app: web
  9. ingress: ##指定特定端口
  10. - ports:
  11. - port: 80
  12. from: [] ##来自于任何地方均可以

【注】上述代码只给出了核心代码,测试时需要编写相应的POD和SVC的yml文件

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/2023面试高手/article/detail/128375
推荐阅读
相关标签
  

闽ICP备14008679号