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
崩潰時重啟該pod
,kubelete
也無法對他們進行健康檢查。靜態 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。