部署 flannel 网络插件

说明:本部署文章参照了 https://github.com/opsnull/follow-me-install-kubernetes-cluster ,欢迎给做者star

 

kubernetes 要求集群内各节点(包括 master 节点)能经过 Pod 网段互联互通。flannel 使用 vxlan 技术为各节点建立一个能够互通的 Pod 网络,使用的端口为 UDP 8472,须要开放该端口(如公有云 AWS 等)。node

flannel 第一次启动时,从 etcd 获取 Pod 网段信息,为本节点分配一个未使用的地址段,而后建立 flannedl.1(也多是其它名称,如 flannel1 等) 接口。linux

flannel 将分配的 Pod 网段信息写入 /run/flannel/docker 文件,docker 后续使用这个文件中的环境变量设置 docker0 网桥。git

注意:若是没有特殊指明,本文档的全部操做均在 k8s-master1 节点上执行,而后远程分发文件和执行命令。github

 

1.下载和分发 flanneld 二进制文件

到 https://github.com/coreos/flannel/releases 页面下载最新版本的发布包:docker

cd /opt/k8s/work
mkdir flannel
wget https://github.com/coreos/flannel/releases/download/v0.10.0/flannel-v0.10.0-linux-amd64.tar.gz
tar -xzvf flannel-v0.10.0-linux-amd64.tar.gz -C flannel

分发 flanneld 二进制文件到集群全部节点:json

cd /opt/k8s/work
source /opt/k8s/bin/environment.sh
for node_ip in ${NODE_IPS[@]}
  do
    echo ">>> ${node_ip}"
    scp flannel/{flanneld,mk-docker-opts.sh} root@${node_ip}:/opt/k8s/bin/
    ssh root@${node_ip} "chmod +x /opt/k8s/bin/*"
  done

 

2.建立 flannel 证书和私钥

flannel 从 etcd 集群存取网段分配信息,而 etcd 集群启用了双向 x509 证书认证,因此须要为 flanneld 生成证书和私钥。网络

建立证书签名请求:ssh

cd /opt/k8s/work
cat > flanneld-csr.json <<EOF
{
  "CN": "flanneld",
  "hosts": [],
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "ST": "BeiJing",
      "L": "BeiJing",
      "O": "k8s",
      "OU": "4Paradigm"
    }
  ]
}
EOF
  • 该证书只会被 kubectl 当作 client 证书使用,因此 hosts 字段为空;

生成证书和私钥:ui

cfssl gencert -ca=/opt/k8s/work/ca.pem \
  -ca-key=/opt/k8s/work/ca-key.pem \
  -config=/opt/k8s/work/ca-config.json \
  -profile=kubernetes flanneld-csr.json | cfssljson -bare flanneld
ls flanneld*pem

将生成的证书和私钥分发到全部节点(master 和 worker):spa

cd /opt/k8s/work
source /opt/k8s/bin/environment.sh
for node_ip in ${NODE_IPS[@]}
  do
    echo ">>> ${node_ip}"
    ssh root@${node_ip} "mkdir -p /etc/flanneld/cert"
    scp flanneld*.pem root@${node_ip}:/etc/flanneld/cert
  done

3.向 etcd 写入集群 Pod 网段信息

注意:本步骤只需执行一次。

cd /opt/k8s/work
source /opt/k8s/bin/environment.sh
etcdctl \
  --endpoints=${ETCD_ENDPOINTS} \
  --ca-file=/opt/k8s/work/ca.pem \
  --cert-file=/opt/k8s/work/flanneld.pem \
  --key-file=/opt/k8s/work/flanneld-key.pem \
  set ${FLANNEL_ETCD_PREFIX}/config '{"Network":"'${CLUSTER_CIDR}'", "SubnetLen": 21, "Backend": {"Type": "vxlan"}}'
  • flanneld 当前版本 (v0.10.0) 不支持 etcd v3,故使用 etcd v2 API 写入配置 key 和网段数据;
  • 写入的 Pod 网段 ${CLUSTER_CIDR} 地址段如 /16 必须小于 SubnetLen,必须与 kube-controller-manager 的 --cluster-cidr 参数值一致;

4.建立 flanneld 的 systemd unit 文件

cd /opt/k8s/work
source /opt/k8s/bin/environment.sh
cat > flanneld.service << EOF
[Unit]
Description=Flanneld overlay address etcd agent
After=network.target
After=network-online.target
Wants=network-online.target
After=etcd.service
Before=docker.service

[Service]
Type=notify
ExecStart=/opt/k8s/bin/flanneld \\
  -etcd-cafile=/etc/kubernetes/cert/ca.pem \\
  -etcd-certfile=/etc/flanneld/cert/flanneld.pem \\
  -etcd-keyfile=/etc/flanneld/cert/flanneld-key.pem \\
  -etcd-endpoints=${ETCD_ENDPOINTS} \\
  -etcd-prefix=${FLANNEL_ETCD_PREFIX} \\
  -iface=${IFACE} \\
  -ip-masq
ExecStartPost=/opt/k8s/bin/mk-docker-opts.sh -k DOCKER_NETWORK_OPTIONS -d /run/flannel/docker
Restart=always
RestartSec=5
StartLimitInterval=0

[Install]
WantedBy=multi-user.target
RequiredBy=docker.service
EOF
  • 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。

完整 unit 见 flanneld.service

 

5.分发 flanneld systemd unit 文件到全部节点

source /opt/k8s/bin/environment.sh
for node_ip in ${NODE_IPS[@]}
  do
    echo ">>> ${node_ip}"
    scp flanneld.service root@${node_ip}:/etc/systemd/system/
  done

6.启动 flanneld 服务

source /opt/k8s/bin/environment.sh
for node_ip in ${NODE_IPS[@]}
  do
    echo ">>> ${node_ip}"
    ssh root@${node_ip} "systemctl daemon-reload && systemctl enable flanneld && systemctl restart flanneld"
  done

 

7.检查启动结果

source /opt/k8s/bin/environment.sh
for node_ip in ${NODE_IPS[@]}
  do
    echo ">>> ${node_ip}"
    ssh root@${node_ip} "systemctl status flanneld|grep Active"
  done

 

确保状态为 active (running),不然查看日志,确认缘由:

$ journalctl -u flanneld

 

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

查看集群 Pod 网段(/16):

source /opt/k8s/bin/environment.sh
etcdctl \
  --endpoints=${ETCD_ENDPOINTS} \
  --ca-file=/etc/kubernetes/cert/ca.pem \
  --cert-file=/etc/flanneld/cert/flanneld.pem \
  --key-file=/etc/flanneld/cert/flanneld-key.pem \
  get ${FLANNEL_ETCD_PREFIX}/config

输出:

{"Network":"172.30.0.0/16", "SubnetLen": 21, "Backend": {"Type": "vxlan"}}

 

 

查看已分配的 Pod 子网段列表(/24):

source /opt/k8s/bin/environment.sh
etcdctl \
  --endpoints=${ETCD_ENDPOINTS} \
  --ca-file=/etc/kubernetes/cert/ca.pem \
  --cert-file=/etc/flanneld/cert/flanneld.pem \
  --key-file=/etc/flanneld/cert/flanneld-key.pem \
  ls ${FLANNEL_ETCD_PREFIX}/subnets

输出:

/kubernetes/network/subnets/172.30.192.0-21
/kubernetes/network/subnets/172.30.24.0-21
/kubernetes/network/subnets/172.30.160.0-21
/kubernetes/network/subnets/172.30.32.0-21
/kubernetes/network/subnets/172.30.240.0-21
/kubernetes/network/subnets/172.30.120.0-21

 

 

查看某一 Pod 网段对应的节点 IP 和 flannel 接口地址:

source /opt/k8s/bin/environment.sh
etcdctl \
  --endpoints=${ETCD_ENDPOINTS} \
  --ca-file=/etc/kubernetes/cert/ca.pem \
  --cert-file=/etc/flanneld/cert/flanneld.pem \
  --key-file=/etc/flanneld/cert/flanneld-key.pem \
  get ${FLANNEL_ETCD_PREFIX}/subnets/172.30.120.0-21

输出:

{"PublicIP":"192.168.161.171","BackendType":"vxlan","BackendData":{"VtepMAC":"ae:20:b2:91:62:ac"}}

 

9.验证各节点能经过 Pod 网段互通

在各节点上部署 flannel 后,检查是否建立了 flannel 接口(名称可能为 flannel0、flannel.0、flannel.1 等):

source /opt/k8s/bin/environment.sh
for node_ip in ${NODE_IPS[@]}
  do
    echo ">>> ${node_ip}"
    ssh ${node_ip} "/usr/sbin/ip addr show flannel.1|grep -w inet"
  done

 

输出:

>>> 192.168.161.150
    inet 172.30.24.0/32 scope global flannel.1
>>> 192.168.161.151
    inet 172.30.160.0/32 scope global flannel.1
>>> 192.168.161.152
    inet 172.30.32.0/32 scope global flannel.1
>>> 192.168.161.170
    inet 172.30.240.0/32 scope global flannel.1
>>> 192.168.161.171
    inet 172.30.120.0/32 scope global flannel.1
>>> 192.168.161.172
    inet 172.30.192.0/32 scope global flannel.1

 

在各节点上 ping 全部 flannel 接口 IP,确保能通:

source /opt/k8s/bin/environment.sh
for node_ip in ${NODE_IPS[@]}
  do
    echo ">>> ${node_ip}"

ssh ${node_ip} "ping -c 1 172.30.24.0"
ssh ${node_ip} "ping -c 1 172.30.160.0"
ssh ${node_ip} "ping -c 1 172.30.32.0"
ssh ${node_ip} "ping -c 1 172.30.240.0"
ssh ${node_ip} "ping -c 1 172.30.120.0"
ssh ${node_ip} "ping -c 1 172.30.190.0"

 
 
  done
相关文章
相关标签/搜索