flannel网络
介绍
Flannel是CoreOS团队针对Kubernetes设计的一个网络规划服务,简单来说,它的功能是让集群中的不同节点主机创建的Docker容器都具有全集群唯一的虚拟IP地址。
flannel在k8s工作
kubernetes 要求集群内各节点(包括 master 节点)能通过 Pod 网段互联互通。flannel 使用 vxlan 技术为各节点创建一个可以互通的 Pod 网络,使用的端口为 UDP 8472(需要开放该端口,如公有云 AWS 等)。
flanneld 第一次启动时,从 etcd 获取配置的 Pod 网段信息,为本节点分配一个未使用的地址段,然后创建 flannedl.1
网络接口(也可能是其它名称,如 flannel1 等)。
flannel 将分配给自己的 Pod 网段信息写入 /run/flannel/docker
文件,docker 后续使用这个文件中的环境变量设置 docker0
网桥,从而从这个地址段为本节点的所有 Pod 容器分配 IP。
部署
下载和分发 flanneld 二进制文件
从 flannel 的 release 页面 下载最新版本的安装包:
1 | cd /opt/k8s/work |
分发二进制文件到集群所有节点:
1 | cd /opt/k8s/work |
创建 flannel 证书和私钥
flanneld 从 etcd 集群存取网段分配信息,而 etcd 集群启用了双向 x509 证书认证,所以需要为 flanneld 生成证书和私钥。
创建证书签名请求:
1 | cd /opt/k8s/work |
- 该证书只会被 kubectl 当做 client 证书使用,所以 hosts 字段为空;
生成证书和私钥:
1 | cfssl gencert -ca=/opt/k8s/work/ca.pem \ |
将生成的证书和私钥分发到所有节点(master 和 worker):
1 | cd /opt/k8s/work |
在etcd 写入集群 Pod 网段信息
注意:本步骤只需执行一次。
1 | cd /opt/k8s/work |
- flanneld 当前版本 (v0.11.0) 不支持 etcd v3,故使用 etcd v2 API 写入配置 key 和网段数据;
- 写入的 Pod 网段
${CLUSTER_CIDR}
地址段(如 /16)必须小于SubnetLen
,必须与kube-controller-manager
的--cluster-cidr
参数值一致;
创建 flanneld 的 systemd
1 | cd /opt/k8s/work |
mk-docker-opts.sh
脚本将分配给 flanneld 的 Pod 子网段信息写入/run/flannel/docker
文件,后续 docker 启动时使用这个文件中的环境变量配置 docker0 网桥;- flanneld 使用系统缺省路由所在的接口与其它节点通信,对于有多个网络接口(如内网和公网)的节点,可以用
-iface
参数指定通信接口; - flanneld 运行时需要 root 权限;
-ip-masq
: flanneld 为访问 Pod 网络外的流量设置 SNAT 规则,同时将传递给 Docker 的变量--ip-masq
(/run/flannel/docker
文件中)设置为 false,这样 Docker 将不再创建 SNAT 规则; Docker 的--ip-masq
为 true 时,创建的 SNAT 规则比较“暴力”:将所有本节点 Pod 发起的、访问非 docker0 接口的请求做 SNAT,这样访问其他节点 Pod 的请求来源 IP 会被设置为 flannel.1 接口的 IP,导致目的 Pod 看不到真实的来源 Pod IP。 flanneld 创建的 SNAT 规则比较温和,只对访问非 Pod 网段的请求做 SNAT。
分发 flanneld systemd unit
1 | cd /opt/k8s/work |
启动 flanneld 服务
1 | source /opt/k8s/bin/environment.sh |
检查启动结果
1 | source /opt/k8s/bin/environment.sh |
确保状态为 active (running)
检查分配给各 flanneld 的 Pod 网段信息
查看集群 Pod 网段(/16):
1 | source /opt/k8s/bin/environment.sh |
输出:
{"Network":"172.30.0.0/16", "SubnetLen": 21, "Backend": {"Type": "vxlan"}}
查看已分配的 Pod 子网段列表(/24):
1 | source /opt/k8s/bin/environment.sh |
输出(结果视部署情况而定):
1 | [root@node1 ~]# etcdctl \ |
查看某一 Pod 网段对应的节点 IP 和 flannel 接口地址:
1 | source /opt/k8s/bin/environment.sh |
输出:
1 | [root@node1 ~]# etcdctl \ |
验证各节点能通过 Pod 网段互通
在各节点上部署 flannel 后,检查是否创建了 flannel 接口(名称可能为 flannel0、flannel.0、flannel.1 等):
1 | source /opt/k8s/bin/environment.sh |
输出:
1 | [root@node1 ~]# for node_ip in ${NODE_IPS[@]} |
在各节点上 ping 所有 flannel 接口 IP,确保能通
kubectl
下载和分发 kubectl 二进制文件
下载和解压:
1 | cd /opt/k8s/work |
分发到所有使用 kubectl 的节点:
1 | cd /opt/k8s/work |
创建 admin 证书和私钥
kubectl 与 apiserver https 安全端口通信,apiserver 对提供的证书进行认证和授权。
kubectl 作为集群的管理工具,需要被授予最高权限,这里创建具有最高权限的 admin 证书。
创建证书签名请求:
1 | cd /opt/k8s/work |
- O 为
system:masters
,kube-apiserver 收到该证书后将请求的 Group 设置为 system:masters; - 预定义的 ClusterRoleBinding
cluster-admin
将 Groupsystem:masters
与 Rolecluster-admin
绑定,该 Role 授予所有 API的权限; - 该证书只会被 kubectl 当做 client 证书使用,所以 hosts 字段为空;
生成证书和私钥:
1 | cd /opt/k8s/work |
创建 kubeconfig 文件
kubeconfig 为 kubectl 的配置文件,包含访问 apiserver 的所有信息,如 apiserver 地址、CA 证书和自身使用的证书;
1 | cd /opt/k8s/work |
--certificate-authority
:验证 kube-apiserver 证书的根证书;--client-certificate
、--client-key
:刚生成的admin
证书和私钥,连接 kube-apiserver 时使用;--embed-certs=true
:将 ca.pem 和 admin.pem 证书内容嵌入到生成的 kubectl.kubeconfig 文件中(不加时,写入的是证书文件路径,后续拷贝 kubeconfig 到其它机器时,还需要单独拷贝证书文件,不方便。);
分发 kubeconfig 文件
分发到所有使用 kubectl
命令的节点:
1 | cd /opt/k8s/work |
- 保存的文件名为
~/.kube/config
;