亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

K8s網絡組件Flannel的介紹和部署

發布時間:2020-06-18 15:06:25 來源:億速云 閱讀:5611 作者:元一 欄目:系統運維

Flannel
flannel是一個網絡組件,可以為不同node節點的分配不同的子網,實現容器間的跨機通信,從而實現整個kubenets層級通信。 由此可知,該組件運行于node節點上,依賴組件為etcd,docker。

其實k8s網絡組件flannel和calico主要解決的問題是k8s節點之間容器網絡的通信,flannel要保證每個pod的IP是唯一的,怎么保證是唯一的,大部分組件的做法是在每個Node上分配一個唯一的子網,node1是一個單獨的子網,node2是一個單獨的子網,可以理解是不同網段,不同vlan,所以每個節點都是一個子網,所以flannel會預先設置一個大的子網,然后在這個每個node上分配子網,這些信息都會由flannel存儲到etcd中,并且每個子網綁定到node上都有關系記錄的,然后方便下次進行二次的數據包傳輸,并且flannel在node上會啟動一個守護進程并運行,守護進程主要維護的是本地的路由規則,和維護etcd中的信息。

1、Flannel 部署

 https://github.com/coreos/flannel 
kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml

部署好之后會以daemonset的形式在每個node上啟動一個pod,來啟動一個flannel的守護進程,主要負責本機路由表的設定和etcd中的數據,本地的子網上報到etcd中,所以守護進程是非常重要的
可以在flannel的配置文件去設定大的子網,還有屬性模式

 net-conf.json: |
    {
      "Network": "10.244.0.0/16",
      "Backend": {
        "Type": "vxlan"
      }
    }

---

這個配置完之后會放到cni這個目錄下,由于flannel是使用網橋的模式,實現的同節點數據包到達宿主機這個的通信,所以子網信息并沒寫到這個配置文件里,而是放到了這個 cat /var/run/flannel/subnet.env 下,這個通過ip a也能看到設備分配的ip,每個節點都會分配一個子網,網絡接口設備為cni0,也就是一個node上可以分配255個小的子網

[root@k8s-node2 ~]# cat /var/run/flannel/subnet.env 
FLANNEL_NETWORK=10.244.0.0/16
FLANNEL_SUBNET=10.244.0.1/24
FLANNEL_MTU=1450
FLANNEL_IPMASQ=true

還有一個cni的二進制文件, /opt/cni/bin,這個就是kubelet調用這個二進制接口為創建的每個pod創建網絡信息,并且是從我們的配置的子網中去拿IP

配置的話修改的是就是預先設定它的子網,以及工作模式,另外就是這個網絡不能與k8s本身的內網沖突,否則導致網絡不通的狀況

2、 Flannel工作模式及原理
Flannel支持多種數據轉發方式:
UDP:最早支持的一種方式,由于性能最差,目前已經棄用。
VXLAN:Overlay Network方案,源數據包封裝在另一種網絡包里面進行路由轉發和通信
這也是網絡的虛擬化技術,也就是原來是有一個包數據包,有源IP和目的IP,但由于某些情況這個數據包到達不了目的地址上,這可能就會借助物理上的以太網網絡進行封裝一個數據包帶上,然后通過這種物理網絡傳輸到目的地址上,這是一種疊加式的網絡,里面是有兩種數據包的,這種也叫做隧道方案
Host-GW:Flannel通過在各個節點上的Agent進程,將容器網絡的路由信息刷到主機的路由表上,這樣一來所有的主機都有整個容器網絡的路由數據了,這樣它就知道這個數據包到達這個節點轉發到這個機器上,也就是路由表之間轉發的,這種也叫路由方案
VXLAN

使用kubeadm部署的話默認是支持的

kubeadm部署指定Pod網段
kubeadm init --pod-network-cidr=10.244.0.0/16

但是使用二進制部署就得去啟動cni的支持,默認我ansible部署的k8s集群都是啟動的
二進制部署指定

