<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          7個步驟,教你搞懂 K8S 網(wǎng)絡(luò)之 Flannel 工作原理

          共 4294字,需瀏覽 9分鐘

           ·

          2021-12-29 00:57


          一、Docker 網(wǎng)絡(luò)模式

          在討論 Kubernetes 網(wǎng)絡(luò)之前,讓我們先來看一下 Docker 網(wǎng)絡(luò)。Docker 采用插件化的網(wǎng)絡(luò)模式,默認提供 bridge、host、none、overlay、maclan 和 Network plugins 這幾種網(wǎng)絡(luò)模式,運行容器時可以通過–network 參數(shù)設(shè)置具體使用那一種模式。

          • bridge:這是Docker默認的網(wǎng)絡(luò)驅(qū)動,此模式會為每一個容器分配Network Namespace和設(shè)置IP等,并將容器連接到一個虛擬網(wǎng)橋上。如果未指定網(wǎng)絡(luò)驅(qū)動,這默認使用此驅(qū)動。

          • host:此網(wǎng)絡(luò)驅(qū)動直接使用宿主機的網(wǎng)絡(luò)。

          • none:此驅(qū)動不構(gòu)造網(wǎng)絡(luò)環(huán)境。采用了none 網(wǎng)絡(luò)驅(qū)動,那么就只能使用loopback網(wǎng)絡(luò)設(shè)備,容器只能使用127.0.0.1的本機網(wǎng)絡(luò)。

          • overlay:此網(wǎng)絡(luò)驅(qū)動可以使多個Docker daemons連接在一起,并能夠使用swarm服務(wù)之間進行通訊。也可以使用overlay網(wǎng)絡(luò)進行swarm服務(wù)和容器之間、容器之間進行通訊,

          • macvlan:此網(wǎng)絡(luò)允許為容器指定一個MAC地址,允許容器作為網(wǎng)絡(luò)中的物理設(shè)備,這樣Docker daemon就可以通過MAC地址進行訪問的路由。對于希望直接連接網(wǎng)絡(luò)網(wǎng)絡(luò)的遺留應(yīng)用,這種網(wǎng)絡(luò)驅(qū)動有時可能是最好的選擇。

          • Network plugins:可以安裝和使用第三方的網(wǎng)絡(luò)插件。可以在Docker Store或第三方供應(yīng)商處獲取這些插件。

          在默認情況,Docker 使用 bridge 網(wǎng)絡(luò)模式,bridge 網(wǎng)絡(luò)驅(qū)動的示意圖如下,此文以bridge 模式對 Docker 的網(wǎng)絡(luò)進行說明。

          1.1 bridge網(wǎng)絡(luò)的構(gòu)建過程

          1)安裝Docker時,創(chuàng)建一個名為 docke0 的虛擬網(wǎng)橋,虛擬網(wǎng)橋使用“10.0.0.0 -10.255.255.255 “、”172.16.0.0-172.31.255.255″和“192.168.0.0——192.168.255.255”這三個私有網(wǎng)絡(luò)的地址范圍。

          通過 ifconfig 命令可以查看 docker0 網(wǎng)橋的信息:

          通過 docker network inspect bridge 可以查看網(wǎng)橋的子網(wǎng)網(wǎng)絡(luò)范圍和網(wǎng)關(guān):

          2)運行容器時,在宿主機上創(chuàng)建虛擬網(wǎng)卡 veth pair 設(shè)備,veth pair 設(shè)備是成對出現(xiàn)的,從而組成一個數(shù)據(jù)通道,數(shù)據(jù)從一個設(shè)備進入,就會從另一個設(shè)備出來。

          將veth pair設(shè)備的一端放在新創(chuàng)建的容器中,命名為eth0;另一端放在宿主機的docker0中,以veth為前綴的名字命名。通過 brctl show 命令查看放在docker0中的veth pair設(shè)備。

          1.2 外部訪問

          bridge 的 docker0 是虛擬出來的網(wǎng)橋,因此無法被外部的網(wǎng)絡(luò)訪問。因此需要在運行容器時通過 -p 和 -P 參數(shù)對將容器的端口映射到宿主機的端口。實際上 Docker 是采用 NAT的方式,將容器內(nèi)部的服務(wù)監(jiān)聽端口與宿主機的某一個端口 port 進行綁定,使得宿主機外部可以將網(wǎng)絡(luò)報文發(fā)送至容器。
          1)通過-P參數(shù),將容器的端口映射到宿主機的隨機端口:
          $ docker run -P {images}
          2)通過-p參數(shù),將容器的端口映射到宿主機的制定端口:
          $ docker run -p {hostPort}:{containerPort} {images}

          二、Kubernetes 網(wǎng)絡(luò)模式

          Kubernetes與Docker網(wǎng)絡(luò)有些不同。Kubernetes網(wǎng)絡(luò)需要解決下面的4個問題:

          集群內(nèi):

          • 容器與容器之間的通信

          • Pod和Pod之間的通信

          • Pod和服務(wù)之間的通信

          集群外:

          • 外部應(yīng)用與服務(wù)之間的通信
          因此,Kubernetes假設(shè)Pod之間能夠進行通訊,這些Pod可能部署在不同的宿主機上。每一個Pod都擁有自己的IP地址,因此能夠?qū)od看作為物理主機或者虛擬機,從而能實現(xiàn)端口設(shè)置、命名、服務(wù)發(fā)現(xiàn)、負載均衡、應(yīng)用配置和遷移。為了滿足上述需求,則需要通過集群網(wǎng)絡(luò)來實現(xiàn)。
          在本文主要分析容器與容器之間,以及Pod和Pod之間的通信;Pod和服務(wù)之間,以及外部應(yīng)用與服務(wù)之間的通信請參考《Kubernetes-核心資源之Service》和《Kubernetes-核心資源之Ingress》。

          2.1 同一個 Pod 中容器之間的通信

          這種場景對于Kubernetes來說沒有任何問題,根據(jù)Kubernetes的架構(gòu)設(shè)計。Kubernetes 創(chuàng)建 Pod 時,首先會創(chuàng)建一個 pause 容器,為 Pod 指派一個唯一的IP地址。然后,以pause的網(wǎng)絡(luò)命名空間為基礎(chǔ),創(chuàng)建同一個Pod內(nèi)的其它容器(–net=container:xxx)。
          因此,同一個Pod內(nèi)的所有容器就會共享同一個網(wǎng)絡(luò)命名空間,在同一個Pod之間的容器可以直接使用localhost進行通信。

          2.2 不同 Pod 中容器之間的通信

          對于此場景,情況現(xiàn)對比較復(fù)雜一些,這就需要解決 Pod 間的通信問題。在Kubernetes 通過 flannel、calic 等網(wǎng)絡(luò)插件解決 Pod 間的通信問題。本文以 flannel 為例說明在 Kubernetes 中網(wǎng)絡(luò)模型,flannel 是 kubernetes 默認提供網(wǎng)絡(luò)插件。Flannel 是由 CoreOS 團隊開發(fā)社交的網(wǎng)絡(luò)工具,CoreOS 團隊采用 L3 Overlay 模式設(shè)計 flannel, 規(guī)定宿主機下各個Pod屬于同一個子網(wǎng),不同宿主機下的Pod屬于不同的子網(wǎng)。

          flannel會在每一個宿主機上運行名為flanneld代理,其負責為宿主機預(yù)先分配一個子網(wǎng),并為Pod分配IP地址。Flannel使用Kubernetes或etcd來存儲網(wǎng)絡(luò)配置、分配的子網(wǎng)和主機公共IP等信息。數(shù)據(jù)包則通過VXLAN、UDP或host-gw這些類型的后端機制進行轉(zhuǎn)發(fā)。

          2.3 Flannel 在 K8S 中運行的整體過程

          1)設(shè)置集群網(wǎng)絡(luò)
          flannel默認使用etcd作為配置和協(xié)調(diào)中心,首先使用etcd設(shè)置集群的整體網(wǎng)絡(luò)。通過如下的命令能夠查詢網(wǎng)絡(luò)配置信息:
          $ etcdctl ls /coreos.com/network/config

          2)設(shè)置 Node 節(jié)點上的子網(wǎng)

          基于在 etcd 中設(shè)置的網(wǎng)絡(luò),flannel 為每一個 Node 分配 IP 子網(wǎng)。

          獲取子網(wǎng)列表

          $ etcdctl ls /coreos.com/network/subnets
          獲取子網(wǎng)信息
          $ etcdctl ls /coreos.com/network/subnets/{IP網(wǎng)段}

          3)在每個 Node 上啟動 flanneld

          flannel 在每個 Node 上啟動了一個 flanneld 的服務(wù),在flanneld啟動后,將從etcd中讀取配置信息,并請求獲取子網(wǎng)的租約。
          所有 Node 上的 flanneld 都依賴 etcd cluster 來做集中配置服務(wù),etcd 保證了所有node 上 flanned 所看到的配置是一致的。同時每個 node 上的 flanned 監(jiān)聽etcd上的數(shù)據(jù)變化,實時感知集群中node的變化。flanneld一旦獲取子網(wǎng)租約、配置后端后,會將一些信息寫入/run/flannel/subnet.env文件。
          $ cat /var/run/flannel/subnet.env

          4)創(chuàng)建虛擬網(wǎng)卡

          在Node節(jié)點上,會創(chuàng)建一個名為flannel.1的虛擬網(wǎng)卡。

          $ ip addr show flannel.1

          5)創(chuàng)建Docker網(wǎng)橋

          并為容器配置名為docker0的網(wǎng)橋,實際是通過修改Docker的啟動參數(shù)–bip來實現(xiàn)的。通過這種方式,為每個節(jié)點的Docker0網(wǎng)橋設(shè)置在整個集群范圍內(nèi)唯一的網(wǎng)段,從保證創(chuàng)建出來的Pod的IP地址是唯一。

          $ ip addr show docker0

          6)修改路由表

          flannel會對路由表進行修改,從而能夠?qū)崿F(xiàn)容器跨主機的通信。

          $ route -n

          2.4 數(shù)據(jù)傳遞過程

          在源容器宿主機中的數(shù)據(jù)傳遞過程:

          1)源容器向目標容器發(fā)送數(shù)據(jù),數(shù)據(jù)首先發(fā)送給 docker0 網(wǎng)橋

          在源容器內(nèi)容查看路由信息:

          $ kubectl exec -it -p {Podid} -c {ContainerId} -- ip route

          2)docker0 網(wǎng)橋接受到數(shù)據(jù)后,將其轉(zhuǎn)交給 flannel.1 虛擬網(wǎng)卡處理

          docker0 收到數(shù)據(jù)包后,docker0的內(nèi)核棧處理程序會讀取這個數(shù)據(jù)包的目標地址,根據(jù)目標地址將數(shù)據(jù)包發(fā)送給下一個路由節(jié)點:

          查看源容器所在Node的路由信息:

          $ ip route

          3)flannel.1 接受到數(shù)據(jù)后,對數(shù)據(jù)進行封裝,并發(fā)給宿主機的 eth0

          flannel.1收到數(shù)據(jù)后,flannelid會將數(shù)據(jù)包封裝成二層以太包。

          Ethernet Header的信息:

          • From:{源容器flannel.1虛擬網(wǎng)卡的MAC地址}

          • To:{目錄容器flannel.1虛擬網(wǎng)卡的MAC地址}

          4)對在flannel路由節(jié)點封裝后的數(shù)據(jù),進行再封裝后,轉(zhuǎn)發(fā)給目標容器 Node 的 eth0

          由于目前的數(shù)據(jù)包只是vxlan tunnel上的數(shù)據(jù)包,因此還不能在物理網(wǎng)絡(luò)上進行傳輸。因此,需要將上述數(shù)據(jù)包再次進行封裝,才能源容器節(jié)點傳輸?shù)侥繕巳萜鞴?jié)點,這項工作在由linux內(nèi)核來完成。
          Ethernet Header 的信息:
          • From: {源容器 Node 節(jié)點網(wǎng)卡的 MAC 地址}
          • To: {目錄容器 Node 節(jié)點網(wǎng)卡的 MAC 地址}

          IP Header的信息:

          • From:{源容器Node節(jié)點網(wǎng)卡的IP地址}

          • To:{目錄容器Node節(jié)點網(wǎng)卡的IP地址}

          通過此次封裝,就可以通過物理網(wǎng)絡(luò)發(fā)送數(shù)據(jù)包。

          在目標容器宿主機中的數(shù)據(jù)傳遞過程:

          5)目標容器宿主機的eth0接收到數(shù)據(jù)后,對數(shù)據(jù)包進行拆封,并轉(zhuǎn)發(fā)給flannel.1虛擬網(wǎng)卡;

          6)flannel.1 虛擬網(wǎng)卡接受到數(shù)據(jù),將數(shù)據(jù)發(fā)送給docker0網(wǎng)橋;

          7)最后,數(shù)據(jù)到達目標容器,完成容器之間的數(shù)據(jù)通信。

          來源:本文轉(zhuǎn)自公眾號 K8S技術(shù)棧(k8sstack)

          Linux學習指南

          有收獲,點個在看?

          瀏覽 35
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  人人做人人摸 | 国产一级婬乱片A片 | 日韩在线V | 又黄又爽视频 | 爽爽爽网站 |