天天看點

k8s flannel 插件 基本通信原理flannel

flannel

是一種 CNI 解決方案,也可以為 Dokcer 提供服務,對 k8s 而言,是一個網絡插件。

  • 實作了 CNI 的網絡控制平面軟體
  • 屬于 coreOS 的子項目
  • 通過配置主機路由或者 overlay,避免對實體路由器進行配置
    • VxLAN
    • UDP
    • Host-GW

和 k8s 內建時,運作在 work node 上面,監聽 k8s master 的狀态,共用 k8s 的控制節點的 etcd 作為自己的資料庫。

k8s flannel 插件 基本通信原理flannel

安裝

實驗節點分布

k8s flannel 插件 基本通信原理flannel
  1. master node
    # 初始化 master 節點
    sudo kubeadm reset
    sudo kubeadm init --config kubadm.yaml 
    # 下載下傳 flannel 配置檔案
    wget https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
    # 修改配置檔案,net-json 改為 k8s 安裝的 podSubnet,type 預設為 vxlan 
      net-conf.json: |
        {
          "Network": "10.244.0.0/16",
          "Backend": {
            "Type": "vxlan"
          }
        }
    # 部署
    kubectl apply -f kube-flannel.yml
    # 檢視
    kubectl get pods --all-namespaces
    ---
    NAMESPACE     NAME                           READY   STATUS              RESTARTS   AGE
    kube-system   coredns-66bff467f8-m7ghl       0/1     ContainerCreating   0          11m
    kube-system   coredns-66bff467f8-mgnj7       0/1     ContainerCreating   0          11m
    kube-system   etcd-x-vm                      1/1     Running             0          11m
    kube-system   kube-apiserver-x-vm            1/1     Running             1          11m
    kube-system   kube-controller-manager-x-vm   1/1     Running             0          11m
    kube-system   kube-flannel-ds-amd64-g7hl9    1/1     Running             0          35s
    kube-system   kube-proxy-5x7l5               1/1     Running             0          11m
    kube-system   kube-scheduler-x-vm            1/1     Running             0          11m
    # 多次檢視,可以看到 coredns Pending -> ContainerCreating -> Running,因為 flannel 初始化初始化完成之後,k8s 認為目前節點可用,就建立了 coredns
    
               
  2. worker node

    安裝 docker、kubeadm,關閉 swap,加入到叢集中,hostname 不能重複

    # 在 master node 上初始化完成之後,會輸出如下 token
    kubeadm join 192.168.121.137:6443 --token abcdef.0123456789abcdef \
        --discovery-token-ca-cert-hash sha256:719b052641c7681b770f9609e82d6a8001ef9aa1125db6cea7b1a452d555c34a
    # 加入完成後,在 master node 上檢視
    kubectl get nodes
    NAME     STATUS   ROLES    AGE   VERSION
    worker   Ready    <none>   52s   v1.18.4
    x-vm     Ready    master   23m   v1.18.4
               
    在 worker node 上檢視容器,确認 flannel、kube-proxy 已經運作
    k8s flannel 插件 基本通信原理flannel
  3. 調整 coredns,使其分布到 worker node 上
    # -n 指定 namespace,先删除
    kubectl scale -n kube-system  deployment.v1.apps/coredns --replicas=0
    # 再将數量調整為 2,期望結果是兩個 codedns 的 pod 分布到兩個節點上
    kubectl scale -n kube-system  deployment.v1.apps/coredns --replicas=2
               
    檢視 pod 分布情況

    kubectl get pods --all-namespaces -o wide

    ,已經分布到兩個節點上
    k8s flannel 插件 基本通信原理flannel
    檢視 worker node 網卡資訊,可以看到 doredns 容器對應的 veth 已經存在,而且也有了 cni 網卡
    k8s flannel 插件 基本通信原理flannel

host-gw 實作

基本原理

在 kube-net 網絡實作中:

  • 同 node 中的 pod 互相通信是通過 cbr0 網橋二層互通
  • 跨 node 通信是通過主機的預設路由,路由到實體網絡中進行資料轉發,此時需要在實體路由器上進行路由相關的配置

部署 flannel 時,将配置檔案中

net-json

字段的

Type

修改為

host-gw

Flannel host-gw 實作方案中,由于 linux 具有路由轉發功能,是以可以将實體路由器相關的配置下沉到 work node (主機)上,由主機進行路由,類似于DVR,也避免了單點故障。

Flannel 連接配接 k8s 的資料庫,每個 node 上的 flanned 程序知道所有 podSubnet 對應的 node,進而在主機的網絡空間中配置 podSubnet 的路由指向對應的 node。

Flannel 環境中連接配接 pod 的 Linuxbridge 為 cni0(kube-net 是 cbr0),所有的 work node 必須在同一個二層網絡中(添加路由時必須是二層可達才會生效)

實操

