Kubernetes 网络配置方案

为了实现各 Node 上 Pod 之间的互通,需要一些方案来打通网络,这是 Kubernetes 能够正常工作的前提。本篇将对常用的直接路由、Flannel 和 Open vSwitch 三种配置进行详细说明。

直接路由

通过在每个 Node 上添加到其他 Node 上 docker0 的静态路由规则,就可以将不同物理服务器上 Docker Daemon 创建的 docker0 网桥互联互通。

例如 Pod1 所在 docker0 网桥的 IP 子网是 10.1.10.0,Node 地址为 192.168.1.128;而 Pod2 所在 docker0 网桥的 IP 子网是 10.1.20.0,Node 地址为 192.168.1.129.

在 Node1 上增加一条到 Node2 上 docker0 的静态路由规则:

1
route add -net 10.1.20.0 netmask 255.255.255.0 gw 192.168.1.129

同样,在 Node2 上增加一条到 Node1 上 docker0 的静态路由规则:

1
route add -net 10.1.10.0 netmask 255.255.255.0 gw 192.168.1.128

我们的集群中机器数量通常很多。假设有 100 台服务器,那么就需要在每台服务器上手工添加到另外 99 台服务器 docker0 的路由规则。为了减少手工操作,可以使用 Quagga 软件来实现路由规则的动态添加。

除了在每台服务器上安装 Quagga 软件并启动,还可以使用互联网上的一个 Quagga 容器来运行,在这里使用 index.alauda.cn/georce/router 镜像启动 Quagga。在每台 Node 上下载该 Docker 镜像:

1
$ docker pull index.alauda.cn/georce/router

在运行 Quagga 路由器之前,需要确保每个 Node 上 docker0 网桥的子网地址不能重叠,也不能与物理机所在的网络重叠,这需要网络管理员仔细规划。

下面以 3 个 Node 为例,使用 ifconfig 命令修改 docker0 网桥的地址和子网(假设 Node 所在的物理网络不是 10.1.X.X地址段):

1
2
3
Node 1: # ifconfig docker0 10.1.10.1/24
Node 2: # ifconfig docker0 10.1.20.1/24
Node 3: # ifconfig docker0 10.1.30.1/24

然后在每个 Node 上启动 Quagga 容器。需要说明的是,Quagga 需要以 –privileged 特权模式运行,并且指定 –net=host,表示直接使用物理机的网络:

1
$ docker run -itd --name=router --privileged --net=host index.alauda.cn/georce/router

启动成功后,Quagga 会相互学习来完成到其他机器的 docker0 路由的添加。

使用 flannel 叠加网络

falnnel 采用叠加网络(Overlay Network)模型来完成网络的打通。

安装 etcd

由于 flannel 使用 etcd 作为数据库,所以需要预先安装好 etcd。

安装 flannel

需要在每台 Node 上都安装 flannel。flannel 软件的下载地址为 (https://github.com/coreos/flannel/releases)。将下载的压缩包解压,把二进制文件 flanneld 和 mk-docker-opts.sh 复制到 /usr/bin(或其他 PATH 环境变量中的目录),即可完成对 flannel 的安装。

配置 flannel

此处以使用 systemd 系统为例对 flanneld 服务进行配置。编辑服务配置文件 /etc/systemd/system/flanneld.service:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
[Unit]
Description=Flanneld overlay address etcd agent
After=network.target
Before=docker.service
[Service]
Type=notify
EnvironmentFile=/etc/sysconfig/flanneld
EnvironmentFile=-/etc/sysconfig/docker-network
ExecStart=/usr/bin/flanneld -etcd-endpoints=${FLANNEL_ETCD} $FLANNEL_OPTIONS
[Install]
RequiredBy=docker.service
WantedBy=multi-user.target

编辑配置文件/etc/sysconfig/flannel,设置 etcd 的 URL 地址:

1
2
3
4
5
6
7
8
9
10
# Flanneld configuration options
# etcd url location. Point this to the server where etcd runs
FLANNEL_ETCD="http://192.168.1.128:2379"
# etcd config key. THis is the configuration key that flannel queries
# For address range assignment
FLANNEL_ETCD_KEY="/coreos.com/network"
# Any additional options that you want to pass
#FLANNEL_OPTIONS=" "

在启动 flannel 之前,需要在 etcd 中添加一条网络配置记录,这个配置将用于 flannel 分配给每个 Docker 的虚拟 IP 地址段:

1
# etcdctl set /coreos.com/network/config '{ "Network" : " 10.1.0.0/16 " }'

由于 flannel 将覆盖 docker0 网桥,所以如果 Docker 服务网已启动,则停止 Docker 服务。

启动 flanneld 服务

1
# systemctl restart flanneld

在每个 Node 节点执行以下命令来完成对 docker0 网桥的配置:

1
2
3
# mk-docker-opts.sh -i
# source /run/flannel/subnet.env
# ifconfig docker0 ${FLANNEL_SUBNET}

重新启动 Docker 服务

使用 Open vSwitch

以两个 Node 为例,首先确保节点 192.168.18.128 的 Docker0 采用 172.17.43.0/24 网段,而 192.168.18.131 的 Docker0 采用 172.17.42.0/24 网段,对应参数为 DockerDaemon 进程里的 bip 参数。

安装 ovs

1
# yum install openvswitch-x.x.x-x.x86_64.rpm

禁止 SELINUX 功能,配置后重启机器

1
2
# vi /etc/selinux/config
SELINUX=disabled

查看 Open vSwitch 的服务状态,应该启动两个进程:ovsdb-server 与 ovs-vswitchd。

创建网桥和 GRE 隧道

接下来需要在每个 Node 上建立 ovs 的网桥 br0,然后在网桥上创建一个 GRE 隧道连接对端网桥,最后把 ovs 的网桥 br0 作为一个端口连接到 docker0 这个 Linux 网桥上。这样以来,两个节点上的 docker0 网段就能互通了。

创建网桥

1
# ovs-vsctl add-br br0

创建 GRE 隧道连接对端,remote_ip 为对端 eth0 的网卡地址

1
# ovs-vsctl add-port br0 grel -- set interface grel type=gre option:remote_ip=192.168.18.128

添加 br0 到本地 docker0,使得容器流量通过 OVS 流经 tunnel

1
# brctl addif docker0 br0

启动 br0 与 docker0 网桥

1
2
# ip link set dev br0 up
# ip link set dev docker0 up

添加路由规则。由于 192.168.18.128 与 192.168.18.131 的 docker0 网段分别为 172.17.43.0/24 与 172.17.42.0/24,这两个网段的路由都需要经过本机的 docker0 网桥路由,其中一个 24 网段是通过 OVS 的 GRE 隧道到达对端的,因此需要在每个 Node 上添加通过 docker0 网桥转发的 172.17.0.0/16 段的路由规则:

1
# ip route add 172.17.0.0/16 dev docker0

清空 Docker 自带的 iptables 规则及 Linux 的规则 ,后者存在拒绝 icmp 报文通过防火墙的规则:

1
# iptables -t nat -F; iptables -F

在 192.168.18.131 上完成上述步骤后,在 192.168.18.128 节点执行同样的操作。注意,GRE 隧道里的 IP 地址药改为对端节点(192.168.18.131)的 IP 地址。

Node 上容器之间的互通测试

1
# tshark -i br0 -R ip proto great