什么是 Kubernetes Pod?用實(shí)際例子解釋
Kubernetes(簡(jiǎn)稱K8S)是一個(gè)開源的容器編排平臺(tái),用于自動(dòng)化容器化應(yīng)用的部署、擴(kuò)展和管理。在Kubernetes中,Pod是最小的部署單元。理解Pod的概念對(duì)于掌握Kubernetes至關(guān)重要。本篇文章將詳細(xì)解釋什么是Kubernetes Pod,并通過實(shí)際例子幫助讀者更好地理解這一概念。

一、什么是 Kubernetes Pod?
在了解 Kubernetes Pod 概念之前,先來了解容器容器,眾所周知,是一個(gè)自包含的環(huán)境,用于打包應(yīng)用程序及其依賴項(xiàng)。通常,一個(gè)容器運(yùn)行單個(gè)進(jìn)程(盡管也有方法可以運(yùn)行多個(gè)進(jìn)程)。每個(gè)容器都有一個(gè)IP地址,并且可以附加存儲(chǔ)卷以及控制CPU和內(nèi)存資源等。這些都是通過命名空間和控制組(namespaces and control groups)的概念實(shí)現(xiàn)的。
Kubernetes 是一個(gè)用于部署、擴(kuò)展和管理容器化應(yīng)用程序的容器編排系統(tǒng),它有自己運(yùn)行容器的方式,我們稱之為 Pod。Pod 是 Kubernetes 中最小的可部署單元,代表一個(gè)應(yīng)用程序的單個(gè)實(shí)例。
例如,如果你想運(yùn)行 Nginx 應(yīng)用程序,你可以將它運(yùn)行在一個(gè) Pod 中。
1.那么,Pod 與容器有何不同呢?
容器是一個(gè)單獨(dú)的單位。然而,Pod 可以包含多個(gè)容器。你可以將 Pod 想象成一個(gè)可以同時(shí)容納一個(gè)或多個(gè)容器的盒子。
Pod 提供了更高層次的抽象,允許你將多個(gè)容器作為一個(gè)單元進(jìn)行管理。在這里,每個(gè)容器不再單獨(dú)獲得 IP 地址,而是 Pod 獲得一個(gè)唯一的 IP 地址,并且運(yùn)行在 Pod 內(nèi)的容器通過 localhost 在不同端口上相互連接。

這意味著 Kubernetes Pod 內(nèi)的容器共享以下內(nèi)容:
- 網(wǎng)絡(luò)命名空間:Pod 內(nèi)的所有容器通過 localhost 進(jìn)行通信。
- IPC 命名空間:所有容器使用共享的進(jìn)程間通信命名空間。
- UTS 命名空間:所有容器共享相同的主機(jī)名。
2.Pod 內(nèi)的容器不共享什么?
- 默認(rèn)情況下,PID 命名空間不共享,但 Kubernetes 提供選項(xiàng),通過 shareProcessNamespace 選項(xiàng)在 Pod 內(nèi)啟用進(jìn)程共享。
- 掛載命名空間不在容器之間共享。每個(gè)容器都有自己的私有文件系統(tǒng)和目錄。然而,Pod 掛載的存儲(chǔ)卷在容器之間共享。
總的來說,你需要了解以下關(guān)于 Pod 的信息:
- Pod 是 Kubernetes 中最小的可部署單元。
- Pod 具有短暫性;它們可以被創(chuàng)建、刪除和更新。
- 一個(gè) Pod 可以有多個(gè)容器;沒有限制一個(gè) Pod 中可以運(yùn)行多少個(gè)容器。
- 每個(gè) Pod 都有一個(gè)唯一的 IP 地址。
- Pod 之間通過 IP 地址進(jìn)行通信。
- Pod 內(nèi)的容器使用 localhost 通過不同的端口進(jìn)行連接。
- 在 Pod 內(nèi)運(yùn)行的容器應(yīng)該有不同的端口號(hào),以避免端口沖突。
- 你可以為 Pod 內(nèi)運(yùn)行的每個(gè)容器設(shè)置 CPU 和內(nèi)存資源。
- Pod 內(nèi)的容器共享相同的存儲(chǔ)卷掛載。
- Pod 內(nèi)的所有容器都調(diào)度到同一個(gè)節(jié)點(diǎn)上;它不能跨多個(gè)節(jié)點(diǎn)。
- 如果有多個(gè)容器,在 Pod 啟動(dòng)期間,所有主要容器并行啟動(dòng)。而 Pod 內(nèi)的 init 容器按順序運(yùn)行。
二、Pod YAML
現(xiàn)在我們已經(jīng)對(duì) Pod 有了基本的了解,接下來看看如何定義 Pod。Pod 是原生的 Kubernetes 對(duì)象,如果你想創(chuàng)建一個(gè) Pod,需要以 YAML 格式聲明 Pod 的需求。你也可以使用 kubectl 命令創(chuàng)建 Pod,這將在后面的主題中介紹。
以下是一個(gè)創(chuàng)建 Nginx Web 服務(wù)器 Pod 的 Pod YAML 示例。這個(gè) YAML 文件只是一個(gè) Pod 的聲明性期望狀態(tài)。
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讓我們來了解這個(gè) Pod YAML。一旦你理解了基本的 YAML 格式,就會(huì)更容易操作 Pod 和相關(guān)對(duì)象,如 Deployment、DaemonSet、StatefulSet 等。
每個(gè) Kubernetes 對(duì)象都有一些通用的參數(shù)。這些參數(shù)的值會(huì)根據(jù)我們創(chuàng)建的對(duì)象類型而變化。讓我們看看 Kubernetes Pod 對(duì)象。

我們現(xiàn)在已經(jīng)看到了一個(gè)基本的Pod YAML清單。需要注意的是,這個(gè)清單文件支持許多參數(shù)。我們將逐步探索這些額外的參數(shù)與實(shí)踐的方法。
現(xiàn)在我們對(duì)Pod有了一些基本的了解,讓我們創(chuàng)建一個(gè)Pod。
三、創(chuàng)建Pod
你可以用兩種方法創(chuàng)建pod:
- 使用kubectl命令式命令:主要用于學(xué)習(xí)和測(cè)試目的。命令式命令有其自身的局限性。
- 聲明式方法:使用YAML方式。在開發(fā)項(xiàng)目時(shí),YAML清單文件用于部署pods。
讓我們看看這兩個(gè)方式。我們將使用以下內(nèi)容創(chuàng)建一個(gè)NGINX pod:
- pod的名稱是web-server-pod
- 它應(yīng)該有標(biāo)簽:app: web-server和environment: production
- 添加一個(gè)注釋來描述pod。
- 使用nginx:1.14.2容器鏡像。
- 暴露集裝箱端口80。
方法1:使用Kubectl命令創(chuàng)建Pod
對(duì)于討論的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被部署在默認(rèn)命名空間中。你可以獲得部署的pod kubectl的狀態(tài)。
kubectl get pods部署pod后,您將看到pod的運(yùn)行狀態(tài),如下所示。在我們的例子中,pod中只有一個(gè)容器。所以它顯示1/1就緒并運(yùn)行。

如果你想知道運(yùn)行pod的所有細(xì)節(jié),可以使用kubectl describe pod。
kubectl describe pod web-server-pod在下面的輸出中,你可以看到pod的所有細(xì)節(jié)。它的IP地址、命名空間、容器細(xì)節(jié)、QoS類等。

這里是描述命令顯示的所有重要pod信息的圖形視圖。

現(xiàn)在讓我們使用以下命令刪除pod。
kubectl delete pod web-server-pod方法2:使用聲明式Y(jié)AML創(chuàng)建Pod
在實(shí)際項(xiàng)目中,你將不得不通過聲明的方法來創(chuàng)建pods。
讓我們看看如何使用YAML清單文件創(chuàng)建pod。
創(chuàng)建名為nginx的文件。內(nèi)容如下:
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現(xiàn)在,要部署清單文件,您需要使用文件名執(zhí)行以下kubectl命令:
kubectl create -f nginx.yaml我們應(yīng)該記住創(chuàng)建YAML時(shí)的每個(gè)參數(shù)嗎?不用。你可以使用--dry-run標(biāo)志創(chuàng)建YAML文件:
kubectl run nginx-pod --image=nginx:1.14.2 --dry-run=client -o yaml四、訪問在 Pod 中運(yùn)行的應(yīng)用程序
現(xiàn)在我們有了一個(gè)運(yùn)行中的pod和Nginx web服務(wù)器。整個(gè)想法是部署和訪問在pod中運(yùn)行的應(yīng)用程序。
Kubectl提供了一個(gè)port-forward命令來從本地工作站訪問Kubernetes集群中運(yùn)行的pods。
我們有一個(gè)名為web-server-pod的運(yùn)行pod。讓我們通過port-forward命令訪問它。

現(xiàn)在,如果您打開瀏覽器并訪問http://localhost:8080,您應(yīng)該會(huì)看到如下所示的Nginx主頁。網(wǎng)頁由我們的Nginx web服務(wù)器pod提供服務(wù)。

現(xiàn)在你可以按CTRL+C斷開端口轉(zhuǎn)發(fā)。
以下是運(yùn)行kubectl port-forward時(shí)發(fā)生的情況:
- Kubectl綁定本地系統(tǒng)中的指定端口。在我們的例子中是8080。
- 然后,它與Kubernetes集群API通信,以建立到所需節(jié)點(diǎn)的隧道(單個(gè)HTTP連接),然后到指定的pod和容器端口(80)。
注意:kubectl端口轉(zhuǎn)發(fā)更多的是一個(gè)調(diào)試實(shí)用程序。你需要使用Kubernetes服務(wù)對(duì)象來公開在pod中運(yùn)行的應(yīng)用程序。我們將在另一個(gè)博客中實(shí)際地研究Kubernetes service 的概念。
五、訪問 Pod Shell
我們已經(jīng)學(xué)習(xí)了如何訪問在pod中運(yùn)行的應(yīng)用程序。
現(xiàn)在如果你想進(jìn)入Pod shell怎么辦?
有許多用例需要終端訪問pod。一個(gè)主要用例是調(diào)試和故障排除。
這就是kubectl exec命令派上用場(chǎng)的地方。
您可以使用以下命令訪問web-server-pod的shell。
kubectl exec -it web-server-pod -- /bin/sh在下面的輸出中,我正在pod內(nèi)執(zhí)行whoami命令。

六、Pod 的生命周期
關(guān)于pod你應(yīng)該知道的另一個(gè)重要概念是它的生命周期。pod通常由ReplicaSet controller、Deployment controller等控制器管理。當(dāng)您使用YAML創(chuàng)建單個(gè)pod時(shí),它不受任何控制器的管理。在這兩種情況下,pod都會(huì)經(jīng)歷不同的生命周期階段。Pod的生命周期包括以下幾個(gè)階段:
- Pending:Pod已被Kubernetes API Server接受,但還沒有被調(diào)度到Node上。
- Running:Pod已被調(diào)度到Node上,所有容器都已啟動(dòng)。
- Succeeded:Pod中的所有容器都正常終止,且不會(huì)再被重啟。
- Failed:Pod中的某個(gè)容器意外終止,且不會(huì)再被重啟。
- Unknown:由于某種原因,無法獲取Pod的狀態(tài)。
如果你通過kubectl describe pod命令查看Pod的詳細(xì)信息,你可以看到Pod的狀態(tài)。這里有一個(gè)例子。

七、Pod 功能
我們已經(jīng)部署了一個(gè)簡(jiǎn)單的Nginx pod,配置非常少。但是,pod具有許多用于資源管理、配置、機(jī)密、可用性、安全性等方面的特性。
如果你是初學(xué)者,一次性學(xué)習(xí)所有這些概念將是多余的。在使用與pod相關(guān)的對(duì)象(如具有實(shí)際用例的Deployment)時(shí),學(xué)習(xí)所有這些概念更有意義。
此外,您需要通過實(shí)際用例詳細(xì)了解每個(gè)特性。
以下是與pod相關(guān)的主要特性:
- Resource Requests and Limits: Pod CPU/內(nèi)存分配
- Labels: 附加在pod上的鍵值對(duì),用于對(duì)資源進(jìn)行分類。
- Selectors: 根據(jù)標(biāo)簽對(duì)資源進(jìn)行分組。
- Liveness, Readiness和Startup Probes: 容器運(yùn)行狀況檢查
- ConfigMaps: 用于配置管理
- Secrets: 用于秘密管理
- Volumes: 持久數(shù)據(jù)存儲(chǔ)
- Init Containers: 在主容器之前運(yùn)行的容器。
- Ephemeral Containers: 添加到pod中的臨時(shí)容器,用于調(diào)試或故障排除。
- Service Account: :用于限制對(duì)Kubernetes對(duì)象和資源的訪問。
- SecurityContext:主機(jī)權(quán)限和特權(quán)。
- Affinity and Anti-Affinity Rules: 跨節(jié)點(diǎn)的Pod放置控制。
- Pod Preemption & Priority: 設(shè)置Pod調(diào)度和驅(qū)逐的優(yōu)先級(jí)。
- Pod Disruption Budget: 在自愿中斷期間需要運(yùn)行的Pod副本的最小數(shù)量。
- Container Life Cycle Hooks:根據(jù)pod的生命周期階段變化執(zhí)行自定義腳本。
全面的 Pod YAML 配置
如果您添加我上面列出的pod特性,您將得到一個(gè)全面的pod YAML配置,如下所示。此外,這些選項(xiàng)將與Deployment、Statefulset等對(duì)象一起使用。
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 關(guān)聯(lián)對(duì)象
當(dāng)談到在Kubernetes上運(yùn)行應(yīng)用程序時(shí),我們不會(huì)運(yùn)行單個(gè)pod。因?yàn)镵ubernetes是關(guān)于擴(kuò)展和維護(hù)pod可用性的。
所以如果你運(yùn)行一個(gè)單獨(dú)的pod,它將是一個(gè)單點(diǎn)故障。因?yàn)镻od本身不能直接縮放。
正如我們?cè)贙ubernetes架構(gòu)中討論的那樣,我們需要像Replicaset這樣的控制器來確保始終運(yùn)行所需數(shù)量的pod。
針對(duì)不同的用例,Kubernetes有不同類型的對(duì)象與pod相關(guān)聯(lián)。

以下是與pod相關(guān)的重要對(duì)象:
- Replicaset: 維護(hù)一組穩(wěn)定的pod副本在任何給定時(shí)間運(yùn)行。
- Deployment: 運(yùn)行無狀態(tài)應(yīng)用程序,如web服務(wù)器、api等
- StatefulSets: 運(yùn)行有狀態(tài)的應(yīng)用程序,如分布式數(shù)據(jù)庫。
- Daemonsets: 在所有Kubernetes節(jié)點(diǎn)上運(yùn)行代理。
- Jobs: 用于批處理
- CronJobs: 計(jì)劃的作業(yè)
總結(jié)
Kubernetes Pod是容器編排的基本單元,包含一個(gè)或多個(gè)共享網(wǎng)絡(luò)和存儲(chǔ)的容器。通過理解Pod的概念和生命周期,我們可以更有效地在Kubernetes中部署和管理應(yīng)用。本文通過一個(gè)簡(jiǎn)單的Nginx Pod示例展示了如何創(chuàng)建和訪問Pod,希望能幫助讀者更好地理解Kubernetes Pod的基本原理。




























