一、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的工作原理
 
 
  
图例解释:
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封装的“外部数据桢”的格式如下
 在这里插入图片描述
 
 
  
 1.3 host-gw模式和directrouting的设置和测试
 
1.3.1 host-gw模式
host-gw是一种纯三层网络的方案,性能最高。
        工作原理:就是将每个Flannel子网的下一跳,设置成了该子网对应的宿主机的IP地址,也就是说,宿主机(host)充当了这条容器通信路径的“网关”(Gateway),这正是host-gw的含义。所有的子网和主机的信息,都保存在Etcd中,flanneld只需要watch这些数据的变化 ,实时更新路由表就行了。
         核心:IP包在封装成桢的时候,使用路由表的“下一跳”设置上的MAC地址,这样可以经过二层网络到达目的宿主机。
##host-gw模式
[root@server1 fannel]# cp ~/kube-flannel.yml .    ##将flannel.yml pod清单复制到当前目录下
[root@server1 fannel]# vim kube-flannel.yml ##编辑kube-flannel.yml文件,将网络类型改为直接路由模式(host-gw)
[root@server1 fannel]# kubectl apply -f kube-flannel.yml 
Warning: policy/v1beta1 PodSecurityPolicy is deprecated in v1.21+, unavailable in v1.25+
podsecuritypolicy.policy/psp.flannel.unprivileged created
clusterrole.rbac.authorization.k8s.io/flannel created
clusterrolebinding.rbac.authorization.k8s.io/flannel created
serviceaccount/flannel created
configmap/kube-flannel-cfg created
daemonset.apps/kube-flannel-ds created
[root@server1 fannel]# kubectl get pod -n kube-system    ## 查看flannel网络插件应用成功
 
 
 
  
 
 
  
查看三台Node的IP,发现都存在gw:10.96.0.1/32
 
 
  
 
 
  
 
 
  
创建测试用例:
###创建pod:
[root@server1 network]# vim pod2.yml 
  1 Version: apps/v1
  2 kind: Deployment
  3 metadata:
  4   name: deployment-example
  5 spec:
  6   replicas: 4
  7   selector:
  8     matchLabels:
  9       app: myapp
 10   template:
 11     metadata:
 12       labels:
 13         app: myapp
 14     spec:
 15       containers:
 16       - name: myapp
 17         image: nginx
##创建服务:
  1 nd: Service
  2 apiVersion: v1
  3 metadata:
  4   name: myservice
  5 spec:
  6   ports:
  7     - protocol: TCP
  8       port: 80
  9       targetPort: 80
 10   selector:
 11     app: myapp
 12   type: NodePort
 
查看节点上的IP:10.224.1.0/24 10.224.2.0/24
通过外部访问:不卡顿,server2 server3 轮循访问
 
 
  
 
 
  
1.3.2 Flannel——vxlan+Directrouting模式
##删除之前的模式:
[root@server1 fannel]# kubectl delete -f kube-flannel.yml 
##重新设置配置
[root@server1 fannel]# vim  kube-flannel.yml 
##应用新的配置
[root@server1 fannel]# kubectl apply -f kube-flannel.yml 
##查看服务是否启动
[root@server1 fannel]# kubectl get pod -n kube-system 
 
 
 
  
 
 
  
使用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在这里,路由的时候到这里来。
 
 
  
2.2 应用和配置
2.2.1 安装和配置
##安装和配置calico
##下载配置文件
curl https://projectcalico.docs.tigera.io/manifests/calico.yaml -O
##根据配置文件,下载相应的镜像 
[root@server1 fannel]# docker pull docker.io/calico/cni:v3.22.2
[root@server1 fannel]# docker pull docker.io/calico/pod2daemon-flexvol:v3.22.2
[root@server1 fannel]# docker pull docker.io/calico/node:v3.22.2
[root@server1 fannel]# docker pull docker.io/calico/kube-controllers:v3.22.2
##编写配置文件的模式,设置IPIP为OFF
##应用配置文件
[root@server1 calico]# kubectl apply -f calico.yaml 
##查看应用状态
[root@server1 calico]# kubectl get pod -n kube-system
[root@server1 calico]# kubectl get daemonset.apps -n kube-system
##查看运行的模式
[root@server1 calico]# kubectl describe ippools
 
 
 
  
 
 
  
 
 
  
 
 
  
2.2.2 基本的通信状态
##配置pod和svc,查看通信状态
[root@server1 network]# cat pod2.yml 
apiVersion: apps/v1
kind: Deployment
metadata:
  name: deployment-example
spec:
  replicas: 4
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
    spec:
      containers:
      - name: myapp
        image: nginx
[root@server1 network]# cat server2.yml 
kind: Service
apiVersion: v1
metadata:
  name: myservice
spec:
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
  selector:
    app: myapp
  type: NodePort
##查看路由环,观察通信模式
[root@server1 network]# ip route 
 
 
  
2.2.3 打开隧道模式,分配固定的pod ip网段
[root@server1 calico]#  vim calico.yaml
# Enable IPIP
            - name: CALICO_IPV4POOL_IPIP
              value: "Always"
 - name: CALICO_IPV4POOL_CIDR
               value: "192.168.0.0/16"
[root@server1 calico]#  kubectl apply -f calico.yaml 
 
 
 
  
 
 
  
2.3 通过Calico实现网络策略
calico的限制策略都是通过标签来进行匹配,设置相应的主机服务。
官方网址:https://projectcalico.docs.tigera.io/security/
2.3.1 限制访问指定服务
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: deny-nginx
spec:
  podSelector:            ##通过标签选择含有指定label的pod进行通信
    matchLabels:
      app: nginx
 
2.3.2 允许指定pod访问
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
  name: access-nginx
spec:
  podSelector:
    matchLabels:
      app: nginx
  ingress:                ##允许通过
  - from:
      - podSelector:      ##选择含有对应的标签的pod
          matchLabels:
            app: demo
 
2.3.3 禁止 namespace 中所有 Pod 之间的相互访问
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny
  namespace: default
spec:                    
  podSelector: {}        ##没有选择任何标签,则为拒绝所有POD
 
2.3.4 禁止其他 namespace 访问服务
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
  name: deny-namespace
spec:
  podSelector:
    matchLabels:
  ingress:                ##没有选择其他的namespace,则为禁止其他的namespace
  - from:
    - podSelector: {}
 
2.3.5 只允许指定namespace访问服务
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
  name: access-namespace
spec:
  podSelector:
    matchLabels:
      app: myapp
  ingress:
  - from:
    - namespaceSelector:        ##指定有相应标签的namespace
        matchLabels:
          role: prod
 
2.3.6 允许外网访问服务
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
  name: web-allow-external
spec:
  podSelector:
    matchLabels:
      app: web
  ingress:            ##指定特定端口
  - ports:
    - port: 80
    from: []          ##来自于任何地方均可以










