diff --git a/content/zh/docs/concepts/workloads/pods/_index.md b/content/zh/docs/concepts/workloads/pods/_index.md index 17d2efd32c7b3..4689f0aca374b 100644 --- a/content/zh/docs/concepts/workloads/pods/_index.md +++ b/content/zh/docs/concepts/workloads/pods/_index.md @@ -480,21 +480,26 @@ Pod 中的容器所看到的系统主机名与为 Pod 配置的 `name` 属性值 ## 容器的特权模式 {#privileged-mode-for-containers} -Pod 中的任何容器都可以使用容器规约中的 +在 Linux 中,Pod 中的任何容器都可以使用容器规约中的 [安全性上下文](/zh/docs/tasks/configure-pod-container/security-context/)中的 -`privileged` 参数启用特权模式。 +`privileged`(Linux)参数启用特权模式。 这对于想要使用操作系统管理权能(Capabilities,如操纵网络堆栈和访问设备) 的容器很有用。 -容器内的进程几乎可以获得与容器外的进程相同的特权。 + +如果你的集群启用了 `WindowsHostProcessContainers` 特性,你可以使用 Pod 规约中安全上下文的 +`windowsOptions.hostProcess` 参数来创建 +[Windows HostProcess Pod](/zh/docs/tasks/configure-pod-container/create-hostprocess-pod/)。 +这些 Pod 中的所有容器都必须以 Windows HostProcess 容器方式运行。 +HostProcess Pod 可以直接运行在主机上,它也能像 Linux 特权容器一样,用于执行管理任务。 {{< note >}} 你的{{< glossary_tooltip text="容器运行时" term_id="container-runtime" >}}必须支持 @@ -538,6 +543,38 @@ but cannot be controlled from there. 这意味着在节点上运行的 Pod 在 API 服务器上是可见的,但不可以通过 API 服务器来控制。 +{{< note >}} + +静态 Pod 的 `spec` 不能引用其他的 API 对象(例如:{{< glossary_tooltip text="ServiceAccount" term_id="service-account" >}}、{{< glossary_tooltip text="ConfigMap" term_id="configmap" >}}、{{< glossary_tooltip text="Secret" term_id="secret" >}}等)。 +{{< /note >}} + + +## 容器探针 {#container-probes} + +_Probe_ 是由 kubelet 对容器执行的定期诊断。要执行诊断,kubelet 可以执行三种动作: + +- `ExecAction`(借助容器运行时执行) +- `TCPSocketAction`(由 kubelet 直接检测) +- `HTTPGetAction`(由 kubelet 直接检测) + +你可以参阅 Pod 的生命周期文档中的[探针](/zh/docs/concepts/workloads/pods/pod-lifecycle/#container-probes)部分。 + ## {{% heading "whatsnext" %}} * 了解 [Pod 生命周期](/zh/docs/concepts/workloads/pods/pod-lifecycle/) * 了解 [RuntimeClass](/zh/docs/concepts/containers/runtime-class/),以及如何使用它 来配置不同的 Pod 使用不同的容器运行时配置 * 了解 [Pod 拓扑分布约束](/zh/docs/concepts/workloads/pods/pod-topology-spread-constraints/) * 了解 [PodDisruptionBudget](/zh/docs/concepts/workloads/pods/disruptions/),以及你 - 如何可以利用它在出现干扰因素时管理应用的可用性 -* Pod 在 Kubernetes REST API 中是一个顶层资源; - [Pod](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#pod-v1-core) + 如何可以利用它在出现干扰因素时管理应用的可用性。 +* Pod 在 Kubernetes REST API 中是一个顶层资源。 + {{< api-reference page="workload-resources/pod-v1" >}} 对象的定义中包含了更多的细节信息。 -* 博客 [分布式系统工具箱:复合容器模式](https://kubernetes.io/blog/2015/06/the-distributed-system-toolkit-patterns) +* 博客 [分布式系统工具箱:复合容器模式](/blog/2015/06/the-distributed-system-toolkit-patterns/) 中解释了在同一 Pod 中包含多个容器时的几种常见布局。 - 节点下层物理机的硬件故障 @@ -60,7 +60,7 @@ an application. Examples are: - 云提供商或虚拟机管理程序中的故障导致的虚拟机消失 - 内核错误 - 节点由于集群网络隔离从集群中消失 -- 由于节点[资源不足](/zh/docs/tasks/administer-cluster/out-of-resource/)导致 pod 被驱逐。 +- 由于节点[资源不足](/zh/docs/concepts/scheduling-eviction/node-pressure-eviction/)导致 pod 被驱逐。 自愿干扰的频率各不相同。在一个基本的 Kubernetes 集群中,没有自愿干扰(只有用户触发的干扰)。 @@ -170,7 +170,7 @@ in your pod spec can also cause voluntary (and involuntary) disruptions. 实现可能导致碎片整理和紧缩节点的自愿干扰。集群 管理员或托管提供商应该已经记录了各级别的自愿干扰(如果有的话)。 有些配置选项,例如在 pod spec 中 -[使用 PriorityClasses](https://kubernetes.io/docs/concepts/configuration/pod-priority-preemption/) +[使用 PriorityClasses](/zh/docs/concepts/scheduling-eviction/pod-priority-preemption/) 也会产生自愿(和非自愿)的干扰。 -{{< feature-state state="alpha" for_k8s_version="v1.16" >}} +{{< feature-state state="alpha" for_k8s_version="v1.22" >}} -临时容器处于早期的 Alpha 阶段,不适用于生产环境集群。 -应该预料到临时容器在某些情况下不起作用,例如在定位容器的命名空间时。 +临时容器处于 Alpha 阶段,不适用于生产环境集群。 根据 [Kubernetes 弃用政策](/zh/docs/reference/using-api/deprecation-policy/), 此 Alpha 功能将来可能发生重大变化或被完全删除。 {{< /warning >}} @@ -141,151 +139,8 @@ you can view processes in other containers. [进程名字空间共享](/zh/docs/tasks/configure-pod-container/share-process-namespace/) 很有帮助,可以查看其他容器中的进程。 +{{% heading "whatsnext" %}} -关于如何使用临时容器来执行故障排查的例子,可参阅 -[使用临时调试容器来调试](/zh/docs/tasks/debug-application-cluster/debug-running-pod/#ephemeral-container)。 - - -### 临时容器 API {#ephemeral-containers-api} - -{{< note >}} - -本节中的示例要求启用 `EphemeralContainers` -[特性门控](/zh/docs/reference/command-line-tools-reference/feature-gates/), -并且 kubernetes 客户端和服务端版本要求为 v1.16 或更高版本。 -{{< /note >}} - - -本节中的示例演示了临时容器如何出现在 API 中。 -通常,你会使用 `kubectl debug` 或别的 `kubectl` -[插件](/zh/docs/tasks/extend-kubectl/kubectl-plugins/) 自动执行这些步骤,而不是直接调用API。 - - -临时容器是使用 Pod 的 `ephemeralcontainers` 子资源创建的,可以使用 -`kubectl --raw` 命令进行显示。 -首先描述临时容器被添加为一个 `EphemeralContainers` 列表: - -```json -{ - "apiVersion": "v1", - "kind": "EphemeralContainers", - "metadata": { - "name": "example-pod" - }, - "ephemeralContainers": [{ - "command": [ - "sh" - ], - "image": "busybox", - "imagePullPolicy": "IfNotPresent", - "name": "debugger", - "stdin": true, - "tty": true, - "terminationMessagePolicy": "File" - }] -} -``` - - -使用如下命令更新已运行的临时容器 `example-pod`: - -```shell -kubectl replace --raw /api/v1/namespaces/default/pods/example-pod/ephemeralcontainers -f ec.json -``` - - -这将返回临时容器的新列表: - -```json -{ - "kind":"EphemeralContainers", - "apiVersion":"v1", - "metadata":{ - "name":"example-pod", - "namespace":"default", - "selfLink":"/api/v1/namespaces/default/pods/example-pod/ephemeralcontainers", - "uid":"a14a6d9b-62f2-4119-9d8e-e2ed6bc3a47c", - "resourceVersion":"15886", - "creationTimestamp":"2019-08-29T06:41:42Z" - }, - "ephemeralContainers":[ - { - "name":"debugger", - "image":"busybox", - "command":[ - "sh" - ], - "resources":{ - - }, - "terminationMessagePolicy":"File", - "imagePullPolicy":"IfNotPresent", - "stdin":true, - "tty":true - } - ] -} -``` - - -可以使用以下命令查看新创建的临时容器的状态: - -```shell -kubectl describe pod example-pod -``` - -输出为: - -``` -... -Ephemeral Containers: - debugger: - Container ID: docker://cf81908f149e7e9213d3c3644eda55c72efaff67652a2685c1146f0ce151e80f - Image: busybox - Image ID: docker-pullable://busybox@sha256:9f1003c480699be56815db0f8146ad2e22efea85129b5b5983d0e0fb52d9ab70 - Port: - Host Port: - Command: - sh - State: Running - Started: Thu, 29 Aug 2019 06:42:21 +0000 - Ready: False - Restart Count: 0 - Environment: - Mounts: -... -``` - - -可以使用以下命令连接到新的临时容器: - -```shell -kubectl attach -it example-pod -c debugger -``` - +* 了解如何[使用临时调试容器来进行调试](/zh/docs/tasks/debug-application-cluster/debug-running-pod/#ephemeral-container) diff --git a/content/zh/docs/concepts/workloads/pods/init-containers.md b/content/zh/docs/concepts/workloads/pods/init-containers.md index d15fcfebce3bc..8ee5cfb6dce1a 100644 --- a/content/zh/docs/concepts/workloads/pods/init-containers.md +++ b/content/zh/docs/concepts/workloads/pods/init-containers.md @@ -63,16 +63,21 @@ However, if the Pod has a `restartPolicy` of Never, and an init container fails -为 Pod 设置 Init 容器需要在 Pod 的 `spec` 中添加 `initContainers` 字段, +为 Pod 设置 Init 容器需要在 [Pod 规约](/docs/reference/kubernetes-api/workload-resources/pod-v1/#PodSpec) +中添加 `initContainers` 字段, 该字段以 [Container](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#container-v1-core) 类型对象数组的形式组织,和应用的 `containers` 数组同级相邻。 +参阅 API 参考的[容器](/docs/reference/kubernetes-api/workload-resources/pod-v1/#Container)章节了解详情。 + Init 容器的状态在 `status.initContainerStatuses` 字段中以容器状态数组的格式返回 (类似 `status.containerStatuses` 字段)。 @@ -458,15 +463,21 @@ Init 容器具有应用容器的所有字段。然而 Kubernetes 禁止使用 `r Kubernetes 会在校验时强制执行此检查。 在 Pod 上使用 `activeDeadlineSeconds` 和在容器上使用 `livenessProbe` 可以避免 -Init 容器一直重复失败。`activeDeadlineSeconds` 时间包含了 Init 容器启动的时间。 +Init 容器一直重复失败。 +`activeDeadlineSeconds` 时间包含了 Init 容器启动的时间。 +然而,如果用户将他们的应用程序以 Job 方式部署,建议使用 `activeDeadlineSeconds`, +因为 `activeDeadlineSeconds` 在 Init 容器结束后仍有效果。 +如果你设置了 `activeDeadlineSeconds`,已经在正常运行的 Pod 会被杀死。 在 Pod 中的每个应用容器和 Init 容器的名称必须唯一; 与任何其它容器共享同一个名称,会在校验时抛出错误。 @@ -478,7 +489,8 @@ Given the ordering and execution for init containers, the following rules for resource usage apply: * The highest of any particular resource request or limit defined on all init - containers is the *effective init request/limit* + containers is the *effective init request/limit*. If any resource has no + resource limit specified this is considered as the highest limit. * The Pod's *effective request/limit* for a resource is the higher of: * the sum of all app containers request/limit for a resource * the effective init request/limit for a resource @@ -492,7 +504,8 @@ for resource usage apply: 在给定的 Init 容器执行顺序下,资源使用适用于如下规则: -* 所有 Init 容器上定义的任何特定资源的 limit 或 request 的最大值,作为 Pod *有效初始 request/limit* +* 所有 Init 容器上定义的任何特定资源的 limit 或 request 的最大值,作为 Pod *有效初始 request/limit*。 + 如果任何资源没有指定资源限制,这被视为最高限制。 * Pod 对资源的 *有效 limit/request* 是如下两者的较大者: * 所有应用容器对某个资源的 limit/request 之和 * 对某个资源的有效初始 limit/request diff --git a/content/zh/docs/concepts/workloads/pods/pod-lifecycle.md b/content/zh/docs/concepts/workloads/pods/pod-lifecycle.md index 76702d222c2f1..1082713bd38ad 100644 --- a/content/zh/docs/concepts/workloads/pods/pod-lifecycle.md +++ b/content/zh/docs/concepts/workloads/pods/pod-lifecycle.md @@ -558,16 +558,11 @@ specify a readiness probe. In this case, the readiness probe might be the same as the liveness probe, but the existence of the readiness probe in the spec means that the Pod will start without receiving any traffic and only start receiving traffic after the probe starts succeeding. -If your container needs to work on loading large data, configuration files, or -migrations during startup, specify a readiness probe. --> 如果要仅在探测成功时才开始向 Pod 发送请求流量,请指定就绪态探针。 在这种情况下,就绪态探针可能与存活态探针相同,但是规约中的就绪态探针的存在意味着 Pod 将在启动阶段不接收任何数据,并且只有在探针探测成功后才开始接收数据。 -如果你的容器需要加载大规模的数据、配置文件或者在启动期间执行迁移操作,可以添加一个 -就绪态探针。 - +如果你的应用程序对后端服务有严格的依赖性,你可以同时实现存活态和就绪态探针。 +当应用程序本身是健康的,存活态探针检测通过后,就绪态探针会额外检查每个所需的后端服务是否可用。 +这可以帮助你避免将流量导向只能返回错误信息的 Pod。 + +如果你的容器需要在启动期间加载大型数据、配置文件或执行迁移,你可以使用 +[启动探针](#when-should-you-use-a-startup-probe)。 +然而,如果你想区分已经失败的应用和仍在处理其启动数据的应用,你可能更倾向于使用就绪探针。 + {{< note >}} 1. 如果 Pod 中的容器之一定义了 `preStop` - [回调](/zh/docs/concepts/containers/container-lifecycle-hooks/#hook-details), + [回调](/zh/docs/concepts/containers/container-lifecycle-hooks), `kubelet` 开始在容器内运行该回调逻辑。如果超出体面终止限期时,`preStop` 回调逻辑 仍在运行,`kubelet` 会请求给予该 Pod 的宽限期一次性增加 2 秒钟。 diff --git a/content/zh/docs/concepts/workloads/pods/pod-topology-spread-constraints.md b/content/zh/docs/concepts/workloads/pods/pod-topology-spread-constraints.md index 06adbc26f3ced..5ac4fed19226d 100644 --- a/content/zh/docs/concepts/workloads/pods/pod-topology-spread-constraints.md +++ b/content/zh/docs/concepts/workloads/pods/pod-topology-spread-constraints.md @@ -368,25 +368,88 @@ To overcome this situation, you can either increase the `maxSkew` or modify one `whenUnsatisfiable: ScheduleAnyway`。 +### 节点亲和性与节点选择器的相互作用 {#interaction-with-node-affinity-and-node-selectors} + +如果 Pod 定义了 `spec.nodeSelector` 或 `spec.affinity.nodeAffinity`,调度器将从倾斜计算中跳过不匹配的节点。 + + + 假设你有一个跨越 zoneA 到 zoneC 的 5 节点集群: + + {{}} + graph BT + subgraph "zoneB" + p3(Pod) --> n3(Node3) + n4(Node4) + end + subgraph "zoneA" + p1(Pod) --> n1(Node1) + p2(Pod) --> n2(Node2) + end + + classDef plain fill:#ddd,stroke:#fff,stroke-width:4px,color:#000; + classDef k8s fill:#326ce5,stroke:#fff,stroke-width:4px,color:#fff; + classDef cluster fill:#fff,stroke:#bbb,stroke-width:2px,color:#326ce5; + class n1,n2,n3,n4,p1,p2,p3 k8s; + class p4 plain; + class zoneA,zoneB cluster; + {{< /mermaid >}} + + {{}} + graph BT + subgraph "zoneC" + n5(Node5) + end + + classDef plain fill:#ddd,stroke:#fff,stroke-width:4px,color:#000; + classDef k8s fill:#326ce5,stroke:#fff,stroke-width:4px,color:#fff; + classDef cluster fill:#fff,stroke:#bbb,stroke-width:2px,color:#326ce5; + class n5 k8s; + class zoneC cluster; + {{< /mermaid >}} + + 而且你知道 "zoneC" 必须被排除在外。在这种情况下,可以按如下方式编写 yaml, + 以便将 "mypod" 放置在 "zoneB" 上,而不是 "zoneC" 上。同样,`spec.nodeSelector` + 也要一样处理。 + + {{< codenew file="pods/topology-spread-constraints/one-constraint-with-nodeaffinity.yaml" >}} + + +调度器不会预先知道集群拥有的所有区域和其他拓扑域。拓扑域由集群中存在的节点确定。 +在自动伸缩的集群中,如果一个节点池(或节点组)的节点数量为零, +而用户正期望其扩容时,可能会导致调度出现问题。 +因为在这种情况下,调度器不会考虑这些拓扑域信息,因为它们是空的,没有节点。 + + -### 约定 {#conventions} +### 其他值得注意的语义 {#other-noticeable-semantics} 这里有一些值得注意的隐式约定: - 只有与新的 Pod 具有相同命名空间的 Pod 才能作为匹配候选者。 -- 没有 `topologySpreadConstraints[*].topologyKey` 的节点将被忽略。这意味着: +- 调度器会忽略没有 `topologySpreadConstraints[*].topologyKey` 的节点。这意味着: 1. 位于这些节点上的 Pod 不影响 `maxSkew` 的计算。 在上面的例子中,假设 "node1" 没有标签 "zone",那么 2 个 Pod 将被忽略, 因此传入的 Pod 将被调度到 "zoneA" 中。 @@ -406,56 +469,6 @@ There are some implicit conventions worth noting here: 因此,如果这不是你所期望的,建议工作负载的 `topologySpreadConstraints[*].labelSelector` 与其自身的标签匹配。 - -- 如果新 Pod 定义了 `spec.nodeSelector` 或 `spec.affinity.nodeAffinity`,则 - 不匹配的节点会被忽略。 - - 假设你有一个跨越 zoneA 到 zoneC 的 5 节点集群: - - {{}} - graph BT - subgraph "zoneB" - p3(Pod) --> n3(Node3) - n4(Node4) - end - subgraph "zoneA" - p1(Pod) --> n1(Node1) - p2(Pod) --> n2(Node2) - end - - classDef plain fill:#ddd,stroke:#fff,stroke-width:4px,color:#000; - classDef k8s fill:#326ce5,stroke:#fff,stroke-width:4px,color:#fff; - classDef cluster fill:#fff,stroke:#bbb,stroke-width:2px,color:#326ce5; - class n1,n2,n3,n4,p1,p2,p3 k8s; - class p4 plain; - class zoneA,zoneB cluster; - {{< /mermaid >}} - - {{}} - graph BT - subgraph "zoneC" - n5(Node5) - end - - classDef plain fill:#ddd,stroke:#fff,stroke-width:4px,color:#000; - classDef k8s fill:#326ce5,stroke:#fff,stroke-width:4px,color:#fff; - classDef cluster fill:#fff,stroke:#bbb,stroke-width:2px,color:#326ce5; - class n5 k8s; - class zoneC cluster; - {{< /mermaid >}} - - - 而且你知道 "zoneC" 必须被排除在外。在这种情况下,可以按如下方式编写 yaml, - 以便将 "mypod" 放置在 "zoneB" 上,而不是 "zoneC" 上。同样,`spec.nodeSelector` - 也要一样处理。 - - {{< codenew file="pods/topology-spread-constraints/one-constraint-with-nodeaffinity.yaml" >}} -