今日雞湯
我們能夠帶進(jìn)墳?zāi)估锏?,歸根結(jié)底,也只有盡心盡責(zé)的滿足感,以及拼盡全力的證據(jù)。
今天好好搞一搞K8S網(wǎng)絡(luò)模型和存儲模型。
Linux網(wǎng)絡(luò)基礎(chǔ)
1. Namespace
Namespace設(shè)置的意圖是什么?
獨立的協(xié)議棧被隔離到不同的命名空間中,處于不同命名空間中的網(wǎng)絡(luò)棧是完全隔離的,彼此之間無法通信。
每個 Namespace需要包含什么?
進(jìn)程、套接字、網(wǎng)絡(luò)設(shè)備等。
如何在Linux網(wǎng)絡(luò)協(xié)議棧的基礎(chǔ)上支持這些私有的獨立的協(xié)議棧?
實現(xiàn)的核心:讓Linux網(wǎng)絡(luò)的全局變量成為一個Namespace變量的成員,然后為協(xié)議棧的函數(shù)調(diào)用加入一個Namespacee參數(shù)。所有網(wǎng)絡(luò)設(shè)備都只屬于一個命名空間(物理設(shè)備關(guān)聯(lián)到root,虛擬設(shè)備創(chuàng)建并關(guān)聯(lián)到給定的ns,但可以在不同的網(wǎng)絡(luò)ns之間轉(zhuǎn)移設(shè)備)。
不同ns網(wǎng)絡(luò)如何相互通信呢?
使用Veth設(shè)備對,利用成對的Veth設(shè)備對能直接將兩個網(wǎng)絡(luò)ns連接起來。
# 創(chuàng)建Veth設(shè)備對
ip link add veth0 type veth peer name veth1
# 查看Veth設(shè)備對信息
ip link show
# 將veth1轉(zhuǎn)移到netns1中
ip link set veth1 netns netns1
# 分配ip地址
ip netns exec netns1 ip addr add 10.1.1.1/24 dev veth1
# 啟動
ip netns exec netns1 ip link set dev veth1 up
怎么查看對端的veth設(shè)備?
使用ethtool工具。
# Step1:查詢對端接口在設(shè)備列表中的序列號
ip netns exec netns1 ethtool -S veth1
# Step2:通過grep查看特定序列號代表的設(shè)備
ip netns exec netns2 ip link | grep 5
Docker網(wǎng)絡(luò)實現(xiàn)
docker支持幾種網(wǎng)絡(luò)模式?
四種。host;container;none;bridge(默認(rèn))
docker bridge模式如何支持網(wǎng)絡(luò)的?
- Docker Deamon啟動時會創(chuàng)建一個虛擬網(wǎng)橋(docker0),并給網(wǎng)橋分配一個子網(wǎng)。
- 每個docker容器,都創(chuàng)建一個虛擬以太網(wǎng)設(shè)備(Veth設(shè)備對),一端連接docker0,一端連接使用namespace容器內(nèi)的eth0設(shè)備,然后從網(wǎng)橋地址段給eth0接口分配一個IP地址。
docker網(wǎng)絡(luò)模型的局限是什么?
Docker沒有考慮多主機互聯(lián)的網(wǎng)絡(luò)方案。在同一臺機器內(nèi)的容器之間可以互相通信,不同主機間的容器不能互相通信,甚至有可能因為在不同主機上的docker0地址段相同而導(dǎo)致不同主機的容器在相同的地址范圍內(nèi)。
可以協(xié)調(diào)好端口分配或使用動態(tài)端口分配技術(shù)來解決這個問題。
K8S網(wǎng)絡(luò)模型
K8S網(wǎng)絡(luò)要解決的問題
- 容器與容器的通信
- Pod到Pod的通信
- Pod與Service的通信
- 集群外部與內(nèi)部組件的通信
K8S設(shè)計的基礎(chǔ)原則
每個Pod都有一個獨立的IP地址;所有Pod都在一個可以直連、扁平的網(wǎng)絡(luò)空間中;Pod要求可以直接通過對方ip進(jìn)行訪問。
IP-per-Pod模型:IP以Pod為單位進(jìn)行分配。一個Pod內(nèi)部的所有容器共享一個網(wǎng)絡(luò)堆棧。
K8S對集群網(wǎng)絡(luò)的要求
1) 所有容器都可以在不用NAT的方式下同別的容器通信。
2)所有節(jié)點都可以在不用NAT的方式下同所有容器通信,反之亦然。
3)容器的地址和別人看到的地址是同一個地址。
K8S內(nèi)容器到容器的通信是怎么做的?
同一個Pod內(nèi)的容器共享同一個netns,所以各類網(wǎng)絡(luò)操作可以直接操作,就像在同一臺機器上。
K8S內(nèi)Pod是怎么通信的?
分為兩種情況,在同一個node上Pod的通信和不同node上的pod進(jìn)行通信。
- 對于同一個node上的Pod,他們都通過Veth連接到同一個docker0網(wǎng)橋上,IP地址都是從docker0的網(wǎng)段上動態(tài)獲取的,他們和網(wǎng)橋本身在同一個網(wǎng)段上,因此可以直接通信。
- 對于不同node上的Pod,只能通過宿主機的網(wǎng)卡進(jìn)行。于是需要滿足兩個條件:
- 在整個K8S集群中對Pod進(jìn)行IP分配,不能有沖突——Flannel管理資源分配
2)將Pod的IP與Node的IP關(guān)聯(lián)起來
K8S中Pod的IP數(shù)據(jù)流的目標(biāo)是哪里?
使用pause容器,將Pod里面的所有容器都連接到pause容器上,所有應(yīng)用容器的端口映射都到pause容器上。
K8S中Service與Pod怎么通信?
使用kube-proxy服務(wù)。Service在多個pod之間抽象一些服務(wù),而且可以在同一個service創(chuàng)建的pod中做負(fù)載均衡。kube-proxy 為每個新創(chuàng)建的服務(wù)都關(guān)聯(lián)一個隨機端口號,并創(chuàng)建負(fù)載均衡對象,直接和負(fù)載均衡到的Pod進(jìn)行網(wǎng)絡(luò)交互。
CNI網(wǎng)絡(luò)模型
CNI網(wǎng)絡(luò)模型是什么?
一種容器網(wǎng)絡(luò)規(guī)范。包括容器和網(wǎng)絡(luò)兩種概念。
對容器網(wǎng)絡(luò)的設(shè)置都通過插件來實現(xiàn)。CNI插件包括兩種類型:CNI Plugin和IPAM。
CNI Plugin負(fù)責(zé)為容器配置網(wǎng)絡(luò)資源,IPAM負(fù)責(zé)對容器IP地址進(jìn)行分配管理。
CNI Plugin提供哪些操作?
ADD, DELETE, CHECK, VERSION
K8S存儲模型
為什么K8S需要網(wǎng)絡(luò)共享存儲?
在docker容器中,為了實現(xiàn)數(shù)據(jù)的持久性存儲,在宿主機和容器內(nèi)做映射,可以保證在容器的生命周期結(jié)束,數(shù)據(jù)依舊可以實現(xiàn)持久性存儲。
在k8s中,對于在同一節(jié)點的pod,可以使用本地數(shù)據(jù)卷來進(jìn)行持久化存儲。有三種方式:
1)emptyDir:Pod掛載在本地的磁盤或者內(nèi)存,被稱為emptyDir,稱為臨時空目錄,隨著Pod刪除,也會被刪除。適用于pod中容器之間的數(shù)據(jù)共享。
- gitrepo目錄:只是emptydir上補添一個git命令來拉取文件而已。當(dāng)pod創(chuàng)建時候,會拉取git(依賴于宿主機git命令驅(qū)動)倉庫中數(shù)據(jù)克隆到本地,并且作為存儲卷定義在pod之上。gitrepo基于emptyDir,此存儲卷是emptyDir,git倉庫中拉取的代碼存放在emptyDir后被定義到pod。
- hostPath類型:映射node文件系統(tǒng)中的文件或者目錄到pod里。可實現(xiàn)針對某一節(jié)點的數(shù)據(jù)持久化,如果節(jié)點宕機了,那數(shù)據(jù)就丟失了。應(yīng)用于Pod中容器需要訪問宿主機時。
對于分布在不同節(jié)點的pod,并不能實現(xiàn)不同節(jié)點之間持久性數(shù)據(jù)的共享,并且,在節(jié)點故障時,可能會導(dǎo)致數(shù)據(jù)的永久性丟失。為此,k8s就引入了外部存儲卷的功能,通常是PVC和PV組合使用。
PV是對底層網(wǎng)絡(luò)共享存儲的抽象,將共享存儲定義為一種“資源”。而PVC是用戶對存儲資源的一個“申請”,用戶在創(chuàng)建應(yīng)用時定義好需要的PVC,PVC會去找K8S當(dāng)前可用的PV,進(jìn)行綁定。使用完后進(jìn)行清理和釋放。
PV是怎樣定義的?有什么關(guān)鍵參數(shù)?
- Storage:存儲能力
- accessMode:訪問模式,分為RWO(讀寫,被單個Node掛載)、ROX(只讀,被多個Node掛載)、RWX(讀寫,被多個Node掛載)三種,不同存儲提供商有不同的訪問模式。
- storageClass:存儲類別,當(dāng)定義StorageClass的時候可以用做動態(tài)綁定。
- ReclaimPolicy:回收策略,有保留、回收空間和刪除三種。
PV的生命周期?
四種。
- Available:可用,未與PVC綁定
- Bound:與PVC綁定
- Released:綁定的PVC已刪除,資源釋放但還沒有回收
- Failed:自動資源回收失敗
PVC和PV的生命周期是什么?
- 資源供應(yīng):靜態(tài)和動態(tài)兩種方式來創(chuàng)建PV。
- 資源綁定:系統(tǒng)根據(jù)PVC對存儲資源的請求,在已存在的PV中選擇一個綁定,如果沒有PVC會一直pending,直到有符合要求的PV。
- 資源使用:Pod根據(jù)volume定義,將PVC掛載到容器內(nèi)某個路徑進(jìn)行使用。
- 資源釋放:用戶刪除PVC,與PVC綁定的PV會被標(biāo)記為“已釋放”。
- 資源回收:如何處理遺留數(shù)據(jù)。
K8S中PV的創(chuàng)建有哪些方式?
兩種。靜態(tài)和動態(tài)模式。
- 靜態(tài)模式:管理員手工創(chuàng)建PV,定義他的屬性。
缺點:當(dāng)PVC申請的資源比PV的資源少時,整個PV空間都會被該PVC占據(jù),造成資源浪費。 - 動態(tài)模式:管理員定義StorageClass,描述后端存儲,標(biāo)記為某種類型,比如Fast, Standard, Slow。
優(yōu)勢:通過聲明StorageClass和PVC完成資源綁定。系統(tǒng)在為PVC找到合適的StorageClass后,將自動創(chuàng)建一個PV并完成與PVC的綁定,沒有資源浪費。
Pod與PV與PVC的關(guān)系?
一個PV只能被一個PVC使用,一個PVC可被多個Pod使用。