建立靜態 Pod
靜態 Pod 由特定節點上的 kubelet daemon 直接管理,而沒有觀察它們的 API 伺服器。與由控制平面管理的 Pod(例如,Deployment)不同;相反地,kubelet 監看每個靜態 Pod(並在失敗時重新啟動它)。
靜態 Pod 始終綁定到特定節點上的單個 Kubelet。
kubelet 會自動嘗試在 Kubernetes API 伺服器上為每個靜態 Pod 建立 鏡像 Pod。這表示在節點上運行的 Pod 在 API 伺服器上可見,但無法從那裡控制。Pod 名稱將以節點主機名稱為後綴,並帶有前導連字符。
注意
如果你正在運行叢集式 Kubernetes,並且正在使用靜態 Pod 在每個節點上運行 Pod,你應該可能改用 DaemonSet。注意
靜態 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 啟動
選擇你要在其中運行靜態 Pod 的節點。在本範例中,它是
my-node1
。ssh my-node1
選擇一個目錄,例如
/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
設定該節點上的 kubelet,以在 kubelet 組態檔 中設定
staticPodPath
值。
請參閱 透過組態檔設定 Kubelet 參數 以取得更多資訊。另一種替代且已棄用的方法是設定該節點上的 kubelet,以使用命令列引數在本機尋找靜態 Pod 清單檔。要使用已棄用的方法,請使用以下命令列引數啟動 kubelet
--pod-manifest-path=/etc/kubernetes/manifests/
引數。重新啟動 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 會套用這些變更。
要使用此方法
建立一個 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
在您選取的節點上設定 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>"
重新啟動 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
注意
crictl
輸出映像檔 URI 和 SHA-256 總和檢查碼。NAME
看起來會更像:docker.io/library/nginx@sha256:0d17b565c37bcbd895e9d92315a05c1c3c9a29f762b011a10c54a66cd53c9b31
。您可以在 API 伺服器上看到鏡像 Pod
kubectl get pods
NAME READY STATUS RESTARTS AGE
static-web-my-node1 1/1 Running 0 2m
注意
請確保 kubelet 具有在 API 伺服器中建立鏡像 Pod 的權限。否則,API 伺服器會拒絕建立請求。標籤 從靜態 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