Flannel 安裝完成後,檢視路由資訊:

k8s flannel 插件 基本通信原理flannel
# 在 master node 上建立一個臨時的 pod,使用 nodeSelector 指定運作的 node
kubectl run -it --rm --restart=Never test1 --image busybox --overrides='{"apiVersion": "v1","spec": {"nodeSelector": {"kubernetes.io/hostname": "x-vm"}}}' sh
# 新開一個視窗,在 work node 上建立一個臨時的 pod
kubectl run -it --rm --restart=Never test2 --image busybox --overrides='{"apiVersion": "v1","spec": {"nodeSelector": {"kubernetes.io/hostname": "worker"}}}' sh
           

新開一個視窗,檢查一個 pod 運作情況,可以看到分布在兩個 node 上,IP 分别是 11.0.0.5 和 11.0.1.3

k8s flannel 插件 基本通信原理flannel

用 pod test1 去 ping test2,在 work node 上抓包

k8s flannel 插件 基本通信原理flannel

可以從實體網卡抓到兩個 pod 之間的通信流量

在 pod test1 上 traceroute test2,可以看到路徑經過了 work node 到達 test2

k8s flannel 插件 基本通信原理flannel

VxLAN 實作

基本原理

  • Ethernet Frame 封裝到 UDP 中
  • 不考慮實體網絡沖突問題
  • 封裝需要額外的 50 位元組(網卡預設 MTU 為 1450)
  • 允許 woker node 分布到三層網絡中

VxLAN 資料包封裝:

k8s flannel 插件 基本通信原理flannel

Flannel VxLAN 基于 Linux 原生的方式實作 VxLAN

# Linux 通過 VxLAN 位元組口實作 VxLAN 的封裝解封裝
ip link add vxlan0 type vxlan id 1 \
remote 192.168.121.137 \
local 192.168.121.138 \
dstport 8472 \
dev eth0
# 通過監聽端口來攔截資料進行封裝解封裝
           

Flannel 的 VxLAN 實作

Flannel 會在 node 上額外建立

flannel.<vni>

裝置,挂載的 ip 為目前 node podSubnet 的第 0 個位址作為 VTEP 位址。

當有多個 node 時,如果按照 Linux 原生方式實作 VxLAN 時,每個 node 都要和其他 node 建立 VxLAN 隧道,也就是每個 node 上都要建立多個類型為 vxlan 的 netdev 裝置,這樣子接口的數量就是 n^2。

為了避免這種情況,flannel 添加 flannel.vni 子接口的時候,并沒有指定 remote ip,而是添加了對端 flannel.vni 的靜态 arp 表項,并添加二層轉規則(bridge fdb 檢視),如果是發往對端的 flannel.vni 的 MAC 位址的話,從本端子接口發出,且指定了遠端的 VTEP 位址。

k8s flannel 插件 基本通信原理flannel

實操

  1. 清理 host-gw 環境,修改配置檔案,重新部署 flannel
    # 删除 flannel
    kubectl delete -f kube-flannel.yml
    # 删除 coredns
    kubectl scale -n kube-system  deployment.v1.apps/coredns --replicas=0
    # 修改 kube-flannel.yml 中 net-json type 為 vxlan
    # 重新部署
    kubectl apply -f kube-flannel.yml
    # 添加 coredns
    kubectl scale -n kube-system  deployment.v1.apps/coredns --replicas=2
               
  2. 檢視網卡資訊

    ip addr,可以看到 vni 接口

    k8s flannel 插件 基本通信原理flannel
    檢視 arp 表
    k8s flannel 插件 基本通信原理flannel
    檢視轉發資料庫,bridge fdb
    k8s flannel 插件 基本通信原理flannel
    在 work node 上檢視接口,MAC 位址和 master node 上的轉發表一緻
    k8s flannel 插件 基本通信原理flannel
  3. 建立 pod ,抓包驗證
    # 在 master node 上建立一個臨時的 pod,使用 nodeSelector 指定運作的 node
    kubectl run -it --rm --restart=Never test1 --image busybox --overrides='{"apiVersion": "v1","spec": {"nodeSelector": {"kubernetes.io/hostname": "x-vm"}}}' sh
    # 新開一個視窗,在 work node 上建立一個臨時的 pod
    kubectl run -it --rm --restart=Never test2 --image busybox --overrides='{"apiVersion": "v1","spec": {"nodeSelector": {"kubernetes.io/hostname": "worker"}}}' sh
    
               
    檢視 pods 分布情況:
    k8s flannel 插件 基本通信原理flannel
    用 test1 ping test2 ,在 worker 實體接口上抓包,可以看到封裝資料包的内容
    k8s flannel 插件 基本通信原理flannel

UDP 實作

非 VxLAN 的 UDP 資料封裝,不推薦使用

資料經過使用者态轉發,性能低

繼續閱讀