之前的博客已经介绍了部署一个简单的Kubernetes集群,但是这个集群环境没有一个合理的网络配置。在实际生产中要实现集群中各个组件的通信,就需要使用第三方提供的网络插件。
Flannel 二进制安装
1、下载fannel组件
wget https://github.com/coreos/flannel/releases/download/v0.10.0/flannel-v0.10.0-linux-amd64.tar.gz
2、安装Flannel 网络组件
tar xf flannel-v0.10.0-linux-amd64.tar.gz
cp flanneld /usr/bin/
cp mk-docker-opts.sh /usr/bin/
3、由于是二进制的文件,将flanneld拷贝到有系统环境变量的可执行路径就完成了安装。下面讲解具体的配置过程和原理。
Flannel 配置
我们之所以要单独使用第三方的网络插件来扩展k8s,主要原因是在使用docker的环境中,在每个node节点的docker0默认的网段都是172.17.0.0/16的网络。如果要实现不同宿主node上pod(这里也可以理解为容器)互相通信,就不能使用默认的docker0提供的网段,我们需要部署一个覆盖网络,让每个node节点的docker0网络都处于不同的网段,这样,通过添加一些路由转发策略,就能让集群中各个pod在同一个虚拟的网络中实现通信。
1、这里编写flanneld的systemd文件:
# cat /usr/lib/systemd/system/flanneld.service
[Unit]
Description=Flanneld overlay address etcd agent
After=network.target
Before=docker.service
[Service]
EnvironmentFile=-/etc/kubernetes/flanneld
ExecStartPre=/usr/bin/remove-docker0.sh
ExecStart=/usr/bin/flanneld ${FLANNEL_ETCD} $FLANNEL_OPTIONS
ExecStartPost=/usr/bin/mk-docker-opts.sh -d /run/flannel/docker
Type=notify
[Install]
WantedBy=multi-user.target
RequiredBy=docker.service
对上面的文件做一下解释:
- Flannel网络必须在宿主机网络能对外(其它node节点)正常通信的情况下启动才有意义,所以这里定义
After=network.target
- 只有当Flannel 网络启动之后,才能创建一个与其它节点不会冲突的网络,而docker的网络需要和fannel 网络相同才能保证跨主机通信,所以docker必须要在flannel网络创建后才能启动,这里定义
Before=docker.service
- 在
/etc/kubernetes/flanneld
文件中,我们会指定flannel相关的启动参数,这里由于需要指定etcd集群,会有一部分不通用的参数,所以单独定义。 - 当前创建flannel网络时,我们会执行
/usr/bin/remove-docker0.sh
这个脚本,将如果已经创建了docker0的网卡,就将他移除,防止产生冲突。(这个脚本来自k8s的源码包) - 启动之后,我们需要使用fannel自带的脚本,创建一个docker使用的启动参数,这个参数就包含配置docker0网卡的网段。
2、配置fannel参数文件:
# cat /etc/kubernetes/flanneld
FLANNEL_ETCD="-etcd-endpoints=http://10.0.0.1:2379" # etcd集群
FLANNEL_ETCD_KEY="/coreos.com/network" # etcd存储flannel网络信息的key
3、etcd中添加fannel的key, 这里指定了flannel的网段:
etcdctl set /coreos.com/network/config '{ "Network": "10.1.0.0/16" }'
4、启动fannel:
systemctl daemon-reload
systemctl start flanneld
docker配置
1、如果要使用flannel网络,在启动docker时,需要添加 --bip
参数,修改systemd启动文件:
# vim /usr/lib/systemd/system/docker.service
[Unit] # 添加如下内容
After=network-online.target firewalld.service flanneld.service
Wants=network-online.target
Requires=flanneld.service
[Service] #增加EnvironmentFile=-/run/flannel/docker,并添加参数
...
EnvironmentFile=-/run/flannel/docker
ExecStart=/usr/bin/dockerd $DOCKER_OPTS
...
修改配置说明:
- docker的网络配置需要依赖于Fannel, 所以定义
Requires=flanneld.service
- 运行docker时,需要加载配置参数,而此文件是执行flannel脚本后生成的。
- 在启动docker是指定参数。
2、验证docker0信息:
[root@node-3 ~]# ifconfig docker0
docker0: flags=4099 mtu 1500
inet 10.1.90.1 netmask 255.255.255.0 broadcast 0.0.0.0
ether 02:42:44:54:5b:c5 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
3、在每个节点部署flannel,之后可以创建pod,验证不同节点上的pod能否ping通。这里就不做演示,可以参考我之前的博客。
Flannel 网络原理
Flannel是如何做到让不同主机上的pod 互通呢,下面的网络图很清楚的解释了这个问题: