《深入剖析Kubernetes》總結四:Pod解析

Pod

相當於Linux操作系統的進程組

Pod只是一個邏輯概念,是一組共享了某些資源的容器,它的所有容器共享的是同一個 Network Namespace,並且可以聲明共享同一個 Volume;
爲了讓Pod裏的多個容器是對等關係而不是拓撲關係,Pod 的實現需要使用一箇中間容器,叫作 Infra 容器,在這個 Pod 中,Infra 容器永遠都是第一個被創建的容器,而其他用戶定義的容器,則通過 Join Network Namespace 的方式,與 Infra 容器關聯在一起(否則容器之間互相join的話,總得有一個先啓動,就成了拓撲關係了)

對於同一個 Pod 裏面的所有用戶容器來說,它們的進出流量,可以認爲都是通過 Infra 容器完成的

有了這個設計之後,共享 Volume 的實現很簡單:把所有 Volume 的定義都設計在Pod 層級即可。

sidecar:容器設計模式
可以在一個 Pod 中,啓動一個輔助容器,來完成一些獨立於主進 程(主容器)之外的工作。
比如有一個tomcat和war,那麼可以把 WAR 包和 Tomcat 分別做成鏡像,然後把它們作爲一個 Pod 裏的兩個容器“組合”在一起(tomcat爲主容器,war爲輔助容器,提供war包而已,類型爲init Container,都會比 spec.containers 定義的用戶容器先啓動。並 且,Init Container 容器會按順序逐一啓動,而直到它們都啓動並且退出了,用戶容器纔會啓動),這樣等Tomcat 容器啓動時,它的 webapps 目錄下就一定會存在 war 文件:這個文件正是 WAR 包容器啓動時拷貝到 Volume 裏面的,而 Volume 是被這兩個容器共享的。

對比虛擬機:Pod可以理解爲虛擬機本身,容器則是這個虛擬機裏的進程

基本概念

  • Pod字段

調度、網絡、存儲、Linux Namespace以及安全相關的屬性基本上是 Pod 級別的

NodeSelector:可以供用戶將 Pod 與 Node 進行綁定

NodeName::該字段被賦值則意味着Kubernetes會認爲這個 Pod 已經經過了調度,調度的結果就是賦值的節點名字,所以,這個字段一般由調度器負責設置;
用戶也可以手動設置它,保證不被調度,一般是在測試或者調試的時候會用到

HostAliases:定義了 Pod 的 hosts 文件(比如 /etc/hosts)裏的內容

Containers、Init Containers:容器

  • Container字段

Image:鏡像

Command:啓動命令

workingDir:容器的工作目錄

Ports:容器要開發的端口

volumeMounts:容器要掛 載的 Volume

ImagePullPolicy:定義了鏡像拉取的策略

Lifecycle:定義了 Container Lifecycle Hooks,也就是在容器狀態發生變化時觸發一系列“鉤子”。

  • Pod生命週期

pod.status.phase,就是 Pod 的當前狀態:

  1. Pending:Pod 的 YAML 文件已經提交給了 Kubernetes,API 對象已經被創建並保存在 Etcd 當中;但是,這個 Pod 裏有些容器因爲某種原因而不能被順利創建,比如調度不成功
  2. Running:Pod 已經調度成功,跟一個具體的節點綁定;它包含的容器都已經創建成功,並且至少有一個正在運行中
  3. Succeeded:Pod 裏的所有容器都正常運行完畢,並且已經退出了。這種情況在運行一次性任務時最爲常見
  4. Failed:Pod 裏至少有一個容器以不正常的狀態(非 0 的返回碼)退出;這個狀態的出現,意味着得Debug這個容器的應用,比如查看 Pod 的 Events 和日誌
  5. Unknown:這是一個異常狀態,意味着 Pod 的狀態不能持續地被 kubelet 彙報給 kubeapiserver,很有可能是主從節點(Master 和 Kubelet)間的通信出現了問題

Pod 對象的 Status 字段,還可以再細分出一組 Conditions;
這些細分狀態的值包 括:PodScheduled、Ready、Initialized,以及 Unschedulable;
它們主要用於描述造成當前 Status 的具體原因是什麼;
比如,Pod 當前的 Status 是 Pending,對應的 Condition 是 Unschedulable,這就意味着它的調度出現了問題;
Ready意味着 Pod 不僅已經正常啓動(Running 狀 態),而且已經可以對外提供服務了;

