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
  • 相关阅读:
    JAVA动态代理
    图解 Tomcat 体系结构
    AdvancedDataGrid的使用
    You have an error in your SQL syntax; check the manual that corresponds...错误解决方案
    更新整站索引时失败,错误原因: [Incorrect integer value: `` for column `uptime` at row 1]
    dedecms转换v9 卡住的解决办法
    IIS 涉及到500和403或者404友好错误的设置!
    PHP Warning: date(): It is not safe to rely on the system's timezone settings
    不能读取记录;在 'MSysObjects' 上没有读取数据权限
    PHP5.3.5如何连接MSSql Server2005
  • 原文地址:https://www.cnblogs.com/JevonWei/p/13184836.html
Copyright © 2011-2022 走看看