K8S flannel 网络

Posted yyselisa

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了K8S flannel 网络相关的知识,希望对你有一定的参考价值。

1. flannel 的作用

https://github.com/coreos/flannel/releases  flannel github 地址

K8S 网络插件用的最多的flannel 和calico,主要是解决不同宿主机之间的pod 通信问题。flannel 支持UDP、VxLAN、host-GW, AWS VPC和GCE路由等数据转发方式。

 1. VxLAN:使用内核中的VxLAN模块进行封装报文。也是flannel推荐的方式.

2. host-gw:要求各节点必须在同一个2层网络,通过在节点上创建目标容器地址的路由直接完成报文转发,对报文转发性能要求较高的场景使用。

3. UDP:使用普通的UDP报文封装完成隧道转发,效率低下,不推荐。

2. Flannel容器的跨主机通信通过程

技术图片

 

flannel 的 配置信息保存在etcd 中的,查看。

  • /opt/etcd/etcdctl ls /coreos.com/network
    /coreos.com/network/config
    /coreos.com/network/subnets
    [root@hdss7-21 ~]#  /opt/etcd/etcdctl get /coreos.com/network/config
    {"Network": "172.7.0.0/16", "Backend": {"Type": "VxLAN","Directrouting": true}}

当需要与其他主机上的容器进行通信时,查找etcd数据库,找到目的容器的子网所对应的outip(目的宿主机的IP);
将原始数据包封装在VXLAN或UDP数据包中,IP层以outip为目的IP进行封装;
由于目的IP是宿主机IP,因此路由是可达的。
VXLAN或UDP数据包到达目的宿主机解封装,解出原始数据包(原始包就是pod 之前访问的包),通过内核转发将数据包从宿主机转到本地容器。

3. 部署flannel 网络插件

在7.21 和7.22 上部署

#在7.21 上执行 
wget https://github.com/coreos/flannel/releases/download/v0.11.0/flannel-v0.11.0-linux-amd64.tar.gz
[root@hdss7-21 src]# mkdir /opt/flannel-v0.11.0
[root@hdss7-21 src]# tar xf flannel-v0.11.0-linux-amd64.tar.gz  -C /opt/flannel

[root@hdss7-21 conf]# cd /opt/flannel/cert/
[root@hdss7-21 cert]# scp hdss7-200:/opt/certs/ca.pem .
[root@hdss7-21 cert]# scp hdss7-200:/opt/certs/client.pem .
[root@hdss7-21 cert]# scp hdss7-200:/opt/certs/client-key.pem .

cd /opt/flannel
 vi subnet.env
FLANNEL_NETWORK=172.7.0.0/16
FLANNEL_SUBNET=172.7.21.1/24   #7.22 要改成 172.7.22.1/24
FLANNEL_MTU=1500
FLANNEL_IPMASQ=false

[root@hdss7-21 flannel]# vi flanneld.sh
#!/bin/sh
./flanneld   --public-ip=10.4.7.21       #7.22 改下ip
  --etcd-endpoints=https://10.4.7.12:2379,https://10.4.7.21:2379,https://10.4.7.22:2379   --etcd-keyfile=./cert/client-key.pem   --etcd-certfile=./cert/client.pem   --etcd-cafile=./cert/ca.pem   --iface=eth0   --subnet-file=./subnet.env   --healthz-port=2401

chmod +x flanneld.sh 
mkdir -p /data/logs/flanneld

vi /etc/supervisord.d/flannel.ini
[program:flanneld]
command=/opt/flannel/flanneld.sh                             ; the program (relative uses PATH, can take args)
numprocs=1                                                   ; number of processes copies to start (def 1)
directory=/opt/flannel                                       ; directory to cwd to before exec (def no cwd)
autostart=true                                               ; start at supervisord start (default: true)
autorestart=true                                             ; retstart at unexpected quit (default: true)
startsecs=30                                                 ; number of secs prog must stay running (def. 1)
startretries=3                                               ; max # of serial start failures (default 3)
exitcodes=0,2                                                ; ‘expected‘ exit codes for process (default 0,2)
stopsignal=QUIT                                              ; signal used to kill process (default TERM)
stopwaitsecs=10                                              ; max num secs to wait b4 SIGKILL (default 10)
user=root                                                    ; setuid to this UNIX account to run the program
redirect_stderr=true                                         ; redirect proc stderr to stdout (default false)
stdout_logfile=/data/logs/flanneld/flanneld.stdout.log       ; stderr log path, NONE for none; default AUTO
stdout_logfile_maxbytes=64MB                                 ; max # logfile bytes b4 rotation (default 50MB)
stdout_logfile_backups=4                                     ; # of stdout logfile backups (default 10)
stdout_capture_maxbytes=1MB                                  ; number of bytes in ‘capturemode‘ (default 0)
stdout_events_enabled=false                                  ; emit events on stdout writes (default false)

4. flannel vxlan 模型配置和相关信息查看

在10.4.7.21 和22 上配置 vlxan 模式。

/opt/etcd/etcdctl set /coreos.com/network/config ‘{"Network": "172.7.0.0/16", "Backend": {"Type": "VxLAN"}}‘    # 设置行vxlan 模型

#查看etcd 中保存的信息
/opt/etcd/etcdctl ls /coreos.com/network
/coreos.com/network/config
/coreos.com/network/subnets
[root@hdss7-21 ~]#  /opt/etcd/etcdctl get /coreos.com/network/config
{"Network": "172.7.0.0/16", "Backend": {"Type": "VxLAN"}}

