部署 Flannel 网络

kubernetes 要求集群内各节点能通过 Pod 网段互联互通,本文档介绍使用 Flannel 在所有节点 (Master、Node) 上创建互联互通的 Pod 网段的步骤。

使用的变量

本文档用到的变量定义如下:

  1. $ export NODE_IP=10.64.3.7 # 当前部署节点的 IP
  2. $ # 导入用到的其它全局变量:ETCD_ENDPOINTS、FLANNEL_ETCD_PREFIX、CLUSTER_CIDR
  3. $ source /root/local/bin/environment.sh
  4. $

创建 TLS 秘钥和证书

etcd 集群启用了双向 TLS 认证,所以需要为 flanneld 指定与 etcd 集群通信的 CA 和秘钥。

创建 flanneld 证书签名请求:

  1. $ cat > flanneld-csr.json <<EOF
  2. {
  3. "CN": "flanneld",
  4. "hosts": [],
  5. "key": {
  6. "algo": "rsa",
  7. "size": 2048
  8. },
  9. "names": [
  10. {
  11. "C": "CN",
  12. "ST": "BeiJing",
  13. "L": "BeiJing",
  14. "O": "k8s",
  15. "OU": "System"
  16. }
  17. ]
  18. }
  19. EOF
  • hosts 字段为空;

生成 flanneld 证书和私钥:

  1. $ cfssl gencert -ca=/etc/kubernetes/ssl/ca.pem \
  2. -ca-key=/etc/kubernetes/ssl/ca-key.pem \
  3. -config=/etc/kubernetes/ssl/ca-config.json \
  4. -profile=kubernetes flanneld-csr.json | cfssljson -bare flanneld
  5. $ ls flanneld*
  6. flanneld.csr flanneld-csr.json flanneld-key.pem flanneld.pem
  7. $ sudo mkdir -p /etc/flanneld/ssl
  8. $ sudo mv flanneld*.pem /etc/flanneld/ssl
  9. $ rm flanneld.csr flanneld-csr.json

向 etcd 写入集群 Pod 网段信息

注意:本步骤只需在第一次部署 Flannel 网络时执行,后续在其它节点上部署 Flannel 时无需再写入该信息!

  1. $ /root/local/bin/etcdctl \
  2. --endpoints=${ETCD_ENDPOINTS} \
  3. --ca-file=/etc/kubernetes/ssl/ca.pem \
  4. --cert-file=/etc/flanneld/ssl/flanneld.pem \
  5. --key-file=/etc/flanneld/ssl/flanneld-key.pem \
  6. set ${FLANNEL_ETCD_PREFIX}/config '{"Network":"'${CLUSTER_CIDR}'", "SubnetLen": 24, "Backend": {"Type": "vxlan"}}'
  • flanneld 目前版本 (v0.7.1) 不支持 etcd v3,故使用 etcd v2 API 写入配置 key 和网段数据;
  • 写入的 Pod 网段(${CLUSTER_CIDR},172.30.0.0/16) 必须与 kube-controller-manager 的 --cluster-cidr 选项值一致;

安装和配置 flanneld

下载 flanneld

  1. $ mkdir flannel
  2. $ wget https://github.com/coreos/flannel/releases/download/v0.7.1/flannel-v0.7.1-linux-amd64.tar.gz
  3. $ tar -xzvf flannel-v0.7.1-linux-amd64.tar.gz -C flannel
  4. $ sudo cp flannel/{flanneld,mk-docker-opts.sh} /root/local/bin
  5. $

