Kubernetes静态Pod

一、什么是Static Pod

静态 Pod 在指定的节点上由 kubelet 守护进程直接管理,不需要 API 服务器监管。 与由控制面管理的 Pod(例如,Deployment、RC、DaemonSet) 不同;kubelet 监视每个静态 Pod(在它崩溃之后重新启动)。

静态 Pod 永远都会绑定到一个指定节点上的 Kubelet。

kubelet 会尝试通过 Kubernetes API 服务器自动创建静态Pod。 这意味着节点上运行的静态 Pod 对 API 服务来说是可见的,但是不能通过 API 服务器来控制。 静态 Pod 名称将把以连字符开头的节点主机名作为后缀。

注意:如果你在运行一个 Kubernetes 集群,并且在每个节点上都运行一个静态 Pod, 就可能需要考虑使用 DaemonSet 替代这种方式;静态 Pod 的 spec 不能引用其他 API 对象 (如:ServiceAccount、 ConfigMap、 Secret 等);静态 Pod 不支持临时容器

最常见的 Static Pod:

  • kube-apiserver
  • kube-controller-manager
  • kube-scheduler

二、创建 Static Pod

创建静态Pod的方式有两种:

  • 文件系统上的配置文件
  • Web 网络上的配置文件

2.1 文件系统上的静态 Pod 声明文件

首先需要时设定kubelet启动参数"--pod-manifest-path"或者在kubelet的配置文件中设定staticPodPath,指定的路径是kubelet监控的路径(如果k8s集群由kubeadm搭建,那默认存储在目录/etc/kubernetes/manifests下),kubelet 会定期的扫描该目录下的 YAML/JSON 文件来创建/修改/删除静态 Pod。 

注意:声明文件是标准的 Pod 定义文件,以 JSON 或者 YAML 格式存储在指定目录;kubelet 扫描目录的时候会忽略以点开头的文件。

示例(centos7操作系统下,在k8s集群node1节点创建静态Pod):

1)、查看当前节点kubelet监控静态文件的路径

使用systemctl cat kubelet命令查看通过systemd配置的与kubelet有关的所有配置文件的路径与内容。

[root@node1 ~]# systemctl cat kubelet
# /etc/systemd/system/kubelet.service
[Unit]
Description=kubelet: The Kubernetes Node Agent
Documentation=http://kubernetes.io/docs/

[Service]
ExecStart=/usr/local/bin/kubelet
Restart=always
StartLimitInterval=0
RestartSec=10

[Install]
WantedBy=multi-user.target

# /etc/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" generate 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/default/kubelet
Environment="KUBELET_EXTRA_ARGS=--node-ip=10.20.30.31 --hostname-override=node1 "
ExecStart=
ExecStart=/usr/local/bin/kubelet $KUBELET_KUBECONFIG_ARGS $KUBELET_CONFIG_ARGS $KUBELET_KUBEADM_ARGS $KUBELET_EXTRA_ARGS

通过查看配置文件/var/lib/kubelet/config.yaml可以当前节点kubelet监控静态文件的路径为/etc/kubernetes/manifests。

[root@node1 ~]# cat /var/lib/kubelet/config.yaml
apiVersion: kubelet.config.k8s.io/v1beta1
authentication:
  anonymous:
    enabled: false
  webhook:
    cacheTTL: 0s
    enabled: true
  x509:
    clientCAFile: /etc/kubernetes/pki/ca.crt
authorization:
  mode: Webhook
  webhook:
    cacheAuthorizedTTL: 0s
    cacheUnauthorizedTTL: 0s
cgroupDriver: cgroupfs
clusterDNS:
- 169.254.25.10
clusterDomain: cluster.local
cpuManagerReconcilePeriod: 0s
evictionHard:
  memory.available: 5%
evictionMaxPodGracePeriod: 120
evictionPressureTransitionPeriod: 30s
evictionSoft:
  memory.available: 10%
evictionSoftGracePeriod:
  memory.available: 2m
featureGates:
  ExpandCSIVolumes: true
  RotateKubeletServerCertificate: true
