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 网络的主要内容,如果未能解决你的问题,请参考以下文章