目录
什么是Flannel
Flannel原理
部署
环境准备
安装etcd
安装fannel
在server2上装flannel
测试
什么是Flannel
flannel是 CoreOS 团队针对 Kubernetes 设计的一个覆盖网络(Overlay Network)工具,其目的在于帮助每一个使用 Kuberentes 的 CoreOS 主机拥有一个完整的子网。这次的分享内容将从Flannel的介绍、工作原理及安装和配置三方面来介绍这个工具的使用方法。 Flannel通过给每台宿主机分配一个子网的方式为容器提供虚拟网络,它基于Linux TUN/TAP,使用UDP封装IP包来创建overlay网络,并借助etcd维护网络的分配情况。 Flannel is a simple and easy way to configure a layer 3 network fabric designed for Kubernetes.
Flannel原理
Flannel是CoreOS团队针对Kubernetes设计的一个网络规划服务,简单来说,它的功能是让集群中的不同节点主机创建的Docker容器都具有全集群唯一的虚拟IP地址。但在默认的Docker配置中,每个Node的Docker服务会分别负责所在节点容器的IP分配。Node内部得容器之间可以相互访问,但是跨主机(Node)网络相互间是不能通信。Flannel设计目的就是为集群中所有节点重新规划IP地址的使用规则,从而使得不同节点上的容器能够获得"同属一个内网"且"不重复的"IP地址,并让属于不同节点上的容器能够直接通过内网IP通信。 Flannel 使用etcd存储配置数据和子网分配信息。flannel 启动之后,后台进程首先检索配置和正在使用的子网列表,然后选择一个可用的子网,然后尝试去注册它。etcd也存储这个每个主机对应的ip。flannel 使用etcd的watch机制监视/coreos.com/network/subnets
下面所有元素的变化信息,并且根据它来维护一个路由表。为了提高性能,flannel优化了Universal TAP/TUN设备,对TUN和UDP之间的ip分片做了代理。 在Flannel的GitHub页面有如下的一张原理图:
对上图的简单说明 (Flannel的工作原理可以解释如下):
- 数据从源容器中发出后,经由所在主机的docker0虚拟网卡转发到flannel0虚拟网卡,这是个P2P的虚拟网卡,flanneld服务监听在网卡的另外一端。
- Flannel通过Etcd服务维护了一张节点间的路由表,该张表里保存了各个节点主机的子网网段信息。
- 源主机的flanneld服务将原本的数据内容UDP封装后根据自己的路由表投递给目的节点的flanneld服务,数据到达以后被解包,然后直接进入目的节点的flannel0虚拟网卡,然后被转发到目的主机的docker0虚拟网卡,最后就像本机容器通信一样的由docker0路由到达目标容器。
部署
环境准备
节点名称 | IP地址 | 安装软件 |
docker-server1 | 192.168.100.5 | etcd、flannel、docker |
docker-server2 | 192.168.100.6 | flannel、docker |
#首先需要在两台机子开启 地址转发
[root@docker-server1 ~]# echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf^C
[root@docker-server1 ~]# sysctl -p
net.ipv4.ip_forward = 1
安装etcd
[root@docker-server1 ~]# yum -y install etcd
[root@docker-server1 ~]# vim /etc/etcd/etcd.conf
#[Member]
ETCD_DATA_DIR="/var/lib/etcd/default.etcd"
ETCD_LISTEN_CLIENT_URLS="http://192.168.100.5:2379,http://127.0.0.1:2379"
ETCD_NAME="default"
#[Clustering]
ETCD_ADVERTISE_CLIENT_URLS="http://192.168.100.5:2379"
[root@docker-server1 ~]# systemctl start etcd.service
[root@docker-server1 ~]# etcdctl mk /atomic.io/network/config '{"Network":"172.20.0.0/16","SubnetMin":"172.20.1.0","SubnetMax":"172.20.254.0"}'
{"Network":"172.20.0.0/16","SubnetMin":"172.20.1.0","SubnetMax":"172.20.254.0"}
[root@docker-server1 ~]# etcdctl get /atomic.io/network/config
{"Network":"172.20.0.0/16","SubnetMin":"172.20.1.0","SubnetMax":"172.20.254.0"}
安装fannel
[root@docker-server1 ~]# yum install -y docker
[root@docker-server1 ~]# yum install -y flannel
[root@docker-server1 ~]# vim /etc/sysconfig/flanneld
FLANNEL_ETCD_ENDPOINTS="http://192.168.100.5:2379"
# etcd config key. This is the configuration key that flannel queries
# For address range assignment
FLANNEL_ETCD_PREFIX="/atomic.io/network"
[root@docker-server1 ~]# systemctl restart flanneld
#我们查看网桥,看到了flannel0,而且ip的地址端是我们自己指定的172.20.0.0/16网段中的地址段172.20.75.0/24
[root@docker-server1 ~]# ip a
4: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
link/ether 02:42:98:e9:7d:c6 brd ff:ff:ff:ff:ff:ff
inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
valid_lft forever preferred_lft forever
#而且还生成了配置文件/run/flannel/subnet.env和/run/flannel/docker存储了这个服务器端信息。
启动flanneld后,会有一张网卡产生:而且此网卡的地址就是使用etcdctl mk定义的网段地址。
[root@docker-server1 ~]# cat /run/flannel/subnet.env
FLANNEL_NETWORK=172.20.0.0/16
FLANNEL_SUBNET=172.20.66.1/24
FLANNEL_MTU=1472
FLANNEL_IPMASQ=false
[root@docker-server1 ~]# cat /run/flannel/docker
DOCKER_OPT_BIP="--bip=172.20.66.1/24"
DOCKER_OPT_IPMASQ="--ip-masq=true"
DOCKER_OPT_MTU="--mtu=1472"
DOCKER_NETWORK_OPTIONS=" --bip=172.20.66.1/24 --ip-masq=true --mtu=1472"
修改Docker启动文件
[root@docker-server1 ~]# vim /usr/lib/systemd/system/docker.service
#修改[service]
[Service]
Type=notify
#添加这一行
EnvironmentFile=-/run/flannel/docker
#在-H前添加$DOCKER_NETWORK_OPTIONS
ExecStart=/usr/bin/dockerd $DOCKER_NETWORK_OPTIONS -H fd:// --containerd=/run/containerd/containerd.sock
ExecReload=/bin/kill -s HUP $MAINPID
TimeoutStartSec=0
RestartSec=2
Restart=always
[root@docker-server1 ~]# systemctl daemon-reload
[root@docker-server1 ~]# systemctl restart docker
[root@docker-server1 ~]# systemctl enable flanneld.service
[root@docker-server1 ~]# systemctl enable docker.service
[root@docker-server1 ~]# systemctl enable etcd.service
#查看docker的ip
[root@docker-server1 ~]# ip a
4: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
link/ether 02:42:98:e9:7d:c6 brd ff:ff:ff:ff:ff:ff
inet 172.20.66.1/24 brd 172.20.66.255 scope global docker0
valid_lft forever preferred_lft forever
在server2上装flannel
[root@docker-server2 ~]# yum -y install docker
[root@docker-server2 ~]# yum -y install flannel
[root@docker-server2 ~]# vim /etc/sysconfig/flanneld
#这里设置的是etcd的IP地址
FLANNEL_ETCD_ENDPOINTS="http://192.168.100.5:2379"
[root@docker-server2 ~]# systemctl restart flanneld
在server2上也要修改docker启动脚本,修改方法和server1一样
[root@docker-server2 ~]# systemctl enable flanneld.service --now
[root@docker-server2 ~]# systemctl enable docker.service --now
测试
#首先在两台服务器上拉取镜像
[root@docker-server1 ~]# docker pull centos:7.9.2009
[root@docker-server2 ~]# docker pull centos:7.9.2009
#运行
[root@docker-server1 ~]# docker run -itd --name=centos1 centos:7.9.2009
[root@docker-server2 ~]# docker run -itd --name=centos1 centos:7.9.2009
#分别查看各自的IP地址
[root@docker-server1 ~]# docker inspect --format='{{.NetworkSettings.IPAddress}}' centos1
172.20.66.2
[root@docker-server2 ~]# docker inspect --format='{{.NetworkSettings.IPAddress}}' centos1
172.20.13.2
#进入容器,互相ping一下,看看是否ping通
[root@docker-server1 ~]# docker exec -it centos1 bash
[root@6fce48324a03 /]# ping 172.20.13.2 -c4
PING 172.20.13.2 (172.20.13.2) 56(84) bytes of data.
64 bytes from 172.20.13.2: icmp_seq=1 ttl=60 time=0.632 ms
64 bytes from 172.20.13.2: icmp_seq=2 ttl=60 time=0.697 ms
64 bytes from 172.20.13.2: icmp_seq=3 ttl=60 time=2.89 ms
64 bytes from 172.20.13.2: icmp_seq=4 ttl=60 time=2.32 ms
--- 172.20.13.2 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3001ms
rtt min/avg/max/mdev = 0.632/1.637/2.897/0.995 ms
[root@6fce48324a03 /]#
[root@docker-server2 ~]# docker exec -it centos1 bash
[root@56b694f654fa /]# ping 172.20.66.2 -c 4
PING 172.20.66.2 (172.20.66.2) 56(84) bytes of data.
64 bytes from 172.20.66.2: icmp_seq=1 ttl=60 time=11.5 ms
64 bytes from 172.20.66.2: icmp_seq=2 ttl=60 time=2.07 ms
64 bytes from 172.20.66.2: icmp_seq=3 ttl=60 time=4.52 ms
64 bytes from 172.20.66.2: icmp_seq=4 ttl=60 time=2.08 ms
--- 172.20.66.2 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3005ms
rtt min/avg/max/mdev = 2.076/5.050/11.515/3.864 ms
[root@56b694f654fa /]#