diff --git a/content/zh/docs/concepts/workloads/controllers/_index.md b/content/zh/docs/concepts/workloads/controllers/_index.md index 05824cb190..1518d9341d 100644 --- a/content/zh/docs/concepts/workloads/controllers/_index.md +++ b/content/zh/docs/concepts/workloads/controllers/_index.md @@ -1,4 +1,4 @@ --- -title: "控制器" +title: "工作负载资源" weight: 20 --- diff --git a/content/zh/docs/concepts/workloads/controllers/deployment.md b/content/zh/docs/concepts/workloads/controllers/deployment.md index af26b817cb..8969cad235 100644 --- a/content/zh/docs/concepts/workloads/controllers/deployment.md +++ b/content/zh/docs/concepts/workloads/controllers/deployment.md @@ -201,20 +201,20 @@ Follow the steps given below to create the above Deployment: 3. 要查看 Deployment 上线状态,运行 `kubectl rollout status deployment.v1.apps/nginx-deployment`。 输出类似于: - ``` - Waiting for rollout to finish: 2 out of 3 new replicas have been updated... - deployment "nginx-deployment" successfully rolled out - ``` + ``` + Waiting for rollout to finish: 2 out of 3 new replicas have been updated... + deployment "nginx-deployment" successfully rolled out + ``` 4. 几秒钟后再次运行 `kubectl get deployments`。输出类似于: - ``` - NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE - nginx-deployment 3 3 3 3 18s - ``` + ``` + NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE + nginx-deployment 3 3 3 3 18s + ``` -超过截止时间后, Deployment 控制器将添加具有以下属性的 DeploymentCondition 到 +超过截止时间后,Deployment 控制器将添加具有以下属性的 DeploymentCondition 到 Deployment 的 `.status.conditions` 中: * Type=Progressing @@ -1514,7 +1514,9 @@ Deployment 的 `.status.conditions` 中: -参考 [Kubernetes API 约定](https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#typical-status-properties) 获取更多状态状况相关的信息。 +参考 +[Kubernetes API 约定](https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#typical-status-properties) +获取更多状态状况相关的信息。 diff --git a/content/zh/docs/concepts/workloads/controllers/job.md b/content/zh/docs/concepts/workloads/controllers/job.md index 513591b317..6690a96d13 100644 --- a/content/zh/docs/concepts/workloads/controllers/job.md +++ b/content/zh/docs/concepts/workloads/controllers/job.md @@ -5,7 +5,7 @@ feature: title: 批量执行 description: > 除了服务之外,Kubernetes 还可以管理你的批处理和 CI 工作负载,在期望时替换掉失效的容器。 -weight: 60 +weight: 50 --- diff --git a/content/zh/docs/concepts/workloads/controllers/replicaset.md b/content/zh/docs/concepts/workloads/controllers/replicaset.md index 60fb6bc36d..4446ad496b 100644 --- a/content/zh/docs/concepts/workloads/controllers/replicaset.md +++ b/content/zh/docs/concepts/workloads/controllers/replicaset.md @@ -1,8 +1,17 @@ --- title: ReplicaSet content_type: concept -weight: 10 +weight: 20 --- + @@ -18,30 +27,25 @@ ReplicaSet 的目的是维护一组在任何时候都处于运行状态的 Pod ## ReplicaSet 的工作原理 {#how-a-replicaset-works} RepicaSet 是通过一组字段来定义的,包括一个用来识别可获得的 Pod -的集合的选择算符,一个用来标明应该维护的副本个数的数值,一个用来指定应该创建新 Pod -以满足副本个数条件时要使用的 Pod 模板等等。每个 ReplicaSet 都通过根据需要创建和 -删除 Pod 以使得副本个数达到期望值,进而实现其存在价值。当 ReplicaSet 需要创建 -新的 Pod 时,会使用所提供的 Pod 模板。 +的集合的选择算符、一个用来标明应该维护的副本个数的数值、一个用来指定应该创建新 Pod +以满足副本个数条件时要使用的 Pod 模板等等。 +每个 ReplicaSet 都通过根据需要创建和 删除 Pod 以使得副本个数达到期望值, +进而实现其存在价值。当 ReplicaSet 需要创建新的 Pod 时,会使用所提供的 Pod 模板。 ReplicaSet 通过 Pod 上的 [metadata.ownerReferences](/zh/docs/concepts/workloads/controllers/garbage-collection/#owners-and-dependents) @@ -51,41 +55,14 @@ ReplicaSet 所获得的 Pod 都在其 ownerReferences 字段中包含了属主 R 并据此计划其操作行为。 ReplicaSet 使用其选择算符来辨识要获得的 Pod 集合。如果某个 Pod 没有 OwnerReference 或者其 OwnerReference 不是一个 {{< glossary_tooltip text="控制器" term_id="controller" >}},且其匹配到 某 ReplicaSet 的选择算符,则该 Pod 立即被此 ReplicaSet 获得。 - -## 怎样使用 ReplicaSet {#how-to-use-a-replicaset} - -大多数支持 Replication Controllers 的[`kubectl`](/zh/docs/reference/kubectl/kubectl/)命令也支持 ReplicaSets。但[`rolling-update`](/docs/reference/generated/kubectl/kubectl-commands#rolling-update) 命令是个例外。如果您想要滚动更新功能请考虑使用 Deployment。[`rolling-update`](/docs/reference/generated/kubectl/kubectl-commands#rolling-update) 命令是必需的,而 Deployment 是声明性的,因此我们建议通过 [`rollout`](/docs/reference/generated/kubectl/kubectl-commands#rollout)命令使用 Deployment。 - -虽然 ReplicaSets 可以独立使用,但今天它主要被[Deployments](/zh/docs/concepts/workloads/controllers/deployment/) 用作协调 Pod 创建、删除和更新的机制。 -当您使用 Deployment 时,您不必担心还要管理它们创建的 ReplicaSet。Deployment 会拥有并管理它们的 ReplicaSet。 - - -## 什么时候使用 ReplicaSet +## 何时使用 ReplicaSet ReplicaSet 确保任何时间都有指定数量的 Pod 副本在运行。 -然而,Deployment 是一个更高级的概念,它管理 ReplicaSet,并向 Pod 提供声明式的更新以及许多其他有用的功能。 -因此,我们建议使用 Deployment 而不是直接使用 ReplicaSet,除非您需要自定义更新业务流程或根本不需要更新。 +然而,Deployment 是一个更高级的概念,它管理 ReplicaSet,并向 Pod +提供声明式的更新以及许多其他有用的功能。 +因此,我们建议使用 Deployment 而不是直接使用 ReplicaSet,除非 +你需要自定义更新业务流程或根本不需要更新。 -这实际上意味着,您可能永远不需要操作 ReplicaSet 对象:而是使用 Deployment,并在 spec 部分定义您的应用。 +这实际上意味着,你可能永远不需要操作 ReplicaSet 对象:而是使用 +Deployment,并在 spec 部分定义你的应用。 +将此清单保存到 `frontend.yaml` 中,并将其提交到 Kubernetes 集群, +应该就能创建 yaml 文件所定义的 ReplicaSet 及其管理的 Pod。 -将此清单保存到 `frontend.yaml` 中,并将其提交到 Kubernetes 集群,应该就能创建 yaml 文件所定义的 ReplicaSet 及其管理的 Pod。 ```shell -$ kubectl create -f http://k8s.io/examples/controllers/frontend.yaml -replicaset.apps/frontend created -$ kubectl describe rs/frontend +kubectl apply -f https://kubernetes.io/examples/controllers/frontend.yaml +``` + + +你可以看到当前被部署的 ReplicaSet: + +```shell +kubectl get rs +``` + + +并看到你所创建的前端: + +``` +NAME DESIRED CURRENT READY AGE +frontend 3 3 3 6s +``` + + +你也可以查看 ReplicaSet 的状态: + +```shell +kubectl describe rs/frontend +``` + + +你会看到类似如下的输出: + +``` Name: frontend Namespace: default -Selector: tier=frontend,tier in (frontend) +Selector: tier=frontend Labels: app=guestbook tier=frontend -Annotations: +Annotations: kubectl.kubernetes.io/last-applied-configuration: + {"apiVersion":"apps/v1","kind":"ReplicaSet","metadata":{"annotations":{},"labels":{"app":"guestbook","tier":"frontend"},"name":"frontend",... Replicas: 3 current / 3 desired Pods Status: 3 Running / 0 Waiting / 0 Succeeded / 0 Failed Pod Template: - Labels: app=guestbook - tier=frontend + Labels: tier=frontend Containers: php-redis: Image: gcr.io/google_samples/gb-frontend:v3 - Port: 80/TCP - Requests: - cpu: 100m - memory: 100Mi - Environment: - GET_HOSTS_FROM: dns + Port: + Host Port: + Environment: Mounts: Volumes: Events: - FirstSeen LastSeen Count From SubobjectPath Type Reason Message - --------- -------- ----- ---- ------------- -------- ------ ------- - 1m 1m 1 {replicaset-controller } Normal SuccessfulCreate Created pod: frontend-qhloh - 1m 1m 1 {replicaset-controller } Normal SuccessfulCreate Created pod: frontend-dnjpy - 1m 1m 1 {replicaset-controller } Normal SuccessfulCreate Created pod: frontend-9si5l -$ kubectl get pods -NAME READY STATUS RESTARTS AGE -frontend-9si5l 1/1 Running 0 1m -frontend-dnjpy 1/1 Running 0 1m -frontend-qhloh 1/1 Running 0 1m + Type Reason Age From Message + ---- ------ ---- ---- ------- + Normal SuccessfulCreate 117s replicaset-controller Created pod: frontend-wtsmm + Normal SuccessfulCreate 116s replicaset-controller Created pod: frontend-b2zdv + Normal SuccessfulCreate 116s replicaset-controller Created pod: frontend-vcmts ``` + +最后可以查看启动了的 Pods: + +```shell +kubectl get pods +``` + + +你会看到类似如下的 Pod 信息: + +``` +NAME READY STATUS RESTARTS AGE +frontend-b2zdv 1/1 Running 0 6m36s +frontend-vcmts 1/1 Running 0 6m36s +frontend-wtsmm 1/1 Running 0 6m36s +``` + + +你也可以查看 Pods 的属主引用被设置为前端的 ReplicaSet。 +要实现这点,可取回运行中的 Pods 之一的 YAML: + +```shell +kubectl get pods frontend-b2zdv -o yaml +``` + + +输出将类似这样,frontend ReplicaSet 的信息被设置在 metadata 的 +`ownerReferences` 字段中: + +```yaml +apiVersion: v1 +kind: Pod +metadata: + creationTimestamp: "2020-02-12T07:06:16Z" + generateName: frontend- + labels: + tier: frontend + name: frontend-b2zdv + namespace: default + ownerReferences: + - apiVersion: apps/v1 + blockOwnerDeletion: true + controller: true + kind: ReplicaSet + name: frontend + uid: f391f6db-bb9b-4c09-ae74-6a1f77f3d5cf +... +``` + + +## 非模板 Pod 的获得 + + +尽管你完全可以直接创建裸的 Pods,强烈建议你确保这些裸的 Pods 并不包含可能与你 +的某个 ReplicaSet 的选择算符相匹配的标签。原因在于 ReplicaSet 并不仅限于拥有 +在其模板中设置的 Pods,它还可以像前面小节中所描述的那样获得其他 Pods。 + +{{< codenew file="pods/pod-rs.yaml" >}} + + +由于这些 Pod 没有控制器(Controller,或其他对象)作为其属主引用,并且 +其标签与 frontend ReplicaSet 的选择算符匹配,它们会立即被该 ReplicaSet +获取。 + +假定你在 frontend ReplicaSet 已经被部署之后创建 Pods,并且你已经在 ReplicaSet +中设置了其初始的 Pod 副本数以满足其副本计数需要: + +```shell +kubectl apply -f https://kubernetes.io/examples/pods/pod-rs.yaml +``` + + +新的 Pods 会被该 ReplicaSet 获取,并立即被 ReplicaSet 终止,因为 +它们的存在会使得 ReplicaSet 中 Pod 个数超出其期望值。 + +取回 Pods: + + +```shell +kubectl get pods +``` + + +输出显示新的 Pods 或者已经被终止,或者处于终止过程中: + +```shell +NAME READY STATUS RESTARTS AGE +frontend-b2zdv 1/1 Running 0 10m +frontend-vcmts 1/1 Running 0 10m +frontend-wtsmm 1/1 Running 0 10m +pod1 0/1 Terminating 0 1s +pod2 0/1 Terminating 0 1s +``` + + +如果你先行创建 Pods: + +```shell +kubectl apply -f https://kubernetes.io/examples/pods/pod-rs.yaml +``` + + +之后再创建 ReplicaSet: + +```shell +kubectl apply -f https://kubernetes.io/examples/controllers/frontend.yaml +``` + + +你会看到 ReplicaSet 已经获得了该 Pods,并仅根据其规约创建新的 Pods,直到 +新的 Pods 和原来的 Pods 的总数达到其预期个数。 +这时取回 Pods: + +```shell +kubectl get pods +``` + + +将会生成下面的输出: + +``` +NAME READY STATUS RESTARTS AGE +frontend-hmmj2 1/1 Running 0 9s +pod1 1/1 Running 0 36s +pod2 1/1 Running 0 36s +``` + +采用这种方式,一个 ReplicaSet 中可以包含异质的 Pods 集合。 + +## 编写 ReplicaSet 的 spec -## 编写 ReplicaSet Spec +与所有其他 Kubernetes API 对象一样,ReplicaSet 也需要 `apiVersion`、`kind`、和 `metadata` 字段。 +对于 ReplicaSets 而言,其 kind 始终是 ReplicaSet。 +在 Kubernetes 1.9 中,ReplicaSet 上的 API 版本 `apps/v1` 是其当前版本,且被 +默认启用。API 版本 `apps/v1beta2` 已被废弃。 +参考 `frontend.yaml` 示例的第一行。 -与所有其他 Kubernetes API 对象一样,ReplicaSet 也需要 `apiVersion`、`kind`、和 `metadata` 字段。有关使用清单的一般信息,请参见 [使用 kubectl 管理对象](/zh/docs/concepts/overview/working-with-objects/object-management/)。 +ReplicaSet 对象的名称必须是合法的 +[DNS 子域名](/zh/docs/concepts/overview/working-with-objects/names#dns-subdomain-names)。 -ReplicaSet 也需要 [`.spec`](https://git.k8s.io/community/contributors/devel/api-conventions.md#spec-and-status) 部分。 +ReplicaSet 也需要 [`.spec`](https://git.k8s.io/community/contributors/devel/api-conventions.md#spec-and-status) +部分。 - ### Pod 模版 -`.spec.template` 是 `.spec` 唯一需要的字段。`.spec.template` 是 [Pod 模版](/zh/docs/concepts/workloads/pods/#pod-templates)。它和 [Pod](/zh/docs/concepts/workloads/pods/) 的语法几乎完全一样,除了它是嵌套的并没有 `apiVersion` 和 `kind`。 +`.spec.template` 是一个[Pod 模版](/zh/docs/concepts/workloads/pods/#pod-templates), +要求设置标签。在 `frontend.yaml` 示例中,我们指定了标签 `tier: frontend`。 +注意不要将标签与其他控制器的选择算符重叠,否则那些控制器会尝试收养此 Pod。 -除了所需的 Pod 字段之外,ReplicaSet 中的 Pod 模板必须指定适当的标签和适当的重启策略。 - -对于标签,请确保不要与其他控制器重叠。更多信息请参考 [Pod 选择器](#pod-selector)。 - -对于 [重启策略](/zh/docs/concepts/workloads/pods/pod-lifecycle/#restart-policy),`.spec.template.spec.restartPolicy` 唯一允许的取值是 `Always`,这也是默认值. - -对于本地容器重新启动,ReplicaSet 委托给了节点上的代理去执行,例如[Kubelet](/zh/docs/reference/command-line-tools-reference/kubelet/) 或 Docker 去执行。 +对于模板的[重启策略](/zh/docs/concepts/workloads/pods/pod-lifecycle/#restart-policy) +字段,`.spec.template.spec.restartPolicy`,唯一允许的取值是 `Always`,这也是默认值. +### Pod 选择算符 {#pod-selector} -### Pod 选择器 +`.spec.selector` 字段是一个[标签选择算符](/zh/docs/concepts/overview/working-with-objects/labels/)。 +如前文中[所讨论的](how-a-replicaset-works),这些是用来标识要被获取的 Pods +的标签。在签名的 `frontend.yaml` 示例中,选择算符为: -`.spec.selector` 字段是[标签选择器](/zh/docs/concepts/overview/working-with-objects/labels/)。ReplicaSet 管理所有标签匹配与标签选择器的 Pod。它不区分自己创建或删除的 Pod 和其他人或进程创建或删除的pod。这允许在不影响运行中的 Pod 的情况下替换副本集。 +```yaml +matchLabels: + tier: frontend +``` -`.spec.template.metadata.labels` 必须匹配 `.spec.selector`,否则它将被 API 拒绝。 +在 ReplicaSet 中,`.spec.template.metadata.labels` 的值必须与 `spec.selector` 值 +相匹配,否则该配置会被 API 拒绝。 -Kubernetes 1.9 版本中,API 版本 `apps/v1` 中的 ReplicaSet 类型的版本是当前版本并默认开启。API 版本 `apps/v1beta2` 被弃用。 +{{< note >}} + +对于设置了相同的 `.spec.selector`,但 +`.spec.template.metadata.labels` 和 `.spec.template.spec` 字段不同的 +两个 ReplicaSet 而言,每个 ReplicaSet 都会忽略被另一个 ReplicaSet 所 +创建的 Pods。 +{{< /note >}} - -另外,通常您不应该创建标签与此选择器匹配的任何 Pod,或者直接与另一个 ReplicaSet 或另一个控制器(如 Deployment)标签匹配的任何 Pod。 -如果你这样做,ReplicaSet 会认为它创造了其他 Pod。Kubernetes 并不会阻止您这样做。 - -如果您最终使用了多个具有重叠选择器的控制器,则必须自己负责删除。 - - - ### Replicas -通过设置 `.spec.replicas` 您可以指定要同时运行多少个 Pod。 -在任何时间运行的 Pod 数量可能高于或低于 `.spec.replicas` 指定的数量,例如在副本刚刚被增加或减少后、或者 Pod 正在被优雅地关闭、以及替换提前开始。 +你可以通过设置 `.spec.replicas` 来指定要同时运行的 Pod 个数。 +ReplicaSet 创建、删除 Pods 以与此值匹配。 -如果您没有指定 `.spec.replicas`, 那么默认值为 1。 +如果你没有指定 `.spec.replicas`, 那么默认值为 1。 - -## 使用 ReplicaSets 的具体方法 +## 使用 ReplicaSets ### 删除 ReplicaSet 和它的 Pod -要删除 ReplicaSet 和它的所有 Pod,使用[`kubectl delete`](/docs/reference/generated/kubectl/kubectl-commands#delete) 命令。 -默认情况下,[垃圾收集器](/zh/docs/concepts/workloads/controllers/garbage-collection/) 自动删除所有依赖的 Pod。 +要删除 ReplicaSet 和它的所有 Pod,使用 +[`kubectl delete`](/docs/reference/generated/kubectl/kubectl-commands#delete) 命令。 +默认情况下,[垃圾收集器](/zh/docs/concepts/workloads/controllers/garbage-collection/) +自动删除所有依赖的 Pod。 -当使用 REST API 或 `client-go` 库时,您必须在删除选项中将 `propagationPolicy` 设置为 `Background` 或 `Foreground`。例如: +当使用 REST API 或 `client-go` 库时,你必须在删除选项中将 `propagationPolicy` +设置为 `Background` 或 `Foreground`。例如: ```shell kubectl proxy --port=8080 curl -X DELETE 'localhost:8080/apis/apps/v1/namespaces/default/replicasets/frontend' \ -> -d '{"kind":"DeleteOptions","apiVersion":"v1","propagationPolicy":"Foreground"}' \ -> -H "Content-Type: application/json" + -d '{"kind":"DeleteOptions","apiVersion":"v1","propagationPolicy":"Foreground"}' \ + -H "Content-Type: application/json" ``` - ### 只删除 ReplicaSet -您可以只删除 ReplicaSet 而不影响它的 Pod,方法是使用[`kubectl delete`](/docs/reference/generated/kubectl/kubectl-commands#delete) 命令并设置 `--cascade=false` 选项。 +你可以只删除 ReplicaSet 而不影响它的 Pod,方法是使用 +[`kubectl delete`](/docs/reference/generated/kubectl/kubectl-commands#delete) +命令并设置 `--cascade=false` 选项。 -当使用 REST API 或 `client-go` 库时,您必须将 `propagationPolicy` 设置为 `Orphan`。例如: +当使用 REST API 或 `client-go` 库时,你必须将 `propagationPolicy` 设置为 `Orphan`。 +例如: ```shell kubectl proxy --port=8080 curl -X DELETE 'localhost:8080/apis/apps/v1/namespaces/default/replicasets/frontend' \ -> -d '{"kind":"DeleteOptions","apiVersion":"v1","propagationPolicy":"Orphan"}' \ -> -H "Content-Type: application/json" + -d '{"kind":"DeleteOptions","apiVersion":"v1","propagationPolicy":"Orphan"}' \ + -H "Content-Type: application/json" ``` - 一旦删除了原来的 ReplicaSet,就可以创建一个新的来替换它。 由于新旧 ReplicaSet 的 `.spec.selector` 是相同的,新的 ReplicaSet 将接管老的 Pod。 但是,它不会努力使现有的 Pod 与新的、不同的 Pod 模板匹配。 -若想要以可控的方式将 Pod 更新到新的 spec,就要使用 [滚动更新](#rolling-updates)的方式。 - +若想要以可控的方式更新 Pod 的规约,可以使用 +[Deployment](/zh/docs/concepts/workloads/controllers/deployment/#creating-a-deployment) +资源,因为 ReplicaSet 并不直接支持滚动更新。 - ### 将 Pod 从 ReplicaSet 中隔离 -可以通过改变标签来从 ReplicaSet 的目标集中移除 Pod。这种技术可以用来从服务中去除 Pod,以便进行排错、数据恢复等。 +可以通过改变标签来从 ReplicaSet 的目标集中移除 Pod。 +这种技术可以用来从服务中去除 Pod,以便进行排错、数据恢复等。 以这种方式移除的 Pod 将被自动替换(假设副本的数量没有改变)。 - ### 缩放 RepliaSet -通过更新 `.spec.replicas` 字段,ReplicaSet 可以被轻松的进行缩放。ReplicaSet 控制器能确保匹配标签选择器的数量的 Pod 是可用的和可操作的。 +通过更新 `.spec.replicas` 字段,ReplicaSet 可以被轻松的进行缩放。ReplicaSet +控制器能确保匹配标签选择器的数量的 Pod 是可用的和可操作的。 - ### ReplicaSet 作为水平的 Pod 自动缩放器目标 -ReplicaSet 也可以作为 [水平的 Pod 缩放器 (HPA)](/docs/tasks/run-application/horizontal-pod-autoscale/) 的目标。也就是说,ReplicaSet 可以被 HPA 自动缩放。 +ReplicaSet 也可以作为 +[水平的 Pod 缩放器 (HPA)](/zh/docs/tasks/run-application/horizontal-pod-autoscale/) +的目标。也就是说,ReplicaSet 可以被 HPA 自动缩放。 以下是 HPA 以我们在前一个示例中创建的副本集为目标的示例。 - {{< codenew file="controllers/hpa-rs.yaml" >}} - -将这个列表保存到 `hpa-rs.yaml` 并提交到 Kubernetes 集群,就能创建它所定义的 HPA,进而就能根据复制的 Pod 的 CPU 利用率对目标 ReplicaSet进行自动缩放。 +将这个列表保存到 `hpa-rs.yaml` 并提交到 Kubernetes 集群,就能创建它所定义的 +HPA,进而就能根据复制的 Pod 的 CPU 利用率对目标 ReplicaSet进行自动缩放。 ```shell -kubectl create -f https://k8s.io/examples/controllers/hpa-rs.yaml +kubectl apply -f https://k8s.io/examples/controllers/hpa-rs.yaml ``` - -或者,可以使用 `kubectl autoscale` 命令完成相同的操作。 -(而且它更简单!) +或者,可以使用 `kubectl autoscale` 命令完成相同的操作。 (而且它更简单!) ```shell -kubectl autoscale rs frontend +kubectl autoscale rs frontend --max=10 --min=3 --cpu-percent=50 ``` - ## ReplicaSet 的替代方案 ### Deployment (推荐) -[`Deployment`](/zh/docs/concepts/workloads/controllers/deployment/) 是一个高级 API 对象,它以 `kubectl rolling-update` 的方式更新其底层副本集及其Pod。 -如果您需要滚动更新功能,建议使用 Deployment,因为 Deployment 与 `kubectl rolling-update` 不同的是:它是声明式的、服务器端的、并且具有其他特性。 -有关使用 Deployment 来运行无状态应用的更多信息,请参阅 [使用 Deployment 运行无状态应用](/zh/docs/tasks/run-application/run-stateless-application-deployment/)。 +[`Deployment`](/zh/docs/concepts/workloads/controllers/deployment/) 是一个 +可以拥有 ReplicaSet 并使用声明式方式在服务器端完成对 Pods 滚动更新的对象。 +尽管 ReplicaSet 可以独立使用,目前它们的主要用途是提供给 Deployment 作为 +编排 Pod 创建、删除和更新的一种机制。当使用 Deployment 时,你不必关心 +如何管理它所创建的 ReplicaSet,Deployment 拥有并管理其 ReplicaSet。 +因此,建议你在需要 ReplicaSet 时使用 Deployment。 - ### 裸 Pod -与用户直接创建 Pod 的情况不同,ReplicaSet 会替换那些由于某些原因被删除或被终止的 Pod,例如在节点故障或破坏性的节点维护(如内核升级)的情况下。 -因为这个好处,我们建议您使用 ReplicaSet,即使应用程序只需要一个 Pod。 -想像一下,ReplicaSet 类似于进程监视器,只不过它在多个节点上监视多个 Pod,而不是在单个节点上监视单个进程。 +与用户直接创建 Pod 的情况不同,ReplicaSet 会替换那些由于某些原因被删除或被终止的 +Pod,例如在节点故障或破坏性的节点维护(如内核升级)的情况下。 +因为这个原因,我们建议你使用 ReplicaSet,即使应用程序只需要一个 Pod。 +想像一下,ReplicaSet 类似于进程监视器,只不过它在多个节点上监视多个 Pod, +而不是在单个节点上监视单个进程。 ReplicaSet 将本地容器重启的任务委托给了节点上的某个代理(例如,Kubelet 或 Docker)去完成。 ### Job -使用[`Job`](/zh/docs/concepts/workloads/controllers/job/) 代替ReplicaSet,可以用于那些期望自行终止的 Pod。 +使用[`Job`](/zh/docs/concepts/workloads/controllers/job/) 代替ReplicaSet, +可以用于那些期望自行终止的 Pod。 - ### DaemonSet -对于管理那些提供主机级别功能(如主机监控和主机日志)的容器,就要用[`DaemonSet`](/zh/docs/concepts/workloads/controllers/daemonset/) 而不用 ReplicaSet。 -这些 Pod 的寿命与主机寿命有关:这些 Pod 需要先于主机上的其他 Pod 运行,并且在机器准备重新启动/关闭时安全地终止。 +对于管理那些提供主机级别功能(如主机监控和主机日志)的容器, +就要用 [`DaemonSet`](/zh/docs/concepts/workloads/controllers/daemonset/) +而不用 ReplicaSet。 +这些 Pod 的寿命与主机寿命有关:这些 Pod 需要先于主机上的其他 Pod 运行, +并且在机器准备重新启动/关闭时安全地终止。 +### ReplicationController + +ReplicaSet 是 [ReplicationController](/zh/docs/concepts/workloads/controllers/replicationcontroller/) +的后继者。二者目的相同且行为类似,只是 ReplicationController 不支持 +[标签用户指南](/zh/docs/concepts/overview/working-with-objects/labels/#label-selectors) +中讨论的基于集合的选择算符需求。 +因此,相比于 ReplicationController,应优先考虑 ReplicaSet。 diff --git a/content/zh/docs/concepts/workloads/controllers/replicationcontroller.md b/content/zh/docs/concepts/workloads/controllers/replicationcontroller.md index 7c3b5988e1..bc28f4cbef 100644 --- a/content/zh/docs/concepts/workloads/controllers/replicationcontroller.md +++ b/content/zh/docs/concepts/workloads/controllers/replicationcontroller.md @@ -7,7 +7,7 @@ feature: 重新启动失败的容器,在节点死亡时替换并重新调度容器,杀死不响应用户定义的健康检查的容器,并且在它们准备好服务之前不会将它们公布给客户端。 content_type: concept -weight: 20 +weight: 90 --- @@ -499,7 +499,7 @@ API object can be found at: ### ReplicaSet [`ReplicaSet`](/docs/concepts/workloads/controllers/replicaset/) is the next-generation ReplicationController that supports the new [set-based label selector](/docs/concepts/overview/working-with-objects/labels/#set-based-requirement). -It’s mainly used by [`Deployment`](/docs/concepts/workloads/controllers/deployment/) as a mechanism to orchestrate Pod creation, deletion and updates. +It’s mainly used by [Deployment](/docs/concepts/workloads/controllers/deployment/) as a mechanism to orchestrate Pod creation, deletion and updates. Note that we recommend using Deployments instead of directly using Replica Sets, unless you require custom update orchestration or don’t require updates at all. --> ## ReplicationController 的替代方案 @@ -508,8 +508,10 @@ Note that we recommend using Deployments instead of directly using Replica Sets, [`ReplicaSet`](/zh/docs/concepts/workloads/controllers/replicaset/) 是下一代 ReplicationController, 支持新的[基于集合的标签选择算符](/zh/docs/concepts/overview/working-with-objects/labels/#set-based-requirement)。 -它主要被 [`Deployment`](/zh/docs/concepts/workloads/controllers/deployment/) 用来作为一种编排 Pod 创建、删除及更新的机制。 -请注意,我们推荐使用 Deployment 而不是直接使用 ReplicaSet,除非你需要自定义更新编排或根本不需要更新。 +它主要被 [`Deployment`](/zh/docs/concepts/workloads/controllers/deployment/) +用来作为一种编排 Pod 创建、删除及更新的机制。 +请注意,我们推荐使用 Deployment 而不是直接使用 ReplicaSet,除非 +你需要自定义更新编排或根本不需要更新。 ### Pod 模版 {#pod-templates} @@ -405,7 +405,7 @@ or POSIX shared memory. Containers in different Pods have distinct IP addresses and can not communicate by IPC without [special configuration](/docs/concepts/policy/pod-security-policy/). Containers that want to interact with a container running in a different Pod can -use IP networking to comunicate. +use IP networking to communicate. --> 在同一个 Pod 内,所有容器共享一个 IP 地址和端口空间,并且可以通过 `localhost` 发现对方。 他们也能通过如 SystemV 信号量或 POSIX 共享内存这类标准的进程间通信方式互相通信。 @@ -487,7 +487,7 @@ but cannot be controlled from there. - -本页提供了 Init 容器的概览,它是一种特殊容器,在 {{< glossary_tooltip text="Pod" term_id="pod" >}} -内的应用容器启动之前运行,可以包括一些应用镜像中不存在的实用工具和安装脚本。 +本页提供了 Init 容器的概览。Init 容器是一种特殊容器,在 {{< glossary_tooltip text="Pod" term_id="pod" >}} +内的应用容器启动之前运行。Init 容器可以包括一些应用镜像中不存在的实用工具和安装脚本。 你可以在 Pod 的规约中与用来描述应用容器的 `containers` 数组平行的位置指定 Init 容器。 @@ -26,7 +35,9 @@ Init 容器。 ## 理解 Init 容器 @@ -35,6 +46,7 @@ A {{< glossary_tooltip text="Pod" term_id="pod" >}} can have multiple containers @@ -44,15 +56,20 @@ Init 容器与普通的容器非常像,除了如下两点: * 每个都必须在下一个启动之前成功完成。 -如果 Pod 的 Init 容器失败,Kubernetes 会不断地重启该 Pod,直到 Init 容器成功为止。 -然而,如果 Pod 对应的 `restartPolicy` 值为 Never,Kubernetes 不会重新启动 Pod。 +如果 Pod 的 Init 容器失败,kubelet 会不断地重启该 Init 容器直到该容器成功为止。 +然而,如果 Pod 对应的 `restartPolicy` 值为 "Never",Kubernetes 不会重新启动 Pod。 为 Pod 设置 Init 容器需要在 Pod 的 `spec` 中添加 `initContainers` 字段, 该字段以 [Container](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#container-v1-core) @@ -62,9 +79,19 @@ Init 容器的状态在 `status.initContainerStatuses` 字段中以容器状态 ### 与普通容器的不同之处 @@ -80,12 +107,24 @@ Kubernetes 才会为 Pod 初始化应用容器并像平常一样运行。 ## 使用 Init 容器 @@ -108,12 +147,15 @@ Because init containers have separate images from app containers, they have some ### 示例 {#examples} @@ -156,24 +202,10 @@ Here are some ideas for how to use init containers: ### 使用 Init 容器的情况 @@ -201,63 +233,40 @@ spec: command: ['sh', '-c', "until nslookup mydb.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; do echo waiting for mydb; sleep 2; done"] ``` -下面的 yaml 文件展示了 `mydb` 和 `myservice` 两个 Service: - -``` -kind: Service -apiVersion: v1 -metadata: - name: myservice -spec: - ports: - - protocol: TCP - port: 80 - targetPort: 9376 ---- -kind: Service -apiVersion: v1 -metadata: - name: mydb -spec: - ports: - - protocol: TCP - port: 80 - targetPort: 9377 -``` - -要启动这个 Pod,可以执行如下命令: + +你通过运行下面的命令启动 Pod: ```shell kubectl apply -f myapp.yaml ``` - -输出为: - ``` pod/myapp-pod created ``` -要检查其状态: + +使用下面的命令检查其状态: ```shell kubectl get -f myapp.yaml ``` - -输出类似于: - ``` NAME READY STATUS RESTARTS AGE myapp-pod 0/1 Init:0/2 0 6m ``` -如需更详细的信息: + +或者查看更多详细信息: ```shell kubectl describe -f myapp.yaml ``` -输出类似于: - ``` Name: myapp-pod Namespace: default @@ -293,6 +302,9 @@ Events: 13s 13s 1 {kubelet 172.17.4.201} spec.initContainers{init-myservice} Normal Started Started container with docker id 5ced34a04634 ``` + 如需查看 Pod 内 Init 容器的日志,请执行: ```shell @@ -301,7 +313,8 @@ kubectl logs myapp-pod -c init-mydb # 查看第二个 Init 容器 ``` @@ -332,23 +345,27 @@ spec: targetPort: 9377 ``` + 创建 `mydb` 和 `myservice` 服务的命令: ```shell kubectl create -f services.yaml ``` - -输出类似于: - ``` service "myservice" created service "mydb" created ``` + 这样你将能看到这些 Init 容器执行完毕,随后 `my-app` 的 Pod 进入 `Running` 状态: ```shell -$ kubectl get -f myapp.yaml +kubectl get -f myapp.yaml ``` ``` @@ -356,32 +373,43 @@ NAME READY STATUS RESTARTS AGE myapp-pod 1/1 Running 0 9m ``` -一旦我们启动了 `mydb` 和 `myservice` 这两个服务,我们能够看到 Init 容器完成, -并且 `myapp-pod` 被创建。 - 这个简单例子应该能为你创建自己的 Init 容器提供一些启发。 -[接下来](#what-s-next)节提供了更详细例子的链接。 +[接下来](#whats-next)节提供了更详细例子的链接。 ## 具体行为 {#detailed-behavior} -在 Pod 启动过程中,每个 Init 容器在网络和数据卷初始化之后会按顺序启动。 +在 Pod 启动过程中,每个 Init 容器会在网络和数据卷初始化之后按顺序启动。 +kubelet 运行依据 Init 容器在 Pod 规约中的出现顺序依次运行之。 + 每个 Init 容器成功退出后才会启动下一个 Init 容器。 -如果它们因为容器运行时的原因无法启动,或以错误状态退出,它会根据 Pod 的 `restartPolicy` 策略进行重试。 -然而,如果 Pod 的 `restartPolicy` 设置为 "Always",Init 容器失败时会使用 `restartPolicy` -的 "OnFailure" 策略。 +如果某容器因为容器运行时的原因无法启动,或以错误状态退出,kubelet 会根据 +Pod 的 `restartPolicy` 策略进行重试。 +然而,如果 Pod 的 `restartPolicy` 设置为 "Always",Init 容器失败时会使用 +`restartPolicy` 的 "OnFailure" 策略。 在所有的 Init 容器没有成功之前,Pod 将不会变成 `Ready` 状态。 Init 容器的端口将不会在 Service 中进行聚集。正在初始化中的 Pod 处于 `Pending` 状态, @@ -390,11 +418,17 @@ Init 容器的端口将不会在 Service 中进行聚集。正在初始化中的 如果 Pod [重启](#pod-restart-reasons),所有 Init 容器必须重新执行。 对 Init 容器规约的修改仅限于容器的 `image` 字段。 更改 Init 容器的 `image` 字段,等同于重启该 Pod。 @@ -407,9 +441,12 @@ Init 容器具有应用容器的所有字段。然而 Kubernetes 禁止使用 `r Kubernetes 会在校验时强制执行此检查。 在 Pod 上使用 `activeDeadlineSeconds` 和在容器上使用 `livenessProbe` 可以避免 Init 容器一直重复失败。`activeDeadlineSeconds` 时间包含了 Init 容器启动的时间。 @@ -418,17 +455,21 @@ Init 容器一直重复失败。`activeDeadlineSeconds` 时间包含了 Init 容 与任何其它容器共享同一个名称,会在校验时抛出错误。 ### 资源 {#resources} @@ -442,15 +483,27 @@ Pod level control groups (cgroups) are based on the effective Pod request and li 这些资源在 Pod 生命周期过程中并没有被使用。 * Pod 的 *有效 QoS 层* ,与 Init 容器和应用容器的一样。 -配额和限制适用于有效 Pod的 limit/request。 -Pod 级别的 cgroups 是基于有效 Pod 的 limit/request,和调度器相同。 + +配额和限制适用于有效 Pod 的请求和限制值。 +Pod 级别的 cgroups 是基于有效 Pod 的请求和限制值,和调度器相同。 ### Pod 重启的原因 {#pod-restart-reasons} @@ -471,7 +524,6 @@ Pod 重启会导致 Init 容器重新执行,主要有如下几个原因: * Read about [creating a Pod that has an init container](/docs/tasks/configure-pod-container/configure-pod-initialization/#create-a-pod-that-has-an-init-container) * Learn how to [debug init containers](/docs/tasks/debug-application-cluster/debug-init-containers/) --> - * 阅读[创建包含 Init 容器的 Pod](/zh/docs/tasks/configure-pod-container/configure-pod-initialization/#create-a-pod-that-has-an-init-container) * 学习如何[调试 Init 容器](/zh/docs/tasks/debug-application-cluster/debug-init-containers/) diff --git a/content/zh/docs/concepts/workloads/pods/pod-lifecycle.md b/content/zh/docs/concepts/workloads/pods/pod-lifecycle.md index 3cbca2f16d..bd465ddcc8 100644 --- a/content/zh/docs/concepts/workloads/pods/pod-lifecycle.md +++ b/content/zh/docs/concepts/workloads/pods/pod-lifecycle.md @@ -19,7 +19,8 @@ of its primary containers starts OK, and then through either the `Succeeded` or Whilst a Pod is running, the kubelet is able to restart containers to handle some kind of faults. Within a Pod, Kubernetes tracks different container -[states](#container-states) and handles +[states](#container-states) and determines what action to take to make the Pod +healthy again. --> 本页面讲述 Pod 的生命周期。 Pod 遵循一个预定义的生命周期,起始于 `Pending` [阶段](#pod-phase),如果至少 @@ -28,7 +29,7 @@ Pod 遵循一个预定义的生命周期,起始于 `Pending` [阶段](#pod-pha 在 Pod 运行期间,`kubelet` 能够重启容器以处理一些失效场景。 在 Pod 内部,Kubernetes 跟踪不同容器的[状态](#container-states) -并处理可能出现的状况。 +并确定使 Pod 重新变得健康所需要采取的动作。 ### `Running`(运行中) {#container-state-running} `Running` 状态表明容器正在执行状态并且没有问题发生。 -如果配置了 `postStart` 回调,那么该回调已经执行完成。 +如果配置了 `postStart` 回调,那么该回调已经执行且已完成。 如果你使用 `kubectl` 来查询包含 `Running` 状态的容器的 Pod 时,你也会看到 关于容器进入 `Running` 状态的信息。 ## 容器重启策略 {#restart-policy} @@ -426,7 +427,8 @@ When a Pod's containers are Ready but at least one custom condition is missing o ## Container probes A [Probe](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#probe-v1-core) is a diagnostic -performed periodically by the [kubelet](/docs/admin/kubelet/) +performed periodically by the +[kubelet](/docs/reference/command-line-tools-reference/kubelet/) on a Container. To perform a diagnostic, the kubelet calls a [Handler](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#handler-v1-core) implemented by @@ -434,10 +436,10 @@ the container. There are three types of handlers: --> ## 容器探针 {#container-probes} -[探针](/zh/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#probe-v1-core) +[Probe](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#probe-v1-core) 是由 [kubelet](/zh/docs/reference/command-line-tools-reference/kubelet/) 对容器执行的定期诊断。 要执行诊断,kubelet 调用由容器实现的 -[Handler](/zh/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#handler-v1-core) +[Handler](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#handler-v1-core) (处理程序)。有三种类型的处理程序: ### 何时该使用启动探针? {#when-should-you-use-a-startup-probe} -{{< feature-state for_k8s_version="v1.16" state="alpha" >}} +{{< feature-state for_k8s_version="v1.18" state="beta" >}} 通常情况下,容器运行时会发送一个 TERM 信号到每个容器中的主进程。 +很多容器运行时都能够注意到容器镜像中 `STOPSIGNAL` 的值,并发送该信号而不是 TERM。 一旦超出了体面终止限期,容器运行时会向所有剩余进程发送 KILL 信号,之后 Pod 就会被从 {{< glossary_tooltip text="API 服务器" term_id="kube-apiserver" >}} 上移除。如果 `kubelet` 或者容器运行时的管理服务在等待进程终止期间被重启, @@ -666,9 +671,9 @@ An example flow: 1. You use the `kubectl` tool to manually delete a specific Pod, with the default grace period (30 seconds). 1. The Pod in the API server is updated with the time beyond which the Pod is considered "dead" - along with the grace period. + along with the grace period. If you use `kubectl describe` to check on the Pod you're deleting, that Pod shows up as - "Terminating". + "Terminating". On the node where the Pod is running: as soon as the kubelet sees that a Pod has been marked as terminating (a graceful shutdown duration has been set), the kubelet begins the local Pod shutdown process. @@ -737,7 +742,7 @@ An example flow: `SIGKILL` to any processes still running in any container in the Pod. The kubelet also cleans up a hidden `pause` container if that container runtime uses one. 1. The kubelet triggers forcible removal of Pod object from the API server, by setting grace period - to 0 (immediate deletion). + to 0 (immediate deletion). 1. The API server deletes the Pod's API object, which is then no longer visible from any client. --> 4. 超出终止宽限期线时,`kubelet` 会触发强制关闭过程。容器运行时会向 Pod 中所有容器内 @@ -745,14 +750,14 @@ An example flow: `kubelet` 也会清理隐藏的 `pause` 容器,如果容器运行时使用了这种容器的话。 5. `kubelet` 触发强制从 API 服务器上删除 Pod 对象的逻辑,并将体面终止限期设置为 0 - (这意味着马上删除)。 + (这意味着马上删除)。 6. API 服务器删除 Pod 的 API 对象,从任何客户端都无法再看到该对象。