當前位置: 妍妍網 > 碼農

【運維幹貨分享】實際例子來解釋什麽是kubernetes中的pod

2024-08-24碼農

在本文章中,我透過實際範例和用例詳細介紹了 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 功能和關聯的物件。