diff --git a/content/zh/docs/tasks/configure-pod-container/static-pod.md b/content/zh/docs/tasks/configure-pod-container/static-pod.md new file mode 100644 index 0000000000..cc249882ac --- /dev/null +++ b/content/zh/docs/tasks/configure-pod-container/static-pod.md @@ -0,0 +1,402 @@ +--- +reviewers: +- jsafrane +title: 创建静态 Pod +weight: 170 +content_template: templates/task +--- + +{{% capture overview %}} + + + +*静态 Pod* 在指定的节点上由 kubelet 守护进程直接管理,不需要 {{< glossary_tooltip text="API 服务" term_id="kube-apiserver" >}} 监管。 +不像 Pod 是由控制面管理的(例如,{{< glossary_tooltip text="Deployment" term_id="deployment" >}});相反 kubelet 监视每个静态 Pod(在它崩溃之后重新启动)。 + + + +静态 Pod 永远都会绑定到一个指定节点上的 {{< glossary_tooltip term_id="kubelet" >}}。 + +kubelet 会尝试通过 Kubernetes API 服务器为每个静态 Pod 自动创建一个 {{< glossary_tooltip text="镜像 Pod" term_id="mirror-pod" >}}。 +这意味着节点上运行的静态 Pod 对 API 服务来说是不可见的,但是不能通过 API 服务器来控制。 + +{{< note >}} +如果你在运行一个 Kubernetes 集群,并且在每个节点上都运行一个静态 Pod,就可能需要考虑使用 {{< glossary_tooltip text="DaemonSet" term_id="daemonset" >}} 替代这种方式。 +{{< /note >}} + +{{% /capture %}} + +{{% capture prerequisites %}} + + + +{{< include "task-tutorial-prereqs.md" >}} {{< version-check >}} + +本文假定你在使用 {{< glossary_tooltip term_id="docker" >}} 来运行 Pod,并且你的节点是运行着 Fedora 操作系统。 +其它发行版或者 Kubernetes 部署版本上操作方式可能不一样。 + +{{% /capture %}} + +{{% capture steps %}} + + + +## 创建静态 Pod {#static-pod-creation} + +可以通过[文件系统上的配置文件](/docs/tasks/configure-pod-container/static-pod/#configuration-files)或者 [web 网络上的配置文件](/docs/tasks/configure-pod-container/static-pod/#pods-created-via-http)来配置静态 Pod。 + + + +### 文件系统上的静态 Pod 声明文件 {#configuration-files} + +声明文件是标准的 Pod 定义文件,以 JSON 或者 YAML 格式存储在指定目录。路径设置在 [Kubelet 配置文件](/docs/tasks/administer-cluster/kubelet-config-file)的 `staticPodPath: <目录>` 字段,kubelet 会定期的扫描这个文件夹下的 YAML/JSON 文件来创建/删除静态 Pod。 +注意 kubelet 扫描目录的时候会忽略以点开头的文件。 + +例如:下面是如何以静态 Pod 的方式启动一个简单 web 服务: + + + +1. 选择一个要运行静态 Pod 的节点。在这个例子中选择 `my-node1`。 + + ```shell + ssh my-node1 + ``` + + +1. 选择一个目录,比如在 `/etc/kubelet.d` 目录来保存 web 服务 Pod 的定义文件, `/etc/kubelet.d/static-web.yaml`: + + ```shell + # 在 kubelet 运行的节点上执行以下命令 + mkdir /etc/kubelet.d/ + cat </etc/kubelet.d/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,使用这个参数执行 `--pod-manifest-path=/etc/kubelet.d/`: + + ``` + KUBELET_ARGS="--cluster-dns=10.254.0.10 --cluster-domain=kube.local --pod-manifest-path=/etc/kubelet.d/" + ``` + 或者在 [Kubelet配置文件](/docs/tasks/administer-cluster/kubelet-config-file)中添加 `staticPodPath: <目录>`字段。 + + + +1. 重启 kubelet。Fedora 上使用下面的命令: + + ```shell + # 在 kubelet 运行的节点上执行以下命令 + systemctl restart kubelet + ``` + + +### Web 网上的静态 Pod 声明文件 {#pods-created-via-http} + +Kubelet 根据 `--manifest-url=` 参数的配置定期的下载指定文件,并且转换成 JSON/YAML 格式的 Pod 容器定义文件。 +与[文件系统上的声明文件](#configuration-files)使用方式类似,kubelet 调度获取声明文件。如果静态 Pod 的声明文件有改变,kubelet会应用这些改变。 + +按照下面的方式来: + + + +1. 创建一个 YAML 文件,并保存在保存在 web 服务上,为 kubelet 生成一个 URL。 + + ```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. 通过在选择的节点上使用 `--manifest-url=` 配置运行 kubelet。在 Fedora 添加下面这行到 `/etc/kubernetes/kubelet` : + + ``` + KUBELET_ARGS="--cluster-dns=10.254.0.10 --cluster-domain=kube.local --manifest-url=" + ``` + + +1. 重启 kubelet。在 Fedora 上运行如下命令: + + ```shell + # 在 kubelet 运行的节点上执行以下命令 + systemctl restart kubelet + ``` + + +## 观察静态 pod 的行为 {#behavior-of-static-pods} + +当 kubelet 启动时,会自动启动所有定义的静态 Pod。当定义了一个静态 Pod 并重新启动 kubelet 时,新的静态 Pod 就应该已经在运行了。 + +可以在节点上云心下面的命令来看运行的容器(包括静态 Pod): +```shell +# 在 kubelet 运行的节点上执行以下命令 +docker ps +``` + + +输出可能会像这样: + +``` +CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES +f6d05272b57e nginx:latest "nginx" 8 minutes ago Up 8 minutes k8s_web.6f802af4_static-web-fk-node1_default_67e24ed9466ba55986d120c867395f3c_378e5f3c +``` + + +可以在 API 服务上看到镜像 Pod: + +```shell +kubectl get pods +``` +``` +NAME READY STATUS RESTARTS AGE +static-web-my-node1 1/1 Running 0 2m +``` + + +{{< note >}} +要确保 kubelet 在 API 服务上有创建镜像 Pod 的权限。如果没有,创建请求会被 API 服务拒绝。可以看[Pod安全策略](/docs/concepts/policy/pod-security-policy/)。 +{{< /note >}} + + +静态 Pod 上的{{< glossary_tooltip term_id="label" text="标签" >}} 被传到镜像 Pod。 你可以通过 {{< glossary_tooltip term_id="selector" text="选择算符" >}} 使用这些标签,比如。 + + +如果你用 `kubectl` 从 API 服务上删除镜像 Pod,kubelet _不会_ 移除静态 Pod: + +```shell +kubectl delete pod static-web-my-node1 +``` +``` +pod "static-web-my-node1" deleted +``` + +可以看到 Pod 还在运行: +```shell +kubectl get pods +``` +``` +NAME READY STATUS RESTARTS AGE +static-web-my-node1 1/1 Running 0 12s +``` + + +回到 kubelet 运行的节点上,可以手工停止 Docker 容器。 +可以看到过了一段时间后 kubelet 会发现容器停止了并且会自动重启 Pod: + +```shell +# 在 kubelet 运行的节点上执行以下命令 +docker stop f6d05272b57e # 把 ID 换为你的容器的 ID +sleep 20 +docker ps +``` +``` +CONTAINER ID IMAGE COMMAND CREATED ... +5b920cbaf8b1 nginx:latest "nginx -g 'daemon of 2 seconds ago ... +``` + +## 动态增加和删除静态 pod + +运行的 kubelet 定期扫描配置的目录(比如例子中的 `/etc/kubelet.d` 目录)中的变化,并且根据文件中出现/消失的 Pod 来添加/删除 Pod。 + +```shell +# 前提是你在用主机文件系统上的静态 Pod 配置文件 +# 在 kubelet 运行的节点上执行以下命令 +# +mv /etc/kubelet.d/static-web.yaml /tmp +sleep 20 +docker ps +# 可以看到没有 nginx 容器在运行 +mv /tmp/static-web.yaml /etc/kubelet.d/ +sleep 20 +docker ps +``` +``` +CONTAINER ID IMAGE COMMAND CREATED ... +e7a62e3427f1 nginx:latest "nginx -g 'daemon of 27 seconds ago +``` + +{{% /capture %}}