fileCheckFrequency: 0s
healthzBindAddress: 127.0.0.1
healthzPort: 10248
httpCheckFrequency: 0s
imageMinimumGCAge: 0s
kind: KubeletConfiguration
kubeReserved:
  cpu: 200m
  memory: 250Mi
logging: {}
maxPods: 220
nodeStatusReportFrequency: 0s
nodeStatusUpdateFrequency: 0s
rotateCertificates: true
runtimeRequestTimeout: 0s
shutdownGracePeriod: 0s
shutdownGracePeriodCriticalPods: 0s
staticPodPath: /etc/kubernetes/manifests
streamingConnectionIdleTimeout: 0s
syncFrequency: 0s
systemReserved:
  cpu: 200m
  memory: 250Mi
volumeStatsAggPeriod: 0s

2)、在当前节点kubelet监控静态文件的目录下创建static_pod.yaml文件,内容如下: 

# 在 kubelet 运行的节点上执行以下命令
cat <<EOF >/etc/kubernetes/manifests/static-web.yaml
apiVersion: v1
kind: Pod
metadata:
  name: static-web
  labels:
    role: myrole
spec:
  containers:
    - name: web
      image: nginx
      ports:
        - name: web
          containerPort: 80
          protocol: TCP
EOF

3)、查看静态Pod

创建static_pod.yaml文件后,稍等片刻(1s内),便能够发现集群启动了一个Pod(如长时间未启动,查看docker服务服务引擎日志),通过kubectl客户端命令可以看到,静态 Pod 名称将把以连字符开头的节点主机名作为后缀。

[root@node1 manifests]# kubectl get pods
NAME               READY   STATUS    RESTARTS   AGE
static-web-node1   1/1     Running   0          2m2s

查看静态Pod详细配置文件,可以看到静态被节点直接级联管理。

[root@node1 manifests]# kubectl get pods static-web-node1 -o yaml
apiVersion: v1
kind: Pod
metadata:
  annotations:
    kubernetes.io/config.hash: 09d714a297ac22f2112f71f774fcdcfc
    kubernetes.io/config.mirror: 09d714a297ac22f2112f71f774fcdcfc
    kubernetes.io/config.seen: "2022-12-07T08:11:09.980870695+08:00"
    kubernetes.io/config.source: file
  creationTimestamp: "2022-12-07T00:11:10Z"
  labels:
    role: myrole
  name: static-web-node1
  namespace: default
  ownerReferences:
  - apiVersion: v1
    controller: true
    kind: Node
    name: node1
    uid: 1f6f54e7-5c40-4006-8bee-f8b1d9ddd2e8
  resourceVersion: "130431997"
  selfLink: /api/v1/namespaces/default/pods/static-web-node1
  uid: 2ab31bb8-deab-424d-80e4-5d8b9d7cbf2d
spec:
  containers:
......
......

至此,成功通过文件系统上的静态 Pod 声明文件创建静态Pod。

2.2 Web 网上的静态 Pod 声明文件(不常用)

Kubelet 根据 --manifest-url=<URL> 参数的配置定期的下载指定文件,并且转换成 JSON/YAML 格式的 Pod 定义文件。 与文件系统上的清单文件使用方式类似,kubelet 调度获取清单文件。 如果静态 Pod 的清单文件有改变,kubelet 会应用这些改变。

示例(centos7操作系统下,在k8s集群node1节点创建静态Pod):
1)、创建一个 YAML 文件,并保存在 web 服务上,为 kubelet 生成一个 URL。
apiVersion: v1
kind: Pod
metadata:
  name: static-web
  labels:
    role: myrole
spec:
  containers:
    - name: web
      image: nginx
      ports:
        - name: web
          containerPort: 80
          protocol: TCP

2)、通过在选择的节点上使用 --manifest-url=<manifest-url> 配置运行 kubelet,修改/etc/systemd/system/kubelet.service.d/10-kubeadm.conf配置文件,增加--manifest-url配置项。

Environment="KUBELET_SYSTEM_PODS_ARGS=--manifest-url=<manifest-url>"

3)、重启节点kubelet服务使配置生效

systemctl restart kubelet

稍等片刻(1s内),便能够发现集群启动了一个Pod。至此,成功通过Web 网上的静态 Pod 声明文件创建静态Pod。

三、修改Static Pod

