在本文章中,我透過實際範例和用例詳細介紹了 Kubernetes pod 概念。
所以如果你想了解,
Pod 核心概念
如何建立 pod
存取 Pod
Pod 關聯物件
那麽本文章適合你。
本文章的目的是讓你理解 pod 的構建塊,並實際實作部署 pod 並存取在其上執行的應用程式。
此外,還有許多與 Pod 物件相關的概念。因此,我已經提供了與 Pod 相關的所有資訊和概念,以進一步構建你學到的基礎知識。
註意:在開始探索 Kubernetes Pod 之前,請確保你對 概念有深入的理解。
什麽是 Kubernetes Pod?
在深入了解 Kubernetes Pod 概念之前,讓我們先了解一下容器。
眾所周知,容器是一個獨立的環境,我們在其中打包應用程式及其依賴項。通常,容器執行單個行程(盡管有一些方法可以執行多個行程)。每個容器都有一個 IP 地址,並且可以附加卷並控制 CPU 和記憶體資源等。所有這些都是透過名稱空間和控制組的概念實作的。
Kubernetes 是一個容器編排系統,用於部署、擴充套件和管理容器化應用程式,它有自己的容器執行方式。我們稱它為豆莢。Pod 是 Kubernetes 中最小的可部署單元,代表應用程式的單個例項。
例如,如果要執行 Nginx 應用程式,則可以在 pod 中執行它。
那麽它與容器有何不同呢?
容器是一個單獨的單元。但是,一個 Pod 可以包含多個容器。你可以將 Pod 視為一個可以將一個或多個容器放在一起的盒子。
Pod 提供了更高級別的抽象,允許你將多個容器作為一個單元進行管理。在這裏,Pod 獲得的不是每個容器都有一個 IP 地址,而是獲得一個唯一的 IP 地址,並且在 Pod 內部執行的容器使用 localhost 在不同的埠上相互連線。
這意味著 Kubernetes Pod 內的容器共享以下內容
網路名稱空間 – Pod 內的所有容器都透過 localhost 進行通訊。
IPC 名稱空間:所有容器都使用共享的行程間通訊名稱空間。
UTS名稱空間:所有容器共享相同的主機名。
Pod 內的容器之間不共享哪些內容?
預設情況下,PID 名稱空間不會共享,但是 kubernetes 提供了使用 Option 在 pod 內的容器之間啟用行程共享的選項。shareProcessNamespace
掛載名稱空間不會在容器之間共享。每個容器都有自己的私有檔案系統和目錄。但是,Pod 掛載卷在容器之間共享。
簡而言之,以下是你應該了解的有關 pod 的資訊:
Pod 是 Kubernetes 中最小的可部署單元。
pod本質上是短暫的;可以建立、刪除和更新它們。
一個 Pod 可以有多個容器;你可以在 Pod 內執行的容器數量沒有限制。
每個 pod 都有一個唯一的 IP 地址。
Pod 使用 IP 地址相互通訊。
Pod 內的容器在不同的埠上使用 localhost 進行連線。
在 Pod 內執行的容器應該有不同的埠號,以避免埠沖突。
你可以為 Pod 內部執行的每個容器設定 CPU 和記憶體資源。
Pod 內的容器共享相同的卷掛載。
Pod 內的所有容器都排程在同一節點上;它不能跨越多個節點。
如果有多個容器,則在 Pod 啟動期間,所有主容器將並列啟動。而 pod 內的 init 容器是按順序執行的。
Pod YAML(物件定義)
現在我們已經對 Pod 有了基本的了解,讓我們來看看我們如何定義 Pod。Pod 是原生的 Kubernetes 物件,如果要建立 Pod,需要以 YAML 格式聲明 Pod 需求。你還可以使用 kubectl 命令式命令建立 pod。我們將在後面的主題中看到這一點。
下面是一個建立 Nginx Web 伺服器 pod 的 Pod YAML 範例。此 YAML 只不過是 Pod 的聲明性期望狀態。
apiVersion: v1
kind: Pod
metadata:
name: web-server-pod
labels:
app: web-server
environment: production
annotations:
description: This pod runs the web server
spec:
containers:
- name: web-server
image: nginx:latest
ports:
- containerPort: 80
讓我們了解一下這個 pod YAML。一旦你理解了基本的 YAML,你就會更容易地使用 pod 和關聯的物件,如部署、守護行程集、有狀態副本集等。
正如我們在 Kubernetes 物件部落格中所討論的,每個 Kubernetes 物件都有一些通用的參數集。這些值會根據我們正在建立的物件型別而變化。
讓我們看一下 Kubernetes pod 物件。
參數 | 描述 |
---|---|
apiVersion | pod 的 API 版本。在我們的例子中,它是v1 |
kind | 物件的種類。它是pod |
metadata | 後設資料用於唯一標識和描述 Pod |
lables(用於表示 Pod 的鍵值對集)。這類似於雲環境中的標記。每個物體都必須用標準標簽標記。它有助於對物件進行分組。 | |
– name (pod 的名稱) | |
– namespace (pod 的名稱空間) | |
– annotations (鍵值格式的附加數據) | |
spec | 在 'spec' 部份下,我們聲明了 pod 的所需狀態。這些是我們想要在 pod 內執行的容器的規格。 |
containers | 在容器下,我們聲明 pod 內容器的所需狀態。貨櫃影像、暴露的埠等。 |
現在,我們已經檢視了一個基本的 Pod YAML 清單。請務必註意,此清單支持許多參數。我們將透過動手實踐的方法逐步探索這些額外的參數。
現在我們已經對 Pod 有了基本的了解,讓我們建立一個 Pod。
建立 Pod(實際範例)
你可以透過兩種方式建立 Pod
使用 kubectl 命令式命令: 主要用於學習和測試目的。命令式命令有其自身的局限性。 聲明式方法:使用 YAML 清單。在處理計畫時,YAML 清單用於部署 Pod。 讓我們看看這兩個選項。我們將使用以下內容建立一個 NGINX pod
pod 的名稱是 web-server-pod
它應該有標簽 app: web-server 和環境: production
添加註釋以描述 pod。
使用 nginx:1.14.2 容器映像。
暴露容器埠 80。
方法一:使用 kubectl 命令建立 pod
註意:當你參加 Kubernetes 認證時,Kubectl 命令式命令非常重要。
對於討論的 pod 要求,這裏是 kubectl 命令。
kubectl run web-server-pod \
--image=nginx:1.14.2 \
--restart=Never \
--port=80 \
--labels=app=web-server,environment=production \
--annotations description="This pod runs the web server"
在這裏,pod 部署在預設名稱空間中。你可以獲取已部署的 pod kubectl 的狀態。
kubectl get pods
部署 Pod 後,你將看到 Pod 正在執行的狀態,如下所示。在我們的範例中,pod 內部只有一個容器。所以它顯示 1/1 準備好並正在執行。
描述 Pod
如果你想了解正在執行的 pod 的所有細節,你可以使用 kubectl 來描述 pod。
kubectl describe pod web-server-pod
在以下輸出中,你可以看到有關 Pod 的所有詳細資訊。其 IP 地址、名稱空間、容器詳細資訊、QoS 類等。
以下是 describe 命令顯示的所有重要 pod 資訊的圖形檢視。
現在,讓我們使用以下命令刪除 pod。
kubectl delete pod web-server-pod
方法二:使用聲明式 YAML 建立 Pod
在處理實際計畫時,你將不得不主要透過聲明式方法建立 pod。
讓我們看看如何使用 YAML 清單建立 pod。
使用以下內容建立名為 nginx.yaml 的檔。
apiVersion: v1
kind: Pod
metadata:
name: web-server-pod
labels:
app: web-server
environment: production
annotations:
description: This pod runs the web server
spec:
containers:
- name: web-server
image: nginx:1.14.2
ports:
- containerPort: 80
現在,要部署清單,你需要使用檔名執行以下 kubectl 命令。
kubectl create -f nginx.yaml
我們是否應該記住每個參數來建立 YAML?不。可以使用 –dry-run 標誌建立 YAML 檔。
下面是一個範例。
kubectl run nginx-pod --image=nginx:1.14.2 --dry-run=client -o yaml
你可以透過將試執行輸出重新導向到檔來保存 YAML 輸出。
kubectl run nginx-pod --image=nginx:1.14.2 --dry-run=client -o yaml > nginx-pod.yaml
存取在 Pod 中執行的應用程式
現在我們有一個帶有 Nginx Web 伺服器的正在執行的 pod。整個想法是部署和存取在 pod 內部執行的應用程式。
Kubectl 提供了一個 port-forward 命令,用於從本地工作站存取 Kubernetes 集群中正在執行的 pod。
我們有一個名為 web-server-pod 的正在執行的 pod。讓我們透過 port-forward 命令存取它。
kubectl port-forward pod/web-server-pod 8080:80
你應該看到如下所示的輸出。
kubectl 埠轉發以存取本地系統中的 pod 現在,如果你轉到瀏覽器並存取 http://localhost:8080,你應該會看到 Nginx 主頁,如下所示。該網頁由我們的 Nginx Web 伺服器 pod 提供服務。
現在,你可以透過按 CTRL+C 來斷開埠轉發。
以下是執行 kubectl port-forward 時發生的情況
Kubectl 繫結了本地系統中的指定埠。在我們的例子中,它是 8080。
然後,它與 Kubernetes 集群 API 通訊,以建立到所需節點的隧道(單個 HTTP 連線),然後到指定的 pod 和容器埠,即 80。
註意:kubectl 埠轉發更像是一個偵錯工具。你需要使用 Kubernetes Service 物件來公開在 Pod 中執行的應用程式。我們將在另一篇部落格中實際了解 Kubernetes 服務概念
存取 Pod Shell
我們已經學習了如何存取在 pod 內部執行的應用程式。
現在,如果你想存取 pod shell,該怎麽辦?
在許多用例中,你需要對 pod 進行終端存取。一個主要用例是偵錯和故障排除。
這就是 kubectl exec 命令派上用場的地方。
你可以使用以下命令存取 web-server-pod 的 shell。
kubectl exec -it web-server-pod -- /bin/sh
在以下輸出中,我正在 pod 內執行 whoami 命令。
註意: 容器映像通常設計得非常小,因此你可能會發現無法執行在普通 Linux 系統上執行的所有命令。此限制取決於映像的生成方式以及容器映像中包含的實用程式
Pod 生命周期
你應該了解的有關 Pod 的另一個重要概念是其生命周期。
Pod 通常由 ReplicaSet 控制器、部署控制器等控制器管理。使用 YAML 建立單個 pod 時,它不受任何控制器的管理。在這兩種情況下,Pod 都會經歷不同的生命周期階段。
以下是 Pod 生命周期階段。
Pending:表示 Pod 建立請求成功,但是,計劃正在進行中。例如,它正在下載容器映像。
Running:Pod 已成功執行並按預期執行。例如,pod 是服務客戶端請求。
Succeeded:Pod 內的所有容器都已成功終止。例如,成功完成 CronJob 物件。
Failed:所有 Pod 都已終止,但至少有一個容器因失敗而終止。例如,由於配置問題,在 Pod 內部執行的應用程式無法啟動,並且容器以非零結束程式碼結束。
Unknown:Pod 的狀態未知。例如,集群無法監控 Pod 的狀態。
如果描述 Pod,則可以檢視 Pod 的階段。下面是一個範例。
如果你想了解更多資訊,請檢視有關 pod 生命周期的詳細部落格。
Pod 特性
我們已經部署了一個簡單的 Nginx pod,只需非常少的配置。但是,Pod 有很多資源管理、配置、機密、可用性、安全性等功能。
如果你是初學者,一次性學習所有這些概念將是矯枉過正的。在實際用例中使用與 pod 相關的物件(如部署)時,學習所有這些概念更有意義。
此外,你需要透過實際用例詳細了解每個功能。
以下是與 pod 相關的主要功能。
資源請求和限制:Pod CPU/記憶體分配
標簽:附加到 Pod 的鍵值對,用於對資源進行分類。
Selectors: 根據標簽對資源進行分組。
Liveness, Readiness, and Startup Probes: 容器執行狀況檢查
ConfigMaps:用於配置管理
Secrets:用於機密管理
Volumes:永續性數據儲存
Init Containers:在主容器之前執行的容器。
臨時容器:添加到 Pod 的臨時容器,用於偵錯或故障排除。
服務帳戶: 限制對 Kubernetes 物件和資源的存取。
SecurityContext:主機許可權和特權。
關聯性和反關聯性規則:跨節點的 Pod 放置控制
Pod 搶占和優先級:設定 pod 排程和逐出的優先級。
Pod 中斷預算:在自願中斷期間需要執行的 Pod 副本的最小數量。
貨櫃生命周期勾點:根據 Pod 的生命周期階段更改執行自訂指令碼。
全面的 Pod YAML 配置
註意:我給出了以下範例僅供參考。不要被所有參數所淹沒。它並不像看起來那麽復雜。一旦你了解了基礎知識,這將很容易。
如果添加我上面列出的 Pod 功能,你將獲得一個全面的 Pod YAML 配置,如下所示。此外,這些選項將與 Deployment、Statefulset 等物件一起使用。
apiVersion: v1
kind: Pod
metadata:
name: web-server-pod
spec:
initContainers:
- name: init-myservice
image: busybox:1.28
command: ['sh', '-c', 'echo "Init container started!"']
containers:
- name: web-server
image: nginx:latest
ports:
- containerPort: 80
volumeMounts:
- name: shared-data
mountPath: /usr/share/nginx/html
- name: secret-volume
mountPath: /etc/my-secret
- name: configmap-volume
mountPath: /etc/config
securityContext:
capabilities:
add: ["NET_ADMIN", "SYS_TIME"]
resources:
requests:
memory: "64Mi"
cpu: "250m"
limits:
memory: "128Mi"
cpu: "500m"
readinessProbe:
httpGet:
path: /index.html
port: 80
initialDelaySeconds: 5
periodSeconds: 5
livenessProbe:
httpGet:
path: /index.html
port: 80
initialDelaySeconds: 15
periodSeconds: 20
startupProbe:
httpGet:
path: /index.html
port: 80
failureThreshold: 30
periodSeconds: 10
lifecycle:
postStart:
exec:
command: ["/bin/sh", "-c", "echo 'PostStart'"]
preStop:
exec:
command: ["/bin/sh", "-c", "echo 'PreStop'"]
serviceAccountName: nginx-service-account
securityContext:
runAsUser: 1000
runAsGroup: 3000
fsGroup: 2000
shareProcessNamespace: true
volumes:
- name: shared-data
emptyDir: {}
- name: secret-volume
secret:
secretName: nginx-secret
- name: configmap-volume
configMap:
name: nginx-configmap
Pod 關聯物件
在 Kubernetes 上執行應用程式時,我們不會執行單個 pod。因為 Kubernetes 是關於擴充套件和維護 Pod 可用性的。
因此,如果你執行單個 pod,它將是單點故障。因為 Pod 本身是不能直接縮放的。
正如我們在 Kubernetes 架構中所討論的,我們需要像 Replicaset 這樣的控制器來確保所需數量的 pod 始終處於執行狀態。
Kubernetes 具有與不同用例的 Pod 關聯的不同型別的物件。
以下是與 Pod 關聯的重要物件。
Replicaset:維護一組穩定的 Pods 副本在任何給定時間執行。
Deployment:執行無狀態應用程式,如 Web 伺服器、API 等
StatefulSets:執行分布式資料庫等有狀態應用程式。
Daemonsets: 在所有 Kubernetes 節點上執行代理。
Jobs:用於批次處理
CronJobs的:計劃作業
結論
在本文章中,我們了解了 Kubernetes Pod 的所有核心概念。正如我在介紹中提到的,當涉及到 kubernetes 生產級實作時,pod 有很多特性。
在接下來的系列部落格中,我們將詳細介紹每個 Pod 功能和關聯的物件。