K8s 中什么是靜態 pod (static pod)


本文轉載自:靜態 Pod · 從 Docker 到 Kubernetes 進階手冊 (qikqiak.com)

靜態 Pod

我們上節課給大家講解了 YAML 文件的使用,也手動的創建了一個簡單的 Pod,這節課開始我們就來深入的學習下我們的 Pod。在Kubernetes集群中除了我們經常使用到的普通的 Pod 外,還有一種特殊的 Pod,叫做Static Pod,就是我們說的靜態 Pod,靜態 Pod 有什么特殊的地方呢?

靜態 Pod 直接由特定節點上的kubelet進程來管理,不通過 master 節點上的apiserver。無法與我們常用的控制器Deployment或者DaemonSet進行關聯,它由kubelet進程自己來監控,當pod崩潰時重啟該podkubelet也無法對他們進行健康檢查。靜態 pod 始終綁定在某一個kubelet,並且始終運行在同一個節點上。 kubelet會自動為每一個靜態 pod 在 Kubernetes 的 apiserver 上創建一個鏡像 Pod(Mirror Pod),因此我們可以在 apiserver 中查詢到該 pod,但是不能通過 apiserver 進行控制(例如不能刪除)。

創建靜態 Pod 有兩種方式:配置文件和 HTTP 兩種方式

配置文件

配置文件就是放在特定目錄下的標准的 JSON 或 YAML 格式的 pod 定義文件。用kubelet --pod-manifest-path=<the directory>來啟動kubelet進程,kubelet 定期的去掃描這個目錄,根據這個目錄下出現或消失的 YAML/JSON 文件來創建或刪除靜態 pod。

比如我們在 node01 這個節點上用靜態 pod 的方式來啟動一個 nginx 的服務。我們登錄到node01節點上面,可以通過下面命令找到kubelet對應的啟動配置文件

$ systemctl status kubelet

配置文件路徑為:

$ /etc/systemd/system/kubelet.service.d/10-kubeadm.conf

打開這個文件我們可以看到其中有一條如下的環境變量配置: Environment="KUBELET_SYSTEM_PODS_ARGS=--pod-manifest-path=/etc/kubernetes/manifests --allow-privileged=true"

所以如果我們通過kubeadm的方式來安裝的集群環境,對應的kubelet已經配置了我們的靜態 Pod 文件的路徑,那就是/etc/kubernetes/manifests,所以我們只需要在該目錄下面創建一個標准的 Pod 的 JSON 或者 YAML 文件即可:

如果你的 kubelet 啟動參數中沒有配置上面的--pod-manifest-path參數的話,那么添加上這個參數然后重啟 kubelet 即可。

[root@ node01 ~] $ cat <<EOF >/etc/kubernetes/manifest/static-web.yaml apiVersion: v1 kind: Pod metadata: name: static-web labels: app: static spec: containers: - name: web image: nginx ports: - name: web containerPort: 80 EOF 

通過 HTTP 創建靜態 Pods

kubelet 周期地從–manifest-url=參數指定的地址下載文件,並且把它翻譯成 JSON/YAML 格式的 pod 定義。此后的操作方式與–pod-manifest-path=相同,kubelet 會不時地重新下載該文件,當文件變化時對應地終止或啟動靜態 pod。

靜態pods的動作行為

kubelet 啟動時,由--pod-manifest-path= or --manifest-url=參數指定的目錄下定義的所有 pod 都會自動創建,例如,我們示例中的 static-web。(可能要花些時間拉取nginx 鏡像,耐心等待…)

[root@node01 ~] $ docker ps
CONTAINER ID IMAGE         COMMAND  CREATED        STATUS         PORTS     NAMES
f6d05272b57e nginx:latest  "nginx"  8 minutes ago  Up 8 minutes             k8s_web.6f802af4_static-web-fk-node1_default_67e24ed9466ba55986d120c867395f3c_378e5f3c

現在我們通過kubectl工具可以看到這里創建了一個新的鏡像 Pod:

[root@node01 ~] $ kubectl get pods
NAME                       READY     STATUS    RESTARTS   AGE
static-web-my-node01        1/1       Running   0          2m

靜態 pod 的標簽會傳遞給鏡像 Pod,可以用來過濾或篩選。 需要注意的是,我們不能通過 API 服務器來刪除靜態 pod(例如,通過kubectl命令),kebelet 不會刪除它。

[root@node01 ~] $ kubectl delete pod static-web-my-node01
[root@node01 ~] $ kubectl get pods
NAME                       READY     STATUS    RESTARTS   AGE
static-web-my-node01        1/1       Running   0          12s

我們嘗試手動終止容器,可以看到kubelet很快就會自動重啟容器。

[root@node01 ~] $ docker ps
CONTAINER ID        IMAGE         COMMAND                CREATED       ...
5b920cbaf8b1        nginx:latest  "nginx -g 'daemon of   2 seconds ago ...

靜態pods的動態增加和刪除

運行中的kubelet周期掃描配置的目錄(我們這個例子中就是/etc/kubernetes/manifests)下文件的變化,當這個目錄中有文件出現或消失時創建或刪除pods。

[root@node01 ~] $ mv /etc/kubernetes/manifests/static-web.yaml /tmp
[root@node01 ~] $ sleep 20
[root@node01 ~] $ docker ps
// no nginx container is running
[root@node01 ~] $ mv /tmp/static-web.yaml  /etc/kubernetes/manifests
[root@node01 ~] $ sleep 20
[root@node01 ~] $ docker ps
CONTAINER ID        IMAGE         COMMAND                CREATED           ...
e7a62e3427f1        nginx:latest  "nginx -g 'daemon of   27 seconds ago

其實我們用 kubeadm 安裝的集群,master 節點上面的幾個重要組件都是用靜態 Pod 的方式運行的,我們登錄到 master 節點上查看/etc/kubernetes/manifests目錄:

[root@master ~]# ls /etc/kubernetes/manifests/
etcd.yaml  kube-apiserver.yaml  kube-controller-manager.yaml  kube-scheduler.yaml

現在明白了吧,這種方式也為我們將集群的一些組件容器化提供了可能,因為這些 Pod 都不會受到 apiserver 的控制,不然我們這里kube-apiserver怎么自己去控制自己呢?萬一不小心把這個 Pod 刪掉了呢?所以只能有kubelet自己來進行控制,這就是我們所說的靜態 Pod。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM