建立靜態 Pod

靜態 Pod 由特定節點上的 kubelet daemon 直接管理,而沒有觀察它們的 API 伺服器。與由控制平面管理的 Pod(例如,Deployment)不同;相反地,kubelet 監看每個靜態 Pod(並在失敗時重新啟動它)。

靜態 Pod 始終綁定到特定節點上的單個 Kubelet

kubelet 會自動嘗試在 Kubernetes API 伺服器上為每個靜態 Pod 建立 鏡像 Pod。這表示在節點上運行的 Pod 在 API 伺服器上可見,但無法從那裡控制。Pod 名稱將以節點主機名稱為後綴,並帶有前導連字符。

開始之前

你需要有一個 Kubernetes 叢集,並且必須設定 kubectl 命令列工具以與你的叢集通訊。建議在至少有兩個節點且不充當控制平面主機的叢集上運行本教學課程。如果你還沒有叢集,你可以使用 minikube 建立一個,或者你可以使用這些 Kubernetes 實驗環境之一

要檢查版本,請輸入 kubectl version

本頁假設你正在使用 CRI-O 運行 Pod,並且你的節點正在運行 Fedora 作業系統。其他發行版或 Kubernetes 安裝的說明可能會有所不同。

建立靜態 Pod

你可以使用 檔案系統託管的組態檔Web 託管的組態檔 來設定靜態 Pod。

檔案系統託管的靜態 Pod 清單檔

清單檔是特定目錄中 JSON 或 YAML 格式的標準 Pod 定義。使用 kubelet 組態檔 中的 staticPodPath: <目錄> 欄位,它會定期掃描目錄並在 YAML/JSON 檔案出現/消失時建立/刪除靜態 Pod。請注意,kubelet 在掃描指定的目錄時會忽略以點開頭的檔案。

例如,以下是如何將簡單的 Web 伺服器作為靜態 Pod 啟動

  1. 選擇你要在其中運行靜態 Pod 的節點。在本範例中,它是 my-node1

    ssh my-node1
    
  2. 選擇一個目錄,例如 /etc/kubernetes/manifests,並在那裡放置一個 Web 伺服器 Pod 定義,例如 /etc/kubernetes/manifests/static-web.yaml

    # Run this command on the node where kubelet is running
    mkdir -p /etc/kubernetes/manifests/
    cat <<EOF >/etc/kubernetes/manifests/static-web.yaml
    apiVersion: v1
    kind: Pod
    metadata:
      name: static-web
      labels:
        role: myrole
    spec:
      containers:
        - name: web
          image: nginx
          ports:
            - name: web
              containerPort: 80
              protocol: TCP
    EOF
    
  3. 設定該節點上的 kubelet,以在 kubelet 組態檔 中設定 staticPodPath 值。
    請參閱 透過組態檔設定 Kubelet 參數 以取得更多資訊。

    另一種替代且已棄用的方法是設定該節點上的 kubelet,以使用命令列引數在本機尋找靜態 Pod 清單檔。要使用已棄用的方法,請使用以下命令列引數啟動 kubelet
    --pod-manifest-path=/etc/kubernetes/manifests/ 引數。

  4. 重新啟動 kubelet。在 Fedora 上,你將運行

    # Run this command on the node where the kubelet is running
    systemctl restart kubelet
    

Web 託管的靜態 Pod 清單

Kubelet 定期下載由 --manifest-url=<URL> 引數指定的文件,並將其解譯為包含 Pod 定義的 JSON/YAML 文件。與 檔案系統託管的清單 的運作方式類似,kubelet 會排程重新提取清單。如果靜態 Pod 列表有變更,kubelet 會套用這些變更。

要使用此方法

  1. 建立一個 YAML 檔案並將其儲存在網路伺服器上,以便您可以將該檔案的 URL 傳遞給 kubelet。

    apiVersion: v1
    kind: Pod
    metadata:
      name: static-web
      labels:
        role: myrole
    spec:
      containers:
        - name: web
          image: nginx
          ports:
            - name: web
              containerPort: 80
              protocol: TCP
    
  2. 在您選取的節點上設定 kubelet 以使用此網路清單,方法是使用 --manifest-url=<manifest-url> 執行它。在 Fedora 上,編輯 /etc/kubernetes/kubelet 以包含此行

    KUBELET_ARGS="--cluster-dns=10.254.0.10 --cluster-domain=kube.local --manifest-url=<manifest-url>"
    
  3. 重新啟動 kubelet。在 Fedora 上,你將運行

    # Run this command on the node where the kubelet is running
    systemctl restart kubelet
    

觀察靜態 pod 行為

當 kubelet 啟動時,它會自動啟動所有已定義的靜態 Pod。由於您已定義一個靜態 Pod 並重新啟動 kubelet,因此新的靜態 Pod 應該已經在執行中。

您可以透過執行(在節點上)來檢視正在執行的容器(包括靜態 Pod)

# Run this command on the node where the kubelet is running
crictl ps

輸出可能如下所示

CONTAINER       IMAGE                                 CREATED           STATE      NAME    ATTEMPT    POD ID
129fd7d382018   docker.io/library/nginx@sha256:...    11 minutes ago    Running    web     0          34533c6729106

您可以在 API 伺服器上看到鏡像 Pod

kubectl get pods
NAME                  READY   STATUS    RESTARTS        AGE
static-web-my-node1   1/1     Running   0               2m

標籤 從靜態 Pod 傳播到鏡像 Pod。您可以像平常一樣透過 選取器 等使用這些標籤。

如果您嘗試使用 kubectl 從 API 伺服器刪除鏡像 Pod,kubelet 不會 移除靜態 Pod

kubectl delete pod static-web-my-node1
pod "static-web-my-node1" deleted

您可以看到 Pod 仍在執行中

kubectl get pods
NAME                  READY   STATUS    RESTARTS   AGE
static-web-my-node1   1/1     Running   0          4s

回到執行 kubelet 的節點上,您可以嘗試手動停止容器。您會看到,過一段時間後,kubelet 會注意到並自動重新啟動 Pod

# Run these commands on the node where the kubelet is running
crictl stop 129fd7d382018 # replace with the ID of your container
sleep 20
crictl ps
CONTAINER       IMAGE                                 CREATED           STATE      NAME    ATTEMPT    POD ID
89db4553e1eeb   docker.io/library/nginx@sha256:...    19 seconds ago    Running    web     1          34533c6729106

一旦您識別出正確的容器,您可以使用 crictl 取得該容器的日誌

# Run these commands on the node where the container is running
crictl logs <container_id>
10.240.0.48 - - [16/Nov/2022:12:45:49 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.47.0" "-"
10.240.0.48 - - [16/Nov/2022:12:45:50 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.47.0" "-"
10.240.0.48 - - [16/Nove/2022:12:45:51 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.47.0" "-"

若要瞭解更多關於如何使用 crictl 進行偵錯的資訊,請造訪 使用 crictl 偵錯 Kubernetes 節點

動態新增和移除靜態 pod

正在執行的 kubelet 定期掃描設定的目錄(在我們的範例中為 /etc/kubernetes/manifests)以尋找變更,並在檔案出現在此目錄中/從此目錄中消失時新增/移除 Pod。

# This assumes you are using filesystem-hosted static Pod configuration
# Run these commands on the node where the container is running
#
mv /etc/kubernetes/manifests/static-web.yaml /tmp
sleep 20
crictl ps
# You see that no nginx container is running
mv /tmp/static-web.yaml  /etc/kubernetes/manifests/
sleep 20
crictl ps
CONTAINER       IMAGE                                 CREATED           STATE      NAME    ATTEMPT    POD ID
f427638871c35   docker.io/library/nginx@sha256:...    19 seconds ago    Running    web     1          34533c6729106

下一步

上次修改時間:2023 年 12 月 08 日 早上 7:08 PST:變更以反映 pod-manifest-path 引數的棄用 (8a0a983d32)