创建静态 Pod
静态 Pods 直接由特定节点上的 kubelet 守护进程管理,API 服务器 不会监测它们。与由控制平面管理的 Pods(例如,一个Deployment)不同,kubelet 会监视每个静态 Pod(如果它失败,就会重启它)。
静态 Pods 总是绑定到特定节点上的一个 Kubelet。
kubelet 会自动尝试在 Kubernetes API 服务器上为每个静态 Pod 创建一个 镜像 Pod。这意味着运行在节点上的 Pods 在 API 服务器上是可见的,但无法从那里控制。Pod 名称将以节点主机名作为后缀,前面带有连字符。
注意
如果你正在运行集群式 Kubernetes 并使用静态 Pods 在每个节点上运行 Pod,你应该考虑使用 DaemonSet 代替。注意
静态 Pods 不支持临时容器。准备工作
你需要拥有一个 Kubernetes 集群,并且 kubectl 命令行工具已配置为与你的集群通信。建议在至少有两个非控制平面主机的节点组成的集群上运行本教程。如果你还没有集群,可以使用minikube 创建一个,或者你可以使用以下 Kubernetes 演练场之一
要检查版本,请输入 kubectl version
。
本页面假定你正在使用CRI-O 运行 Pods,并且你的节点正在运行 Fedora 操作系统。其他发行版或 Kubernetes 安装的说明可能会有所不同。
创建静态 Pod
你可以使用文件系统托管的配置文件或Web 托管的配置文件配置静态 Pod。
文件系统托管的静态 Pod 清单
清单是标准的 Pod 定义,以 JSON 或 YAML 格式存储在特定目录中。使用kubelet 配置文件中的 staticPodPath: <目录>
字段,它会定期扫描该目录,并随着 YAML/JSON 文件在该目录中出现/消失来创建/删除静态 Pods。请注意,kubelet 在扫描指定目录时会忽略以点开头的文件。
例如,下面是如何将一个简单的 Web 服务器作为静态 Pod 启动:
选择要运行静态 Pod 的节点。本例中为
my-node1
。ssh my-node1
选择一个目录,例如
/etc/kubernetes/manifests
,并将 Web 服务器 Pod 定义文件放在那里,例如/etc/kubernetes/manifests/static-web.yaml
# Run this command on the node where kubelet is running mkdir -p /etc/kubernetes/manifests/ 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
配置该节点上的 kubelet,在kubelet 配置文件中设置
staticPodPath
值。
有关更多信息,请参阅通过配置文件设置 Kubelet 参数。另一种已弃用的方法是,配置该节点上的 kubelet 以使用命令行参数在本地查找静态 Pod 清单。要使用此已弃用的方法,请使用以下参数启动 kubelet:
--pod-manifest-path=/etc/kubernetes/manifests/
参数。重启 kubelet。在 Fedora 上,你可以运行:
# Run this command on the node where the kubelet is running systemctl restart kubelet
Web 托管的静态 Pod 清单
Kubelet 定期下载由 --manifest-url=<URL>
参数指定的文件,并将其解释为包含 Pod 定义的 JSON/YAML 文件。与文件系统托管的清单工作方式类似,kubelet 会按计划重新获取清单。如果静态 Pod 列表发生变化,kubelet 会应用这些变化。
要使用此方法:
创建一个 YAML 文件并将其存储在 Web 服务器上,以便你可以将该文件的 URL 传递给 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
配置选定节点上的 kubelet 以使用此 Web 清单,方法是使用
--manifest-url=<清单 URL>
参数运行 kubelet。在 Fedora 上,编辑文件/etc/kubernetes/kubelet
,添加以下行:KUBELET_ARGS="--cluster-dns=10.254.0.10 --cluster-domain=kube.local --manifest-url=<manifest-url>"
重启 kubelet。在 Fedora 上,你可以运行:
# Run this command on the node where the kubelet is running systemctl restart kubelet
观察静态 Pod 行为
当 kubelet 启动时,它会自动启动所有已定义的静态 Pods。由于你已定义了一个静态 Pod 并重启了 kubelet,新的静态 Pod 应该已经运行起来了。
你可以通过在节点上运行以下命令来查看正在运行的容器(包括静态 Pods):
# Run this command on the node where the kubelet is running
crictl ps
输出可能类似于:
CONTAINER IMAGE CREATED STATE NAME ATTEMPT POD ID
129fd7d382018 docker.io/library/nginx@sha256:... 11 minutes ago Running web 0 34533c6729106
注意
crictl
输出镜像 URI 和 SHA-256 校验和。NAME
将看起来更像:docker.io/library/nginx@sha256:0d17b565c37bcbd895e9d92315a05c1c3c9a29f762b011a10c54a66cd53c9b31
。你可以在 API 服务器上看到镜像 Pod:
kubectl get pods
NAME READY STATUS RESTARTS AGE
static-web-my-node1 1/1 Running 0 2m
注意
请确保 kubelet 在 API 服务器中具有创建镜像 Pod 的权限。否则,创建请求将被 API 服务器拒绝。静态 Pod 的标签会传播到镜像 Pod 中。你可以通过选择器等方式正常使用这些标签。
如果你尝试使用 kubectl
从 API 服务器删除镜像 Pod,kubelet 不会 删除静态 Pod:
kubectl delete pod static-web-my-node1
pod "static-web-my-node1" deleted
你可以看到 Pod 仍在运行:
kubectl get pods
NAME READY STATUS RESTARTS AGE
static-web-my-node1 1/1 Running 0 4s
回到运行 kubelet 的节点上,你可以尝试手动停止容器。你会看到,过一段时间后,kubelet 会注意到并自动重启 Pod:
# Run these commands on the node where the kubelet is running
crictl stop 129fd7d382018 # replace with the ID of your container
sleep 20
crictl ps
CONTAINER IMAGE CREATED STATE NAME ATTEMPT POD ID
89db4553e1eeb docker.io/library/nginx@sha256:... 19 seconds ago Running web 1 34533c6729106
确定正确的容器后,可以使用 crictl
获取该容器的日志:
# Run these commands on the node where the container is running
crictl logs <container_id>
10.240.0.48 - - [16/Nov/2022:12:45:49 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.47.0" "-"
10.240.0.48 - - [16/Nov/2022:12:45:50 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.47.0" "-"
10.240.0.48 - - [16/Nove/2022:12:45:51 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.47.0" "-"
要了解更多关于如何使用 crictl
调试的信息,请访问 使用 crictl 调试 Kubernetes 节点。
动态添加和移除静态 Pods
正在运行的 kubelet 会定期扫描配置的目录(本例中是 /etc/kubernetes/manifests
)以查找变化,并随着文件在该目录中出现/消失而添加/移除 Pods。
# This assumes you are using filesystem-hosted static Pod configuration
# Run these commands on the node where the container is running
#
mv /etc/kubernetes/manifests/static-web.yaml /tmp
sleep 20
crictl ps
# You see that no nginx container is running
mv /tmp/static-web.yaml /etc/kubernetes/manifests/
sleep 20
crictl ps
CONTAINER IMAGE CREATED STATE NAME ATTEMPT POD ID
f427638871c35 docker.io/library/nginx@sha256:... 19 seconds ago Running web 1 34533c6729106