一、Pod 控制器型別
Pod概念
當一個 Pod 建立後,Pause 容器就會隨著 Pod 啟動,只要是有 Pod,Pause 容器就要被啟動。
在同一個 Pod 裡面的容器不能出現埠衝突,否則這個 Pod 可能會出現無法啟動、無限重啟。
一個 Pod 裡面的容器數量是大於等於1。
Pod 裡面的容器都是共享 Pause 的網路棧,在同一個 Pod 裡即共享網路又共享儲存卷。
RC和RS概念
Replication Controller 用來確保容器應用的副本數始終保持在使用者定義的副本數,即如果有容器異常退出,會自動建立新的 Pod 來代替;而如果異常多出來的容器也會自動回收。
在 K8s 新版本中,官方不再使用RC(Replication Controler),建議使用 RS(ReplicaSet)代替,因為RS支援集合式的 selector。
ReplicaSet 跟 Replication Controller 沒有本質區別,只是名字不一樣,並且 ReplicaSet 支援集合式的 selector。
支援集合式的 selector 作用:
在建立 Pod 的時候會為它打上標籤(tag),也會為 Pod 裡面的容器打上標籤,當需要刪除容器或者進行其他操作的時候,可以通過標籤來進行相關操作。
Deployment原理:
RS 不支援滾動更新,但是 Deployment 支援滾動更新,RS 和 Deployment 建議一起使用的原因是 Deployment 不負責 Pod 建立,Deployment 需要建立 RS 來達到建立 Pod 的能力。
Deployment 結合 RS 使用,滾動更新:
Deployment 建立出來之後,它會去建立一個 RS,Deployment 再去負責建立對應 Pod;
當某一天需要版本更新,Deployment 會去新建一個RS-2版本,在RS-2下啟動v2版本的第一個容器,則退出v1版本的第一個容器,以此類推...到達滾動更新狀態。
回滾:
回滾的機制是因為 Deployment 在滾動更新之後,RS-1並沒有刪除,而是被停用狀態,當執行回滾的時候,Deployment 就好啟動舊版本的RS-1,到達一個回滾效果。
StatefulSet概念
StatefulSet 是為了解決有狀態服務的問題,有狀態服務分為 MySQL、MongoDB 等,無狀態服務分為 Nginx、Apache 等。
應用場景包括:
- 穩定的持久化儲存,即Pod重新排程後還是能訪問到相同的持久化資料,基於PVC來實現;
- 穩定的網路標誌,即Pod重新排程後其PodName和HostName不變,基於Headless Service 來實現;
- 有序部署,有序擴充套件;
- 有序收縮,有序刪除。
DaemonSet概念
DaemonSet 確保全部(或者一些)Node上執行一個 Pod 的副本。當有 Node 加入叢集時,也會為他們新增一個 Pod。當有 Node 從叢集移除時,這些 Pod 也會被回收。刪除 DaemonSet 將會刪除它建立的所有 Pod。
使用 DaemonSet 的一些典型用法:
- 執行叢集儲存 daemon,例如在每個 Node 上執行 glusterd、ceph。
- 在每個 Node 上執行日誌收集 daemon,例如fluentd、logstash。
- 在每個 Node 上執行監控 daemon,例如Prometheus Node Exporter。
Job
Job 負責批處理任務,即僅執行一次的任務,它保證批處理任務的一個或多個 Pod 成功結束。
Job 如果判斷這個指令碼不是正常退出,則重新執行一遍,直到正常退出為止,並且還可以設定正常退出次數,比如正常退出次數兩次,才允許這個指令碼執行成功。
二、服務發現
service概念
如果 Pod 之間沒有相干性,是無法通過一個 Service 代理或者收集的。
Service收集的機制:
第一、比如是通一個 RC、RS、Deployment 建立的 Pod;
第二、或者擁有同一組標籤,Service 通過標籤來收集 Pod。
三、網路通訊方式
同一個 Pod 內部通訊
同一個 Pod 共享同一個網路名稱空間,共享同一個Linux協議棧,使用迴環網路卡(lo)通訊。
兩個不同 Pod 之間訪問
Pod1 與 Pod2 不在同一臺主機的情況:
Pod 的地址是與 docker0 在同一個網段的,但是 docker0 網段與宿主機網路卡是兩個完全不同的IP網段,並且不同 Node 之間的通訊只能通過宿主機的物理網路卡進行。
將 Pod 的 IP 和所在 Node 的IP關聯起來,通過這個關聯讓 Pod 可以互相訪問。
假設 Web APP2 需要訪問 Backend:
源地址寫自己的(10.1.15.2/24),目標地址寫(10.1.20.3/24);
由於目標地址不是跟 Web app2 同一網段,所以傳送資料包到閘道器(Docker0);
Docker0閘道器傳送到 Flannel0,Flannel0 有一個路由表儲存在 Etcd 中,根據路由表來進行轉發;
Flannel0 將資料包轉發到 Flanneld,因為 Flannel0 是 Flanneld 中的一個網橋;
到 Flanneld 之後,它會對該資料包文進行二次封裝,請看上圖右邊資料封裝結構;
此時資料包到了66.12這臺機器上:
Flanneld 收到資料包後,解封資料包之後轉發到 Flannel0 網橋中;
Flannel0 轉發到 Docker0,Docker0 根據目標IP地址轉發到 Backend 容器中;
因為 Docker0 只能看到第二層源IP地址和目標IP地址,第一層源IP地址和目標IP地址已經被砍掉了。
Pod1 與 Pod2 在同一臺主機情況:
由 docker0 網橋直接轉發請求到 Pod2,不需要經過 Flannel。
元件通訊示意圖
節點網路:真實網路,就是節點主機的物理網路卡;
Pod 網路:虛擬網路,所有的 Pod 之間通訊都是通過該網路;
Service 網路:虛擬網路,通過 Service 網路訪問後端Pod。
以上有不恰當或者講得不對的地方,希望各位留言指正,謝謝!
站在巨人的肩膀上!