创建 flanneld 的 systemd unit 文件

  1. $ cat > flanneld.service << EOF
  2. [Unit]
  3. Description=Flanneld overlay address etcd agent
  4. After=network.target
  5. After=network-online.target
  6. Wants=network-online.target
  7. After=etcd.service
  8. Before=docker.service
  9. [Service]
  10. Type=notify
  11. ExecStart=/root/local/bin/flanneld \\
  12. -etcd-cafile=/etc/kubernetes/ssl/ca.pem \\
  13. -etcd-certfile=/etc/flanneld/ssl/flanneld.pem \\
  14. -etcd-keyfile=/etc/flanneld/ssl/flanneld-key.pem \\
  15. -etcd-endpoints=${ETCD_ENDPOINTS} \\
  16. -etcd-prefix=${FLANNEL_ETCD_PREFIX}
  17. ExecStartPost=/root/local/bin/mk-docker-opts.sh -k DOCKER_NETWORK_OPTIONS -d /run/flannel/docker
  18. Restart=on-failure
  19. [Install]
  20. WantedBy=multi-user.target
  21. RequiredBy=docker.service
  22. EOF
  • mk-docker-opts.sh 脚本将分配给 flanneld 的 Pod 子网网段信息写入到 /run/flannel/docker 文件中,后续 docker 启动时使用这个文件中参数值设置 docker0 网桥;
  • flanneld 使用系统缺省路由所在的接口和其它节点通信,对于有多个网络接口的机器(如,内网和公网),可以用 --iface 选项值指定通信接口(上面的 systemd unit 文件没指定这个选项),如本着 Vagrant + Virtualbox,就要指定--iface=enp0s8

完整 unit 见 flanneld.service

启动 flanneld

  1. $ sudo cp flanneld.service /etc/systemd/system/
  2. $ sudo systemctl daemon-reload
  3. $ sudo systemctl enable flanneld
  4. $ sudo systemctl start flanneld
  5. $ systemctl status flanneld
  6. $

检查 flanneld 服务

  1. $ journalctl -u flanneld |grep 'Lease acquired'
  2. $ ifconfig flannel.1
  3. $

检查分配给各 flanneld 的 Pod 网段信息

  1. $ # 查看集群 Pod 网段(/16)
  2. $ /root/local/bin/etcdctl \
  3. --endpoints=${ETCD_ENDPOINTS} \
  4. --ca-file=/etc/kubernetes/ssl/ca.pem \
  5. --cert-file=/etc/flanneld/ssl/flanneld.pem \
  6. --key-file=/etc/flanneld/ssl/flanneld-key.pem \
  7. get ${FLANNEL_ETCD_PREFIX}/config
  8. { "Network": "172.30.0.0/16", "SubnetLen": 24, "Backend": { "Type": "vxlan" } }
  9. $ # 查看已分配的 Pod 子网段列表(/24)
  10. $ /root/local/bin/etcdctl \
  11. --endpoints=${ETCD_ENDPOINTS} \
  12. --ca-file=/etc/kubernetes/ssl/ca.pem \
  13. --cert-file=/etc/flanneld/ssl/flanneld.pem \
  14. --key-file=/etc/flanneld/ssl/flanneld-key.pem \
  15. ls ${FLANNEL_ETCD_PREFIX}/subnets
  16. /kubernetes/network/subnets/172.30.19.0-24
  17. $ # 查看某一 Pod 网段对应的 flanneld 进程监听的 IP 和网络参数
  18. $ /root/local/bin/etcdctl \
  19. --endpoints=${ETCD_ENDPOINTS} \
  20. --ca-file=/etc/kubernetes/ssl/ca.pem \
  21. --cert-file=/etc/flanneld/ssl/flanneld.pem \
  22. --key-file=/etc/flanneld/ssl/flanneld-key.pem \
  23. get ${FLANNEL_ETCD_PREFIX}/subnets/172.30.19.0-24
  24. {"PublicIP":"10.64.3.7","BackendType":"vxlan","BackendData":{"VtepMAC":"d6:51:2e:80:5c:69"}}

确保各节点间 Pod 网段能互联互通

各节点上部署完 Flannel 后,查看已分配的 Pod 子网段列表(/24)

  1. $ /root/local/bin/etcdctl \
  2. --endpoints=${ETCD_ENDPOINTS} \
  3. --ca-file=/etc/kubernetes/ssl/ca.pem \
  4. --cert-file=/etc/flanneld/ssl/flanneld.pem \
  5. --key-file=/etc/flanneld/ssl/flanneld-key.pem \
  6. ls ${FLANNEL_ETCD_PREFIX}/subnets
  7. /kubernetes/network/subnets/172.30.19.0-24
  8. /kubernetes/network/subnets/172.30.20.0-24
  9. /kubernetes/network/subnets/172.30.21.0-24

当前三个节点分配的 Pod 网段分别是:172.30.19.0-24、172.30.20.0-24、172.30.21.0-24。

在各节点上分配 ping 这三个网段的网关地址,确保能通:

  1. $ ping 172.30.19.1
  2. $ ping 172.30.20.2
  3. $ ping 172.30.21.3
  4. $