直接修改当前节点kubelet监控静态文件的目录下Pod声明文件即可自动修改静态Pod配置。

示例:

1)、编辑当前节点kubelet监控静态文件的目录下Pod声明文件static-web.yaml,将容器云镜像地址改成nginx:34455。

[root@node1 manifests]# cat static-web.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: static-web
  labels:
    role: myrole
spec:
  containers:
    - name: web
      image: nginx:34455
      ports:
        - name: web
          containerPort: 80
          protocol: TCP

2)、修改static_pod.yaml文件后,稍等片刻(1s内),便能够发现修改的静态Pod重启了。

[root@node1 ~]# kubectl get pods
NAME               READY   STATUS         RESTARTS   AGE
static-web-node1   0/1     ErrImagePull   0          2m13s

通过查看Pod的详细内容,可以看到kubelet会在静态Pod崩溃之后重新启动它。

kubectl describe pod static-web-node1
......
......
Tolerations:        :NoExecute op=Exists
Events:
  Type     Reason   Age                  From     Message
  ----     ------   ----                 ----     -------
  Normal   Pulling  64s (x4 over 2m51s)  kubelet  Pulling image "nginx:34455"
  Warning  Failed   55s (x4 over 2m44s)  kubelet  Failed to pull image "nginx:34455": rpc error: code = Unknown desc = Error response from daemon: manifest for nginx:34455 not found: manifest unknown: manifest unknown
  Warning  Failed   55s (x4 over 2m44s)  kubelet  Error: ErrImagePull
  Warning  Failed   42s (x6 over 2m44s)  kubelet  Error: ImagePullBackOff
  Normal   BackOff  31s (x7 over 2m44s)  kubelet  Back-off pulling image "nginx:34455"

四、删除Static Pod

用 kubectl 从 API 服务上删除静态Pod static-web-node1 ,kubelet 不会移除静态 Pod:

[root@node1 ~]# kubectl delete pod static-web-node1 
pod "static-web-node1" deleted

可以看到 Pod 还在运行:

[root@node1 ~]# kubectl get pods
NAME               READY   STATUS             RESTARTS   AGE
static-web-node1   0/1     ImagePullBackOff   0          76s

在 kubelet 运行节点上手动停止容器。 可以看到过了一段时间后 kubelet 会发现容器停止了并且会自动重启 Pod:

# 在 kubelet 运行的节点上执行以下命令
# 把 ID 换为你的容器的 ID
[root@node1 ~]# docker ps |grep static-web-node1
a0a611424681   ***:443/***/pause:3.4.1              "/pause"                 13 minutes ago   Up 13 minutes                                                                 k8s_POD_static-web-node1_default_3c09375dc8dd5b2929407f92452b960b_0
[root@node1 ~]# docker stop a0a611424681
a0a611424681
[root@node1 ~]# docker ps |grep static-web-node1
3a174630e368   ***:443/***/pause:3.4.1              "/pause"                 2 seconds ago   Up 1 second                                                                   k8s_POD_static-web-node1_default_3c09375dc8dd5b2929407f92452b960b_1
[root@node1 ~]# 
删除该Pod的操作只能是到其所在Node上,将其自定义文件static-web.yaml从监控静态文件的目录下删除 。
[root@node1 manifests]# rm static-web.yaml 
rm: remove regular file ‘static-web.yaml’? y
[root@node1 manifests]# kubectl get pods
No resources found in default namespace.

稍等片刻(1s内),可以看到静态Pod被删除了。

 五、总结

  1. 静态Pod由kubelet进行创建,并在kubelet所在的Node上运行。
  2. 由于静态Pod只受所在节点的kubelet控制,可以有效预防通过kubectl或管理工具操作的误删除,可以用来部署核心组件应用,保障应用服务总是运行稳定数量和提供稳定服务。

参考:https://kubernetes.io/zh-cn/docs/tasks/configure-pod-container/static-pod/

参考:https://blog.csdn.net/qq_34556414/article/details/125625127

参考:https://blog.csdn.net/wzj_110/article/details/109036049

posted @ 2022-12-06 21:40  人艰不拆_zmc  阅读(1109)  评论(1编辑  收藏  举报