cat /opt/kubernetes/cfg/kube-controller-manager.conf
--allocate-node-cidrs=true \     允許node自動分配cidr這個網絡
--cluster-cidr=10.244.0.0/16 \   指定pod網絡的網段,這個網段要和flannel的網段對應上

另外也都要在每個node節點的kubelet的配置文件上進行對cni的支持

[root@k8s-node1 ~]# cat /opt/kubernetes/cfg/kubelet.conf 
--network-plugin=cni \

這樣的話就能以cni的標準來為k8s配置網絡

kube-flannel.yml
net-conf.json: |
    {
      "Network": "10.244.0.0/16",
      "Backend": {
        "Type": "vxlan"
      }
    }

在節點1上有個容器,與節點2上的容器進行通信,這兩個是進行跨主機進行的通信,如果本機通信之間使用網橋使用二層的傳輸了,像原生的docker網就能解決了,最重要的是這兩個節點的數據包傳輸

flannel保證每個node都是唯一的ip,它是在每個node上都分配一個子網
可以看到flannel是基于宿主機創建的,它會為每個node創建獨立的子網,并為當前pod分配ip

[root@k8s-master1 ~]# kubectl get pod -n kube-system -o wide
kube-flannel-ds-amd64-4jjmm           1/1     Running   0          14d   10.4.7.11     k8s-master1   <none>           <none>
kube-flannel-ds-amd64-9f9vq           1/1     Running   0          14d   10.4.7.21     k8s-node2     <none>           <none>
kube-flannel-ds-amd64-gcf9s           1/1     Running   0          14d   10.4.7.12     k8s-node1     <none>           <none>

為了能夠在二層網絡上打通“隧道”,VXLAN 會在宿主機上設置一個特殊的網絡設備作為“隧道”的兩端。這個設備就叫作 VTEP,即:VXLAN Tunnel End Point(虛擬隧道端點)。下圖flannel.1的設備就是VXLAN所需的VTEP設備。示意圖如下:
K8s網絡組件Flannel的介紹和部署

vxlan是怎么工作的?
vxlan是Linux上支持的一個隧道的技術,隧道也就是點到點,端到端的兩個設備的通信,其實vxlan實現是有一個vtep的設備做數據包的封裝與解封裝,而現在已經封裝到flannel.1這個進程里面了,也就是這個虛擬網卡包含了veth來去使用對這個vxlan進行封裝和解封裝。

現在是Node1節點上的pod 1是1.10,現在要與Node2節點上的pod 2的2.10進行通信,他們是不在一個網絡的,當這個數據包發出去的時候,pod1 的容器的網卡eth0,先出這個網卡,然后會連接這個veth這個好比就是一個網線,etch0是一頭,veth是一頭,也就是veth是這個設備的另一頭,
這個veth是在宿主機上,那么這個宿主機就拿到了這個容器的數據包,然后這個數據包到達這個網橋上面,這個網橋也好比一個二層的交換機,所有的容器都會加入到這個網橋里面,可以通過yum -y install bridge-utils看到veth的另一端是不是加入到cni的網橋中,這個網橋就是flannel創建的,并且這個網橋有獨立的mac地址和IP都可以看到

[root@k8s-node2 ~]# brctl show cni0
bridge name bridge id       STP enabled interfaces
cni0        8000.4a025e87aa87   no      veth08925d5a
                            veth3591a36f
                            veth776a1e86
                            veth718beeac
                            veth81dadcbd
                            veth8a96f11c
                            veth8c90fdb6
                            veth8f350182
                            veth90818f0b
                            vetha471152b

這個就是當我們創建好pod的時候由flannel去分配并加入這個網橋中的,這個后面有個interfaces有這個接口,這個相當于交換機的接口,這正是宿主機上的虛擬網卡,如果本地的話,直接走這個網橋就能直接找到了,然后就可以發送一個ARP廣播包進行封包傳輸了,cni0就相當于一個二層交換機,幫你擴散,找目的的mac進行響應,所以說同節點就可以直接走網橋這個,那么這個目的地址不在這個網橋里面,就像2.10,當前的node是不知道2.10上的pod在哪,那么它只能走路由表了,也就是它它不一定目的地址的時候就會走默認網關,所以flannel會在宿主機上生成很多路由表通過ip router可以看到

