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 会应用这些改变。
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 ~]#
[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被删除了。
五、总结
- 静态Pod由kubelet进行创建,并在kubelet所在的Node上运行。
- 由于静态Pod只受所在节点的kubelet控制,可以有效预防通过kubectl或管理工具操作的误删除,可以用来部署核心组件应用,保障应用服务总是运行稳定数量和提供稳定服务。
参考:https://kubernetes.io/zh-cn/docs/tasks/configure-pod-container/static-pod/
参考:https://blog.csdn.net/qq_34556414/article/details/125625127