pod(七):靜態pod

2022-11-02 18:01:25

一.系統環境

伺服器版本 docker軟體版本 Kubernetes(k8s)叢集版本 CPU架構
CentOS Linux release 7.4.1708 (Core) Docker version 20.10.12 v1.21.9 x86_64

Kubernetes叢集架構:k8scloude1作為master節點,k8scloude2,k8scloude3作為worker節點

伺服器 作業系統版本 CPU架構 程序 功能描述
k8scloude1/192.168.110.130 CentOS Linux release 7.4.1708 (Core) x86_64 docker,kube-apiserver,etcd,kube-scheduler,kube-controller-manager,kubelet,kube-proxy,coredns,calico k8s master節點
k8scloude2/192.168.110.129 CentOS Linux release 7.4.1708 (Core) x86_64 docker,kubelet,kube-proxy,calico k8s worker節點
k8scloude3/192.168.110.128 CentOS Linux release 7.4.1708 (Core) x86_64 docker,kubelet,kube-proxy,calico k8s worker節點

二.前言

本文介紹靜態 Pod,靜態 Pod 在指定的節點上由 kubelet 守護行程直接管理,不需要 API 伺服器監管。

建立靜態pod的前提是已經有一套可以正常執行的Kubernetes叢集,關於Kubernetes(k8s)叢集的安裝部署,可以檢視部落格《Centos7 安裝部署Kubernetes(k8s)叢集》https://www.cnblogs.com/renshengdezheli/p/16686769.html

三.靜態pod

3.1 何為靜態pod

靜態 Pod 在指定的節點上由 kubelet 守護行程直接管理,不需要 API 伺服器監管。 與由控制面管理的 Pod(例如,Deployment) 不同;kubelet 監視每個靜態 Pod(在它失敗之後重新啟動)。靜態 Pod 始終都會繫結到特定節點的 Kubelet 上

kubelet 會嘗試通過 Kubernetes API 伺服器為每個靜態 Pod 自動建立一個映象 Pod。 這意味著節點上執行的靜態 Pod 對 API 服務來說是可見的,但是不能通過 API 伺服器來控制。 Pod 名稱將把以連字元開頭的節點主機名作為字尾。

說明:如果你在執行一個 Kubernetes 叢集,並且在每個節點上都執行一個靜態 Pod, 就可能需要考慮使用 DaemonSet 替代這種方式。靜態 Pod 的 spec 不能參照其他 API 物件 (如:ServiceAccount、 ConfigMap、 Secret 等)。

3.2 建立靜態pod

靜態pod的應用場景為:1.使master能正常啟動 2.如果某天我們的master崩潰了,如何讓別人知道我們的伺服器在維護?
目前該名稱空間是沒有pod執行的

[root@k8scloude1 pod]# kubectl get pods
No resources found in pod namespace.

靜態pod的建立方法為:寫一個yaml檔案,然後把yaml檔案放在指定目錄,會自動根據yaml檔案建立pod。有兩種方法來指定這個目錄:

  1. --pod-manifest-path
  2. /etc/kubernetes/manifests

3.2.1 使用--pod-manifest-path指定靜態pod目錄

檢視kubelet的組態檔位置,可以看到kubelet的組態檔在/usr/lib/systemd/system/kubelet.service

注意:我們是在k8s叢集的worker節點k8scloude2上建立靜態pod的

[root@k8scloude2 ~]# systemctl status kubelet
● kubelet.service - kubelet: The Kubernetes Node Agent
   Loaded: loaded (/usr/lib/systemd/system/kubelet.service; enabled; vendor preset: disabled)
  Drop-In: /usr/lib/systemd/system/kubelet.service.d
           └─10-kubeadm.conf
   Active: active (running) since 六 2022-01-15 12:27:34 CST; 5h 30min ago
     Docs: https://kubernetes.io/docs/
 Main PID: 947 (kubelet)
   Memory: 122.6M
   CGroup: /system.slice/kubelet.service
           └─947 /usr/bin/kubelet --bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf --kubeconfig=/etc/kubernetes/kubelet.conf --config=/var/lib/kubelet/config.yaml --network-plugin=cni --pod-infr...

修改kubelet的組態檔/usr/lib/systemd/system/kubelet.service,使用--pod-manifest-path=/etc/kubernetes/kubelet.d指定靜態pod目錄。

[root@k8scloude2 ~]# vim /usr/lib/systemd/system/kubelet.service.d/10-kubeadm.conf 