[root@k8s-node2 ~]# ip route 
default via 10.4.7.1 dev eth0 proto static metric 100 
10.4.7.0/24 dev eth0 proto kernel scope link src 10.4.7.21 metric /
10.244.0.0/24 dev cni0 proto kernel scope link src 10.244.0.1  /
10.244.1.0/24 via 10.244.1.0 dev flannel.1 onlink /
10.244.2.0/24 via 10.244.2.0 dev flannel.1 onlink /
172.17.0.0/16 dev docker0 proto kernel scope link src 172.17.0.1 

部署docker生成的路由表,這里的docker0網橋是沒有用到,當部署flannel的時候是默認使用的是自己的網橋,這個的原理和flannel的是一樣的,只不過flannel用的是自己做的,也是為了方便自己處理數據包

這里的路由表都記錄下來了,它會找哪個是目的地址2.10pod2的IP地址,所以它會根據這個路由表,然后發送到flannel的這個設備上,這個flannel是采用vxlan的模式,vxlan需要veth的數據封裝與解封裝,所以flannel就把這個數據包交給vxlan,而vxlan是一個內核級的驅動程序,有它去封裝這個包,因為vxlan本身是工作在二層的,它還需要目的的mac地址

那么就可以通過ip neigh show dev flannel.1去查看mac地址

 [root@k8s-node2 ~]# ip neigh show dev flannel.1
10.244.2.0 lladdr ea:ca:d6:62:be:21 PERMANENT
10.244.1.0 lladdr 4e:e3:fa:5f:d2:34 PERMANENT

而flannel.1的vxlan實現是有一個vtep的設備做數據包的封裝與解封裝,因為它在2層進行封包,就要知道目的的mac地址,那么這個目的mac就由flannel去提供給vetp,flannel去存儲對應下一跳的網關,那么這個網關肯定不是在本地,當我們拿到目的的mac地址之后你們就封裝成一個完整的幀,那么封裝好之后,對于宿主機沒有太多的實際意義,因為這個數據包幀發不出去,要是按二層的走肯定到不了另外一個節點,因為在不同的子網里面,如果沒有路由的介入肯定是通信不了的,接下來就需要linux內核的數據幀封裝一個宿主機普通的數據幀,也就是udp封裝一個普通的數據幀,也就是在這之上再加一層udp的包,這樣做的目的能讓數據包直接傳輸到目的容器的主機上。
K8s網絡組件Flannel的介紹和部署
vxlan是使用的udp協議,它會將原始的報文放在內部,而外部由udp封裝的源IP與目的地址

[root@k8s-master1 ~]# bridge fdb show  dev flannel.1
a6:a4:e5:5d:19:9b dst 10.4.7.21 self permanent
ea:ca:d6:62:be:21 dst 10.4.7.12 self permanent

可以看到,上面用的對方flannel.1的MAC地址對應宿主機IP,也就是UDP要發往的目的地。使用這個目的IP進行封裝。
也就是這些flannel都是知道的,為什么說flannel維護這etcd的數據,守護本地的路由規則,其實etcd的數據要和flannel,把它當前的數據寫到etcd中,由各個節點都存儲一份,所以根據這個地址拿到了mac地址,然后這又是一個完整的包,由vxlan封裝的udp的包,這個udp包里面就有兩個IP包的存在,udp就直接能發送到node2的節點上,數據包已經傳輸過去了,因為宿主機之間是同網段的,到達31.63上之后,接收到udp的包之后,會進行拆分,解包會將原始的包拿出來,所以這里就有一個vxlan的標記,本身flannel是由vtep處理的,所以在封包的時候對著干包打了個標記,也就是vxlan header的標記,首先打上vxlan的頭部,那么這就意味著這就是一個vxlan的數據包,并且加了一個VNI的編號,VNI是為了區分vxlan的點對點隧道,多個數據包也是分外多個編號,也是為了區分,而這個編號被flannel引用到了,所以這是內部的一個編號,確認這個數據包無誤,然后交給flannel.1這個設備,它處理這個數據包,拿到了源IP和目的IP,而去判斷,會發現這個是cni網橋的,所以它根據路由表放到了cni網橋,根據這個路由表拆分這個目的地址,正好這個目的地址匹配到了,所以它會將這個轉發到cni網橋里,到cni就跟之前一樣了,就相當于一個二層交換機,拿到這個數據包,它會進行一個ARP的廣播,發現正在這個網橋里面,然后就進行數據包的轉發了。

