zoukankan      html  css  js  c++  java
  • K8s之网络通信

    网络通信机制

    k8s的网络基于第三方插件实现,但是定义了一些插件兼容规范,该规范有CoreOS和Google联合定制,叫做 CNI(Container Network Interface)。

    calicoz支持更多的网络层的安全策略,flannel不支持
    公有云大多使用flannel,使用vxlan+Directrouting模式
    自建IDC使用哪种模型都可以,flannel配置比较简单,calico功能较多
    性能差别不大,calico性能会略高于flannel
    私有云推荐使用calico
    公有云推挤使用flannel

    flannel

    官网:https://coreos.com/flannel/docs/latest/
    文档:https://coreos.com/flannel/docs/latest/kubernetes.html

    Flannel 网络模型 (后端),Flannel目前有三种方式实现 UDP/VXLAN/host-gw

    UDP:早期版本的Flannel使用UDP封装完成报文的跨越主机转发,其安全性及性能略有不足。 
    VXLAN:Linux 内核在在2012年底的v3.7.0之后加入了VXLAN协议支持,因此新版本的Flannel也有UDP转换为 VXLAN,VXLAN本质上是一种tunnel(隧道)协议,用来基于3层网络实现虚拟的2层网络,目前flannel 的网络模型已 经是基于VXLAN的叠加(覆盖)网络。 
    Host-gw:也就是Host GateWay,通过在node节点上创建到达各目标容器地址的路由表而完成报文的转发,因此这种 方式要求各node节点本身必须处于同一个局域网(二层网络)中,因此不适用于网络变动频繁或比较大型的网络环境,但是 其性能较好。
    

    Flannel 组件的解释

    • Cni0:网桥设备,每创建一个pod都会创建一对 veth pair,其中一端是pod中的eth0,另一端是Cni0网桥中的端口 (网卡),Pod中从网卡eth0发出的流量都会发送到Cni0网桥设备的端口(网卡)上,Cni0 设备获得的ip地址是该节 点分配到的网段的第一个地址。
    • Flannel.1: overlay网络的设备,用来进行vxlan报文的处理(封包和解包),不同node之间的pod数据流量都从 overlay设备以隧道的形式发送到对端。

    Flannel的系统文件及目录

    • root@node2:~# find / -name flannel
      /run/flannel
      /usr/bin/flannel
      /var/lib/cni/flannel

    flannel pod状态

    root@master1:~#  kubectl get pods -n kube-system
    NAME                          READY   STATUS    RESTARTS   AGE
    coredns-85bd4f9784-95qcb      1/1     Running   0          6h15m
    kube-flannel-ds-amd64-4dvn9   1/1     Running   0          23h
    kube-flannel-ds-amd64-6zk8z   1/1     Running   0          23h
    kube-flannel-ds-amd64-d54j4   1/1     Running   0          23h
    kube-flannel-ds-amd64-hmnsj   1/1     Running   0          22h
    kube-flannel-ds-amd64-k52kz   1/1     Running   0          23h
    kube-flannel-ds-amd64-q42lh   1/1     Running   0          23h
    

    当前node主机IP地址范围

    root@node1:~#  cat /run/flannel/subnet.env
    FLANNEL_NETWORK=10.20.0.0/16
    FLANNEL_SUBNET=10.20.3.1/24
    FLANNEL_MTU=1450
    FLANNEL_IPMASQ=true
    

    当前node主机cni信息

    root@node1:~# cat /var/lib/cni/flannel/0929d39656c75c9518ac16a785c12ebc301a254d03e58387d27ff365e04562a0 
    {"cniVersion":"0.3.1","hairpinMode":true,"ipMasq":false,"ipam":{"routes":[{"dst":"10.20.0.0/16"}],"subnet":"10.20.3.0/24","type":"host-local"},"isDefaultGateway":true,"isGateway":true,"mtu":1450,"name":"cbr0","type":"bridge"}
    

    UDP网络模型(不可用)

    重新执行网络并重启master与node服务器

    • 设置flannel 后端
      • FLANNEL_BACKEND: "host-gw"
      • FLANNEL_BACKEND: "vxlan"
      • FLANNEL_BACKEND: "UDP
    修改backend为UDP

    Type有变量FLANNEL_BACKEND定义

    root@master1:~# vim /etc/ansible/roles/flannel/templates/kube-flannel.yaml.j2
    net-conf.json: |
    {
      "Network": "{{ CLUSTER_CIDR }}",
      "Backend": {
    {% if FLANNEL_BACKEND == "vxlan" and DIRECT_ROUTING %}
            "DirectRouting": true,
    {% endif %}
            "Type": "{{ FLANNEL_BACKEND }}"
          }
        }
    

    查找定义FLANNEL_BACKEND变量的文件

     root@master1:~# grep FLANNEL_BACKEND /etc/ansible/roles/flannel/ -R
    /etc/ansible/roles/flannel/defaults/main.yml:#FLANNEL_BACKEND: "host-gw"
    /etc/ansible/roles/flannel/defaults/main.yml:FLANNEL_BACKEND: "vxlan"
    /etc/ansible/roles/flannel/templates/kube-flannel.yaml.j2:{% if FLANNEL_BACKEND == "vxlan" and DIRECT_ROUTING %}
    /etc/ansible/roles/flannel/templates/kube-flannel.yaml.j2:        "Type": "{{ FLANNEL_BACKEND }}"   
    

    将FLANNEL_BACKEND设置为UDP

    root@master1:~# cat /etc/ansible/roles/flannel/defaults/main.yml
    # 部分flannel配置,参考 docs/setup/network-plugin/flannel.md
    # 设置flannel 后端
    #FLANNEL_BACKEND: "host-gw"
    #FLANNEL_BACKEND: "vxlan"
    FLANNEL_BACKEND: "udp"
    DIRECT_ROUTING: false
    
    #flanneld_image: "quay.io/coreos/flannel:v0.10.0-amd64"
    flanneld_image: "easzlab/flannel:v0.11.0-amd64"
    
    # 离线镜像tar包
    flannel_offline: "flannel_v0.11.0-amd64.tar"
    

    k8s需要重新安装生效

    VxLAN Directrouting

    Directrouting 为在同一个二层网络中的node节点启用直接路由机制,类似于host-gw模式。

    修改flannel支持Directrouting

    需要让配置文件在node节点重新生效

    修改DIRECT_ROUTING:为true
    root@master1:~# vim /etc/ansible/roles/flannel/defaults/main.yml 
    # 部分flannel配置,参考 docs/setup/network-plugin/flannel.md
    
    # 设置flannel 后端
    #FLANNEL_BACKEND: "host-gw"
    FLANNEL_BACKEND: "vxlan"
    DIRECT_ROUTING: true
    
    #flanneld_image: "quay.io/coreos/flannel:v0.10.0-amd64"
    flanneld_image: "easzlab/flannel:v0.11.0-amd64"
    
    # 离线镜像tar包
    flannel_offline: "flannel_v0.11.0-amd64.tar"
    

    重新配置network

    root@master1:/etc/ansible# ansible-playbook 06.network.yml
    

    master和node节点重启或重装k8s生效

    root@node1:~# reboot
    
    修改前的路由表
    root@node1:~# route -n
    Kernel IP routing table
    Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
    0.0.0.0         10.203.104.254  0.0.0.0         UG    0      0        0 ens160
    10.20.0.0       10.20.0.0       255.255.255.0   UG    0      0        0 flannel.1
    10.20.1.0       10.20.1.0       255.255.255.0   UG    0      0        0 flannel.1
    10.20.2.0       10.20.2.0       255.255.255.0   UG    0      0        0 flannel.1
    10.20.3.0       0.0.0.0         255.255.255.0   U     0      0        0 cni0
    10.20.4.0       10.20.4.0       255.255.255.0   UG    0      0        0 flannel.1
    10.20.5.0       10.20.5.0       255.255.255.0   UG    0      0        0 flannel.1
    10.203.104.0    0.0.0.0         255.255.255.0   U     0      0        0 ens160
    172.17.0.0      0.0.0.0         255.255.0.0     U     0      0        0 docker0
    
    修改后的路由表
    root@node1:~# route -n
    Kernel IP routing table
    Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
    0.0.0.0         10.203.104.254  0.0.0.0         UG    0      0        0 ens160
    10.20.0.0       10.203.104.21   255.255.255.0   UG    0      0        0 ens160
    10.20.1.0       10.203.104.20   255.255.255.0   UG    0      0        0 ens160
    10.20.2.0       10.203.104.27   255.255.255.0   UG    0      0        0 ens160
    10.20.3.0       0.0.0.0         255.255.255.0   U     0      0        0 cni0
    10.20.4.0       10.203.104.28   255.255.255.0   UG    0      0        0 ens160
    10.20.5.0       10.203.104.22   255.255.255.0   UG    0      0        0 ens160
    10.203.104.0    0.0.0.0         255.255.255.0   U     0      0        0 ens160
    172.17.0.0      0.0.0.0         255.255.0.0     U     0      0        0 docker0
    

    host-gw网络模型

    修改FLANNEL_BACKEND为host-gw模型

    root@master1:~# vim /etc/ansible/roles/flannel/defaults/main.yml 
    # 部分flannel配置,参考 docs/setup/network-plugin/flannel.md
    
    # 设置flannel 后端
    FLANNEL_BACKEND: "host-gw"
    #FLANNEL_BACKEND: "vxlan"
    DIRECT_ROUTING: false
    
    #flanneld_image: "quay.io/coreos/flannel:v0.10.0-amd64"
    flanneld_image: "easzlab/flannel:v0.11.0-amd64"
    
    # 离线镜像tar包
    flannel_offline: "flannel_v0.11.0-amd64.tar"
    

    重新配置network

    root@master1:/etc/ansible# ansible-playbook 06.network.yml
    

    master和node节点重启或重装k8s生效

    root@node1:~# reboot
    

    Flannel不同node上的pod的通信流程

    Flannel.1 是一个overlay网络的设备,用来进行 vxlan 报文的处理(封包和解包),不同node之间的pod数据流量 都从overlay设备以隧道的形式发送到对端。

    ->: pod中产生数据,根据pod的路由信息,将数据发送到Cni0 
    ->: Cni0 根据节点的路由表,将数据发送到隧道设备flannel.1 
    ->: Flannel.1查看数据包的目的ip,从flanneld获得对端隧道设备的必要信息,封装数据包。 
    ->: Flannel.1将数据包发送到对端设备,对端节点的网卡接收到数据包 
    ->: 对端节点发现数据包为overlay数据包,解开外层封装,并发送到到本机flannel.1设备。 
    ->: Flannel.1设备查看数据包,根据路由表匹配,将数据发送给Cni0设备。 
    ->: Cni0匹配路由表,发送数据给网桥上对应的端口(pod)。
    

    Calico

    官网:https://www.projectcalico.org/
    github: https://github.com/projectcalico/calico

    Calico是一个纯三层的网络解决方案,为容器提供多node间的访问通信,calico将每一个node节点都当做为一个路 由器(router),各节点通过BGP(Border Gateway Protocol) 边界网关协议学习并在node节点生成路由规则,从而 将不同node节点上的pod连接起来进行通信。

    BGP是一个去中心化的协议,它通过自动学习和维护路由表实现网络的可用性,但是并不是所有的网络都支持 BGP,另外为了跨网络实现更大规模的网络管理,calico 还支持IP-in-IP的叠加模型,简称IPIP,IPIP可以实现跨不 同网段建立路由通信,但是会存在安全性问题,其在内核内置,可以通过Calico的配置文件设置是否启用IPIP,在 公司内部如果k8s的node节点没有跨越网段建议关闭IPIP。

    IPIP是一种将各Node的路由之间做一个tunnel,再把两个网络连接起来的模式。启用IPIP模式时,Calico将在各 Node上创建一个名为"tunl0"的虚拟网络接口。 
    BGP模式则直接使用物理机作为虚拟路由路(vRouter),不再创建额外的tunnel。
    

    calico 核心组件

    Felix:calico的agent,运行在每一台node节点上,其主要是维护路由规则、汇报当前节点状态以确保pod的夸主机 通信。 
    BGP Client:每台node都运行,其主要负责监听node节点上由felix生成的路由信息,然后通过BGP协议广播至其他剩 余的node节点,从而相互学习路由实现pod通信。 
    Route Reflector:集中式的路由反射器,calico v3.3开始支持,当Calico BGP客户端将路由从其FIB(Forward Information dataBase,转发信息库)通告到Route Reflector时,Route Reflector会将这些路由通告给部署 集群中的其他节点,Route Reflector专门用于管理BGP网络路由规则,不会产生pod数据通信。 
    
    注:calico默认工作模式是BGP的node-to-node mesh,如果要使用Route Reflector需要进行相关配置。 https://docs.projectcalico.org/v3.4/usage/routereflector https://docs.projectcalico.org/v3.2/usage/routereflector/calico-routereflector
    

    部署过程

    修改ansible的hosts文件中的CLUSTER_NETWORK为calico

    root@master1:~# grep CLUSTER_NETWORK /etc/ansible/hosts 
    CLUSTER_NETWORK="calico"
    

    下载镜像并上传到harbor

    root@master1:~# docker images | grep calico
    calico/node                                                                       v3.4.4              a8dbf15bbd6f        14 months ago       79.6MB
    calico/cni                                                                        v3.4.4              f5e5bae3eb87        14 months ago       75.4MB
    calico/kube-controllers                                                           v3.4.4              0030ff291350        14 months ago       56.5MB
    
    root@master1:~# docker tag calico/node:v3.4.4 harbor.linux.com/calico/node:v3.4.4
    root@master1:~# docker push harbor.linux.com/calico/node:v3.4.4
    
    
    root@master1:~# docker tag calico/cni:v3.4.4 harbor.linux.com/calico/cni:v3.4.4
    root@master1:~# docker push harbor.linux.com/calico/cni:v3.4.4
    
    root@master1:~# docker tag calico/kube-controllers:v3.4.4 harbor.linux.com/calico/kube-controllers:v3.4.4
    root@master1:~# docker push harbor.linux.com/calico/kube-controllers:v3.4.4
    

    calico-v3.4.yaml.j2配置文件

    将image修改为harbor的地址,其他字段不需要修改
    root@master1:/etc/ansible/roles/calico/templates# vim calico-v3.4.yaml.j2
    

    开启和关闭IPIP

    root@master1:/etc/ansible# cat roles/calico/defaults/main.yml 
    # 部分calico相关配置,更全配置可以去roles/calico/templates/calico.yaml.j2自定义
    
    # 如果 node 节点有多块网卡,请设置 true
    # 另外发现设置为 true 时能够解决v1.10使用ipvs偶尔出现pod内‘dial tcp 10.68.0.1:443: i/o timeout’的 bug
    NODE_WITH_MULTIPLE_NETWORKS: "true"
    
    # etcd 集群服务地址列表, 根据etcd组成员自动生成
    TMP_ENDPOINTS: "{% for h in groups['etcd'] %}https://{{ h }}:2379,{% endfor %}"
    ETCD_ENDPOINTS: "{{ TMP_ENDPOINTS.rstrip(',') }}"
    
    # 设置 CALICO_IPV4POOL_IPIP=“off”,可以提高网络性能,条件限制详见 docs/setup/calico.md
    CALICO_IPV4POOL_IPIP: "Always"    # 开启IPIP
    
    # 设置 Felix 日志级别
    FELIX_LOG_LVL: "warning"
    
    # 设置 calico-node使用的host IP,bgp邻居通过该地址建立,可手工指定也可以自动发现
    #IP_AUTODETECTION_METHOD: "interface=eth0"
    IP_AUTODETECTION_METHOD: "can-reach={{ groups['kube-master'][0] }}"
    
    # 更新支持calico 版本: [v3.2.x] [v3.3.x] [v3.4.x]
    calico_ver: "v3.4.4"
    
    # calico 主版本
    calico_ver_main: "{{ calico_ver.split('.')[0] }}.{{ calico_ver.split('.')[1] }}"
    
    # 离线镜像tar包
    calico_offline: "calico_{{ calico_ver }}.tar"
    

    部署集群

    root@master1:/etc/ansible# ansible-playbook 06.network.yml
    

    验证当前路由表

    root@node1:~# calicoctl node status
  • 相关阅读:
    准备 FRM 考试——方法、工具与教训
    930. 和相同的二元子数组 前缀和
    1906. 查询差绝对值的最小值 前缀和
    剑指 Offer 37. 序列化二叉树 二叉树 字符串
    815. 公交路线 BFS
    518. 零钱兑换 II dp 完全背包
    1049. 最后一块石头的重量 II dp
    5779. 装包裹的最小浪费空间 二分
    5778. 使二进制字符串字符交替的最少反转次数 字符串 滑动窗口
    474. 一和零 dp
  • 原文地址:https://www.cnblogs.com/JevonWei/p/13184836.html
Copyright © 2011-2022 走看看