当然,在单独安装Flanneld之前回顾一下本人前面写的相关的flanneld 的文章


Flannel是一种基于overlay网络的跨主机容器网络解决方案,也就是将TCP数据包封装在另一种网络包里面进行路由转发和通信,

Flannel是CoreOS开发,专门用于docker多机互联的一个工具,让集群中的不同节点主机创建的容器都具有全集群唯一的虚拟ip地址

Flannel使用go语言编写

Flannel为每个host分配一个subnet,容器从这个subnet中分配IP,这些IP可以在host间路由,容器间无需使用nat和端口映射即可实现跨主机通信

每个subnet都是从一个更大的IP池中划分的,flannel会在每个主机上运行一个叫flanneld的agent,其职责就是从池子中分配subnet

Flannel使用etcd存放网络配置、已分配 的subnet、host的IP等信息

Flannel数据包在主机间转发是由backend实现的,目前已经支持UDP、VxLAN、host-gw、AWS VPC和GCE路由等多种backend

k8s安装ingressContraller k8s安装flannel_docker

  1. 容器直接使用目标容器的ip访问,默认通过容器内部的eth0发送出去。
  2. 报文通过veth pair被发送到vethXXX。
  3. vethXXX是直接连接到虚拟交换机docker0的,报文通过虚拟bridge docker0发送出去。
  4. 查找路由表,外部容器ip的报文都会转发到flannel0虚拟网卡,这是一个P2P的虚拟网卡,然后报文就被转发到监听在另一端的flanneld。
  5. flanneld通过etcd维护了各个节点之间的路由表,把原来的报文UDP封装一层,通过配置的iface发送出去。
  6. 报文通过主机之间的网络找到目标主机。
  7. 报文继续往上,到传输层,交给监听在8285端口的flanneld程序处理。
  8. 数据被解包,然后发送给flannel0虚拟网卡。
  9. 查找路由表,发现对应容器的报文要交给docker0。
  10. docker0找到连到自己的容器,把报文发送过去。 

Falnnel要用etcd存储自身一个子网信息,所以要保证能成功连接Etcd,写入预定义子网段:

cd /etc/ssl/kubernetes/ 

etcdctl \

--ca-file=ca.pem --cert-file=kubernetes.pem --key-file=kubernetes-key.pem \

--endpoints="https://10.211.55.11:2379,https://10.211.55.12:2379,https://10.211.55.13:2379" ls

set /coreos.com/network/config  '{ "Network": "172.17.0.0/16", "Backend": {"Type": "vxlan"}}'

  • Network:用于指定Flannel地址池
  • SubnetLen:用于指定分配给单个宿主机的docker0的ip段的子网掩码的长度
  • SubnetMin:用于指定最小能够分配的ip段
  • SudbnetMax:用于指定最大能够分配的ip段,在上面的示例中,表示每个宿主机可以分配一个16位掩码长度的子网
  • Backend:用于指定数据包以什么方式转发,默认为udp模式,host-gw模式性能最好,但不能跨宿主机网络 

下载二进制包

wget https://github.com/coreos/flannel/releases/download/v0.11.0/flannel-v0.11.0-linux-amd64.tar.gz

tar -zxvf  flannel-v0.11.0-linux-amd64.tar.gz

mv flanneld mk-docker-opts.sh /usr/bin/ 

vim /etc/flanneld.conf 

FLANNEL_OPTIONS="--etcd-endpoints=https://10.211.55.11:2379,

https://10.211.55.12:2379,https://10.211.55.13:2379 -etcd-cafile=/etc/kubernetes/ca.pem

-etcd-certfile=/etc/kubernetes/kubernetes.pem -etcd-keyfile=/etc/kubernetes/kubernetes-key.pem"

启动脚本

[Unit]

Description=Flanneld overlay address etcd agent

After=network-online.target network.target

Before=docker.service

[Service]

Type=notify

EnvironmentFile=/etc/flanneld.conf

ExecStart=/usr/bin/flanneld --ip-masq $FLANNEL_OPTIONS

ExecStartPost=/usr/bin/mk-docker-opts.sh -k DOCKER_NETWORK_OPTIONS -d /run/flannel/subnet.env 

Restart=on-failure

[Install]

WantedBy=multi-user.target

 

systemctl daemon-reload

systemctl start flanneld

systemctl enable flanneld

 