從此看來;vxlan使用重疊網絡,進行封包解封包,性能就下降了很多

小結:

  1. 容器路由:容器根據路由表從eth0發出
    / # ip route
    default via 10.244.0.1 dev eth0 
    10.244.0.0/24 dev eth0 scope link  src 10.244.0.45 
    10.244.0.0/16 via 10.244.0.1 dev eth0 
  2. 主機路由:數據包進入到宿主機虛擬網卡cni0,根據路由表轉發到flannel.1虛擬網卡,也就是,來到了隧道的入口。
    ip route
    default via 192.168.31.1 dev ens33 proto static metric 100 
    10.244.0.0/24 dev cni0 proto kernel scope link src 10.244.0.1 
    10.244.1.0/24 via 10.244.1.0 dev flannel.1 onlink 
    10.244.2.0/24 via 10.244.2.0 dev flannel.1 onlink 
  3. VXLAN封裝:而這些VTEP設備(二層)之間組成二層網絡必須要知道目的MAC地址。這個MAC地址從哪獲取到呢?其實在flanneld進程啟動后,就會自動添加其他節點ARP記錄,可以通過ip命令查看,如下所示:
ip neigh show dev flannel.1
10.244.1.0 lladdr ca:2a:a4:59:b6:55 PERMANENT
10.244.2.0 lladdr d2:d0:1b:a7:a9:cd PERMANENT
  1. 二次封包:知道了目的MAC地址,封裝二層數據幀(容器源IP和目的IP)后,對于宿主機網絡來說這個幀并沒有什么實際意義。接下來,Linux內核還要把這個數據幀進一步封裝成為宿主機網絡的一個普通數據幀,好讓它載著內部數據幀,通過宿主機的eth0網卡進行傳輸。
  2. 封裝到UDP包發出去:現在能直接發UDP包嘛?到目前為止,我們只知道另一端的flannel.1設備的MAC地址,卻不知道對應的宿主機地址是什么。
    flanneld進程也維護著一個叫做FDB的轉發數據庫,可以通過bridge fdb命令查看:

    bridge fdb show  dev flannel.1
    
    d2:d0:1b:a7:a9:cd dst 192.168.31.61 self permanent
    ca:2a:a4:59:b6:55 dst 192.168.31.63 self permanent

    可以看到,上面用的對方flannel.1的MAC地址對應宿主機IP,也就是UDP要發往的目的地。使用這個目的IP進行封裝。

  3. 數據包到達目的宿主機:Node1的eth0網卡發出去,發現是VXLAN數據包,把它交給flannel.1設備。flannel.1設備則會進一步拆包,取出原始二層數據幀包,發送ARP請求,經由cni0網橋轉發給container。

Host-GW
host-gw模式相比vxlan簡單了許多, 直接添加路由,將目的主機當做網關,直接路由原始封包。
切換成host-gw的模式,上面的轉發還是一樣,pod1容器的網卡先連接veth到宿主機上,然后到達cni0的網橋上,這個網橋就相當于一個二層的交換機,這個數據包到cni的網橋之后,也就是到達宿主機上,那么宿主機的網絡協議棧會根據路由表決定轉發到哪個網關上,因為它的目的IP地址不是同網段的,肯定走路由表,它會根據路由表判斷目的地址是2.10,也就是來自這個數據的數據包轉發到了它的下一跳,也就是網關,通過接口之間轉發到31.63上了,也就是直接安照宿主機的網絡,因為這個數據包是宿主機處理的,所以宿主機要想訪問31.63,會進行重新封包,目的地址就是31.63,它判斷了31.63下一跳的網關是同一子網,而且是二層的傳輸,二層的傳輸又需要獲取到目的的mac地址,如果它本地不知道31.63的mac地址的話,它會發送一個ARP廣播包,知道了對方的mac就進行封包,所以經過二層的傳輸到達31.63,31.63收到之后數據包之后,它又會去判斷路由表了,然后進入cni的網橋,二層又轉發到了容器里面。

