创建静态 Pod

静态 Pod 由特定节点上的 kubelet 守护进程直接管理,而无需 API 服务器 观察它们。与由控制平面管理的 Pod(例如,部署)不同,kubelet 会监视每个静态 Pod(如果 Pod 失败,则会重新启动它)。

静态 Pod 始终绑定到特定节点上的一个 Kubelet

kubelet 会自动尝试在 Kubernetes API 服务器上为每个静态 Pod 创建一个 镜像 Pod。这意味着在节点上运行的 Pod 在 API 服务器上可见,但无法从那里控制。Pod 名称将以节点主机名作为前缀,并在前面加上连字符。

开始之前

您需要拥有一个 Kubernetes 集群,并且 kubectl 命令行工具必须配置为与您的集群通信。建议您在至少有两个节点(不充当控制平面主机)的集群上运行本教程。如果您还没有集群,可以使用 minikube 创建一个,或者可以使用以下 Kubernetes 游乐场之一

要检查版本,请输入 kubectl version

此页面假设您使用的是 CRI-O 运行 Pod,并且您的节点正在运行 Fedora 操作系统。其他发行版或 Kubernetes 安装的说明可能有所不同。

创建静态 Pod

您可以使用 文件系统托管的配置文件网络托管的配置文件 配置静态 Pod。

文件系统托管的静态 Pod 清单

清单是特定目录中以 JSON 或 YAML 格式表示的标准 Pod 定义。在 kubelet 配置文件 中使用 staticPodPath: <the directory> 字段,该字段会定期扫描目录并根据 YAML/JSON 文件的出现/消失创建/删除静态 Pod。请注意,kubelet 在扫描指定的目录时会忽略以点开头的文件。

例如,以下是如何将简单的 Web 服务器作为静态 Pod 启动

  1. 选择您要运行静态 Pod 的节点。在本例中,它是 my-node1

    ssh my-node1
    
  2. 选择一个目录,例如 /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
    
  3. 配置该节点上的 kubelet,以便在 kubelet 配置文件 中设置 staticPodPath 值。
    有关更多信息,请参阅 通过配置文件设置 Kubelet 参数

    一种替代方法(已弃用)是在该节点上配置 kubelet,使其使用命令行参数在本地查找静态 Pod 清单。要使用已弃用的方法,请使用以下命令启动 kubelet:
    --pod-manifest-path=/etc/kubernetes/manifests/ 参数。

  4. 重新启动 kubelet。在 Fedora 上,您将运行

    # Run this command on the node where the kubelet is running
    systemctl restart kubelet
    

网络托管的静态 Pod 清单

Kubelet 会定期下载由 --manifest-url=<URL> 参数指定的特定文件,并将其解释为包含 Pod 定义的 JSON/YAML 文件。与 文件系统托管的清单 的工作方式类似,kubelet 会按照计划重新获取清单。如果静态 Pod 列表有更改,kubelet 会应用这些更改。

要使用此方法

  1. 创建一个 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
    
  2. 通过运行 --manifest-url=<manifest-url> 来配置选定节点上的 kubelet 以使用此网络清单。在 Fedora 上,编辑 /etc/kubernetes/kubelet 以包含以下行

    KUBELET_ARGS="--cluster-dns=10.254.0.10 --cluster-domain=kube.local --manifest-url=<manifest-url>"
    
  3. 重新启动 kubelet。在 Fedora 上,您将运行

    # Run this command on the node where the kubelet is running
    systemctl restart kubelet
    

观察静态 Pod 行为

kubelet 启动时,会自动启动所有定义的静态 Pod。由于您已定义静态 Pod 并重新启动了 kubelet,因此新的静态 Pod 应该已经在运行。

您可以通过运行以下命令查看正在运行的容器(包括静态 Pod)(在节点上)

# 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

您可以在 API 服务器上看到镜像 Pod

kubectl get pods
NAME                  READY   STATUS    RESTARTS        AGE
static-web-my-node1   1/1     Running   0               2m

标签 从静态 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 节点

动态添加和删除静态 Pod

正在运行的 kubelet 会定期扫描配置的目录(在本例中为 /etc/kubernetes/manifests),以查找更改,并在该目录中出现/消失文件时添加/删除 Pod。

# 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

下一步

上次修改时间:2023 年 12 月 8 日,太平洋标准时间上午 7:08:更改以反映 pod-manifest-path 参数的弃用 (8a0a983d32)