Flannel启动过程解析: 

  • 从etcd中获取network的配置信息
  • 划分subnet,并在etcd中进行注册
  • 将子网信息记录到/run/flannel/subnet.env中 

查看etcd中存入的子网信息

[root@k8s-master1 ~]# etcdctl --ca-file=/etc/etcd/ssl/ca.pem -etcd-cafile=/etc/kubernetes/ca.pem \
-etcd-certfile=/etc/kubernetes/kubernetes.pem -etcd-keyfile=/etc/kubernetes/kubernetes-key.pem \

--endpoints="https://10.211.55.11:2379,https://10.211.55.12:2379,https://10.211.55.13:2379"  ls /coreos.com/network/subnets

/coreos.com/network/subnets/172.17.69.0-24

/coreos.com/network/subnets/172.17.55.0-24

/coreos.com/network/subnets/172.17.51.0-24

对应的网卡信息: 

ifconfig flannel.1 

flannel.1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1450

        inet 172.17.55.0  netmask 255.255.255.255  broadcast 0.0.0.0

        ether 1e:5b:2c:3d:ae:89  txqueuelen 0  (Ethernet)

        RX packets 0  bytes 0 (0.0 B)

        RX errors 0  dropped 0  overruns 0  frame 0

        TX packets 0  bytes 0 (0.0 B)

        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

可以看到flannel0网卡的地址和etcd存储的地址一样,这样flannel网络配置完成

Docker安装以后需要修改其启动参数以使其能够使用flannel进行IP分配,以及网络通讯

在Flannel运行之后,会生成一个环境变量文件/run/flannel/subnet.env ,可以使用flannel提供的脚本将subnet.env转写成Docker启动参数,创建好的启动参数默认生成在/run/docker_opts.env文件中:
,包含了当前主机要使用flannel通讯的相关参数,如下:

 

可以使用flannel提供的脚本将subnet.env转写成Docker启动参数,创建好的启动参数默认生成在/run/docker_opts.env文件中:

# /opt/flannel/mk-docker-opts.sh -c

[root@k8s-master1 ~]# cat /run/flannel/subnet.env

DOCKER_OPTS=" --bip=172.17.55.1/24 --ip-masq=false --mtu=1450"

通过上面flanneld的启动脚本可以看到(红色部分),我们把 DOCKER 启动需要的参数生成到 /run/flannel/subnet.env,当然也可以指定默认配置文件/run/docker_opts.env

# vim /lib/systemd/system/docker.service

EnvironmentFile=/run/docker_opts.env

ExecStart=/usr/bin/dockerd $DOCKER_OPTS -H fd://

 我们这里面推荐下面的方式

vim /usr/lib/systemd/system/docker.service

修改docker的服务启动文件

vim /usr/lib/systemd/system/docker.service

[Service]

EnvironmentFile=/run/flannel/subnet.env

ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock $DOCKER_NETWORK_OPTIONS

systemctl daemon-reload

systemctl start flanneld

systemctl enable flanneld

systemctl restart docker

 

说明一下Flannel必须先于Docker启动,因为docker 依赖的参数是flanneld启动生成的

这时可以看到docker0的ip已经位于flannel网卡的网段之中:

查看生成的路由规则

我3台都部署了flanneld 

所以会看到3条路由表,同时和etcd存储的消息一致 

route -n

Kernel IP routing table

Destination     Gateway         Genmask         Flags Metric Ref    Use Iface

0.0.0.0         10.211.55.1     0.0.0.0         UG    0      0        0 eth0

10.0.0.0        0.0.0.0         255.0.0.0       U     0      0        0 eth0

169.254.0.0     0.0.0.0         255.255.0.0     U     1002   0        0 eth0

172.17.51.0     172.17.51.0     255.255.255.0   UG    0      0        0 flannel.1

172.17.55.0     0.0.0.0         255.255.255.0   U     0      0        0 docker0

172.17.69.0     172.17.69.0     255.255.255.0   UG    0      0        0 flannel.1

172.18.0.0      0.0.0.0         255.255.0.0     U     0      0        0 br-18d0011e4542 

测试

在各节点依次ping 各个docker0 的地址 

如果能通说明Flannel部署成功。如果不通检查下日志:

journalctl -u flannel

tail -f /var/log/messages

这里说明一下,一定要确保连接的ETCD 没问题,确保3台节点的数据都一致,之前遇到一个问题是ETCD 各节点数据不一致,导致路由规则生成有问题

各节点分配的iP不通