Docker网络方案之Flannel

Docker网络方案之Flannel

docker夸主机网络方案可选的很多,有大家说的隧道方案和路由方案,对应的有Flannel,Calico,还有swarm默认的跨主机网络docker overlay。本文主要介绍Flannel的工作机制。本文实验基础是centos7上的k8s集群。

Flannel解决跨主机通讯,简单来说,就是打通子网,使用同一个网段,每个主机分配一部分,让后给每个容器分配一个同网段IP。下面详细介绍。

一、flannel配置

flannel需要etcd配合使用,安装就不作详细介绍。下面看看k8s集群中etc和flannel的配置和运行状态。

etcd

$ ps -ef|grep etcd
etcd       917     1  0 12:55 ?        00:02:15 /usr/bin/etcd --name=default --data-dir=/var/lib/etcd/default.etcd --listen-client-urls=http://0.0.0.0:2379

etcd已经起来,端口是2379。

 $ etcdctl get /kube-centos/network/config
{ "Network": "172.30.0.0/16", "SubnetLen": 24, "Backend": { "Type": "vxlan" } }

etcd有一个key:/kube-centos/network/config,对应网络配置。

flannel

配置

$ cat /etc/sysconfig/flanneld
# 配置etcd 的地址
FLANNEL_ETCD_ENDPOINTS="http://${ETCD_IP}:2379"
# 配置etcd建的网络(key)
FLANNEL_ETCD_PREFIX="/kube-centos/network"

进程

$ ps -ef|grep flanneld
root      2060     1  0 12:55 ?        00:00:00 /usr/bin/flanneld -etcd-endpoints=http://172.16.69.129:2379 -etcd-prefix=/kube-centos/network

子网信息

$ cat /run/flannel/subnet.env
FLANNEL_NETWORK=172.30.0.0/16
FLANNEL_SUBNET=172.30.22.1/24
FLANNEL_MTU=1450
FLANNEL_IPMASQ=false

主机网络

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: enp0s3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 08:00:27:f0:ad:cd brd ff:ff:ff:ff:ff:ff
    inet 172.16.69.129/24 brd 172.16.69.255 scope global dynamic enp0s3
       valid_lft 1523sec preferred_lft 1523sec
    inet6 fe80::a00:27ff:fef0:adcd/64 scope link
       valid_lft forever preferred_lft forever
3: flannel.1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue state UNKNOWN
    link/ether 8e:db:22:6f:a1:52 brd ff:ff:ff:ff:ff:ff
    inet 172.30.22.0/32 scope global flannel.1
       valid_lft forever preferred_lft forever
4: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue state UP
    link/ether 02:42:a2:45:5e:0e brd ff:ff:ff:ff:ff:ff
    inet 172.30.22.1/24 scope global docker0
       valid_lft forever preferred_lft forever
    inet6 fe80::42:a2ff:fe45:5e0e/64 scope link
       valid_lft forever preferred_lft forever

可以看到Flannel.1对应ip为172.30.22.0

二、Docker容器使用Flannel子网

上面我们看到,网桥docker0的ip172.30.22.1和Flannel.1属同一网段。那docker启动时,是怎么获取Flannel子网的?

flannel启动后,子网信息记录到/run/flannel/subnet.env。

$ cat /run/flannel/docker
DOCKER_OPT_BIP="--bip=172.30.22.1/24"
DOCKER_OPT_IPMASQ="--ip-masq=true"
DOCKER_OPT_MTU="--mtu=1450"
DOCKER_NETWORK_OPTIONS=" --bip=172.30.22.1/24 --ip-masq=true --mtu=1450"

Docker deamon启动后,绑定子网。

$ ps -ef|grep docker
root      2096     1  0 12:55 ?        00:00:52 /usr/bin/dockerd-current --add-runtime docker-runc=/usr/libexec/docker/docker-runc-current --default-runtime=docker-runc --exec-opt native.cgroupdriver=systemd --userland-proxy-path=/usr/libexec/docker/docker-proxy-current --selinux-enabled --log-driver=journald --signature-verification=false --bip=172.30.22.1/24 --ip-masq=true --mtu=1450

可以看到docker后台进程信息有--bip=172.30.22.1/24 --ip-masq=true --mtu=1450

三、容器通讯

现有2台centos7虚拟机

172.16.69.129  # 容器a,容器b 
172.16.69.100 # 容器c

如果从容器a访问容器b,他们在同一台机器上,都桥接到docker0,可以通过brctl查看docker0上绑定的interfaces。

$ brctl show docker0
bridge name	bridge id		STP enabled	interfaces
docker0		8000.0242a2455e0e	no		veth6cf7408
						                veth94eb2a0

所以,通过docker0即可实现同主机容器间通讯

如果容器a访问容器c,容器ip对应为:

a 172.30.22.2
c 172.30.59.2

容器a访问容器c,a把数据发到flannel.1,flannel.1到etc下寻找172.30.59.2对应的主机。

$ etcdctl get /kube-centos/network/subnets/172.30.59.0-24
{"PublicIP":"172.16.69.100","BackendType":"vxlan","BackendData":{"VtepMAC":"22:00:3e:3a:0b:e

找到主机是172.16.69.100,然后把数据发送到172.16.69.100,再由主机完成分发给容器c。

CONTENTS