Running 和 Ready是有區別的, 有Pod(即容器)的狀態是 Running,但是應用其實已經停止服務的例子:https://www.dazhuanlan.com/2019/12/16/5df6fd55a05d7/

1. 程序本身有 bug,本來應該返回 200,但因爲代碼問題,返回的是500;
2. 程序因爲內存問題,已經僵死,但進程還在,但無響應;
3. Dockerfile 寫的不規範,應用程序不是主進程,那麼主進程出了什麼問題都無法發現;
4. 程序出現死循環。

進階

Projected Volume:投射數據卷,是一種特殊的 Volume,存在的意義不是爲了存放容器裏的數據,也不是用來進行容器和宿主機之間的數據交換,而是爲容器提供預先定義好的數據;
所以,從容器的角度來看,這些 Volume 裏的信息就是彷彿是被 Kubernetes“投射”(Project)進入容器當中的

支持的Projected Volume種類:Secret、ConfigMap、Downward API、ServiceAccountToken

  • Secret

作用:可以把 Pod 想要訪問的加密數據,存放到 Etcd 中。然後就可以通過在 Pod 的容器裏掛載 Volume 的方式,訪問到這些 Secret 裏保存的信息

場景:存放數據庫的Credential信息

  • ConfigMap

與Secret類似,區別在於ConfigMap保存的是不需要加密的、 應用所需的配置信息

  • Downward API

作用:讓 Pod 裏的容器能夠直接獲取到這個 Pod API 對象本身 的信息。

注意:Downward API 能夠獲取到的信息,一定是 Pod 裏的容器進程啓動之前就能夠確定下來的信息;
如果想要獲取 Pod 容器運行後纔會出現的信息,比如,容器進程的 PID,那就肯定不能使用 Downward API 了,而應該考慮在 Pod 裏定義一個 sidecar 容器。

  • Service Account(特殊的Secret)

需求:現在有了一個 Pod我能不能在這個 Pod 裏安裝一個 Kubernetes 的 Client,這樣就可以從容器裏直接訪問並且操作這個 Kubernetes 的 API ?

首先要解決 API Server 的授權問題

Service Account 對象的作用,就是 Kubernetes 系統內置的一種“服務賬戶”;
它是 Kubernetes 進行權限分配的對象,比如,Service Account A,可以只被允許對 Kubernetes API 進行 GET 操 作,而 Service Account B,則可以有 Kubernetes API 的所有操作的權限

Service Account 的授權信息和文件,實際上保存在它所綁定的一個特殊的 Secret 對象裏 的,這個特殊的 Secret 對象,就叫作ServiceAccountToken,任何運行在 Kubernetes 集羣上的 應用,都必須使用 ServiceAccountToken 裏保存的授權信息,也就是 Token,纔可以合法地訪問 API Server

Kubernetes已經提供了一個默認的Service Account,Pod 創建完成後,容器裏的應用就可以直接從默認 Service Account對應的ServiceAccountToken 的掛載目錄裏訪問到授權信息和文件,只要直接加載這些授權文件,就可以訪問並操作 Kubernetes API 了

容器健康檢查和恢復機制

可以爲 Pod 裏的容器定義一個健康檢查“探針”(Probe);
這樣, kubelet 就會根據這個 Probe 的返回值決定這個容器的狀態,而不是直接以容器進行是否運行(來自 Docke 返回的信息)作爲依據;
這種機制,是生產環境中保證應用健康存活的重要手段。

pod.spec.restartPolicy字段則用來恢復,值有:

Always:在任何情況下,只要容器不在運行狀態,就自動重啓容器

OnFailure: 只在容器 異常時才自動重啓容器

Never: 從來不重啓容器。

其基本設計原理:

  1. 只要 Pod 的 restartPolicy 指定的策略允許重啓異常的容器(比如:Always),那麼這個 Pod 就會保持 Running 狀態,並進行容器重啓;
    否則,Pod 就會進入 Failed 狀態 。
  2. 對於包含多個容器的 Pod,只有它裏面所有的容器都進入異常狀態後,Pod 纔會進入 Failed 狀態;
    在此之前,Pod 都是 Running 狀態;
    此時,Pod 的 READY 字段會顯示正常容器的個數
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章