最重要兩條,host-gw是把每個節點都當成一個網關,它會加入其他節點并設成網關,當數據包到達這個節點的時候,就根據路由表之間發送到下一跳了,也就是節點IP,這個都是同網段的IP,直接通過2層之間把這個數據,轉發到另一個節點上,另一個節點再根據另一條規則,根據目的的地址轉發到cni網橋,cni網橋根據2層又轉發到容器里面,一個是數據的流入,就是當數據包到達這個節點之后,然后發給誰,這是流入數據包,一個是數據包的流出,當從節點出來的數據包,應該轉發到哪個node上,這些都是由flannel去維護的
這個的局限是每個node在2層都能通,否則下一跳轉發不過去,但是它的性能要比vxlan的性能高很多,不需要封包解封包,這種接近原生,性能也是最好的

下面是示意圖:
K8s網絡組件Flannel的介紹和部署

kube-flannel.yml

net-conf.json: |
    {
      "Network": "10.244.0.0/16",
      "Backend": {
        "Type": "host-gw"
      }
    }

看名字就能看出hots-gw它把目的的主機當作網關,直接路由原始的封包
將vxlan切換成host-gw的模式,重建之后可以看到路由表發生變化,切換的時候也會對網絡進行影響,一般是在夜深人靜的時候去做

之前的路由表都是通過flannel.1去轉發到設備上,也就是使用host-gw,flannel.1這個設備就不用了,所以就不會用vxlan進行去封包了
當你設置flannel使用host-gw模式,flanneld會在宿主機上創建節點的路由表:

ip route

default via 192.168.31.1 dev ens33 proto static metric 100 
10.244.0.0/24 dev cni0 proto kernel scope link src 10.244.0.1 
10.244.1.0/24 via 192.168.31.63 dev ens33 
10.244.2.0/24 via 192.168.31.61 dev ens33 
192.168.31.0/24 dev ens33 proto kernel scope link src 192.168.31.62 metric 100

目的 IP 地址屬于 10.244.1.0/24 網段的 IP 包,應該經過本機的 eth0 設備發出去(即:dev eth0);并且,它下一跳地址是 192.168.31.63(即:via 192.168.31.63)。
一旦配置了下一跳地址,那么接下來,當 IP 包從網絡層進入鏈路層封裝成幀的時候,eth0 設備就會使用下一跳地址對應的 MAC 地址,作為該數據幀的目的 MAC 地址。
而 Node 2 的內核網絡棧從二層數據幀里拿到 IP 包后,會“看到”這個 IP 包的目的 IP 地址是 10.244.1.20,即 container-2 的 IP 地址。這時候,根據 Node 2 上的路由表,該目的地址會匹配到第二條路由規則(也就是 10.244.1.0 對應的路由規則),從而進入 cni0 網橋,進而進入到 container-2 當中。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

延川县| 齐齐哈尔市| 兴仁县| 社旗县| 兴隆县| 安徽省| 日照市| 武隆县| 梁平县| 临海市| 大同市| 开原市| 连江县| 临颍县| 中山市| 扶余县| 文水县| 城步| 专栏| 华容县| 通河县| 文山县| 柳林县| 沅江市| 甘洛县| 顺义区| 林甸县| 宁津县| 榆中县| 青冈县| 烟台市| 青神县| 拉萨市| 大港区| 新疆| 盐亭县| 中江县| 奎屯市| 安西县| 关岭| 贡觉县|