#--pod-manifest-path=/etc/kubernetes/kubelet.d表示靜態pod的目錄為/etc/kubernetes/kubelet.d
[root@k8scloude2 ~]# cat /usr/lib/systemd/system/kubelet.service.d/10-kubeadm.conf
# Note: This dropin only works with kubeadm and kubelet v1.11+
[Service]
Environment="KUBELET_KUBECONFIG_ARGS=--bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf --kubeconfig=/etc/kubernetes/kubelet.conf --pod-manifest-path=/etc/kubernetes/kubelet.d"
Environment="KUBELET_CONFIG_ARGS=--config=/var/lib/kubelet/config.yaml"
# This is a file that "kubeadm init" and "kubeadm join" generates at runtime, populating the KUBELET_KUBEADM_ARGS variable dynamically
EnvironmentFile=-/var/lib/kubelet/kubeadm-flags.env
# This is a file that the user can use for overrides of the kubelet args as a last resort. Preferably, the user should use
# the .NodeRegistration.KubeletExtraArgs object in the configuration files instead. KUBELET_EXTRA_ARGS should be sourced from this file.
EnvironmentFile=-/etc/sysconfig/kubelet
ExecStart=
ExecStart=/usr/bin/kubelet $KUBELET_KUBECONFIG_ARGS $KUBELET_CONFIG_ARGS $KUBELET_KUBEADM_ARGS $KUBELET_EXTRA_ARGS

建立靜態pod目錄,並使kubelet組態檔生效

[root@k8scloude2 ~]# mkdir /etc/kubernetes/kubelet.d

[root@k8scloude2 ~]# systemctl daemon-reload 

[root@k8scloude2 ~]# systemctl restart kubelet

[root@k8scloude2 ~]# systemctl status kubelet
● kubelet.service - kubelet: The Kubernetes Node Agent
   Loaded: loaded (/usr/lib/systemd/system/kubelet.service; enabled; vendor preset: disabled)
  Drop-In: /usr/lib/systemd/system/kubelet.service.d
           └─10-kubeadm.conf
   Active: active (running) since 六 2022-01-15 18:02:15 CST; 6s ago
     Docs: https://kubernetes.io/docs/
 Main PID: 108844 (kubelet)
   Memory: 30.7M
   CGroup: /system.slice/kubelet.service
           ├─108844 /usr/bin/kubelet --bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf --kubeconfig=/etc/kubernetes/kubelet.conf --pod-manifest-path=/etc/kubernetes/kubelet.d --config=/var/lib/ku...
           └─108999 /usr/bin/kubelet --bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf --kubeconfig=/etc/kubernetes/kubelet.conf --pod-manifest-path=/etc/kubernetes/kubelet.d --config=/var/lib/ku...

進入靜態pod的目錄,然後建立pod yaml檔案

[root@k8scloude2 ~]# cd /etc/kubernetes/kubelet.d/

[root@k8scloude2 kubelet.d]# ls

[root@k8scloude2 kubelet.d]# vim pod.yaml

[root@k8scloude2 kubelet.d]# cat pod.yaml 
apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: null
  labels:
    run: pod
  name: pod
spec:
  containers:
  - image: nginx
    imagePullPolicy: IfNotPresent
    name: pod
    resources: {}
    ports:
    - name: http
      containerPort: 80
      protocol: TCP
  dnsPolicy: ClusterFirst
  restartPolicy: Always
status: {}

在k8s叢集的master節點上檢視pod,在master上可以看到該pod,由於pod.yaml沒有指定namespace,預設在default下,可以看到Pod 名稱(pod-k8scloude2)是以連字元開頭的節點主機名作為字尾

[root@k8scloude1 pod]# kubectl get pods -n default -o wide
NAME             READY   STATUS    RESTARTS   AGE    IP               NODE         NOMINATED NODE   READINESS GATES
pod-k8scloude2   1/1     Running   0          109s   10.244.112.153   k8scloude2   <none>           <none>

當把這個pod.yaml檔案從靜態pod目錄移走,pod就消失了

[root@k8scloude2 kubelet.d]# mv pod.yaml ~/

[root@k8scloude2 kubelet.d]# ls

#當把這個yaml檔案移走,pod消失
[root@k8scloude1 pod]# kubectl get pods -n default -o wide
No resources found in default namespace.

現在指定靜態pod的namespace為pod

[root@k8scloude2 kubelet.d]# vim pod.yaml 

