本文轉載自:靜態 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
,kubelet
也無法對他們進行健康檢查。靜態 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。