1. 程式人生 > 其它 >Pod詳解

Pod詳解

Pod基礎概念:

Pod是kubernetes中最小的資源管理元件,Pod也是最小化執行容器化應用的資源物件。一個Pod代表著叢集中執行的一個程序。kubernetes中其他大多陣列件都是圍繞著Pod來進行支撐和擴充套件Pod功能的,例如,用於管理Pod執行的StatefulSet和Deployment等控制器物件,用於暴露Pod應用的Service和Ingress物件,為Pod提供儲存的PersistentVolume儲存資源物件等。

在Kubrenetes叢集中Pod有如下兩種使用方式:

一個Pod中執行一個容器

“每個Pod中一個容器”的模式是最常見的用法;在這種使用方式中,你可以把Pod想象成是單個容器的封裝,kuberentes管理的是Pod而不是直接管理容器。

在一個Pod中同時執行多個容器

一個Pod中也可以同時封裝幾個需要緊密耦合互相協作的容器,它們之間共享資源。這些在同一個Pod中的容器可以互相協作成為一個service單位,比如一個容器共享檔案,另一個“sidecar”容器來更新這些檔案。Pod將這些容器的儲存資源作為一個實體來管理。

一個Pod下的容器必須運行於同一節點上。現代容器技術建議一個容器只執行一個程序,該程序在容器中PID命令空間中的程序號為1,可直接接收並處理訊號,程序終止時容器生命週期也就結束了。若想在容器內執行多個程序,需要有一個類似Linux作業系統init程序的管控類程序,以樹狀結構完成多程序的生命週期管理。運行於各自容器內的程序無法直接完成網路通訊,這是由於容器間的隔離機制導致,k8s中的Pod資源抽象正是解決此類問題,Pod物件是一組容器的集合,這些容器共享Network、UTS及IPC命令空間,因此具有相同的域名、主機名和網路介面,並可通過IPC直接通訊。

Pod資源中針對各容器提供網路命令空間等共享機制的是底層基礎容器pause,基礎容器(也可稱為父容器)pause就是為了管理Pod容器間的共享操作,這個父容器需要能夠準確地知道如何去建立共享執行環境的容器,還能管理這些容器的生命週期。為了實現這個父容器的構想,kubernetes中,用pause容器來作為一個Pod中所有容器的父容器。這個pause容器有兩個核心的功能,一是它提供整個Pod的Linux名稱空間的基礎。二來啟用PID名稱空間,它在每個Pod中都作為PID為1程序(init程序),並回收殭屍程序。

pasue容器使得Pod中的所有容器可以共享兩種資源:

網路:

每個Pod都會被分配一個唯一的IP地址。Pod中的所有容器共享網路空間,包括IP地址和埠。Pod內部的容器可以使用localhost互相通訊。Pod中的容器與外界通訊時,必須分配共享網路資源(例如使用宿主機的埠對映)。

儲存:

可以Pod指定多個共享的Volume。Pod中的所有的容器都可以訪問共享的Volume。Volume也可以用來持久化Pod中的儲存資源,以防容器重啟後文件丟失。

總結:

每個Pod都有一個特殊的被稱為“基礎容器”的Pause容器。Pause容器對應的映象屬於Kubernetes平臺的一部分,除了Pause容器,每個Pod還包含一個或者多個緊密相關的使用者應用容器。

kubernetes中的pause容器主要為每個容器提供以下功能:

  • 在pod中擔任Linux名稱空間(如網路命令空間)共享的基礎
  • 啟用PID名稱空間,開啟init程序

Kubernetes設計這樣的Pod概念和特殊組成結構有什麼用意?

  • 原因一:在一組容器作為一個單元的情況下,難以對整體的容器簡單的進行判斷及有效地進行行動。比如,一個容器死亡了,此時是算整體掛了嗎?那麼引入與業務無關的Pause容器作為Pod的基礎容器,以他的狀態代表著整個容器組的狀態,這樣就可以解決該問題。
  • 原因二:Pod裡的 多個應用容器共享Pause容器的IP,共享Pause容器掛載的Volume,這樣簡化了應用容器之間的通訊問題,也解決了容器之間的檔案共享問題。

通常把Pod分為兩類:

自主式Pod:

這種Pod本身是不能自我修復的,噹噹Pod被建立後(不論是由你直接建立還是被其他Controller),都會被Kuberentes排程到叢集的Node上。直到Pod的程序終止、被刪掉、因為缺少資源而被驅逐、或者Node故障之前這個Pod都會一直保持在那個Node上。Pod不會自愈。如果Pod執行的Node故障,或者是排程器本身故障,這個Pod就會被刪除。同樣的,如果Pod所在Node缺少資源或者Pod處於維護狀態,Pod也會被驅逐。

控制器管理的Pod

Kubernetes使用更高階的稱為Controller的抽象層,來管理Pod例項。Controller可以建立和管理多個Pod,提供副本管理、滾動升級和叢集級別的自愈能力。例如,如果一個Node故障,Controller就能自動將該節點上的Pod排程到其他健康的Node上。雖然可以直接使用Pod,但是在Kubernetes中通常是使用Controller來管理Pod的。

Pod容器的分類

1、基礎容器

  • 維護整個Pod網路和儲存空間
  • node節點中操作
  • 啟動一個容器時,k8s會自動啟動一個基礎容器
  • 每次建立Pod時候就會建立,執行的每一個容器都有一個pause-amd64的基礎容器自動會執行,對於使用者是透明的

2、初始化容器(initcontainers)

Init容器必須在應用程式容器啟動之前執行完成,而應用程式容器是並行執行的,所以Init容器能夠提供了一種簡單的阻塞或延遲應用容器的啟動的方法。

Init容器與普通的容器肥成像,除了一下兩點:

  • Init容器總是執行到成功完成為止
  • 每個Init容器都必須在下一個Init容器啟動之前成功完成啟動和退出:如果Pod的Init容器失敗,k8s會不斷地重啟該Pod,直到Init容器成功為止。然而,如果Pod物件的重啟策略(restartPolicy)為Never,它不會重新啟動

Init的容器的作用

因為init容器具有與應用容器分離的單獨映象,其啟動相關程式碼具有如下優勢:

  • Init容器可以包含一些安裝過程應用容器中不存在的實用工具或個性化程式碼。例如,沒有必要僅為了在安裝過程中使用類似sed、awk、python或dig這樣的工具而去FROM一個映象來生成一個新的映象。
  • Init 容器可以安全地執行這些工具,避免這些工具導致應用映象的安全性降低。
  • 應用映象的建立者和部署者可以各自獨立工作,而沒有必要聯合構建一個單獨的應用映象。
  • Init 容器能以不同於Pod內應用容器的檔案系統檢視執行。因此,Init容器可具有訪問 Secrets 的許可權,而應用容器不能夠訪問。
  • 由於 Init 容器必須在應用容器啟動之前執行完成,因此 Init 容器提供了一種機制來阻塞或延遲應用容器的啟動,
    直到滿足了一組先決條件。一旦前置條件滿足,Pod內的所有的應用容器會並行啟動。

3、應用容器(Maincontainer)

##並行啟動

apiVersion: v1
kind: Pod
metadata:
name: myapp-pod
labels:
app: myapp
spec:
containers:
- name: myapp-container
image: busybox:1.28
command: ['sh', '-c', 'echo The app is running! && sleep 3600']
initContainers:
- name: init-myservice
image: busybox:1.28
command: ['sh', '-c', 'until nslookup myservice; do echo waiting for myservice; sleep 2; done;']
- name: init-mydb
image: busybox:1.28
command: ['sh', '-c', 'until nslookup mydb; do echo waiting for mydb; sleep 2; done;']

這個例子是定義了一個具有 2 個 Init 容器的簡單 Pod。 第一個等待 myservice 啟動, 第二個等待 mydb 啟動。 一旦這兩個 Init容器都啟動完成,Pod 將啟動 spec 中的應用容器。

特別說明:

  • 在Pod啟動過程中,Init容器會按順序在網路和資料卷初始化之後啟動。每個容器必須在下一個容器啟動之前成功退出。
  • 如果由於執行時或失敗退出,將導致容器啟動失敗,它會根據Pod的restartPolicy指定的策略進行重試。然而,如果Pod的restartPolicy設定為Always,Init容器失敗時會使用RestartPolicy策略。
  • 在所有的Init容器沒有成功之前,Pod將不會變成Ready狀態。Init容器的埠將不會在Service中進行聚集。正在初始化中的Pod處於Pending狀態,但應該會將Initializing狀態設定為true。
  • 如果Pod重啟,所有Init容器必須重新執行。
  • 對Init容器spec的修改被限制在容器image欄位,修改其他欄位都不會生效。更改Init容器的image欄位,等價於重啟該Pod。
  • Init容器具有應用容器的所有欄位。除了readinessProbe,因為Init容器無法定義不同於完成(completion)的就緒(readiness)之外的其他狀態。這會在驗證過程中強制執行。
  • 在Pod中的每個app和Init容器的名稱必須唯一;與任何其它容器共享同一個名稱,會在驗證時丟擲錯誤。

映象拉取策略(image PullPolicy):

Pod 的核心是執行容器,必須指定容器引擎,比如 Docker,啟動容器時,需要拉取映象,k8s 的映象拉取策略可以由使用者指定:

  • IfNotPresent:在映象已經存在的情況下,kubelet 將不再去拉取映象,僅當本地缺失時才從倉庫中拉取,預設的映象拉取策略
  • Always:每次建立 Pod 都會重新拉取一次映象;
  • Never:Pod 不會主動拉取這個映象,僅使用本地映象。

注意:對於標籤為“:latest”的映象檔案,其預設的映象獲取策略即為“Always”;而對於其他標籤的映象,其預設策略則為“IfNotPresent”。

修改檔案