部署 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
相關文章
相關標籤/搜索