# 创建静态 Pod

LLMS index: [llms.txt](/llms.txt)

---

<!--
reviewers:
- jsafrane
title: Create static Pods
weight: 220
content_type: task
-->

<!-- overview -->

<!--
This page shows you how to create _static Pods_ on a node.
For an overview of what static Pods are and when to use them, see
[Static Pods](/docs/concepts/workloads/pods/static-pods/).
-->
本页面介绍如何在节点上创建静态 Pod。
有关静态 Pod 的概述以及何时使用它们，
请参阅[静态 Pod](/zh-cn/docs/concepts/workloads/pods/static-pods/)。

## 准备开始

<!--
You need to have a Kubernetes cluster, and the kubectl command-line tool must
be configured to communicate with your cluster. It is recommended to run this tutorial on a cluster with at least two nodes that are not acting as control plane hosts. If you do not already have a
cluster, you can create one by using
[minikube](https://minikube.sigs.k8s.io/docs/tutorials/multi_node/)
or you can use one of these Kubernetes playgrounds:
-->
<p>你必须拥有一个 Kubernetes 的集群，且必须配置 kubectl 命令行工具让其与你的集群通信。
建议运行本教程的集群至少有两个节点，且这两个节点不能作为控制平面主机。
如果你还没有集群，你可以通过 <a href="https://minikube.sigs.k8s.io/docs/tutorials/multi_node/">Minikube</a>
构建一个你自己的集群，或者你可以使用下面的 Kubernetes 练习环境之一：</p>
<!--
* [iximiuz Labs](https://labs.iximiuz.com/playgrounds?category=kubernetes&filter=all)
* [Killercoda](https://killercoda.com/playgrounds/scenario/kubernetes)
* [KodeKloud](https://kodekloud.com/public-playgrounds)
-->
<ul>
<li><a href="https://labs.iximiuz.com/playgrounds?category=kubernetes&filter=all">iximiuz Labs</a></li>
<li><a href="https://killercoda.com/playgrounds/scenario/kubernetes">Killercoda</a></li>
<li><a href="https://kodekloud.com/public-playgrounds">KodeKloud</a></li>
</ul>
 
  <p>要获知版本信息，请输入  <code>kubectl version</code>.</p>


<!--
This page assumes you're using <a class='glossary-tooltip' title='专用于 Kubernetes 的轻量级容器运行时软件' data-bs-toggle='tooltip' data-bs-placement='top' href='https://cri-o.io/#what-is-cri-o' target='_blank' aria-label='CRI-O'>CRI-O</a> to run Pods,
and that your nodes are running the Fedora operating system.
Instructions for other distributions or Kubernetes installations may vary.
-->
本文假定你在使用 <a class='glossary-tooltip' title='Docker 是一种可以提供操作系统级别虚拟化（也称作容器）的软件技术。' data-bs-toggle='tooltip' data-bs-placement='top' href='https://docs.docker.com/engine/' target='_blank' aria-label='Docker'>Docker</a> 来运行 Pod，
并且你的节点是运行着 Fedora 操作系统。
其它发行版或者 Kubernetes 部署版本上操作方式可能不一样。

<!-- steps -->

<!--
## Create a static pod {#static-pod-creation}

You can configure a static Pod with either a [file system hosted configuration file](#configuration-files)
or a [web hosted configuration file](#pods-created-via-http).
-->
## 创建静态 Pod {#static-pod-creation}

可以通过[文件系统上的配置文件](#configuration-files)或者
[Web 网络上的配置文件](#pods-created-via-http)来配置静态 Pod。

<!--
### Filesystem-hosted static Pod manifest {#configuration-files}

Manifests are standard Pod definitions in JSON or YAML format in a specific directory.
Use the `staticPodPath: <the directory>` field in the
[kubelet configuration file](/docs/reference/config-api/kubelet-config.v1beta1/),
which periodically scans the directory and creates/deletes static Pods as YAML/JSON files appear/disappear there.
Note that the kubelet will ignore files starting with dots when scanning the specified directory.
-->
### 文件系统上的静态 Pod 声明文件  {#configuration-files}

声明文件是标准的 Pod 定义文件，以 JSON 或者 YAML 格式存储在指定目录。路径设置在
[Kubelet 配置文件](/zh-cn/docs/reference/config-api/kubelet-config.v1beta1/)的
`staticPodPath: <目录>` 字段，kubelet 会定期的扫描这个文件夹下的 YAML/JSON
文件来创建/删除静态 Pod。
注意 kubelet 扫描目录的时候会忽略以点开头的文件。

<div class="alert alert-caution" role="note"><h4 class="alert-heading">注意：</h4><!--
The kubelet processes **all files not starting with a dot** in the static Pod directory
— there is no filtering by file extension. For example, if you create a backup of a
manifest by running `cp kube-apiserver.yaml kube-apiserver.yaml.backup`, the kubelet
will read **both** files and attempt to create a static Pod from each. When two files
define a Pod with the same name, the resulting behavior is undefined and can cause the
backup's outdated spec to silently take effect instead of the current manifest. If you
do create a backup, store it **outside** the static Pod directory (for example, in
`/etc/kubernetes/backup/`).
-->
<p>kubelet 会处理静态 Pod 目录中<strong>所有不是以点开头的文件</strong> —— 不会根据文件扩展名进行过滤。
例如，如果你通过执行 <code>cp kube-apiserver.yaml kube-apiserver.yaml.backup</code>
来创建一个清单文件的备份，kubelet 将读取<strong>这两个</strong>文件，
并尝试分别从中创建一个静态 Pod。当两个文件定义了同名的 Pod 时，
其结果行为是未定义的，并且可能导致备份文件中过时的规范静默生效，
而不是使用当前的清单文件。如果你确实创建了备份文件，
应将其存储在静态 Pod 目录<strong>之外</strong>（例如，<code>/etc/kubernetes/backup/</code> 目录）。</p></div>


<!--
For example, this is how to start a simple web server as a static Pod:
-->
例如：下面是如何以静态 Pod 的方式启动一个简单 Web 服务：

<!--
1. Choose a node where you want to run the static Pod. In this example, it's `my-node1`.
-->
1. 选择一个要运行静态 Pod 的节点。在这个例子中选择 `my-node1`。

   ```shell
   ssh my-node1
   ```

<!--
1. Choose a directory, say `/etc/kubernetes/manifests` and place a web server
   Pod definition there, for example `/etc/kubernetes/manifests/static-web.yaml`:

   # Run this command on the node where kubelet is running
-->
2. 选择一个目录，比如在 `/etc/kubernetes/manifests`
   目录来保存 Web 服务 Pod 的定义文件，例如
   `/etc/kubernetes/manifests/static-web.yaml`：

   ```shell
   # 在 kubelet 运行的节点上执行以下命令
   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
   ```

<!--
1. Configure the kubelet on that node to set a `staticPodPath` value in the
   [kubelet configuration file](/docs/reference/config-api/kubelet-config.v1beta1/).  
   See [Set Kubelet Parameters Via A Configuration File](/docs/tasks/administer-cluster/kubelet-config-file/)
   for more information.

   An alternative and deprecated method is to configure the kubelet on that node
   to look for static Pod manifests locally, using a command line argument.
   To use the deprecated approach, start the kubelet with the
   `--pod-manifest-path=/etc/kubernetes/manifests/` argument.
-->
3. 在该节点上配置 kubelet，在
   [kubelet 配置文件](/zh-cn/docs/reference/config-api/kubelet-config.v1beta1/)中设定
   `staticPodPath` 值。欲了解更多信息，
   请参考[通过配置文件设定 kubelet 参数](/zh-cn/docs/tasks/administer-cluster/kubelet-config-file/)。

   另一个已弃用的方法是，在该节点上通过命令行参数配置 kubelet，以便从本地查找静态 Pod 清单。
   若使用这种弃用的方法，请启动 kubelet 时加上
   `--pod-manifest-path=/etc/kubernetes/manifests/` 参数。
<!--
1. Restart the kubelet. On Fedora, you would run:

   ```shell
   # Run this command on the node where the kubelet is running
   systemctl restart kubelet
   ```
-->
4. 重启 kubelet。在 Fedora 上，你将使用下面的命令：

   ```shell
   # 在 kubelet 运行的节点上执行以下命令
   systemctl restart kubelet
   ```

<!--
### Web-hosted static pod manifest {#pods-created-via-http}

Kubelet periodically downloads a file specified by `--manifest-url=<URL>` argument
and interprets it as a JSON/YAML file that contains Pod definitions.
Similar to how [filesystem-hosted manifests](#configuration-files) work, the kubelet
refetches the manifest on a schedule. If there are changes to the list of static
Pods, the kubelet applies them.

To use this approach:
-->
### Web 网上的静态 Pod 声明文件 {#pods-created-via-http}

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

按照下面的方式来：

<!--
1. Create a YAML file and store it on a web server so that you can pass the URL of that file to the kubelet.
-->
1. 创建一个 YAML 文件，并保存在 Web 服务器上，这样你就可以将该文件的
   URL 传递给 kubelet。

   ```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
   ```

<!--
1. Configure the kubelet on your selected node to use this web manifest by
   updating your kubelet configuration file to include the `staticPodURL` field:
-->
2. 通过在选择的节点上更新 kubelet 配置文件并添加 `staticPodURL`
   字段运行 kubelet 以使用此 Web 清单：

   ```yaml
   apiVersion: kubelet.config.k8s.io/v1beta1
   kind: KubeletConfiguration
   staticPodURL: "<manifest-url>"
   ```

<!--
1. Restart the kubelet. On Fedora, you would run:

   ```shell
   # Run this command on the node where the kubelet is running
   systemctl restart kubelet
   ```
-->
3. 重启 kubelet。在 Fedora 上，你将运行如下命令：

   ```shell
   # 在 kubelet 运行的节点上执行以下命令
   systemctl restart kubelet
   ```

<!--
## Observe static pod behavior {#behavior-of-static-pods}

When the kubelet starts, it automatically starts all defined static Pods. As you have
defined a static Pod and restarted the kubelet, the new static Pod should
already be running.
-->
## 观察静态 Pod 的行为 {#behavior-of-static-pods}

当 kubelet 启动时，会自动启动所有定义的静态 Pod。
当定义了一个静态 Pod 并重新启动 kubelet 时，新的静态 Pod 就应该已经在运行了。

<!--
You can view running containers (including static Pods) by running (on the node):
```
-->
可以在节点上运行下面的命令来查看正在运行的容器（包括静态 Pod）：

<!--
```shell
# Run this command on the node where the kubelet is running
crictl ps
-->
```shell
# 在 kubelet 运行的节点上执行以下命令
crictl ps
```

<!--
The output might be something like:
-->
输出可能会像这样：

```console
CONTAINER       IMAGE                                 CREATED           STATE      NAME    ATTEMPT    POD ID
129fd7d382018   docker.io/library/nginx@sha256:...    11 minutes ago    Running    web     0          34533c6729106
```


<div class="alert alert-info" role="note"><h4 class="alert-heading">说明：</h4><!--
`crictl` outputs the image URI and SHA-256 checksum. `NAME` will look more like:
`docker.io/library/nginx@sha256:0d17b565c37bcbd895e9d92315a05c1c3c9a29f762b011a10c54a66cd53c9b31`.
-->
<p><code>crictl</code> 会输出镜像 URI 和 SHA-256 校验和。<code>NAME</code> 看起来像：
<code>docker.io/library/nginx@sha256:0d17b565c37bcbd895e9d92315a05c1c3c9a29f762b011a10c54a66cd53c9b31</code>。</p></div>


<!--
You can see the mirror Pod on the API server:
-->
可以在 API 服务上看到镜像 Pod：

```shell
kubectl get pods
```

```console
NAME                  READY   STATUS    RESTARTS        AGE
static-web-my-node1   1/1     Running   0               2m
```


<div class="alert alert-info" role="note"><h4 class="alert-heading">说明：</h4><!--
Make sure the kubelet has permission to create the mirror Pod in the API server.
If not, the creation request is rejected by the API server.
-->
<p>要确保 kubelet 在 API 服务上有创建镜像 Pod 的权限。
如果没有，创建请求会被 API 服务拒绝。</p></div>


<!--
<a class='glossary-tooltip' title='用来为对象设置可标识的属性标记；这些标记对用户而言是有意义且重要的。' data-bs-toggle='tooltip' data-bs-placement='top' href='/zh-cn/docs/concepts/overview/working-with-objects/labels/' target='_blank' aria-label='Labels'>Labels</a> from the static Pod are
propagated into the mirror Pod. You can use those labels as normal via
<a class='glossary-tooltip' title='选择算符允许用户通过标签对一组资源对象进行筛选过滤。' data-bs-toggle='tooltip' data-bs-placement='top' href='/zh-cn/docs/concepts/overview/working-with-objects/labels/' target='_blank' aria-label='selectors'>selectors</a>, etc.
-->
静态 Pod 上的<a class='glossary-tooltip' title='用来为对象设置可标识的属性标记；这些标记对用户而言是有意义且重要的。' data-bs-toggle='tooltip' data-bs-placement='top' href='/zh-cn/docs/concepts/overview/working-with-objects/labels/' target='_blank' aria-label='标签'>标签</a>被传播到镜像 Pod。
你可以通过<a class='glossary-tooltip' title='选择算符允许用户通过标签对一组资源对象进行筛选过滤。' data-bs-toggle='tooltip' data-bs-placement='top' href='/zh-cn/docs/concepts/overview/working-with-objects/labels/' target='_blank' aria-label='选择算符'>选择算符</a>使用这些标签。

<!--
If you try to use `kubectl` to delete the mirror Pod from the API server,
the kubelet _doesn't_ remove the static Pod:
-->
如果你用 `kubectl` 从 API 服务上删除镜像 Pod，
kubelet **不会**移除静态 Pod：

```shell
kubectl delete pod static-web-my-node1
```

```console
pod "static-web-my-node1" deleted
```

<!--
You can see that the Pod is still running:
-->
可以看到 Pod 还在运行：

```shell
kubectl get pods
```

```console
NAME                  READY   STATUS    RESTARTS   AGE
static-web-my-node1   1/1     Running   0          4s
```

<!--
Back on your node where the kubelet is running, you can try to stop the container manually.
You'll see that, after a time, the kubelet will notice and will restart the Pod
automatically:
-->
回到 kubelet 运行所在的节点上，你可以手动停止容器。
可以看到过了一段时间后 kubelet 会发现容器停止了并且会自动重启 Pod：

<!--
```shell
# 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
```
-->
```shell
# 在 kubelet 运行的节点上执行以下命令
# 把 ID 换为你的容器的 ID
crictl stop 129fd7d382018
sleep 20
crictl ps
```

```console
CONTAINER       IMAGE                                 CREATED           STATE      NAME    ATTEMPT    POD ID
89db4553e1eeb   docker.io/library/nginx@sha256:...    19 seconds ago    Running    web     1          34533c6729106
```

<!--
Once you identify the right container, you can get the logs for that container with `crictl`:

```shell
# Run these commands on the node where the container is running
crictl logs <container_id>
```
-->
一旦你找到合适的容器，你就可以使用 `crictl` 获取该容器的日志。

```shell
# 在容器运行所在的节点上执行以下命令
crictl logs <container_id>
```

```console
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" "-"
```

<!--
To find more about how to debug using `crictl`, please visit
[_Debugging Kubernetes nodes with crictl_](/docs/tasks/debug/debug-cluster/crictl/).
-->
若要找到如何使用 `crictl` 进行调试的更多信息，
请访问[**使用 `crictl` 对 Kubernetes 节点进行调试**](/zh-cn/docs/tasks/debug/debug-cluster/crictl/)。

<!--
## Dynamic addition and removal of static pods

The running kubelet periodically scans the configured directory
(`/etc/kubernetes/manifests` in our example) for changes and
adds/removes Pods as files appear/disappear in this directory.
-->
## 动态增加和删除静态 Pod  {#dynamic-addition-and-removal-of-static-pods}

运行中的 kubelet 会定期扫描配置的目录（比如例子中的 `/etc/kubernetes/manifests` 目录）中的变化，
并且根据文件中出现/消失的 Pod 来添加/删除 Pod。

<!--
```shell
# 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
```
-->
```shell
# 这里假定你在用主机文件系统上的静态 Pod 配置文件
# 在容器运行所在的节点上执行以下命令
mv /etc/kubernetes/manifests/static-web.yaml /tmp
sleep 20
crictl ps
# 可以看到没有 nginx 容器在运行
mv /tmp/static-web.yaml /etc/kubernetes/manifests/
sleep 20
crictl ps
```

```console
CONTAINER       IMAGE                                 CREATED           STATE      NAME    ATTEMPT    POD ID
f427638871c35   docker.io/library/nginx@sha256:...    19 seconds ago    Running    web     1          34533c6729106
```

## 接下来

<!--
* [Static Pods](/docs/concepts/workloads/pods/static-pods/)
* [Generate static Pod manifests for control plane components](/docs/reference/setup-tools/kubeadm/implementation-details/#generate-static-pod-manifests-for-control-plane-components)
* [Generate static Pod manifest for local etcd](/docs/reference/setup-tools/kubeadm/implementation-details/#generate-static-pod-manifest-for-local-etcd)
* [Debugging Kubernetes nodes with `crictl`](/docs/tasks/debug/debug-cluster/crictl/)
* [Learn more about `crictl`](https://github.com/kubernetes-sigs/cri-tools)
* [Set up etcd instances as static pods managed by a kubelet](/docs/setup/production-environment/tools/kubeadm/setup-ha-etcd-with-kubeadm/)
-->
* [静态 Pod](/zh-cn/docs/concepts/workloads/pods/static-pods/)
* [为控制面组件生成静态 Pod 清单](/zh-cn/docs/reference/setup-tools/kubeadm/implementation-details/#generate-static-pod-manifests-for-control-plane-components)
* [为本地 etcd 生成静态 Pod 清单](/zh-cn/docs/reference/setup-tools/kubeadm/implementation-details/#generate-static-pod-manifest-for-local-etcd)
* [使用 `crictl` 对 Kubernetes 节点进行调试](/zh-cn/docs/tasks/debug/debug-cluster/crictl/)
* 更多细节请参阅 [`crictl`](https://github.com/kubernetes-sigs/cri-tools)
* [将 etcd 实例设置为由 kubelet 管理的静态 Pod](/zh-cn/docs/setup/production-environment/tools/kubeadm/setup-ha-etcd-with-kubeadm/)
