flannel
- 前言
- 一、Flannel简介
- 二、Flannel原理
- 三、Flannel的作用
- 四、模拟实验
-
- 4.1 master配置
- 4.2 node节点操作
前言
此文接着上篇博客kubernetes(k8s)二进制部署——etcd部署继续学习k8s
当一个k8s集群创建好后一般会存在三种IP,分别是:
Pod IP
、
Node IP
、
Cluster IP
这些IP可以理解为简单的套娃关系,即其中一个Cluster IP之下包含多个Node IP,而一个Node IP之下又包含多个Pod IP,同一个Pod包含多个容器(这些容器的网络都在同一个命名空间,因此可以自由的通信),同一个Node包含多个Pod,这些Pod又通过veth pair技术与同一个cni网桥进行连接,通常这个cni网桥就是我们熟知的docker0网卡,这个是在你安装docker后就会创建在宿主机上的一个虚拟网卡,因此相同Node节点下的Pod又可以通过cni网桥进行通信。
但是不同Node节点下的Pod又是如何进行通信的,尤其是在成千上万个容器的情况下进行通信,就这需要用到flannel网络插件来解决这个问题。
一、Flannel简介
- Flannel是CoreOS团队针对Kubernetes设计的一个网络规划服务,简单来说,它的功能是让集群中的不同节点主机创建的Docker容器都具有
的虚拟IP地址。全集群唯一
- 在默认的Docker配置中,每个节点上的Docker服务会分别负责所在节点容器的IP分配。这样导致的一个问题是,不同节点上容器可能获得相同的内外IP地址。并使这些容器之间能够之间通过IP地址相互找到,也就是相互ping通。
- Flannel的设计目的就是为集群中的所有节点重新规划IP地址的使用规则,从而使得不同节点上的容器能够获得
且同属一个内网
IP地址,并让属于不同节点上的容器能够直接通过内网IP通信。不重复的
- Flannel实质上是一种“覆盖网络(overlaynetwork)”,也就是将TCP数据包装在另一种网络包里面进行路由转发和通信,目前已经支持udp、vxlan、host-gw、aws-vpc、gce和alloc路由等数据转发方式,默认的节点间数据通信方式是UDP转发。
二、Flannel原理
- 首先,Flannel通过Kubernetes API把整个集群的网络配置存储在Etcd中,其中最主要的内容为设置集群的网络地址空间。例如,指定整个集群内所有容器的IP都取自“10.1.0.0/16”网段。
- 接着,Flannel在每个主机中运行flanneld作为agent,它会为所在主机从集群的网络地址空间中,获取一个小的网段
,本主机内所有容器的IP地址都将从中分配。subnet(子网)
- 然后,Flanneld再将本主机获取的subnet以及用于主机间通信的Public IP,同样通过Kubernetes API存储在Etcd中。
- 最后,Flannel利用各种数据转发方式,例如udp、vxlan、AWS、VPC和GCE路由等等,跨主机转发容器间的网络流量,完成容器间的跨主机通信。
- 如图所示,集群范围内的网络地址空间为10.1.0.0/16,节点1获取的subnet为10.1.15.0/24,且其中的两个Pod IP分别为10.1.15.2/24和10.1.15.3/24,两者都在10.1.15.0/24这一子网范围内,节点2同理。
- 如果上方节点1中的
的容器想要与下方节点2中的Pod1(10.1.15.2/24)
的容器进行通信,数据包是如何进行转发的。从上文可知,每个主机的flanneld会将自己与所获取subnet的关联信息存入Etcd中。例如,子网段pod1(10.1.20.2/24)
所在主机可通过10.1.15.0/24
访问,子网段Public IP 192.168.0.100
可通过10.1.20.0/24
访问。反之,每台主机上的flanneld通过监听Etcd,也能够知道其他的子网段与哪些主机相关联。如上图,节点1上的flanneld通过监听etcd已经知道子网段Public IP 192.168.0.200
所在的主机可以通过10.1.20.0/24
访问,而且熟悉docker桥接模式的同学肯定知道,目的地址为10.1.20.2/24的数据包一旦到达节点2,就能通过cni0网桥转发到相应的pod,从而达到跨宿主机通信的目的。Public IP 192.168.0.200
- 因此,flanneld只要想办法将封包从
转发到节点1
就可以了,而上文中的backend就是用于完成这一任务。不过,达到这个目的的方法是多种多样的,所以我们也就有了很多种数据转发方式。节点2
三、Flannel的作用
- 使集群中的不同Node主机创建的Docker容器都具有全集群唯一的虚拟IP地址。
- 建立一个覆盖网络(overlay network),通过这个覆盖网络,将数据包原封不动的传递到目标容器。覆盖网络是建立在另一个网络之上并由其基础设施支持的虚拟网络。覆盖网络通过将一个分组封装在另一个分组内来将网络服务与底层基础设施分离。在将封装的数据包转发到端点后,将其解封装。
- 创建一个新的虚拟网卡flannel0接收docker网桥的数据,通过维护路由表,对接收到的数据进行封包和转发(vxlan)。
- etcd保证了所有node上flanned所看到的配置是一致的。同时每个node上的flanned监听etcd上的数据变化,实时感知集群中node的变化
- Overlay Network:覆盖网络,在基础网络上叠加的一种虚拟网络技术模式,该网络中的主机通过虚拟链路连接起来
- VXLAN:将源数据包封装到UDP中,并使用基础网络的IP/MAC作外层报文头进行封装,然后再以太网上传输,到达目的地后由隧道端点解封并将数据转发到目标地址
四、模拟实验
开始之前所有
node节点
都必须部署docker引擎,可参考Docker——相关概念及安装方法
4.1 master配置
需要在有证书的目录下使用此命令
写入分配的子网段到ETCD中,供flannel使用
[[email protected] ~]# cd k8s/etcd-cert/
[[email protected] ~/k8s/etcd-cert]# /opt/etcd/bin/etcdctl --ca-file=ca.pem --cert-file=server.pem --key-file=server-key.pem --endpoints="https://192.168.153.10:2379,https://192.168.153.30:2379,https://192.168.153.40:2379" set /coreos.com/network/config '{ "Network": "172.17.0.0/16", "Backend": {"Type": "vxlan"}}'
#查看写入的信息
[[email protected] ~/k8s/etcd-cert]# /opt/etcd/bin/etcdctl --ca-file=ca.pem --cert-file=server.pem --key-file=server-key.pem --endpoints="https://192.168.153.10:2379,https://192.168.153.30:2379,https://192.168.153.40:2379" get /coreos.com/network/config
4.2 node节点操作
拖入软件包并解压)
flannel-v0.10.0-linux-amd64.tar.gz
创建k8s工作目录
mkdir -p /opt/kubernetes/{cfg,bin,ssl}
mv mk-docker-opts.sh flanneld /opt/kubernetes/bin/
vim flannel.sh
#!/bin/bash
ETCD_ENDPOINTS=${1:-"http://127.0.0.1:2379"}
cat <<EOF >/opt/kubernetes/cfg/flanneld
FLANNEL_OPTIONS="--etcd-endpoints=${ETCD_ENDPOINTS} \
-etcd-cafile=/opt/etcd/ssl/ca.pem \
-etcd-certfile=/opt/etcd/ssl/server.pem \
-etcd-keyfile=/opt/etcd/ssl/server-key.pem"
EOF
cat <<EOF >/usr/lib/systemd/system/flanneld.service
[Unit]
Description=Flanneld overlay address etcd agent
After=network-online.target network.target
Before=docker.service
[Service]
Type=notify
EnvironmentFile=/opt/kubernetes/cfg/flanneld
ExecStart=/opt/kubernetes/bin/flanneld --ip-masq \$FLANNEL_OPTIONS
ExecStartPost=/opt/kubernetes/bin/mk-docker-opts.sh -k DOCKER_NETWORK_OPTIONS -d /run/flannel/subnet.env
Restart=on-failure
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
systemctl enable flanneld
systemctl restart flanneld
开启flannel网络功能
配置docker连接flannel
vim /usr/lib/systemd/system/docker.service
[Service]
Type=notify
# the default is not to use systemd for cgroups because the delegate issues still
# exists and systemd currently does not support the cgroup feature set required
# for containers run by docker
EnvironmentFile=/run/flannel/subnet.env
ExecStart=/usr/bin/dockerd $DOCKER_NETWORK_OPTIONS -H fd:// --containerd=/run/containerd/containerd.sock
ExecReload=/bin/kill -s HUP $MAINPID
TimeoutSec=0
RestartSec=2
Restart=always
重启docker服务
systemctl daemon-reload
systemctl restart docker
查看flannel网络
测试ping通对方docker0网卡 证明flannel起到路由作用
docker run -it 容器ID /bin/bash
yum install net-tools -y
ifconfig
再次测试ping通两个node中的centos:7容器