#namespace: pod:指定pod的名稱空間
[root@k8scloude2 kubelet.d]# cat pod.yaml 
apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: null
  labels:
    run: pod
  name: pod
  namespace: pod
spec:
  containers:
  - image: nginx
    imagePullPolicy: IfNotPresent
    name: pod
    resources: {}
    ports:
    - name: http
      containerPort: 80
      protocol: TCP
  dnsPolicy: ClusterFirst
  restartPolicy: Always
status: {}

[root@k8scloude2 kubelet.d]# ls
pod.yaml

檢視pod

[root@k8scloude1 pod]# kubectl get pods -n pod
NAME             READY   STATUS    RESTARTS   AGE
pod-k8scloude2   1/1     Running   0          6s

3.2.2 靜態pod預設目錄/etc/kubernetes/manifests

注意:進行這一步的時候,先還原kubelet組態檔/usr/lib/systemd/system/kubelet.service.d/10-kubeadm.conf

檢視組態檔,可以發現靜態pod預設目錄為/etc/kubernetes/manifests

[root@k8scloude2 kubelet.d]# cat /usr/lib/systemd/system/kubelet.service.d/10-kubeadm.conf 
# Note: This dropin only works with kubeadm and kubelet v1.11+
[Service]
Environment="KUBELET_KUBECONFIG_ARGS=--bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf --kubeconfig=/etc/kubernetes/kubelet.conf"
Environment="KUBELET_CONFIG_ARGS=--config=/var/lib/kubelet/config.yaml"
# This is a file that "kubeadm init" and "kubeadm join" generates at runtime, populating the KUBELET_KUBEADM_ARGS variable dynamically
EnvironmentFile=-/var/lib/kubelet/kubeadm-flags.env
# This is a file that the user can use for overrides of the kubelet args as a last resort. Preferably, the user should use
# the .NodeRegistration.KubeletExtraArgs object in the configuration files instead. KUBELET_EXTRA_ARGS should be sourced from this file.
EnvironmentFile=-/etc/sysconfig/kubelet
ExecStart=
ExecStart=/usr/bin/kubelet $KUBELET_KUBECONFIG_ARGS $KUBELET_CONFIG_ARGS $KUBELET_KUBEADM_ARGS $KUBELET_EXTRA_ARGS

[root@k8scloude2 kubelet.d]# ls /var/lib/kubelet/config.yaml
/var/lib/kubelet/config.yaml

[root@k8scloude2 kubelet.d]# cat /var/lib/kubelet/config.yaml | grep manifest
staticPodPath: /etc/kubernetes/manifests

#預設的靜態pod的目錄為 ls /etc/kubernetes/manifests
[root@k8scloude2 kubelet.d]# ls /etc/kubernetes/manifests

在預設的靜態pod目錄/etc/kubernetes/manifests/下建立pod yaml檔案

#namespace: pod:指定pod的名稱空間
[root@k8scloude2 kubelet.d]# vim ~/pod.yaml 

[root@k8scloude2 kubelet.d]# cat ~/pod.yaml 
apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: null
  labels:
    run: pod
  name: pod
  namespace: pod
spec:
  containers:
  - image: nginx
    imagePullPolicy: IfNotPresent
    name: pod
    resources: {}
    ports:
    - name: http
      containerPort: 80
      protocol: TCP
  dnsPolicy: ClusterFirst
  restartPolicy: Always
status: {}

[root@k8scloude2 kubelet.d]# cp ~/pod.yaml /etc/kubernetes/manifests/

可以發現,靜態pod已經建立了

[root@k8scloude1 pod]# kubectl get pods -n pod
NAME             READY   STATUS    RESTARTS   AGE
pod-k8scloude2   1/1     Running   0          6s

刪除yaml檔案,靜態pod消失

#刪除yaml檔案
[root@k8scloude2 kubelet.d]# rm -rf /etc/kubernetes/manifests/pod.yaml 

#pod消失
[root@k8scloude1 pod]# kubectl get pods -n pod
No resources found in pod namespace.

前面幾步,靜態pod是在k8s叢集的worker節點上做的,現在在k8s叢集的master節點上做。

注意:如果在/usr/lib/systemd/system/kubelet.service.d/10-kubeadm.conf裡新增了--pod-manifest-path=/etc/kubernetes/kubelet.d,則相應的/etc/kubernetes/manifests/下的yaml檔案也要移動到/etc/kubernetes/kubelet.d目錄下,不然k8s叢集的master節點啟動不起來。

可以看到k8s叢集的master節點有很多靜態pod。

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