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

一、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)商處獲取這些插件。

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è)備出來。

1.2 外部訪問
$ docker run -P {images}$ 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ù)之間的通信
2.1 同一個 Pod 中容器之間的通信
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 中運行的整體過程
$ etcdctl ls /coreos.com/network/config2)設(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
$ 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 route2)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 route3)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
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)
有收獲,點個在看?