/opt/etcd/etcdctl ls /coreos.com/network/subnets
/coreos.com/network/subnets/172.7.21.0-24
/coreos.com/network/subnets/172.7.22.0-24


#会发现宿主机上多了flannel.1 的接口。 这个flannel.1是一个vtep二层设备
ifconfig flannel.1
flannel.1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1450
        inet 172.7.21.0  netmask 255.255.255.255  broadcast 0.0.0.0
        inet6 fe80::5478:5aff:fe1a:7304  prefixlen 64  scopeid 0x20<link>
        ether 56:78:5a:1a:73:04  txqueuelen 0  (Ethernet)
        RX packets 25979967  bytes 17410555331 (16.2 GiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 19077703  bytes 8443811676 (7.8 GiB)
        TX errors 0  dropped 8 overruns 0  carrier 0  collisions 0

#查看路由
ip route ls 
default via 10.4.7.1 dev eth0 proto static metric 100 
10.4.7.0/24 dev eth0 proto kernel scope link src 10.4.7.21 metric 100 
172.7.21.0/24 dev docker0 proto kernel scope link src 172.7.21.1 
172.7.22.0/24 via 172.7.22.0 dev flannel.1 onlink 

会发现多了 172.7.22.0/24 via 172.7.22.0 dev flannel.1 onlink  路由,pod垮宿主机访问都通过这条路由了。

#查看 vxlan fdb(forwarding database) 
[root@hdss7-21 ~]# bridge fdb show dev flannel.1
ea:99:e1:f0:37:cf dst 10.4.7.22 self permanent    #这个mac 就是另外一台的宿主机的flannel.1 的mac ,这样就实现了arp 解析了。
56:eb:a4:dd:7d:a5 dst 10.4.7.22 self permanent
6a:2c:6a:1e:2b:2e dst 10.4.7.22 self permanent
9a:53:36:4c:ef:12 dst 10.4.7.22 self permanent
06:ea:23:b0:6f:b5 dst 10.4.7.22 self permanent

  flannel 另外两种模式配置:

 

/opt/etcd/etcdctl set /coreos.com/network/config ‘{"Network": "172.7.0.0/16", "Backend": {"Type": "VxLAN","Directrouting": true}}‘    #配置vxlan 直接路由

VXLAN的Direct routing模式解释:
两个节点在同一网段时使用host-gw通信,如果不在同一网段中,即 当前pod所在节点与目标pod所在节点中间有路由器,就使用VXLAN这种方式,使用叠加网络。 结合了Host-gw和VXLAN。

./etcdctl set /coreos.com/network/config ‘{"Network": "172.7.0.0/16", "Backend": {"Type": "host-gw"}}‘    #这个是设置host-gw 的,这种模式node 上不会有flannel.1 的接口了,pod 的跨宿主及访问路由先到 docker0 ,再通过宿主机的eth0 出去。这种适合宿主机在同一个网段的情况下,效率比vlxan还高,因为没有了vxlan 封装了。

 ip route ls
default via 10.4.7.1 dev eth0 proto static metric 100 
10.4.7.0/24 dev eth0 proto kernel scope link src 10.4.7.22 metric 100 
172.7.21.0/24 via 10.4.7.21 dev eth0 
172.7.22.0/24 dev docker0 proto kernel scope link src 172.7.22.1 

  

5. 宿主机iptables 优化--非常重要

通过上面配置了 vxan  模式实现了跨宿主访问,但是看日志发下对方看到的flannel.1 的ip!起两台nginx pod,然后curl 

kubectl get pod -o wide 
NAME                                READY   STATUS              RESTARTS   AGE     IP            NODE                NOMINATED NODE   READINESS GATES
nginx-deployment-7bfb85948d-8d4wd   1/1     Running             0          3d19h   172.7.21.15   hdss7-21.host.com   <none>           <none>
nginx-deployment-7bfb85948d-xg4bt   1/1     Running             1          3d19h   172.7.22.10   hdss7-22.host.com   <none>           <none>


 kubectl logs -f nginx-deployment-7bfb85948d-8d4wd   #这个是21 上pod ,看到的却不是172.7.22.10 的ip
172.7.22.0 - - [01/Jul/2020:16:45:16 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.64.0" "-"

  

修改iptables 规则----两台宿主机都要改!

上面情况是由于:
A POSTROUTING -s 172.7.22.0/24  ! -o docker0 -j MASQUERADE   这条规则导致的!
这条规则意思是  172.7.22.0/24  不是 docker0 就转换了。
因为pod 出去是通过flannel.1 接口出了! 所以有了上面的规则后pod 的ip 就被转成flannel.1 的ip 了!
改成:  -A POSTROUTING -s 172.7.22.0/24 ! -d 172.7.0.0/16 ! -o docker0 -j MASQUERADE 

 172.7.0.0/16 是k8s 集群的ip,意思是访问k8s 集群外部的ip 才做nat,这样既保证了pod 可以出外网,也保证了集群内部访问pod ip 不会被转换! 

改完后再看访问日志:

172.7.22.10 - - [02/Jul/2020:19:19:58 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.64.0" "-"
172.7.22.10 - - [02/Jul/2020:19:20:00 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.64.0" "-"

可以看到pod 真是IP 了!

  

  

 

以上是关于K8S flannel 网络的主要内容,如果未能解决你的问题,请参考以下文章

k8s网络之Flannel网络

K8S flannel 网络

k8s flannel网络切换calico步骤

k8s flannel网络切换calico步骤

k8s的Flannel网络

k8s部署flannel网络