[Kubernetes] Pod 基本原理


Pod 原理

Pod 作為最小調度單位

容器——單進程模型:不是指容器只能運行一個進程(線程,輕量級進程),而是說容器沒有管理多個進程的能力。因為容器內PID=1的進程就是容器本身,容器內其他進程都是這個容器進程的子進程,在容器內沒有類似 init 進程和 systemd 這樣執行進程管理功能的進程。

在操作系統中,應用往往不是以單個進程的形式運行,而是以進程組的形式存在(Linux 中的進程實際上是線程,或者說輕量級進程)。進程組之間的進程相互之間可能會基於 IPC(Inter Process Comunication) 進行通信。這就要求這些進程都運行在同一台宿主機上。

由於容器的單進程模型,進程組之間的各個進程各自需要運行在不同的容器中。假設某個應用進程組中有三個進程。

假設每個容器都需要 1 GB 的內存配額。集群中有兩個節點,node-1 有 3 GB,node-2 有 2.5 GB。如果將應用的進程一個個單獨調度,那么可能出現同一應用進程組中的各個進程被調度到了不同節點上,或者在設置了親和性的情況下,出現節點上內存資源不足,可是卻已經把部分進程調度到了該節點的狀況。

在 Kubernetes 中,不是以容器作為基本調度單位,而是以 Pod 作為調度單位,應用所需要的三個容器一起組成一個 Pod,k8s 以 Pod 作為資源分配以及任務調度的單位,就可以解決上述問題。

這種容器之間的緊密聯系,可以稱為“超親密關系”。

容器設計模式

除了上述的調度方面的考慮外,Pod 還有一個重要意義在於容器設計模式。

Pod 的本質是一組共享了某些資源的容器。Pod 中的容器,共享同一個Network Namespace,並且可以聲明共享同一個 Volume

類似於:

$ docker run --net=B --volumes-from=B --name=A image-A ...

但是以上述方式啟動容器,就注定需要容器 B 比容器 A 先啟動。

因此在 kubenetes 中,Pod 的實現需要使用一個中間容器或者說 Infra 容器。在 Kubernetes 創建 Pod 時,首先啟動的都是這個容器,其他用戶定義的容器通過 Join Network Namesapce 的方式使用 Infra 容器的 Network Namespace,這樣就實現了 Pod 內容器共享網絡設備。

Infra 容器本身是一個非常特殊的鏡像,叫做 k8s.gcr.io/pause,這個進程永遠處於“暫停”狀態。

后續用戶定義的容器通過 Join Network Namespace 實現了:

  • 它們可以直接使用 localhost 進行通信
  • 看到的網絡設備就是 Infra 的網絡設備
  • 一個 Pod 只有一個 IP 地址,也就是 Pod 的 Network Namespace 對應的 IP 地址
  • Pod 的生命周期只和 Infra 容器相關,和用戶容器無關

那么實際上,Pod 的網絡通信也是通過 Infra 容器完成的。而 Infra 容器的鏡像中幾乎什么都沒有,那么在開發容器網絡插件時,就不能使用其他的安裝包,只需要關注如何通過 docker 啟動接口配置 Network Namespace 即可

同時,卷的掛載也是一個原理。一個 Volume 對應的宿主機目錄對於 Pod 來說就只有一個,Pod 內的容器只需要聲明掛載這個 Volume 就可以共享這個 Volume 所對應的宿主機目錄。

apiVersion: v1
kind: Pod
metadata:
  name: two-containers
spec:
  restartPolicy: Never
  volumes:
  - name: shared-data
    hostPath:      
      path: /data
  containers:
  - name: nginx-container
    image: nginx
    volumeMounts:
    - name: shared-data
      mountPath: /usr/share/nginx/html
  - name: debian-container
    image: debian
    volumeMounts:
    - name: shared-data
      mountPath: /pod-data
    command: ["/bin/sh"]
    args: ["-c", "echo Hello from the debian container > /pod-data/index.html"]

例如上述 yaml 文件中,ngnix-container 和 debian-container 兩個容器都掛載了宿主機的 /data 文件夾,兩個容器實現了數據共享。

所謂容器設計模式就是充分利用 Pod 的原理,合理地設計 Pod 內容器的功能。
比如為了實現 Pod 內的日志收集。那么我們可以將 Pod 里的一個 Volume 掛載到容器內的 /var/log 目錄中,同時在 Pod 里運行另一個 sidecar 容器,它也掛載該 Volume,接下來 sidecar 容器只需要將日志文件的內容通過 MongoDB 或者 Elasticsearch 保存起來。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM