掌握這些Kubernetes Pod技巧,成為企業必備技能人才
Kubernetes Pod 是什么?
Kubernetes Pod 是 Kubernetes 應用的基本執行單元。可以把它想象成應用程序運行的獨特環境,封裝了一個或多個應用容器以及共享的存儲/網絡資源。Kubernetes 有很多封裝服務、端點和其他實體的概念,但歸根結底一個 Pod 是你的代碼運行的地方。
Kubernetes Pod 和容器的區別
從概念上來說,Pod 可以和 Docker Compose 中的容器進行比較。在與 Docker Compose 相比時,Pod 在 Kubernetes 中扮演的角色與容器在 Docker Compose 中扮演的角色相同,但 Pod 實際上是一種對一個或多個容器的抽象,具有相關的網絡和存儲配置。Pod 可以包含幾個容器,但是最佳實踐是有一個運行應用代碼的主容器,以及 0 個或多個提供應用額外功能(如日志、監控和網絡)的支持容器,這種方式稱為 Sidecar,這些支持容器稱為 sidecar 容器。
Kubernetes Pod 和節點的區別
節點是 Kubernetes 中的工作器,Pod 就是在節點上運行。節點可以是虛擬的,例如 AWS EC2 實例,或者物理的計算機服務器。Pod 被分配到節點上,并在這些節點上運行,消耗節點提供給集群的容量。Pod 并非明確綁定到節點,它們是由 Kubernetes 控制平面分配的,如果有必要可以從一個節點移動到另一個節點。
Kubernetes Pod 和集群的區別
集群本質上是一組提供容量的節點、一組運行應用程序的 Pod 以及其他配置(如服務或入口控制器),所有這些都由 Kubernetes 控制平面管理。從概念上講,Pod 可以被視為 Kubernetes 運行應用程序的方式。
Kubernetes Pod 的工作方式
Pod 是在主容器(運行我們代碼的容器)之上的一層抽象,以及零個或多個支持或 sidecar 容器。除了容器之外,Pod 在 Kubernetes 集群中還有一個身份和幾個配置。
Pod 的生命周期
Pod 在其生命周期中可以經歷幾個階段:
- Pending:系統已接受該 Pod,但一個或多個容器尚未設置和運行。
- Running:該 Pod 已綁定到一個節點,其所有容器都已創建。
- Succeeded:Pod 中的所有容器已成功終止并不會重啟。該 Pod 不再綁定到一個節點和消耗資源。
- Failed:Pod 中至少有一個容器以失敗狀態終止。該 Pod 不再綁定到一個節點和消耗資源。
- Unknown:當由于與 Pod 主機節點的某些通信問題導致狀態不明確時。當一個節點無法向 Kubernetes 控制平面報告其狀態時,在該節點上運行的 Pod 會進入 Unknown 狀態。
Pod 如何管理多個容器
一個 Pod 可以封裝多個容器,確保它們共享相同的存儲和網絡命名空間。這使我們可以將應用程序幫助進程與主應用程序耦合在一起,而不必處理它們之間的網絡配置。在同一個 Pod 中運行的容器共享本地網絡和存儲。這通常用于 sidecar 容器,例如日志記錄、監控或網絡配置。例如,這樣配置一個具有多個容器的 Pod:
apiVersion: v1
kind: Pod
metadata:
name: myapp-pod
labels:
app: myapp
spec:
containers:
- name: myapp-container
image: busybox
command: ['sh', '-c', 'echo The app is running! && sleep 3600']
- name: log-container
image: busybox
command: ['sh', '-c', 'tail -f /dev/null']
這將在一個 Pod 中運行兩個容器,一個運行應用,另一個記錄日志。它們共享網絡和文件系統。這就是 Pod 的強大之處。
使用 Kubernetes 中的 Pod
Kubernetes 是一個復雜的平臺,運行生產負載需要比只定義一個包含容器的 Pod 更多的知識。以下是有效管理 Pod 需要理解的一些額外知識點。
Pod 更新和替換
直接更新正在運行的 Pod 不是一個好的實踐,因為它違反了 Pod 的不變性假設(本質上與容器的不變性相同)。事實上,Kubernetes 在 Pod 層面上執行這種不變性,這意味著它拒絕對 Pod 進行更新。相反,我們應該部署 Pod 的新版本,并平滑地將流量重定向到較新版本。如果這種部署是逐步進行的,每次替換一個 Pod(當為同一應用程序運行多個 Pod 時相關),這稱為滾動更新。如果部署一組全新的 Pod,將流量重定向到它們,驗證它們是否正常工作,然后才終止舊的 Pod,這稱為藍綠部署。
當創建一個 Deployment,其中包含一組 Pod 時,可以定義更新策略。例如,以下是如何定義滾動更新策略:
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp-deployment
spec:
replicas: 3
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
template:
...
這將逐步更新 Pod,每次更新一個,同時保持可用 Pod 數量至少為 2。
Pod 資源限制
可以為 Pod 定義 CPU 和內存請求和限制,以防止 Pod 消耗太多節點資源。例如:
resources:
requests:
memory: "64Mi"
cpu: "250m"
limits:
memory: "128Mi"
cpu: "500m"
這將請求 64MB 內存和 0.25 CPU 核心,并限制為 128MB 內存和 0.5 CPU 核心。了解這些概念將幫助我們在生產中安全可靠地運行 Pod。
Kubernetes 中的 Pod 存儲
Pod 僅具有短暫的存儲,這是通過工作內存實現的。可以使用 Persistent Volume 來創建持久存儲,并通過 Persistent Volume Claim 與 Pod 關聯。從概念上講,持久卷可以與節點進行比較:它們使底層資源(在這種情況下是存儲,而不是計算)可用于 Kubernetes 集群。Persistent Volume Claim 為 Pod 預留這些可用資源,與它們相關聯。這些 Persistent Volume Claim 可以作為卷關聯到 Pod 內的容器,并作為容器本地文件系統的一部分進行訪問。
重要的是,它們可以由 Pod 中的所有容器共享,允許在同一 Pod 中基于文件在容器之間進行通信。日志 sidecar 容器通常使用這種方法來從主容器讀取日志,并將其導出到像 AWS CloudWatch Logs 這樣的外部日志聚合器。
下面是如何定義一個 Persistent Volume Claim,并將其作為卷關聯到 Pod 中的一個容器:
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
containers:
- name: mypod
image: busybox
command: ['sh', '-c', 'echo Hello Kubernetes! > /mnt/vol1/hello-file']
volumeMounts:
- mountPath: /mnt/vol1
name: vol1
volumes:
- name: vol1
persistentVolumeClaim:
claimName: my-pvc
這將在 /mnt/vol1 路徑掛載 PVC my-pvc,容器可以在其中讀寫文件。使用持久卷可以確保Pod重新啟動時數據不會丟失。
Pod 網絡
每個 Pod 都在整個集群中分配一個唯一的 IP 地址,可以從集群內部訪問該地址。還可以定義服務,它允許通過單個 IP 地址或專用 DNS 名稱尋址同類 Pod 組(通常是 Deployment),并在這些 Pod 之間負載均衡流量。還可以定義 Ingress 來通過 Ingress Controller 將服務暴露到集群外部。Pod 之間默認是可以相互通信的,不需要額外的網絡配置。但是,有時可能需要進一步隔離 Pod 網絡。這可以通過 Kubernetes 網絡策略來實現,它允許根據標簽選擇器控制 Pod 之間的流量。
例如,以下網絡策略只允許具有 role=frontend 的 Pod 訪問具有 role=backend 的 Pod:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: backend-policy
spec:
podSelector:
matchLabels:
role: backend
ingress:
- from:
- podSelector:
matchLabels:
role: frontend
理解 Pod 網絡對于在 Kubernetes 中運行基于網絡的應用程序非常重要。主流的網絡模型包括 Flannel、Calico、Cilium 等。
總結
Kubernetes是一個非常強大的平臺,但這種強大也帶來了巨大的復雜性。Pod只是一個起點,但理解它們的工作方式對于掌握Kubernetes在Pod之上用于部署生產級負載的抽象和配置是必要的。
理解Pod的基礎知識,比如它們的生命周期、如何管理多個容器、存儲、資源限制等,是開始使用Kubernetes的關鍵第一步。一旦你理解了這些基礎知識,你就可以構建更復雜的應用程序部署,利用Kubernetes提供的服務發現、負載均衡、滾動更新等高級功能。