1. 程式人生 > 其它 >K8s 中什麼是靜態 pod (static pod)

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崩潰時重啟該podkubelete也無法對他們進行健康檢查。靜態 pod 始終繫結在某一個kubelet,並且始終執行在同一個節點上。kubelet會自動為每一個靜態 pod 在 Kubernetes 的 apiserver 上建立一個映象 Pod(Mirror Pod),因此我們可以在 apiserver 中查詢到該 pod,但是不能通過 apiserver 進行控制(例如不能刪除)。

建立靜態 Pod 有兩種方式:配置檔案和 HTTP 兩種方式

配置檔案

配置檔案就是放在特定目錄下的標準的 JSON 或 YAML 格式的 pod 定義檔案。用kubelet --pod-manifest-path=<thedirectory>

來啟動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。