zh-trans: merge zh content from release-1.16-temporary into release-1.16 (#18216)
* Update http-proxy-access-api.md (#16932) * Update coredns.md (#16930) * zh-trans:/docs/docs/concepts/workloads/pods/ephemeral-containers.md (#16948) * update zh-trans of define-environment-variable-container.md (#16999) Signed-off-by: Yixiang2019 <wang.yixiang@zte.com.cn> * update chinese docs (#16985) * Fix ordered list (#16988) Signed-off-by: PingWang <wang.ping5@zte.com.cn> update Signed-off-by: PingWang <wang.ping5@zte.com.cn> * zh-trans:/docs/reference/setup-tools/kubeadm/kubeadm-upgrade-phase.md (#16951) Signed-off-by: PingWang <wang.ping5@zte.com.cn> update Signed-off-by: PingWang <wang.ping5@zte.com.cn> update Signed-off-by: PingWang <wang.ping5@zte.com.cn> * Remove redundant symbol and fix some ordered list (#17000) Signed-off-by: PingWang <wang.ping5@zte.com.cn> update Signed-off-by: PingWang <wang.ping5@zte.com.cn> * update-zh-translation/docs/reference/setup-tools/kubeadm/kubeadm-init.md (#16997) * update zh translation kubeadm-reset.md kubeadm-upgrade.md (#16992) * Create kubeadm_join_phase_control-plane-join_all.md (#16987) * Update web-ui-dashboard.md (#16976) * update format problem (#16956) Signed-off-by: PingWang <wang.ping5@zte.com.cn> update Signed-off-by: PingWang <wang.ping5@zte.com.cn> * zh-trans:/docs/docs/concepts/storage/volume-pvc-datasource.md (#17021) * update zh translation /docs/reference/access-authn-authz/webhook.md (#16860) * fix confict update zh translation (#16863) * zh-trans:/docs/concepts/workloads/pods/disruptions.md (#16983) * zh-trans:/docs/concepts/workloads/pods/disruptions.md * Update content/zh/docs/concepts/workloads/pods/disruptions.md Co-Authored-By: Qiming <tengqim@cn.ibm.com> * update zh translation content/zh/docs/reference/command-line-tools-reference/kube-scheduler.md (#17006) * Update RC's link (#16935) Signed-off-by: PingWang <wang.ping5@zte.com.cn> Update Signed-off-by: PingWang <wang.ping5@zte.com.cn> update the style Signed-off-by: PingWang <wang.ping5@zte.com.cn> * Update the links for /zh/docs/setup (#16938) Signed-off-by: PingWang <wang.ping5@zte.com.cn> * zh-trans:/docs/docs/concepts/services-networking/dual-stack.md (#17024) * update zh translation /reference/setup-tools/kubeadm/generated/kubeadm.md (#17036) * update zh tanslation /reference/setup-tools/kubeadm/generated/kubeadm_alpha_kubelet_config_download.md (#17037) * update zh translation -/reference/setup-tools/kubeadm/generated/kubeadm_alpha.md (#17038) * update zh translation /docs/contribute/participating.md (#17040) * Fix cri-o's links to match English docs (#16936) Signed-off-by: PingWang <wang.ping5@zte.com.cn> * update zh translation content/zh/docs/reference/kubectl/jsonpath.md (#16862) * update zh translation /docs/reference/setup-tools/kubeadm/generated/kubeadm_token_generate.md (#17049) * update Unkown -> Unknown (#17062) * zh-translation:high-availability.md (#16960) Signed-off-by: yuxiaobo <yuxiaobogo@163.com> * update Runnning -> Running (#17061) * zh-trans:/docs/docs/concepts/storage/volume-snapshots.md (#17054) * update zh transation /docs/reference/setup-tools/kubeadm/generated/kubeadm_reset.md (#17060) * update zh translation /docs/reference/setup-tools/kubeadm/generated/kubeadm_token_create.md (#17052) * update zh translation /docs/reference/setup-tools/kubeadm/generated/kubeadm_token.md (#17055) * update zh translation update-zh-translation-/docs/reference/setup-tools/kubeadm/generated/kubeadm_token_list.md (#17048) * update zh-translation:ha-topology.md (#17099) Signed-off-by: yuxiaobo <yuxiaobogo@163.com> * zh-trans /reference/setup-tools/kubeadm/generated/kubeadm_config_images_list.md (#17093) * update zh translation /reference/setup-tools/kubeadm/generated/kubeadm_init_phase_certs_all.md (#17083) * Add Chinese translation for scheduler-perf-tuning (#17087) Signed-off-by: GeorgeSen <wang.sen2@zte.com.cn> Add Chinese translation for scheduler-perf-tuning Signed-off-by: GeorgeSen <wang.sen2@zte.com.cn> Add Chinese translation for scheduler-perf-tuning Signed-off-by: GeorgeSen <wang.sen2@zte.com.cn> Add Chinese translation for scheduler-perf-tuning Signed-off-by: GeorgeSen <wang.sen2@zte.com.cn> * zh trans content/zh/docs/setup/production-environment/tools/kubeadm/control-plane-flags.md (#17121) * update zh trans content/zh/docs/tasks/access-application-cluster/service-access-application-cluster.md (#17122) * zh-translation:content/zh/docs/tasks/administer-cluster/namespaces-walkthrough.md (#17105) Signed-off-by: yuxiaobo <yuxiaobogo@163.com> * update-zh-translation-/docs/reference/setup-tools/kubeadm/generated/kubeadm_config_migrate.md (#17091) * update zh trans /docs/setup/learning-environment/minikube.md (#17143) * update zh trans /zh/docs/reference/_index.md (#17146) * update zh trans /docs/tasks/access-application-cluster/port-forward-access-application-cluster.md (#17134) * update zh translation 20191020-update-zh-translation-/docs/contribute/localization.md (#17046) * update zh trans /docs/reference/using-api/client-libraries.md (#17144) * update zh trans /docs/reference/setup-tools/kubeadm/generated/kubeadm_version.md (#17145) * update zh /docs/reference/setup-tools/kubeadm/generated/kubeadm_upgrade_node.md (#17131) * update zh translation /reference/setup-tools/kubeadm/generated/kubeadm_init_phase_certs_front-proxy-client.md (#17081) * update zh translation /docs/reference/setup-tools/kubeadm/generated/kubeadm_init_phase_kubeconfig.md (#17078) * add zh translation /docs/reference/setup-tools/kubeadm/generated/kubeadm_join_phase_control-plane-join_update-status.md (#17076) * update zh trans content/zh/docs/contribute/generate-ref-docs/kubectl.md (#17165) * update zh translation /reference/command-line-tools-reference/kube-proxy.md (#17107) * zh-trans:/docs/docs/concepts/workloads/pods/pod-topology-spread-const… (#16955) * zh-trans:/docs/docs/concepts/workloads/pods/pod-topology-spread-constraints.md * Update pod-topology-spread-constraints.md * zh-trans:/docs/concepts/configuration/scheduling-framework.md (#17088) * update zh translation /docs/reference/setup-tools/kubeadm/generated/kubeadm_init_phase_upload-config_kubelet.md (#17079) * update zh translation /docs/reference/setup-tools/kubeadm/generated/kubeadm_init_phase_control-plane_apiserver.md (#17077) * update zh translation /docs/reference/setup-tools/kubeadm/generated/kubeadm_join_phase_control-plane-join.md (#17075) * update zh translation /docs/reference/setup-tools/kubeadm/generated/kubeadm_token_delete.md (#17050) * update zh trans /docs/concepts/overview/working-with-objects/namespaces.md (#17205) * update zh trans /docs/concepts/overview/what-is-kubernetes.md (#17203) * pr_release-1.16_crictl (#17201) * update zh docs/tasks/administer-cluster/dns-debugging-resolution.md (#17186) * update zh trans content/zh/docs/concepts/overview/working-with-objects/field-selectors.md (#17191) * translate configure_upgrade_etcd (#17160) * translate kubeadm_upgrade_apply (#17159) * update zh /docs/tasks/job/coarse-parallel-processing-work-queue.md (#17155) * translate docs/setup/release/version-skew-policy.md to Chinese (#17142) * update zh trans content/zh/docs/tasks/access-application-cluster/create-external-load-balancer.md (#17124) * zh-trans replace the wrong translation (#17103) zh-trans replace the wrong translation * Merged 1.14~1.16 changes (#17117) * zh-trans:/docs/concepts/configuration/assign-pod-node.md (#17129) * update zh trans /docs/contribute/generate-ref-docs/kubernetes-api.md (#17161) * pr_release-1.16_basic-ss (#17169) * Add zh-trans of assign-cpu-resource.md (#17063) Signed-off-by: heqg <he.qingguo@zte.com.cn> Add zh-trans of assign-cpu-resource.md Signed-off-by: heqg <he.qingguo@zte.com.cn> Add zh-trans of assign-cpu-resource.md Signed-off-by: heqg <he.qingguo@zte.com.cn> Add zh-trans of assign-cpu-resource.md Signed-off-by: heqg <he.qingguo@zte.com.cn> Add zh-trans of assign-cpu-resource.md Signed-off-by: heqg <he.qingguo@zte.com.cn> * update zh trans content/zh/docs/concepts/overview/working-with-objects/common-labels.md (#17193) * update zh translation /docs/contribute/intermediate.md (#17041) * zh-trans:docs/setup/production-environment/turnkey/tencent.md (#17207) * pr_release-1.16_mysql-wordpress-pv (#17202) * pr_release-1.16_reconfig-kubelet (#17200) * zh-trans:/docs/docs/concepts/workloads/controllers/jobs-run-completio… (#17020) * zh-trans:/docs/docs/concepts/workloads/controllers/jobs-run-completion.md * Update jobs-run-completion.md * Update jobs-run-completion.md * update zh trans content/zh/docs/concepts/extend-kubernetes/extend-cluster.md (#17212) * update zh trans content/zh/docs/concepts/extend-kubernetes/api-extension/apiserver-aggregation.md (#17213) * add zh trans /docs/reference/setup-tools/kubeadm/generated/kubeadm_join_phase_control-plane-prepare_kubeconfig.md (#17220) kubeadm_join_phase_control-plane-prepare_download-certs.md * add zh trans /reference/setup-tools/kubeadm/generated/kubeadm_init_phase_certs.md and /reference/setup-tools/kubeadm/generated/kubeadm_join_phase_control-plane-prepare.md (#17219) * update zh trans content/zh/docs/concepts/containers/images.md (#17216) * ZH-trans: add _index.md (#17214) * ZH-trans: add _index.md * add _index.md file * add _index.md files * pr_release-1.16_crd-versions (#17198) * update zh translation /docs/reference/setup-tools/kubeadm/generated/kubeadm_config_images_pull.md (#17092) * zh-trans /reference/setup-tools/kubeadm/generated/kubeadm_config_images.md (#17094) * add zh trans content/zh/docs/reference/setup-tools/kubeadm/generated/kubeadm_init_phase_addon_kube-proxy.md and content/zh/docs/reference/setup-tools/kubeadm/generated/kubeadm_init_phase_certs_sa.md (#17222) * add zh trans content/zh/docs/reference/setup-tools/kubeadm/generated/kubeadm_join_phase_control-plane-prepare_all.md content/zh/docs/reference/setup-tools/kubeadm/generated/kubeadm_join_phase_control-plane-prepare_certs.md (#17221) * add zh trans content/zh/docs/reference/setup-tools/kubeadm/generated/kubeadm_init_phase_addon_all.md (#17223) * 013 /docs/concepts/services networking/ingress.md (#17185) * x * update zh trans content/zh/docs/concepts/services-networking/ingress.md * zh-trans:/reference/setup-tools/kubeadm/generated/kubeadm_completion.md and kubeadm_config.md (#17097) * add zh trans reference/glossary/pod-lifecycle (#17226) * update zh-translation document (#17096) Signed-off-by: yuxiaobo <yuxiaobogo@163.com> * update zh-translation:setup-ha-etcd-with-kubeadm.md (#17098) Signed-off-by: yuxiaobo <yuxiaobogo@163.com> * add zh trans /docs/reference/setup-tools/kubeadm/generated/kubeadm_alpha_selfhosting.md and /docs/reference/setup-tools/kubeadm/generated/kubeadm_alpha_kubelet_config_enable-dynamic.md (#17227) * add zh trans /docs/reference/setup-tools/kubeadm/generated/kubeadm_alpha_kubeconfig_user.md and /docs/reference/setup-tools/kubeadm/generated/kubeadm_init_phase_upload-config_kubeadm.md (#17228) * zh-translation:content/zh/docs/tasks/extend-kubectl/kubectl-plugins.md (#17089) Signed-off-by: yuxiaobo <yuxiaobogo@163.com> * update zh translation /docs/reference/setup-tools/kubeadm/generated/kubeadm_join.md (#17080) * update zh translation /reference/setup-tools/kubeadm/generated/kubeadm_config_view.md (#17085) * zh-translation:troubleshooting-kubeadm.md (#17069) Signed-off-by: yuxiaobo <yuxiaobogo@163.com> * zh-trans: docs/concepts/scheduling/kube-scheduler.md (#17067) * Add Chinese translation for kube-scheduler Signed-off-by: GeorgeSen <wang.sen2@zte.com.cn> Add Chinese translation for kube-scheduler Signed-off-by: GeorgeSen <wang.sen2@zte.com.cn> Add Chinese translation for kube-scheduler Signed-off-by: GeorgeSen <wang.sen2@zte.com.cn> Add Chinese translation for kube-scheduler Signed-off-by: GeorgeSen <wang.sen2@zte.com.cn> Add Chinese translation for kube-scheduler Signed-off-by: GeorgeSen <wang.sen2@zte.com.cn> Add Chinese translation for kube-scheduler Signed-off-by: GeorgeSen <wang.sen2@zte.com.cn> Add Chinese translation for kube-scheduler Signed-off-by: GeorgeSen <wang.sen2@zte.com.cn> Add Chinese translation for kube-scheduler Signed-off-by: GeorgeSen <wang.sen2@zte.com.cn> * Update kube-scheduler.md * Add Chinese translation for kube-scheduler * Update kube-scheduler.md * Update kube-scheduler.md * Update kube-scheduler.md * translate pods.md and init-containers.md for branch release-1.16 (#17208) * update zh translation /docs/contribute/start.md (#17039) * zh-translation:2017-10-00-Five-Days-Of-Kubernetes-18.md (#17229) Signed-off-by: yuxiaobo <yuxiaobogo@163.com> * translate kubeadm-certs.md (#17090) * update the Illegal comment such as : (<!--、<--) (#17266) * add zh trans content/zh/docs/reference/setup-tools/kubeadm/generated/kubeadm_init_phase.md and content/zh/docs/reference/setup-tools/kubeadm/generated/kubeadm_init_phase_certs_etcd-ca.md (#17268) * update zh /docs/concepts/architecture/cloud-controller.md (#17263) * update zh /docs/concepts/cluster-administration/logging.md (#17247) * modify the show of zh translation /concepts/overview/what-is-kubernetes.md /reference/setup-tools/kubeadm/generated/kubeadm_init.md /reference/setup-tools/kubeadm/kubeadm-init.md (#17246) * zh-translation:kubeadm_init_phase_control-plane_all.md (#17243) Signed-off-by: yuxiaobo <yuxiaobogo@163.com> * zh-translation:kubeadm_join_phase_control-plane-join_etcd.md (#17236) Signed-off-by: yuxiaobo <yuxiaobogo@163.com> * add zh trans content/zh/docs/reference/setup-tools/kubeadm/generated/kubeadm_init_phase_kubelet-start.md and content/zh/docs/reference/setup-tools/kubeadm/generated/kubeadm_init_phase_upload-certs.md (#17230) * add content/zh/docs/reference/glossary/container-runtime.md file fix-up to pass the ci and trans content/zh/docs/reference/glossary/container-runtime.md、content/zh/docs/concepts/overview/components.md (#17211) * zh-translation:mirror-pod.md (#17231) Signed-off-by: yuxiaobo <yuxiaobogo@163.com> * zh-translation:kubeadm_init_phase_upload-config.md (#17238) Signed-off-by: yuxiaobo <yuxiaobogo@163.com> * update zh /docs/concepts/workloads/pods/pod-overview.md (#17239) * update the format of zh translation content/zh/docs/reference/setup-tools/kubeadm/generated/kubeadm_reset.md content/zh/docs/reference/setup-tools/kubeadm/generated/kubeadm_upgrade.md content/zh/docs/reference/setup-tools/kubeadm/generated/kubeadm_upgrade_apply.md content/zh/docs/reference/setup-tools/kubeadm/generated/kubeadm_upgrade_plan.md content/zh/docs/reference/setup-tools/kubeadm/kubeadm-config.md content/zh/docs/reference/setup-tools/kubeadm/kubeadm-reset.md content/zh/docs/reference/setup-tools/kubeadm/kubeadm-token.md content/zh/docs/reference/setup-tools/kubeadm/kubeadm-upgrade.md (#17248) * Create advanced.md (#17256) * Create advanced.md * trans the advanced.md and fix the build bugs * add zh trans content/zh/docs/reference/setup-tools/kubeadm/generated/kubeadm_init_phase_control-plane.md and content/zh/docs/reference/setup-tools/kubeadm/generated/kubeadm_init_phase_control-plane_scheduler.md (#17269) * zh-translation:kubelet-integration.md (#17272) Signed-off-by: yuxiaobo <yuxiaobogo@163.com> * pr_release-1.16_out-of-resource (#17199) * add zh trans content/zh/docs/reference/setup-tools/kubeadm/generated/kubeadm_init_phase_certs_front-proxy-ca.md and content/zh/docs/reference/setup-tools/kubeadm/generated/kubeadm_init_phase_control-plane_controller-manager.md (#17267) * add zh trans content/zh/docs/reference/setup-tools/kubeadm/generated/kubeadm_init_phase_certs_etcd-peer.md and content/zh/docs/reference/setup-tools/kubeadm/generated/kubeadm_init_phase_kubeconfig_admin.md (#17271) * pr_release-1.16_ext-admission-ctl (#17196) * update zh translation /docs/contribute/advanced.md (#17042) * add zh trans content/zh/docs/reference/setup-tools/kubeadm/generated/kubeadm_init_phase_certs_apiserver-etcd-client.md and content/zh/docs/reference/setup-tools/kubeadm/generated/kubeadm_init_phase_certs_ca.md (#17275) * add zh trans content/zh/docs/reference/setup-tools/kubeadm/generated/kubeadm_config_print.md update zh trans content/zh/docs/reference/setup-tools/kubeadm/generated/kubeadm_config.md、content/zh/docs/reference/setup-tools/kubeadm/generated/kubeadm_config_print_init-defaults.md (#17282) * add zh trans content/zh/docs/reference/setup-tools/kubeadm/generated… (#17287) * add zh trans content/zh/docs/reference/setup-tools/kubeadm/generated/kubeadm_init_phase_etcd.md content/zh/docs/reference/setup-tools/kubeadm/generated/kubeadm_init_phase_upload-config_all.md update zh trans content/zh/docs/reference/setup-tools/kubeadm/generated/kubeadm_init_phase_control-plane.md * Update kubeadm_init_phase_etcd.md * add zh trans content/zh/docs/reference/setup-tools/kubeadm/generated/… (#17285) * add zh trans content/zh/docs/reference/setup-tools/kubeadm/generated/kubeadm_alpha_certs_renew_etcd-server.md content/zh/docs/reference/setup-tools/kubeadm/generated/kubeadm_alpha_kubelet.md update zh trans content/zh/docs/reference/setup-tools/kubeadm/generated/kubeadm_alpha_certs_renew_apiserver.md * Update kubeadm_alpha_kubelet.md * add zh trans content/zh/docs/reference/setup-tools/kubeadm/generated/kubeadm_alpha_certs_renew_all.md and content/zh/docs/reference/setup-tools/kubeadm/generated/kubeadm_init_phase_addon.md fix-up bad comment kubeadm_alpha_certs_renew.md、kubeadm_alpha_certs_renew_apiserver-etcd-client.md、kubeadm_init_phase_addon_all.md (#17276) * add zh trans content/zh/docs/reference/setup-tools/kubeadm/generated/… (#17281) * add zh trans content/zh/docs/reference/setup-tools/kubeadm/generated/kubeadm_init_phase_etcd_local.md and content/zh/docs/reference/setup-tools/kubeadm/generated/kubeadm_config_print_join-defaults.md * Update kubeadm_init_phase_etcd_local.md * zh trans update-daemon-set.md (#16872) * zh trans update-daemon-set.md * Update update-daemon-set.md * managing-tls-in-a-cluster.md (#16874) * update-api-object-kubectl-patch.md (#16875) * improve the zh trans /kubeadm/generated/kubeadm_init_phase_.* 1 (#17295) * improve the zh trans content/zh/docs/reference/setup-tools/kubeadm/generated/kubeadm_config_.* (#17294) * modify the zh translation content/zh/docs/reference/setup-tools/kubea… (#17293) * modify the zh translation content/zh/docs/reference/setup-tools/kubeadm/generated/kubeadm_alpha_.* * Update kubeadm_alpha.md * add zh trans content/zh/docs/reference/setup-tools/kubeadm/generated/kubeadm_init_phase_kubeconfig_all.md and content/zh/docs/reference/setup-tools/kubeadm/generated/kubeadm_init_phase_preflight.md (#17280) * add zh /docs/reference/glossary/cgroup.md (#17291) * add zh trans content/zh/docs/reference/setup-tools/kubeadm/generated/kubeadm_alpha_kubelet_config.md、content/zh/docs/reference/setup-tools/kubeadm/generated/kubeadm_init_phase_certs_apiserver-kubelet-client.md (#17288) * improve zh trans of command in /kubeadm/generated/kubeadm_init_phase_.* files (#17297) * improve zh command translation /kubeadm/generated/kubeadm_init_.* files (#17298) * update zh trans in /kubeadm/generated/kubeadm_.* files (#17306) * add zh trans /reference/setup-tools/kubeadm/generated/kubeadm_alpha_certs_renew_etcd-healthcheck-client.md、/reference/setup-tools/kubeadm/generated/kubeadm_alpha_certs_renew_etcd-peer.md、/reference/setup-tools/kubeadm/generated/kubeadm_alpha_kubeconfig.md (#17308) * Improve previously translated documents (#17327) Signed-off-by: yuxiaobo <yuxiaobogo@163.com> * zh-trans: docs/setup/production-environment/turnkey/aws.md (#17320) * Update zh.toml * update zh trans /generated/kubeadm_join_phase_.* files (#17301) * Update zh.toml * add zh /docs/reference/glossary/pod-disruption-budget.md (#17344) * pr_release-1.16_config-aggregation-layer (#17197) * add zh trans content/zh/docs/reference/setup-tools/kubeadm/generated/kubeadm_alpha_certs_renew_controller-manager.conf.md、content/zh/docs/reference/setup-tools/kubeadm/generated/kubeadm_alpha_certs_renew_scheduler.conf.md (#17390) * add zh trans content/zh/docs/reference/setup-tools/kubeadm/generated/kubeadm_init_phase_kubeconfig_scheduler.md、content/zh/docs/reference/setup-tools/kubeadm/generated/kubeadm_join_phase.md、content/zh/docs/reference/setup-tools/kubeadm/generated/kubeadm_join_phase_control-plane-prepare_control-plane.md (#17381) * add zh trans content/zh/docs/reference/setup-tools/kubeadm/generated/kubeadm_alpha_certs_renew_apiserver-kubelet-client.md、content/zh/docs/reference/setup-tools/kubeadm/generated/kubeadm_join_phase_control-plane-join_mark-control-plane.md、content/zh/docs/reference/setup-tools/kubeadm/generated/kubeadm_join_phase_kubelet-start.md (#17380) * add zh trans content/zh/docs/reference/setup-tools/kubeadm/generated/kubeadm_init_phase_addon_coredns.md、content/zh/docs/reference/setup-tools/kubeadm/generated/kubeadm_init_phase_bootstrap-token.md、content/zh/docs/reference/setup-tools/kubeadm/generated/kubeadm_init_phase_certs_apiserver.md (#17383) * add zh trans content/zh/docs/reference/setup-tools/kubeadm/generated/kubeadm_alpha_certs_certificate-key.md、content/zh/docs/reference/setup-tools/kubeadm/generated/kubeadm_reset_phase_preflight.md、content/zh/docs/reference/setup-tools/kubeadm/generated/kubeadm_reset_phase_update-cluster-status.md (#17385) * add zh trans content/zh/docs/reference/setup-tools/kubeadm/generated/kubeadm_alpha_certs_renew_admin.conf.md、content/zh/docs/reference/setup-tools/kubeadm/generated/kubeadm_reset_phase.md、content/zh/docs/reference/setup-tools/kubeadm/generated/kubeadm_reset_phase_cleanup-node.md (#17387) * add zh trans content/zh/docs/reference/setup-tools/kubeadm/generated/kubeadm_alpha_certs_renew_apiserver-kubelet-client.md、content/zh/docs/reference/setup-tools/kubeadm/generated/kubeadm_alpha_certs_renew_front-proxy-client.md、content/zh/docs/reference/setup-tools/kubeadm/generated/kubeadm_alpha_selfhosting_pivot.md (#17384) * add zh /docs/reference/glossary/limitrange.md (#17324) * add zh trans content/zh/docs/setup/best-practices/cluster-large.md (#17321) * add zh trans content/zh/docs/setup/best-practices/cluster-large.md * Update cluster-large.md * add zh trans /docs/reference/setup-tools/kubeadm/kubeadm-alpha.md、/do… (#17403) * add zh trans /docs/reference/setup-tools/kubeadm/kubeadm-alpha.md、/docs/reference/setup-tools/kubeadm/generated/kubeadm_join_phase_preflight.md、/docs/reference/setup-tools/kubeadm/generated/kubeadm_init_phase_certs_etcd-server.md * Update kubeadm_init_phase_certs_etcd-server.md * add zh /docs/reference/glossary/cluster-operations.md (#17300) * add zh /docs/reference/glossary/applications.md (#17419) * update zh trans kubelet (#17379) * update zh trans kubelet * update the file according to feedback from reviewer tengqm * update 1000-1757 lines * update the advice zh trans * add zh /docs/reference/glossary/static-pod.md (#17418) * add zh /docs/reference/glossary/preemption.md (#17423) * add zh /docs/reference/glossary/pod-priority.md (#17421) * add zh /docs/reference/glossary/control-plane.md (#17425) * add zh /docs/reference/glossary/cluster-infrastructure.md (#17424) * pr_release-1.16_api-overview (#17444) * pr_release-1.16_daemonset (#17435) * pr_release-1.16_gc (#17445) * pr_release-1.16_qos-class (#17442) * fix QoS Class to QoS 类 (#17464) * pr_release-1.16-abac (#17427) * zh-trans:docs/setup/production-environment/turnkey/alibaba-cloud.md (#17345) * pr_release-1.16_endpoint-slice (#17468) * pr_release-1.16_taint (#17469) * pr_release-1.16_operator-pattern (#17467) * pr_release-1.16_ss (#17433) * pr_release-1.16_admission-controller (#17440) * pr_release-1.16_containerd (#17441) * pr_release-1.16_app-container (#17466) * add zh-trans content/zh/docs/setup/_index.md、content/zh/docs/setup/release/_index.md (#17503) * pr-release-1.16_enabling-endpoint-slices (#17504) * update zh trans content/zh/docs/reference/setup-tools/kubeadm/kubeadm… (#17495) * update zh trans content/zh/docs/reference/setup-tools/kubeadm/kubeadm-upgrade-phase.md、content/zh/docs/reference/setup-tools/kubeadm/kubeadm-init-phase.md * add content/zh/docs/reference/setup-tools/kubeadm/generated/kubeadm_init_phase_kubeconfig_kubelet.md * pr-release-1.16_logging (#17491) * pr-release-1.16_cri (#17486) * add zh-trans:docs/setup/production-environment/turnkey/azure.md (#17482) * pattern translate into 模式 (#17485) * fix zk affinity description in zh trans (#17393) * pr-release-1.16_ephemeral-container (#17487) * pr-release-1.16_data-plane (#17489) * pr-release-1.16_cncf (#17490) * zh-trans add content\zh\docs\tools\install-minikube.md (#16920) * zh-trans add content\zh\docs\tools\install-minikube.md * zh-trans update content\zh\docs\tools\install-minikube.md * zh-trans update content\zh\docs\tools\install-minikube.md * update \docs\tasks\tools\install-minikube.md * update docs\concepts\workloads\controllers\deployment.md * update deployment.md * pr-release-1.16_extensions (#17492) * pr-release-1.16_toleration (#17493) * Revert "update zh trans content/zh/docs/reference/setup-tools/kubeadm/kubeadm… (#17495)" (#17521) This reverts commit 1134c14e0a39bdc3d1a920ac9797139a6dcccf4b. * motidy extensions in content/zh/docs/reference/glossary/extensions (#17524) * motidy toleration in content/zh/docs/reference/glossary/toleration.md (#17523) * motidy toleration in content/zh/docs/reference/glossary/toleration.md * Update toleration.md * improve zh-trans in content/zh/docs/setup/_index.md (#17526) * add zh-trans /zh/docs/reference/setup-tools/kubeadm/generated/kubeadm_init_phase_kubeconfig_kubelet.md (#17527) * Broken Link (#17546) Issue available at https://kubernetes.io/zh/docs/concepts/containers/runtime-class/ and introduced by original English documentation (see #17543) * Update trans kubeadm_upgrade_plan.md (#17395) * Update kubeadm_upgrade_plan.md * Update kubeadm_upgrade_plan.md * Update kubeadm_upgrade_plan.md * Update kubeadm_upgrade_plan.md * Update kubeadm_upgrade_plan.md * Update kubeadm_upgrade_plan.md * update zh-trans of define-command-argument-container.md (#17022) Signed-off-by: Yixiang2019 <wang.yixiang@zte.com.cn> update zh-trans of define-command-argument-container.md Signed-off-by: Yixiang2019 <wang.yixiang@zte.com.cn> Add back the Original English Signed-off-by: Yixiang2019 <wang.yixiang@zte.com.cn> update title of define-command-argument-container.md Signed-off-by: Yixiang2019 <wang.yixiang@zte.com.cn> update table title and reference Signed-off-by: Yixiang2019 <wang.yixiang@zte.com.cn> update reference of define-command-argument-container.md Signed-off-by: Yixiang2019 <wang.yixiang@zte.com.cn> * ZH-trans: fix multiple jump links and update files (#17603) * ZH-trans: fix multiple jump links and update files * Update _index.html * update zh trans content/zh/docs/reference/setup-tools/kubeadm/kubeadm-init-phase.md (#17528) * update zh trans /doc/concepts/architecture/nodes.md (#17617) * update zh trans content/zh/docs/concepts/architecture/nodes.md * fix-up content/zh/docs/concepts/architecture/nodes.md * add zh-trans /docs/setup/release/notes.md (#17519) * add zh-trans /docs/setup/release/notes.md update-750 * fix-up 1575 line and udpate 2483 line * update to line 2980 * update to the last line 3160 * add zh-trans:docs/setup/production-environment/turnkey/icp.md (#17568) * zh-trans: /docs/setup/production-environment/container-runtimes.md (#17646) * zh-trs:container-runtimes.md Signed-off-by: yuxiaobo <yuxiaobogo@163.com> * Update container-runtimes.md * Translate /docs/concepts/workloads/controllers/ttlafterfinished.md into Chinese (#17791) * Translate /docs/concepts/cluster-administration/cloud-providers.md into Chinese * Translate /docs/concepts/workloads/controllers/ttlafterfinished.md into Chinese * Sorry, wrong commit, roll back... * Translate /docs/concepts/workloads/controllers/ttlafterfinished.md * Translate /docs/concepts/workloads/controllers/ttlafterfinished.md into Chinese * Translate /docs/concepts/workloads/controllers/ttlafterfinished.md into Chinese * Create trans kubeadm_upgrade_diff.md (#17392) * Update kubeadm_upgrade_diff.md * Update kubeadm_upgrade_diff.md * Update kubeadm_upgrade_diff.md * Create _index.md (#17831) * zh-trans zh-trans-/docs/reference/command-line-tools-reference/feature-gates.md (#17658) * Update volume-snapshots.md (#17829) * Update volume-snapshots.md * Update volume-snapshots.md * Update volume-snapshots.md * Create ovirt.md (#17849) * Create ovirt.md * Update ovirt.md * Translate /docs/concepts/cluster-administration/cloud-providers.md into Chinese (#17761) * Translate /docs/concepts/cluster-administration/cloud-providers.md into Chinese * Translate /docs/concepts/workloads/controllers/ttlafterfinished.md into Chinese * Sorry, wrong commit, roll back... * Update translation after tengqm's review. * Update cloud-providers.md * Update dual-stack.md (#17836) * Update dual-stack.md * Update dual-stack.md * Update dual-stack.md * Update dual-stack.md * Create validate-dual-stack.md (#17833) * Create validate-dual-stack.md * Update validate-dual-stack.md * translation content/zh/docs/reference/setup-tools/kubeadm/ kubeadm-join-phase、kubeadm-reset-phase (#17881) * zh-trans content/zh/docs/contribute/generate-ref-docs/contribute-upstream.md (#17882) * Chinese translation /docs/tasks/administer-cluster/highly-available-master.md (#17884) * Chinese translation /docs/tasks/administer-cluster/highly-available-master.md * Apply suggestions from code review Co-Authored-By: Qiming <tengqim@cn.ibm.com> * Fix format issue (#17921) * Create topology-manager.md (#17901) * Create topology-manager.md * Update topology-manager.md * add zh-trans:docs/setup/production-environment/windows/user-guide-windows-containers.md (#17876) * Update pod-overhead.md (#17931) * Update scheduler-perf-tuning.md (#17934) * Create dcos.md (#17932) * Create dcos.md * Update dcos.md * Update object-management.md (#17937) * zh-translation content/zh/docs/setup/production-environment/tools/kops.md (#17991) * Create imperative-config.md (#17956) * Create imperative-config.md * Update imperative-config.md * Create self-hosting.md (#17950) * Create resource-bin-packing.md (#17935) * Create nodelocaldns.md (#17938) * Update config.toml(release-1.16) for 1.17 (#18025) * Update config.toml(release-1.16) for 1.17 * Update config.toml * Remove ru language * fix shotcode mismatch Co-authored-by: zhangx501 <zhang0000xun@gmail.com> Co-authored-by: ZhongliangXiong <xiong.zhongliang@zte.com.cn> Co-authored-by: Yixiang Wang <wang.yixiang@zte.com.cn> Co-authored-by: li mengyang <hwdef97@gmail.com> Co-authored-by: PingWang <wang.ping5@zte.com.cn> Co-authored-by: chentanjun <tanjunchen20@gmail.com> Co-authored-by: Sophy417 <53026875+Sophy417@users.noreply.github.com> Co-authored-by: Qiming <tengqim@cn.ibm.com> Co-authored-by: yuxiaobo96 <41496192+yuxiaobo96@users.noreply.github.com> Co-authored-by: senwang <wang.sen2@zte.com.cn> Co-authored-by: lichuqiang <lichuqiang@huawei.com> Co-authored-by: lpf7551321 <liupengfei20@huawei.com> Co-authored-by: Hongcai Ren <renhongcai@huawei.com> Co-authored-by: jiajie <jiaj12@chinaunicom.cn> Co-authored-by: heqg <56527988+heqg@users.noreply.github.com> Co-authored-by: IreneByron <zhangbingqing7@huawei.com> Co-authored-by: LiuDui <1693291525@qq.com> Co-authored-by: Wang Bing <wangbing.adam@gmail.com> Co-authored-by: Damini Satya <daminisatya@gmail.com> Co-authored-by: liufangwai <liufangwai@huawei.com> Co-authored-by: wangcong <congfairy2536@gmail.com> Co-authored-by: XuefeiWang2 <wangxuefei2@huawei.com> Co-authored-by: Kubernetes Prow Robot <k8s-ci-robot@users.noreply.github.com> Co-authored-by: Ziqiu Zhu <zzqshu@126.com> Co-authored-by: ten2ton <50288981+ten2ton@users.noreply.github.com> Co-authored-by: Oleg Butuzov <butuzov@users.noreply.github.com> Co-authored-by: jiazxjason <52809535+jiazxjason@users.noreply.github.com> Co-authored-by: Coffey Gao <coffiney@qq.com> Co-authored-by: Bingshen Wang <bingshen.wbs@alibaba-inc.com>
This commit is contained in:
committed by
Kubernetes Prow Robot
parent
6be3e1414d
commit
0f2bd2871b
@@ -8,4 +8,4 @@ weight: 50
|
||||
title: "Workloads"
|
||||
weight: 50
|
||||
---
|
||||
-->
|
||||
-->
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
---
|
||||
title: "控制器"
|
||||
weight: 20
|
||||
---
|
||||
|
||||
<!--
|
||||
---
|
||||
title: "Controllers"
|
||||
weight: 20
|
||||
---
|
||||
-->
|
||||
|
||||
---
|
||||
title: "控制器"
|
||||
weight: 20
|
||||
---
|
||||
|
||||
@@ -1,53 +1,101 @@
|
||||
---
|
||||
approvers:
|
||||
reviewers:
|
||||
- erictune
|
||||
- soltysh
|
||||
- janetkuo
|
||||
title: Cron Job
|
||||
redirect_from:
|
||||
- "/docs/concepts/jobs/cron-jobs/"
|
||||
- "/docs/concepts/jobs/cron-jobs.html"
|
||||
- "/docs/user-guide/cron-jobs/"
|
||||
- "/docs/user-guide/cron-jobs.html"
|
||||
title: CronJob
|
||||
content_template: templates/concept
|
||||
weight: 80
|
||||
---
|
||||
|
||||
{{< toc >}}
|
||||
{{% capture overview %}}
|
||||
|
||||
<!--
|
||||
A _Cron Job_ creates [Jobs](/docs/concepts/workloads/controllers/jobs-run-to-completion/) on a time-based schedule.
|
||||
|
||||
## Cron Job 是什么?
|
||||
|
||||
_Cron Job_ 管理基于时间的 [Job](/docs/concepts/jobs/run-to-completion-finite-workloads/),即:
|
||||
一个 CronJob 对象就像 _crontab_ (cron table) 文件中的一行。它用 [Cron](https://en.wikipedia.org/wiki/Cron) 格式进行编写,并周期性的在给定的调度时间执行 Job。
|
||||
|
||||
* 在给定时间点只运行一次
|
||||
* 在给定时间点周期性地运行
|
||||
{{< note >}}
|
||||
<!--All **CronJob** `schedule:` times are denoted in UTC.-->
|
||||
所有 **CronJob** 的 `schedule:` 时间都是用 UTC 表示。
|
||||
{{< /note >}}
|
||||
|
||||
一个 CronJob 对象类似于 _crontab_ (cron table)文件中的一行。它根据指定的预定计划周期性地运行一个 Job,格式可以参考 [Cron](https://en.wikipedia.org/wiki/Cron) 。
|
||||
<!--
|
||||
For instructions on creating and working with cron jobs, and for an example of a spec file for a cron job, see [Running automated tasks with cron jobs](/docs/tasks/job/automated-tasks-with-cron-jobs).
|
||||
-->
|
||||
|
||||
有关创建和使用 CronJob 的说明及规范文件的示例,请参见 [使用 CronJob 运行自动任务](/docs/tasks/job/automated-tasks-with-cron-jobs)。
|
||||
|
||||
|
||||
|
||||
**注意:** 在预定计划中,问号(`?`)和星号(`*`)的意义是相同的,表示给定字段的取值是任意可用值。
|
||||
|
||||
**注意:** 在 Kubernetes 1.4 版本引入了 ScheduledJob 资源,但从 1.5 版本开始改成了 CronJob。
|
||||
|
||||
典型的用法如下所示:
|
||||
{{% /capture %}}
|
||||
|
||||
|
||||
{{% capture body %}}
|
||||
|
||||
* 在给定的时间点调度 Job 运行
|
||||
* 创建周期性运行的 Job,例如:数据库备份、发送邮件。
|
||||
<!--
|
||||
## Cron Job Limitations
|
||||
|
||||
### 前提条件
|
||||
A cron job creates a job object _about_ once per execution time of its schedule. We say "about" because there
|
||||
are certain circumstances where two jobs might be created, or no job might be created. We attempt to make these rare,
|
||||
but do not completely prevent them. Therefore, jobs should be _idempotent_.
|
||||
-->
|
||||
|
||||
## CronJob 限制
|
||||
|
||||
CronJob 创建 Job 对象,每个 Job 的执行次数大约为一次。
|
||||
我们之所以说 "大约",是因为在某些情况下,可能会创建两个 Job,或者不会创建任何 Job。
|
||||
我们试图使这些情况尽量少发生,但不能完全杜绝。因此,Job 应该是 _幂等的_。
|
||||
|
||||
当使用的 Kubernetes 集群,版本 >= 1.4(对 ScheduledJob),>= 1.5(对 CronJob),当启动 API Server(参考 [为集群开启或关闭 API 版本](/docs/admin/cluster-management/#turn-on-or-off-an-api-version-for-your-cluster) 获取更多信息)时,通过传递选项 `--runtime-config=batch/v2alpha1=true` 可以开启 batch/v2alpha1 API。
|
||||
<!--
|
||||
If `startingDeadlineSeconds` is set to a large value or left unset (the default)
|
||||
and if `concurrencyPolicy` is set to `Allow`, the jobs will always run
|
||||
at least once.
|
||||
-->
|
||||
|
||||
可选地,使用 `kubectl run` 创建一个 Cron Job,不需要写完整的配置:
|
||||
如果 `startingDeadlineSeconds` 设置为很大的数值或未设置(默认),并且 `concurrencyPolicy` 设置为 `Allow`,则作业将始终至少运行一次。
|
||||
|
||||
```shell
|
||||
$ kubectl run hello --schedule="*/1 * * * *" --restart=OnFailure --image=busybox -- /bin/sh -c "date; echo Hello from the Kubernetes cluster"
|
||||
cronjob "hello" created
|
||||
```
|
||||
<!--
|
||||
For every CronJob, the CronJob controller checks how many schedules it missed in the duration from its last scheduled time until now. If there are more than 100 missed schedules, then it does not start the job and logs the error
|
||||
-->
|
||||
|
||||
对于每个 CronJob,CronJob 控制器检查从上一次调度的时间点到现在所错过了调度次数。如果错过的调度次数超过 100 次,那么它就不会启动这个任务,并记录这个错误:
|
||||
|
||||
````
|
||||
Cannot determine if job needs to be started. Too many missed start time (> 100). Set or decrease .spec.startingDeadlineSeconds or check clock skew.
|
||||
|
||||
````
|
||||
|
||||
<!--
|
||||
It is important to note that if the `startingDeadlineSeconds` field is set (not `nil`), the controller counts how many missed jobs occurred from the value of `startingDeadlineSeconds` until now rather than from the last scheduled time until now. For example, if `startingDeadlineSeconds` is `200`, the controller counts how many missed jobs occurred in the last 200 seconds.
|
||||
-->
|
||||
|
||||
需要注意的是,如果设置 `startingDeadlineSeconds` 字段非空,则控制器会统计从 `startingDeadlineSeconds` 的值到现在而不是从上一个计划时间到现在错过了多少次 Job。例如,如果 `startingDeadlineSeconds` 是 `200`,则控制器会统计在过去 200 秒中错过了多少次 Job。
|
||||
|
||||
<!--
|
||||
A CronJob is counted as missed if it has failed to be created at its scheduled time. For example, If `concurrencyPolicy` is set to `Forbid` and a CronJob was attempted to be scheduled when there was a previous schedule still running, then it would count as missed.
|
||||
-->
|
||||
|
||||
如果未能在调度时间内创建 CronJob,则计为错过。例如,如果 `concurrencyPolicy` 被设置为 `Forbid`,并且当前有一个调度仍在运行的情况下,试图调度的 CronJob 将被计算为错过。
|
||||
|
||||
<!--
|
||||
For example, suppose a cron job is set to start at exactly `08:30:00` and its
|
||||
`startingDeadlineSeconds` is set to 10, if the CronJob controller happens to
|
||||
be down from `08:29:00` to `08:42:00`, the job will not start.
|
||||
Set a longer `startingDeadlineSeconds` if starting later is better than not
|
||||
starting at all.
|
||||
-->
|
||||
|
||||
例如,假设一个 CronJob 被设置为`08:30:00` 准时开始,它的 `startingDeadlineSeconds` 属性被设置为10,如果在`08:29:00` 时将 CronJob 控制器的时间改为 `08:42:00`,Job 将不会启动。
|
||||
如果觉得晚些开始比没有启动好,那请设置一个较长的 `startingDeadlineSeconds`。
|
||||
|
||||
<!--
|
||||
The Cronjob is only responsible for creating Jobs that match its schedule, and
|
||||
the Job in turn is responsible for the management of the Pods it represents.
|
||||
-->
|
||||
|
||||
CronJob 只负责创建与其时间表相匹配的 Job,相应的 Job 又会负责管理它所代表的Pod。
|
||||
|
||||
创建该 Cron Job 之后,通过如下命令获取它的状态信息:
|
||||
|
||||
|
||||
@@ -1,163 +1,415 @@
|
||||
---
|
||||
approvers:
|
||||
reviewers:
|
||||
- enisoc
|
||||
- erictune
|
||||
- foxish
|
||||
- janetkuo
|
||||
- kow3ns
|
||||
title: DaemonSet
|
||||
redirect_from:
|
||||
- "/docs/admin/daemons/"
|
||||
- "/docs/admin/daemons.html"
|
||||
content_template: templates/concept
|
||||
weight: 50
|
||||
---
|
||||
|
||||
{{< toc >}}
|
||||
<!--
|
||||
---
|
||||
reviewers:
|
||||
- enisoc
|
||||
- erictune
|
||||
- foxish
|
||||
- janetkuo
|
||||
- kow3ns
|
||||
title: DaemonSet
|
||||
content_template: templates/concept
|
||||
weight: 50
|
||||
---
|
||||
--->
|
||||
|
||||
{{% capture overview %}}
|
||||
|
||||
<!--
|
||||
A _DaemonSet_ ensures that all (or some) Nodes run a copy of a Pod. As nodes are added to the
|
||||
cluster, Pods are added to them. As nodes are removed from the cluster, those Pods are garbage
|
||||
collected. Deleting a DaemonSet will clean up the Pods it created.
|
||||
--->
|
||||
_DaemonSet_ 确保全部(或者某些)节点上运行一个 Pod 的副本。当有节点加入集群时,
|
||||
也会为他们新增一个 Pod 。当有节点从集群移除时,这些 Pod 也会被回收。删除 DaemonSet 将会删除它创建的所有 Pod。
|
||||
|
||||
## 什么是 DaemonSet?
|
||||
<!--
|
||||
Some typical uses of a DaemonSet are:
|
||||
|
||||
_DaemonSet_ 确保全部(或者某些)节点上运行一个 Pod 的副本。当有节点加入集群时,也会为他们新增一个 Pod 。
|
||||
当有节点从集群移除时,这些 Pod 也会被回收。删除 DaemonSet 将会删除它创建的所有 Pod。
|
||||
|
||||
|
||||
|
||||
使用 DaemonSet 的一些典型用法:
|
||||
- running a cluster storage daemon, such as `glusterd`, `ceph`, on each node.
|
||||
- running a logs collection daemon on every node, such as `fluentd` or `logstash`.
|
||||
- running a node monitoring daemon on every node, such as [Prometheus Node Exporter](
|
||||
https://github.com/prometheus/node_exporter), `collectd`, [Dynatrace OneAgent](https://www.dynatrace.com/technologies/kubernetes-monitoring/), [AppDynamics Agent](https://docs.appdynamics.com/display/CLOUD/Container+Visibility+with+Kubernetes), [Datadog agent](https://docs.datadoghq.com/agent/kubernetes/daemonset_setup/), [New Relic agent](https://docs.newrelic.com/docs/integrations/kubernetes-integration/installation/kubernetes-installation-configuration), Ganglia `gmond` or Instana agent.
|
||||
-->
|
||||
|
||||
- 运行集群存储 daemon,例如在每个节点上运行 `glusterd`、`ceph`。
|
||||
- 在每个节点上运行日志收集 daemon,例如`fluentd`、`logstash`。
|
||||
- 在每个节点上运行监控 daemon,例如 [Prometheus Node Exporter](https://github.com/prometheus/node_exporter)、`collectd`、Datadog 代理、New Relic 代理,或 Ganglia `gmond`。
|
||||
- 在每个节点上运行监控 daemon,例如 [Prometheus Node Exporter](https://github.com/prometheus/node_exporter)、[Sysdig 代理](https://sysdigdocs.atlassian.net/wiki/spaces/Platform)、`collectd`、[Dynatrace OneAgent](https://www.dynatrace.com/technologies/kubernetes-monitoring/)、[AppDynamics 代理](https://docs.appdynamics.com/display/CLOUD/Container+Visibility+with+Kubernetes)、[Datadog 代理](https://docs.datadoghq.com/agent/kubernetes/daemonset_setup/)、[New Relic 代理](https://docs.newrelic.com/docs/integrations/kubernetes-integration/installation/kubernetes-installation-configuration),Ganglia `gmond` 或 [Instana 代理](https://www.instana.com/supported-integrations/kubernetes-monitoring/)。
|
||||
|
||||
<!--
|
||||
In a simple case, one DaemonSet, covering all nodes, would be used for each type of daemon.
|
||||
A more complex setup might use multiple DaemonSets for a single type of daemon, but with
|
||||
different flags and/or different memory and cpu requests for different hardware types.
|
||||
-->
|
||||
一个简单的用法是在所有的节点上都启动一个 DaemonSet,将被作为每种类型的 daemon 使用。
|
||||
一个稍微复杂的用法是单独对每种 daemon 类型使用多个 DaemonSet,但具有不同的标志,和/或对不同硬件类型具有不同的内存、CPU要求。
|
||||
|
||||
一个稍微复杂的用法是单独对每种 daemon 类型使用多个 DaemonSet,但具有不同的标志,
|
||||
和/或对不同硬件类型具有不同的内存、CPU要求。
|
||||
|
||||
{{% /capture %}}
|
||||
|
||||
|
||||
{{% capture body %}}
|
||||
|
||||
## 编写 DaemonSet 规约
|
||||
<!--
|
||||
## Writing a DaemonSet Spec
|
||||
|
||||
### Create a DaemonSet
|
||||
-->
|
||||
## 编写 DaemonSet Spec
|
||||
|
||||
### 创建 DaemonSet
|
||||
|
||||
<!--
|
||||
You can describe a DaemonSet in a YAML file. For example, the `daemonset.yaml` file below describes a DaemonSet that runs the fluentd-elasticsearch Docker image:
|
||||
|
||||
{{< codenew file="controllers/daemonset.yaml" >}}
|
||||
|
||||
* Create a DaemonSet based on the YAML file:
|
||||
```
|
||||
kubectl apply -f https://k8s.io/examples/controllers/daemonset.yaml
|
||||
```
|
||||
-->
|
||||
您可以在 YAML 文件中描述 DaemonSet。例如,下面的 daemonset.yaml 文件描述了一个运行 fluentd-elasticsearch Docker 镜像的 DaemonSet:
|
||||
|
||||
{{< codenew file="controllers/daemonset.yaml" >}}
|
||||
|
||||
* 基于 YAML 文件创建 DaemonSet:
|
||||
```
|
||||
kubectl apply -f https://k8s.io/examples/controllers/daemonset.yaml
|
||||
```
|
||||
|
||||
<!--
|
||||
### Required Fields
|
||||
|
||||
As with all other Kubernetes config, a DaemonSet needs `apiVersion`, `kind`, and `metadata` fields. For
|
||||
general information about working with config files, see [deploying applications](/docs/user-guide/deploying-applications/),
|
||||
[configuring containers](/docs/tasks/), and [object management using kubectl](/docs/concepts/overview/working-with-objects/object-management/) documents.
|
||||
|
||||
A DaemonSet also needs a [`.spec`](https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status) section.
|
||||
-->
|
||||
### 必需字段
|
||||
|
||||
|
||||
|
||||
和其它所有 Kubernetes 配置一样,DaemonSet 需要 `apiVersion`、`kind` 和 `metadata` 字段。
|
||||
有关配置文件的基本信息,详见文档 [deploying applications](/docs/user-guide/deploying-applications/)、[配置容器](/docs/user-guide/configuring-containers/) 和 [资源管理](/docs/concepts/tools/kubectl/object-management-overview/) 。
|
||||
和其它所有 Kubernetes 配置一样,DaemonSet 需要 `apiVersion`、`kind` 和 `metadata` 字段。有关配置文件的基本信息,详见文档 [部署应用](/docs/user-guide/deploying-applications/)、[配置容器](/docs/tasks/) 和 [使用kubectl进行对象管理](/docs/concepts/overview/object-management-kubectl/overview/)。
|
||||
|
||||
DaemonSet 也需要一个 [`.spec`](https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status) 配置段。
|
||||
|
||||
<!--
|
||||
### Pod Template
|
||||
|
||||
The `.spec.template` is one of the required fields in `.spec`.
|
||||
|
||||
The `.spec.template` is a [pod template](/docs/concepts/workloads/pods/pod-overview/#pod-templates). It has exactly the same schema as a [Pod](/docs/concepts/workloads/pods/pod/), except it is nested and does not have an `apiVersion` or `kind`.
|
||||
|
||||
In addition to required fields for a Pod, a Pod template in a DaemonSet has to specify appropriate
|
||||
labels (see [pod selector](#pod-selector)).
|
||||
|
||||
A Pod Template in a DaemonSet must have a [`RestartPolicy`](/docs/user-guide/pod-states)
|
||||
equal to `Always`, or be unspecified, which defaults to `Always`.
|
||||
-->
|
||||
### Pod 模板
|
||||
|
||||
`.spec` 唯一必需的字段是 `.spec.template`。
|
||||
|
||||
|
||||
|
||||
`.spec.template` 是一个 [Pod 模板](/docs/user-guide/replication-controller/#pod-template)。
|
||||
它与 [Pod](/docs/user-guide/pods) 具有相同的 schema,除了它是嵌套的,而且不具有 `apiVersion` 或 `kind` 字段。
|
||||
`.spec.template` 是一个 [Pod 模板](/docs/concepts/workloads/pods/pod-overview/#pod-templates)。它与 [Pod](/docs/concepts/workloads/pods/pod/) 具有相同的 schema,除了它是嵌套的,而且不具有 `apiVersion` 或 `kind` 字段。
|
||||
|
||||
除了 Pod 必需字段外,在 DaemonSet 中的 Pod 模板必须指定合理的标签(查看 [Pod Selector](#pod-selector))。
|
||||
|
||||
在 DaemonSet 中的 Pod 模板必须具有一个值为 `Always` 的 [`RestartPolicy`](/docs/user-guide/pod-states),或者未指定它的值,默认是 `Always`。
|
||||
|
||||
|
||||
|
||||
<!--
|
||||
### Pod Selector
|
||||
|
||||
`.spec.selector` 字段表示 Pod Selector,它与 [Job](/docs/concepts/jobs/run-to-completion-finite-workloads/) 或其它资源的 `.spec.selector` 的作用是相同的。
|
||||
The `.spec.selector` field is a pod selector. It works the same as the `.spec.selector` of
|
||||
a [Job](/docs/concepts/jobs/run-to-completion-finite-workloads/).
|
||||
|
||||
As of Kubernetes 1.8, you must specify a pod selector that matches the labels of the
|
||||
`.spec.template`. The pod selector will no longer be defaulted when left empty. Selector
|
||||
defaulting was not compatible with `kubectl apply`. Also, once a DaemonSet is created,
|
||||
its `.spec.selector` can not be mutated. Mutating the pod selector can lead to the
|
||||
unintentional orphaning of Pods, and it was found to be confusing to users.
|
||||
-->
|
||||
### Pod Selector {#pod-selector}
|
||||
|
||||
`.spec.selector` 字段表示 Pod Selector,它与 [Job](/docs/concepts/jobs/run-to-completion-finite-workloads/) 的 `.spec.selector` 的作用是相同的。
|
||||
|
||||
从 Kubernetes 1.8开始,您必须指定与 `.spec.template` 的标签匹配的 pod selector。当不配置时,pod selector 将不再有默认值。selector 默认与 `kubectl apply` 不兼容。 此外,一旦创建了 DaemonSet,它的 `.spec.selector` 就不能修改。修改 pod selector 可能导致成为 孤儿Pod,并且这对用户来说是困惑的。
|
||||
|
||||
<!--
|
||||
The `.spec.selector` is an object consisting of two fields:
|
||||
|
||||
* `matchLabels` - works the same as the `.spec.selector` of a [ReplicationController](/docs/concepts/workloads/controllers/replicationcontroller/).
|
||||
* `matchExpressions` - allows to build more sophisticated selectors by specifying key,
|
||||
list of values and an operator that relates the key and values.
|
||||
|
||||
When the two are specified the result is ANDed.
|
||||
|
||||
If the `.spec.selector` is specified, it must match the `.spec.template.metadata.labels`. Config with these not matching will be rejected by the API.
|
||||
|
||||
Also you should not normally create any Pods whose labels match this selector, either directly, via
|
||||
another DaemonSet, or via other controller such as ReplicaSet. Otherwise, the DaemonSet
|
||||
controller will think that those Pods were created by it. Kubernetes will not stop you from doing
|
||||
this. One case where you might want to do this is manually create a Pod with a different value on
|
||||
a node for testing.
|
||||
-->
|
||||
`spec.selector` 表示一个对象,它由如下两个字段组成:
|
||||
|
||||
* `matchLabels` - 与 [ReplicationController](/docs/concepts/workloads/controllers/replicationcontroller/) 的 `.spec.selector` 的作用相同。
|
||||
* `matchExpressions` - 允许构建更加复杂的 Selector,可以通过指定 key、value 列表,以及与 key 和 value 列表相关的操作符。
|
||||
|
||||
|
||||
* `matchExpressions` - 允许构建更加复杂的 Selector,可以通过指定 key、value 列表
|
||||
,以及与 key 和 value 列表相关的操作符。
|
||||
|
||||
当上述两个字段都指定时,结果表示的是 AND 关系。
|
||||
|
||||
如果指定了 `.spec.selector`,必须与 `.spec.template.metadata.labels` 相匹配。如果没有指定,它们默认是等价的。如果与它们配置的不匹配,则会被 API 拒绝。
|
||||
|
||||
如果 Pod 的 label 与 selector 匹配,或者直接基于其它的 DaemonSet、或者 Controller(例如 ReplicationController),也不可以创建任何 Pod。
|
||||
否则 DaemonSet Controller 将认为那些 Pod 是它创建的。Kubernetes 不会阻止这样做。一个场景是,可能希望在一个具有不同值的、用来测试用的节点上手动创建 Pod。
|
||||
如果指定了 `.spec.selector`,必须与 `.spec.template.metadata.labels` 相匹配。如果与它们配置的不匹配,则会被 API 拒绝。
|
||||
|
||||
此外,您通常不应该创建任何 pods,它们的 label 与 selector 匹配,或者直接创建,或者通过另一个 DaemonSet、或者其他控制器,比如 ReplicaSet。否则,DaemonSet 控制器会认为这些 Pod 是由它创建的。Kubernetes 不会阻止你这样做。 您可能希望这样做的一种情况是在节点上手动创建具有不同值的 Pod 以进行测试。
|
||||
|
||||
<!--
|
||||
### Running Pods on Only Some Nodes
|
||||
|
||||
If you specify a `.spec.template.spec.nodeSelector`, then the DaemonSet controller will
|
||||
create Pods on nodes which match that [node
|
||||
selector](/docs/concepts/configuration/assign-pod-node/). Likewise if you specify a `.spec.template.spec.affinity`,
|
||||
then DaemonSet controller will create Pods on nodes which match that [node affinity](/docs/concepts/configuration/assign-pod-node/).
|
||||
If you do not specify either, then the DaemonSet controller will create Pods on all nodes.
|
||||
-->
|
||||
### 仅在某些节点上运行 Pod
|
||||
|
||||
如果指定了 `.spec.template.spec.nodeSelector`,DaemonSet Controller 将在能够与 [Node Selector](/docs/concepts/configuration/assign-pod-node/) 匹配的节点上创建 Pod。
|
||||
类似这种情况,可以指定 `.spec.template.spec.affinity`,然后 DaemonSet Controller 将在能够与 [Node Affinity](/docs/concepts/configuration/assign-pod-node/) 匹配的节点上创建 Pod。
|
||||
如果指定了 `.spec.template.spec.nodeSelector`,DaemonSet Controller 将在能够与 [Node Selector](/docs/concepts/configuration/assign-pod-node/) 匹配的节点上创建 Pod。类似这种情况,可以指定 `.spec.template.spec.affinity`,然后 DaemonSet Controller 将在能够与 [node Affinity](/docs/concepts/configuration/assign-pod-node/) 匹配>的节点上创建 Pod。
|
||||
如果根本就没有指定,则 DaemonSet Controller 将在所有节点上创建 Pod。
|
||||
|
||||
<!--
|
||||
## How Daemon Pods are Scheduled
|
||||
|
||||
### Scheduled by DaemonSet controller (disabled by default since 1.12)
|
||||
|
||||
## 如何调度 Daemon Pod
|
||||
Normally, the machine that a Pod runs on is selected by the Kubernetes scheduler. However, Pods
|
||||
created by the DaemonSet controller have the machine already selected (`.spec.nodeName` is specified
|
||||
when the Pod is created, so it is ignored by the scheduler). Therefore:
|
||||
|
||||
正常情况下,Pod 运行在哪个机器上是由 Kubernetes 调度器来选择的。然而,由 Daemon Controller 创建的 Pod 已经确定了在哪个机器上(Pod 创建时指定了 `.spec.nodeName`),因此:
|
||||
- The [`unschedulable`](/docs/admin/node/#manual-node-administration) field of a node is not respected
|
||||
by the DaemonSet controller.
|
||||
- The DaemonSet controller can make Pods even when the scheduler has not been started, which can help cluster
|
||||
bootstrap.
|
||||
-->
|
||||
## 如何调度 Daemon Pods
|
||||
|
||||
### 由 DaemonSet 控制器调度(从v1.12 开始默认禁用)
|
||||
|
||||
正常情况下,Pod 运行在哪个机器上是由 Kubernetes 调度器来选择的。然而,由 DaemonSet Controller 创建的 Pod 已经确定了在哪个机器上(Pod 创建时指定了 `.spec.nodeName`,调度器会忽略它),因此:
|
||||
|
||||
- DaemonSet Controller 并不关心一个节点的 [`unschedulable`](/docs/admin/node/#manual-node-administration) 字段。
|
||||
- DaemonSet Controller 可以创建 Pod,即使调度器还没有启动,这对集群启动是非常有帮助的。
|
||||
|
||||
<!--
|
||||
### Scheduled by default scheduler (enabled by default since 1.12)
|
||||
|
||||
{{< feature-state state="beta" for-kubernetes-version="1.12" >}}
|
||||
|
||||
Daemon Pod 关心 [Taint 和 Toleration](/docs/concepts/configuration/assign-pod-node/#taints-and-tolerations-beta-feature),它们会为没有指定 `tolerationSeconds` 的 `node.kubernetes.io/not-ready` 和 `node.alpha.kubernetes.io/unreachable` 的 Taint,创建具有 `NoExecute` 的 Toleration。这确保了当 alpha 特性的 `TaintBasedEvictions` 被启用时,发生节点故障,比如网络分区,这时它们将不会被清除掉(当 `TaintBasedEvictions` 特性没有启用,在这些场景下也不会被清除,但会因为 NodeController 的硬编码行为而被清除,而不会因为 Toleration 导致被清除)。
|
||||
A DaemonSet ensures that all eligible nodes run a copy of a Pod. Normally, the
|
||||
node that a Pod runs on is selected by the Kubernetes scheduler. However,
|
||||
DaemonSet pods are created and scheduled by the DaemonSet controller instead.
|
||||
That introduces the following issues:
|
||||
|
||||
* Inconsistent Pod behavior: Normal Pods waiting to be scheduled are created
|
||||
and in `Pending` state, but DaemonSet pods are not created in `Pending`
|
||||
state. This is confusing to the user.
|
||||
* [Pod preemption](/docs/concepts/configuration/pod-priority-preemption/)
|
||||
is handled by default scheduler. When preemption is enabled, the DaemonSet controller
|
||||
will make scheduling decisions without considering pod priority and preemption.
|
||||
-->
|
||||
### 由默认 scheduler 调度(从v1.12开始默认开启)
|
||||
|
||||
{{< feature-state state="beta" for-kubernetes-version="1.12" >}}
|
||||
|
||||
DaemonSet 确保所有符合条件的节点都运行一个 Pod 的副本。通常,运行 Pod 的节点由 Kubernetes scheduler 选择。然而,DaemonSet pods 由 DaemonSet controller 创建和调度。这将引入以下问题:
|
||||
|
||||
* Pod 行为的不一致性:等待调度的正常 Pod 已被创建并处于 `Pending` 状态,但 DaemonSet pods 未在 `Pending` 状态下创建。 这使用户感到困惑。
|
||||
* [Pod preemption](/docs/concepts/configuration/pod-priority-preemption/)由默认 scheduler 处理。 启用抢占后,DaemonSet 控制器将在不考虑 pod 优先级和抢占的情况下制定调度决策。
|
||||
|
||||
<!--
|
||||
`ScheduleDaemonSetPods` allows you to schedule DaemonSets using the default
|
||||
scheduler instead of the DaemonSet controller, by adding the `NodeAffinity` term
|
||||
to the DaemonSet pods, instead of the `.spec.nodeName` term. The default
|
||||
scheduler is then used to bind the pod to the target host. If node affinity of
|
||||
the DaemonSet pod already exists, it is replaced. The DaemonSet controller only
|
||||
performs these operations when creating or modifying DaemonSet pods, and no
|
||||
changes are made to the `spec.template` of the DaemonSet.
|
||||
-->
|
||||
`ScheduleDaemonSetPods` 允许您使用默认 scheduler 而不是 DaemonSet 控制器来调度 DaemonSets,方法是将 `NodeAffinity` 添加到 DaemonSet pods,而不是 `.spec.nodeName`。 然后使用默认 scheduler 将 pod 绑定到目标主机。 如果 DaemonSet pod的亲和节点已存在,则替换它。 DaemonSet 控制器仅在创建或修改 DaemonSet pods 时执行这些操作,并且不对 DaemonSet的 `spec.template` 进行任何更改。
|
||||
|
||||
```yaml
|
||||
nodeAffinity:
|
||||
requiredDuringSchedulingIgnoredDuringExecution:
|
||||
nodeSelectorTerms:
|
||||
- matchFields:
|
||||
- key: metadata.name
|
||||
operator: In
|
||||
values:
|
||||
- target-host-name
|
||||
```
|
||||
|
||||
<!--
|
||||
In addition, `node.kubernetes.io/unschedulable:NoSchedule` toleration is added
|
||||
automatically to DaemonSet Pods. The default scheduler ignores
|
||||
`unschedulable` Nodes when scheduling DaemonSet Pods.
|
||||
-->
|
||||
此外,`node.kubernetes.io/unschedulable:NoSchedule` toleration 会自动添加到 DaemonSet Pods。 在调度DaemonSet Pod 时,默认调度器会忽略 `unschedulable`节点。
|
||||
|
||||
<!--
|
||||
### Taints and Tolerations
|
||||
|
||||
Although Daemon Pods respect
|
||||
[taints and tolerations](/docs/concepts/configuration/taint-and-toleration),
|
||||
the following tolerations are added to DaemonSet Pods automatically according to
|
||||
the related features.
|
||||
-->
|
||||
### Taints and Tolerations
|
||||
|
||||
尽管 Daemon Pods 尊重[taints and tolerations](/docs/concepts/configuration/taint-and-toleration),根据相关特性,会自动将以下 tolerations 添加到 DaemonSet Pods 中。
|
||||
|
||||
| Toleration Key | Effect | Version | Description |
|
||||
| ---------------------------------------- | ---------- | ------- | ------------------------------------------------------------ |
|
||||
| `node.kubernetes.io/not-ready` | NoExecute | 1.13+ | DaemonSet pods will not be evicted when there are node problems such as a network partition. |
|
||||
| `node.kubernetes.io/unreachable` | NoExecute | 1.13+ | DaemonSet pods will not be evicted when there are node problems such as a network partition. |
|
||||
| `node.kubernetes.io/disk-pressure` | NoSchedule | 1.8+ | |
|
||||
| `node.kubernetes.io/memory-pressure` | NoSchedule | 1.8+ | |
|
||||
| `node.kubernetes.io/unschedulable` | NoSchedule | 1.12+ | DaemonSet pods tolerate unschedulable attributes by default scheduler. |
|
||||
| `node.kubernetes.io/network-unavailable` | NoSchedule | 1.12+ | DaemonSet pods, who uses host network, tolerate network-unavailable attributes by default scheduler. |
|
||||
|
||||
|
||||
|
||||
## 与 Daemon Pod 通信
|
||||
<!--
|
||||
## Communicating with Daemon Pods
|
||||
|
||||
Some possible patterns for communicating with Pods in a DaemonSet are:
|
||||
|
||||
- **Push**: Pods in the DaemonSet are configured to send updates to another service, such
|
||||
as a stats database. They do not have clients.
|
||||
- **NodeIP and Known Port**: Pods in the DaemonSet can use a `hostPort`, so that the pods are reachable via the node IPs. Clients know the list of node IPs somehow, and know the port by convention.
|
||||
- **DNS**: Create a [headless service](/docs/concepts/services-networking/service/#headless-services) with the same pod selector,
|
||||
and then discover DaemonSets using the `endpoints` resource or retrieve multiple A records from
|
||||
DNS.
|
||||
- **Service**: Create a service with the same Pod selector, and use the service to reach a
|
||||
daemon on a random node. (No way to reach specific node.)
|
||||
-->
|
||||
## 与 Daemon Pods 通信
|
||||
|
||||
与 DaemonSet 中的 Pod 进行通信,几种可能的模式如下:
|
||||
|
||||
- **Push**:配置 DaemonSet 中的 Pod 向其它 Service 发送更新,例如统计数据库。它们没有客户端。
|
||||
- **NodeIP 和已知端口**:DaemonSet 中的 Pod 可以使用 `hostPort`,从而可以通过节点 IP 访问到 Pod。客户端能通过某种方法知道节点 IP 列表,并且基于此也可以知道端口。
|
||||
- **DNS**:创建具有相同 Pod Selector 的 [Headless Service](/docs/user-guide/services/#headless-services),然后通过使用 `endpoints` 资源或从 DNS 检索到多个 A 记录来发现 DaemonSet。
|
||||
- **NodeIP 和已知端口**:DaemonSet 中的 Pod 可以使用 `hostPort`,从而可以通过节点 IP 访问到 Pod。客户端能通过某种方法知道节点 IP 列表,并且基于此也可以知道端口
|
||||
。
|
||||
- **DNS**:创建具有相同 Pod Selector 的 [Headless Service](/docs/concepts/services-networking/service/#headless-services),然后通过使用 `endpoints` 资源或从 DNS 检索到多个 A 记录来发现 DaemonSet。
|
||||
- **Service**:创建具有相同 Pod Selector 的 Service,并使用该 Service 随机访问到某个节点上的 daemon(没有办法访问到特定节点)。
|
||||
|
||||
<!--
|
||||
## Updating a DaemonSet
|
||||
|
||||
If node labels are changed, the DaemonSet will promptly add Pods to newly matching nodes and delete
|
||||
Pods from newly not-matching nodes.
|
||||
|
||||
You can modify the Pods that a DaemonSet creates. However, Pods do not allow all
|
||||
fields to be updated. Also, the DaemonSet controller will use the original template the next
|
||||
time a node (even with the same name) is created.
|
||||
|
||||
You can delete a DaemonSet. If you specify `--cascade=false` with `kubectl`, then the Pods
|
||||
will be left on the nodes. If you subsequently create a new DaemonSet with the same selector,
|
||||
the new DaemonSet adopts the existing Pods. If any Pods need replacing the DaemonSet replaces
|
||||
them according to its `updateStrategy`.
|
||||
|
||||
You can [perform a rolling update](/docs/tasks/manage-daemon/update-daemon-set/) on a DaemonSet.
|
||||
-->
|
||||
|
||||
## 更新 DaemonSet
|
||||
|
||||
如果修改了节点标签(Label),DaemonSet 将立刻向新匹配上的节点添加 Pod,同时删除新近不能够匹配的节点上的 Pod。
|
||||
如果修改了节点标签(Label),DaemonSet 将立刻向新匹配上的节点添加 Pod,同时删除不能够匹配的节点上的 Pod。
|
||||
|
||||
我们可以修改 DaemonSet 创建的 Pod。然而,不允许对 Pod 的所有字段进行更新。当下次节点(即使具有相同的名称)被创建时,DaemonSet Controller 还会使用最初的模板。
|
||||
您可以修改 DaemonSet 创建的 Pod。然而,不允许对 Pod 的所有字段进行更新。当下次
|
||||
节点(即使具有相同的名称)被创建时,DaemonSet Controller 还会使用最初的模板。
|
||||
|
||||
您可以删除一个 DaemonSet。如果使用 `kubectl` 并指定 `--cascade=false` 选项,则 Pod 将被保留在节点上。然后可以创建具有不同模板的新 DaemonSet。具有不同模板的新 DaemonSet 将能够通过标签匹配并识别所有已经存在的 Pod。
|
||||
如果有任何 Pod 需要替换,则 DaemonSet 根据它的 `updateStrategy` 来替换。
|
||||
|
||||
<!--
|
||||
## Alternatives to DaemonSet
|
||||
|
||||
可以删除一个 DaemonSet。如果使用 `kubectl` 并指定 `--cascade=false` 选项,则 Pod 将被保留在节点上。然后可以创建具有不同模板的新 DaemonSet。具有不同模板的新 DaemonSet 将能够通过标签匹配并识别所有已经存在的 Pod。它不会修改或删除它们,即使是错误匹配了 Pod 模板。通过删除 Pod 或者删除节点,可以强制创建新的 Pod。
|
||||
|
||||
在 Kubernetes 1.6 或以后版本,可以在 DaemonSet 上 [执行滚动升级](/docs/tasks/manage-daemon/update-daemon-set/)。
|
||||
|
||||
未来的 Kubernetes 版本将支持节点的可控更新。
|
||||
|
||||
### Init Scripts
|
||||
|
||||
It is certainly possible to run daemon processes by directly starting them on a node (e.g. using
|
||||
`init`, `upstartd`, or `systemd`). This is perfectly fine. However, there are several advantages to
|
||||
running such processes via a DaemonSet:
|
||||
|
||||
- Ability to monitor and manage logs for daemons in the same way as applications.
|
||||
- Same config language and tools (e.g. Pod templates, `kubectl`) for daemons and applications.
|
||||
- Running daemons in containers with resource limits increases isolation between daemons from app
|
||||
containers. However, this can also be accomplished by running the daemons in a container but not in a Pod
|
||||
(e.g. start directly via Docker).
|
||||
-->
|
||||
## DaemonSet 的可替代选择
|
||||
|
||||
### init 脚本
|
||||
|
||||
我们很可能希望直接在一个节点上启动 daemon 进程(例如,使用 `init`、`upstartd`、或 `systemd`)。这非常好,但基于 DaemonSet 来运行这些进程有如下一些好处:
|
||||
|
||||
|
||||
|
||||
- 像对待应用程序一样,具备为 daemon 提供监控和管理日志的能力。
|
||||
|
||||
- 为 daemon 和应用程序使用相同的配置语言和工具(如 Pod 模板、`kubectl`)。
|
||||
- Kubernetes 未来版本可能会支持对 DaemonSet 创建 Pod 与节点升级工作流进行集成。
|
||||
|
||||
- 在资源受限的容器中运行 daemon,能够增加 daemon 和应用容器的隔离性。然而,这也实现了在容器中运行 daemon,但却不能在 Pod 中运行(例如,直接基于 Docker 启动)。
|
||||
|
||||
<!--
|
||||
### Bare Pods
|
||||
|
||||
|
||||
It is possible to create Pods directly which specify a particular node to run on. However,
|
||||
a DaemonSet replaces Pods that are deleted or terminated for any reason, such as in the case of
|
||||
node failure or disruptive node maintenance, such as a kernel upgrade. For this reason, you should
|
||||
use a DaemonSet rather than creating individual Pods.
|
||||
-->
|
||||
### 裸 Pod
|
||||
|
||||
可能要直接创建 Pod,同时指定其运行在特定的节点上。
|
||||
然而,DaemonSet 替换了由于任何原因被删除或终止的 Pod,例如节点失败、例行节点维护、内核升级。由于这个原因,我们应该使用 DaemonSet 而不是单独创建 Pod。
|
||||
|
||||
可能要直接创建 Pod,同时指定其运行在特定的节点上。然而,DaemonSet 替换了由于任何原因被删除或终止的 Pod,例如节点失败、例行节点维护、内核升级。由于这个原因,我们应该使用 DaemonSet 而不是单独创建 Pod。
|
||||
|
||||
<!--
|
||||
### Static Pods
|
||||
|
||||
It is possible to create Pods by writing a file to a certain directory watched by Kubelet. These
|
||||
are called [static pods](/docs/concepts/cluster-administration/static-pod/).
|
||||
Unlike DaemonSet, static Pods cannot be managed with kubectl
|
||||
or other Kubernetes API clients. Static Pods do not depend on the apiserver, making them useful
|
||||
in cluster bootstrapping cases. Also, static Pods may be deprecated in the future.
|
||||
-->
|
||||
### 静态 Pod
|
||||
|
||||
可能需要通过在一个指定目录下编写文件来创建 Pod,该目录受 Kubelet 所监视。这些 Pod 被称为 [静态 Pod](/docs/concepts/cluster-administration/static-pod/)。
|
||||
不像 DaemonSet,静态 Pod 不受 kubectl 和其它 Kubernetes API 客户端管理。静态 Pod 不依赖于 apiserver,这使得它们在集群启动的情况下非常有用。
|
||||
而且,未来静态 Pod 可能会被废弃掉。
|
||||
不像 DaemonSet,静态 Pod 不受 kubectl 和其它 Kubernetes API 客户端管理。静态 Pod 不依赖于 apiserver,这使得它们在集群启动的情况下非常有用。而且,未来静态 Pod 可能会被废弃掉。
|
||||
|
||||
<!--
|
||||
### Deployments
|
||||
|
||||
DaemonSets are similar to [Deployments](/docs/concepts/workloads/controllers/deployment/) in that
|
||||
they both create Pods, and those Pods have processes which are not expected to terminate (e.g. web servers,
|
||||
storage servers).
|
||||
|
||||
### Replication Controller
|
||||
Use a Deployment for stateless services, like frontends, where scaling up and down the
|
||||
number of replicas and rolling out updates are more important than controlling exactly which host
|
||||
the Pod runs on. Use a DaemonSet when it is important that a copy of a Pod always run on
|
||||
all or certain hosts, and when it needs to start before other Pods.
|
||||
-->
|
||||
### Deployments
|
||||
|
||||
DaemonSet 与 [Replication Controller](/docs/user-guide/replication-controller) 非常类似,它们都能创建 Pod,这些 Pod 对应的进程都不希望被终止掉(例如,Web 服务器、存储服务器)。
|
||||
为无状态的 Service 使用 Replication Controller,比如前端(Frontend)服务,实现对副本的数量进行扩缩容、平滑升级,比之于精确控制 Pod 运行在某个主机上要重要得多。
|
||||
DaemonSet 与 [Deployments](/docs/concepts/workloads/controllers/deployment/) 非常类似,它们都能创建 Pod,这些 Pod 对应的进程都不希望被终止掉(例如,Web 服务器、存储服务器)。
|
||||
为无状态的 Service 使用 Deployments,比如前端 Frontend 服务,实现对副本的数量进行扩缩容、平滑升级,比基于精确控制 Pod 运行在某个主机上要重要得多。
|
||||
需要 Pod 副本总是运行在全部或特定主机上,并需要先于其他 Pod 启动,当这被认为非常重要时,应该使用 Daemon Controller。
|
||||
|
||||
{{% /capture %}}
|
||||
|
||||
@@ -25,13 +25,43 @@ You should not manage ReplicaSets owned by a Deployment. All the use cases shoul
|
||||
|
||||
The following are typical use cases for Deployments:
|
||||
|
||||
* [Create a Deployment to rollout a ReplicaSet](#creating-a-deployment). The ReplicaSet creates Pods in the background. Check the status of the rollout to see if it succeeds or not.
|
||||
* [Declare the new state of the Pods](#updating-a-deployment) by updating the PodTemplateSpec of the Deployment. A new ReplicaSet is created and the Deployment manages moving the Pods from the old ReplicaSet to the new one at a controlled rate. Each new ReplicaSet updates the revision of the Deployment.
|
||||
* [Rollback to an earlier Deployment revision](#rolling-back-a-deployment) if the current state of the Deployment is not stable. Each rollback updates the revision of the Deployment.
|
||||
* [Scale up the Deployment to facilitate more load.](#scaling-a-deployment)
|
||||
* [Pause the Deployment](#pausing-and-resuming-a-deployment) to apply multiple fixes to its PodTemplateSpec and then resume it to start a new rollout.
|
||||
* [Use the status of the Deployment](#deployment-status) as an indicator that a rollout has stuck
|
||||
* [Clean up older ReplicaSets](#clean-up-policy) that you don't need anymore
|
||||
- [Use Case](#use-case)
|
||||
- [Creating a Deployment](#creating-a-deployment)
|
||||
- [Pod-template-hash label](#pod-template-hash-label)
|
||||
- [Updating a Deployment](#updating-a-deployment)
|
||||
- [Rollover (aka multiple updates in-flight)](#rollover-aka-multiple-updates-in-flight)
|
||||
- [Label selector updates](#label-selector-updates)
|
||||
- [Rolling Back a Deployment](#rolling-back-a-deployment)
|
||||
- [Checking Rollout History of a Deployment](#checking-rollout-history-of-a-deployment)
|
||||
- [Rolling Back to a Previous Revision](#rolling-back-to-a-previous-revision)
|
||||
- [Scaling a Deployment](#scaling-a-deployment)
|
||||
- [Proportional scaling](#proportional-scaling)
|
||||
- [Pausing and Resuming a Deployment](#pausing-and-resuming-a-deployment)
|
||||
- [Deployment status](#deployment-status)
|
||||
- [Progressing Deployment](#progressing-deployment)
|
||||
- [Complete Deployment](#complete-deployment)
|
||||
- [Failed Deployment](#failed-deployment)
|
||||
- [Operating on a failed deployment](#operating-on-a-failed-deployment)
|
||||
- [Clean up Policy](#clean-up-policy)
|
||||
- [Use Cases](#use-cases)
|
||||
- [Canary Deployment](#canary-deployment)
|
||||
- [Writing a Deployment Spec](#writing-a-deployment-spec)
|
||||
- [Pod Template](#pod-template)
|
||||
- [Replicas](#replicas)
|
||||
- [Selector](#selector)
|
||||
- [Strategy](#strategy)
|
||||
- [Recreate Deployment](#recreate-deployment)
|
||||
- [Rolling Update Deployment](#rolling-update-deployment)
|
||||
- [Max Unavailable](#max-unavailable)
|
||||
- [Max Surge](#max-surge)
|
||||
- [Progress Deadline Seconds](#progress-deadline-seconds)
|
||||
- [Min Ready Seconds](#min-ready-seconds)
|
||||
- [Rollback To](#rollback-to)
|
||||
- [Revision](#revision)
|
||||
- [Revision History Limit](#revision-history-limit)
|
||||
- [Paused](#paused)
|
||||
- [Alternative to Deployments](#alternative-to-deployments)
|
||||
- [kubectl rolling update](#kubectl-rolling-update)
|
||||
|
||||
|
||||
## Creating a Deployment
|
||||
|
||||
@@ -5,52 +5,84 @@ redirect_from:
|
||||
- "/docs/concepts/abstractions/controllers/garbage-collection.html"
|
||||
- "/docs/user-guide/garbage-collection/"
|
||||
- "/docs/user-guide/garbage-collection.html"
|
||||
|
||||
content_template: templates/concept
|
||||
---
|
||||
|
||||
<!--
|
||||
---
|
||||
title: Garbage Collection
|
||||
content_template: templates/concept
|
||||
weight: 60
|
||||
---
|
||||
-->
|
||||
|
||||
{{% capture overview %}}
|
||||
|
||||
<!--
|
||||
The role of the Kubernetes garbage collector is to delete certain objects
|
||||
that once had an owner, but no longer have an owner.
|
||||
-->
|
||||
|
||||
|
||||
Kubernetes 垃圾收集器的角色是删除指定的对象,这些对象曾经有但以后不再拥有 Owner 了。
|
||||
|
||||
**注意**:垃圾收集是 beta 特性,在 Kubernetes 1.4 及以上版本默认启用。
|
||||
Kubernetes 垃圾收集器的作用是删除某些曾经拥有所有者(owner)但现在不再拥有所有者的对象。
|
||||
|
||||
{{% /capture %}}
|
||||
|
||||
|
||||
{{% capture body %}}
|
||||
|
||||
<!--
|
||||
## Owners and dependents
|
||||
|
||||
## Owner 和 Dependent
|
||||
Some Kubernetes objects are owners of other objects. For example, a ReplicaSet
|
||||
is the owner of a set of Pods. The owned objects are called *dependents* of the
|
||||
owner object. Every dependent object has a `metadata.ownerReferences` field that
|
||||
points to the owning object.
|
||||
|
||||
某些 Kubernetes 对象是其它一些对象的 Owner。例如,一个 ReplicaSet 是一组 Pod 的 Owner。
|
||||
具有 Owner 的对象被称为是 Owner 的 *Dependent* 。
|
||||
每个 Dependent 对象具有一个指向其所属对象的 `metadata.ownerReferences` 字段。
|
||||
Sometimes, Kubernetes sets the value of `ownerReference` automatically. For
|
||||
example, when you create a ReplicaSet, Kubernetes automatically sets the
|
||||
`ownerReference` field of each Pod in the ReplicaSet. In 1.8, Kubernetes
|
||||
automatically sets the value of `ownerReference` for objects created or adopted
|
||||
by ReplicationController, ReplicaSet, StatefulSet, DaemonSet, Deployment, Job
|
||||
and CronJob.
|
||||
|
||||
You can also specify relationships between owners and dependents by manually
|
||||
setting the `ownerReference` field.
|
||||
|
||||
Here's a configuration file for a ReplicaSet that has three Pods:
|
||||
-->
|
||||
|
||||
## 所有者和附属
|
||||
|
||||
某些 Kubernetes 对象是其它一些对象的所有者。例如,一个 ReplicaSet 是一组 Pod 的所有者。
|
||||
具有所有者的对象被称为是所有者的*附属*。
|
||||
每个附属对象具有一个指向其所属对象的 `metadata.ownerReferences` 字段。
|
||||
|
||||
有时,Kubernetes 会自动设置 `ownerReference` 的值。
|
||||
例如,当创建一个 ReplicaSet 时,Kubernetes 自动设置 ReplicaSet 中每个 Pod 的 `ownerReference` 字段值。
|
||||
在 1.6 版本,Kubernetes 会自动为某些对象设置 `ownerReference` 的值,这些对象是由 ReplicationController、ReplicaSet、StatefulSet、DaemonSet 和 Deployment 所创建或管理。
|
||||
|
||||
|
||||
|
||||
也可以通过手动设置 `ownerReference` 的值,来指定 Owner 和 Dependent 之间的关系。
|
||||
也可以通过手动设置 `ownerReference` 的值,来指定所有者和附属之间的关系。
|
||||
|
||||
这里有一个配置文件,表示一个具有 3 个 Pod 的 ReplicaSet:
|
||||
|
||||
{{< codenew file="controllers/replicaset.yaml" >}}
|
||||
|
||||
<!--
|
||||
If you create the ReplicaSet and then view the Pod metadata, you can see
|
||||
OwnerReferences field:
|
||||
-->
|
||||
|
||||
如果创建该 ReplicaSet,然后查看 Pod 的 metadata 字段,能够看到 OwnerReferences 字段:
|
||||
|
||||
```shell
|
||||
kubectl create -f https://k8s.io/docs/concepts/controllers/my-repset.yaml
|
||||
kubectl apply -f https://k8s.io/examples/controllers/replicaset.yaml
|
||||
kubectl get pods --output=yaml
|
||||
```
|
||||
|
||||
<!--
|
||||
The output shows that the Pod owner is a ReplicaSet named `my-repset`:
|
||||
-->
|
||||
|
||||
|
||||
输出显示了 Pod 的 Owner 是名为 my-repset 的 ReplicaSet:
|
||||
输出显示了 Pod 的所有者是名为 my-repset 的 ReplicaSet:
|
||||
|
||||
```shell
|
||||
apiVersion: v1
|
||||
@@ -58,7 +90,7 @@ kind: Pod
|
||||
metadata:
|
||||
...
|
||||
ownerReferences:
|
||||
- apiVersion: extensions/v1beta1
|
||||
- apiVersion: apps/v1
|
||||
controller: true
|
||||
blockOwnerDeletion: true
|
||||
kind: ReplicaSet
|
||||
@@ -67,101 +99,201 @@ metadata:
|
||||
...
|
||||
```
|
||||
|
||||
{{< note >}}
|
||||
|
||||
## 控制垃圾收集器删除 Dependent
|
||||
<!--
|
||||
Cross-namespace owner references are disallowed by design. This means:
|
||||
1) Namespace-scoped dependents can only specify owners in the same namespace,
|
||||
and owners that are cluster-scoped.
|
||||
2) Cluster-scoped dependents can only specify cluster-scoped owners, but not
|
||||
namespace-scoped owners.
|
||||
-->
|
||||
|
||||
当删除对象时,可以指定是否该对象的 Dependent 也自动删除掉。
|
||||
根据设计,kubernetes 不允许跨命名空间指定所有者。这意味着:
|
||||
|
||||
1)命名空间范围的附属只能在相同的命名空间中指定所有者,并且只能指定集群范围的所有者。
|
||||
|
||||
2)集群范围的附属只能指定集群范围的所有者,不能指定命名空间范围的。
|
||||
|
||||
{{< /note >}}
|
||||
|
||||
<!--
|
||||
## Controlling how the garbage collector deletes dependents
|
||||
|
||||
When you delete an object, you can specify whether the object's dependents are
|
||||
also deleted automatically. Deleting dependents automatically is called *cascading
|
||||
deletion*. There are two modes of *cascading deletion*: *background* and *foreground*.
|
||||
|
||||
If you delete an object without deleting its dependents
|
||||
automatically, the dependents are said to be *orphaned*.
|
||||
|
||||
-->
|
||||
## 控制垃圾收集器删除附属者
|
||||
|
||||
当删除对象时,可以指定是否该对象的附属者也自动删除掉。
|
||||
自动删除 Dependent 也称为 *级联删除* 。
|
||||
Kubernetes 中有两种 *级联删除* 的模式:*background* 模式和 *foreground* 模式。
|
||||
|
||||
如果删除对象时,不自动删除它的 Dependent,这些 Dependent 被称作是原对象的 *孤儿* 。
|
||||
如果删除对象时,不自动删除它的附属者,这些附属者被称作是原对象的*孤儿* 。
|
||||
|
||||
|
||||
<!--
|
||||
### Foreground cascading deletion
|
||||
|
||||
### Background 级联删除
|
||||
In *foreground cascading deletion*, the root object first
|
||||
enters a "deletion in progress" state. In the "deletion in progress" state,
|
||||
the following things are true:
|
||||
|
||||
在 *background 级联删除* 模式下,Kubernetes 会立即删除 Owner 对象,然后垃圾收集器会在后台删除这些 Dependent。
|
||||
* The object is still visible via the REST API
|
||||
* The object's `deletionTimestamp` is set
|
||||
* The object's `metadata.finalizers` contains the value "foregroundDeletion".
|
||||
|
||||
Once the "deletion in progress" state is set, the garbage
|
||||
collector deletes the object's dependents. Once the garbage collector has deleted all
|
||||
"blocking" dependents (objects with `ownerReference.blockOwnerDeletion=true`), it deletes
|
||||
the owner object.
|
||||
|
||||
Note that in the "foregroundDeletion", only dependents with
|
||||
`ownerReference.blockOwnerDeletion=true` block the deletion of the owner object.
|
||||
Kubernetes version 1.7 added an [admission controller](/docs/reference/access-authn-authz/admission-controllers/#ownerreferencespermissionenforcement) that controls user access to set
|
||||
`blockOwnerDeletion` to true based on delete permissions on the owner object, so that
|
||||
unauthorized dependents cannot delay deletion of an owner object.
|
||||
|
||||
### Foreground 级联删除
|
||||
If an object's `ownerReferences` field is set by a controller (such as Deployment or ReplicaSet),
|
||||
blockOwnerDeletion is set automatically and you do not need to manually modify this field.
|
||||
-->
|
||||
|
||||
在 *foreground 级联删除* 模式下,根对象首先进入 “删除中” 状态。在 “删除中” 状态会有如下的情况:
|
||||
### 显式级联删除
|
||||
|
||||
在*显式级联删除*模式下,根对象首先进入 `deletion in progress` 状态。在 `deletion in progress` 状态会有如下的情况:
|
||||
|
||||
* 对象仍然可以通过 REST API 可见。
|
||||
* 会设置对象的 `deletionTimestamp` 字段。
|
||||
* 对象的 `metadata.finalizers` 字段包含了值 "foregroundDeletion"。
|
||||
* 对象的 `metadata.finalizers` 字段包含了值 `foregroundDeletion`。
|
||||
|
||||
一旦对象被设置为 “删除中” 状态,垃圾收集器会删除对象的所有 Dependent。
|
||||
垃圾收集器在删除了所有 “Blocking” 状态的 Dependent(对象的 `ownerReference.blockOwnerDeletion=true`)之后,它会删除 Owner 对象。
|
||||
一旦对象被设置为 `deletion in progress` 状态,垃圾收集器会删除对象的所有附属。
|
||||
垃圾收集器在删除了所有 `Blocking` 状态的附属(对象的 `ownerReference.blockOwnerDeletion=true`)之后,它会删除拥有者对象。
|
||||
|
||||
|
||||
|
||||
注意,在 “foreground 删除” 模式下,只有设置了 `ownerReference.blockOwnerDeletion` 值的 Dependent 才能阻止删除 Owner 对象。
|
||||
在 Kubernetes 1.7 版本中将增加许可控制器(Admission Controller),基于 Owner 对象上的删除权限来控制用户去设置 `blockOwnerDeletion` 的值为 true,所以未授权的 Dependent 不能够延迟 Owner 对象的删除。
|
||||
注意,在 `foregroundDeletion` 模式下,只有设置了 `ownerReference.blockOwnerDeletion` 值的附属者才能阻止删除拥有者对象。
|
||||
在 Kubernetes 1.7 版本中将增加准入控制器(Admission Controller),基于拥有者对象上的删除权限来控制用户去设置 `blockOwnerDeletion` 的值为 true,所以未授权的附属者不能够延迟拥有者对象的删除。
|
||||
|
||||
如果一个对象的 `ownerReferences` 字段被一个 Controller(例如 Deployment 或 ReplicaSet)设置,`blockOwnerDeletion` 会被自动设置,不需要手动修改这个字段。
|
||||
|
||||
|
||||
<!--
|
||||
### Background cascading deletion
|
||||
|
||||
In *background cascading deletion*, Kubernetes deletes the owner object
|
||||
immediately and the garbage collector then deletes the dependents in
|
||||
the background.
|
||||
-->
|
||||
### 隐式级联删除
|
||||
|
||||
在 *隐式级联删除除* 模式下,Kubernetes 会立即删除拥有者对象,然后垃圾收集器会在后台删除这些附属。
|
||||
|
||||
<!--
|
||||
### Setting the cascading deletion policy
|
||||
|
||||
To control the cascading deletion policy, set the `propagationPolicy`
|
||||
field on the `deleteOptions` argument when deleting an Object. Possible values include "Orphan",
|
||||
"Foreground", or "Background".
|
||||
|
||||
Prior to Kubernetes 1.9, the default garbage collection policy for many controller resources was `orphan`.
|
||||
This included ReplicationController, ReplicaSet, StatefulSet, DaemonSet, and
|
||||
Deployment. For kinds in the `extensions/v1beta1`, `apps/v1beta1`, and `apps/v1beta2` group versions, unless you
|
||||
specify otherwise, dependent objects are orphaned by default. In Kubernetes 1.9, for all kinds in the `apps/v1`
|
||||
group version, dependent objects are deleted by default.
|
||||
|
||||
Here's an example that deletes dependents in background:
|
||||
-->
|
||||
|
||||
### 设置级联删除策略
|
||||
|
||||
通过为 Owner 对象设置 `deleteOptions.propagationPolicy` 字段,可以控制级联删除策略。
|
||||
可能的取值包括:“orphan”、“Foreground” 或 “Background”。
|
||||
通过为拥有者对象设置 `deleteOptions.propagationPolicy` 字段,可以控制级联删除策略。
|
||||
可能的取值包括:`orphan`、`Foreground`或`Background`。
|
||||
|
||||
对很多 Controller 资源,包括 ReplicationController、ReplicaSet、StatefulSet、DaemonSet 和 Deployment,默认的垃圾收集策略是 `orphan`。
|
||||
因此,除非指定其它的垃圾收集策略,否则所有 Dependent 对象使用的都是 `orphan` 策略。
|
||||
因此,除非指定其它的垃圾收集策略,否则所有附属对象使用的都是 `orphan` 策略。
|
||||
|
||||
下面是一个在后台删除 Dependent 对象的例子:
|
||||
|
||||
```shell
|
||||
kubectl proxy --port=8080
|
||||
curl -X DELETE localhost:8080/apis/extensions/v1beta1/namespaces/default/replicasets/my-repset \
|
||||
-d '{"kind":"DeleteOptions","apiVersion":"v1","propagationPolicy":"Background"}' \
|
||||
-H "Content-Type: application/json"
|
||||
curl -X DELETE localhost:8080/apis/apps/v1/namespaces/default/replicasets/my-repset \
|
||||
-d '{"kind":"DeleteOptions","apiVersion":"v1","propagationPolicy":"Background"}' \
|
||||
-H "Content-Type: application/json"
|
||||
```
|
||||
|
||||
<!--
|
||||
Here's an example that deletes dependents in foreground:
|
||||
-->
|
||||
|
||||
|
||||
下面是一个在前台删除 Dependent 对象的例子:
|
||||
下面是一个在前台删除附属对象的例子:
|
||||
|
||||
```shell
|
||||
kubectl proxy --port=8080
|
||||
curl -X DELETE localhost:8080/apis/extensions/v1beta1/namespaces/default/replicasets/my-repset \
|
||||
-d '{"kind":"DeleteOptions","apiVersion":"v1","propagationPolicy":"Foreground"}' \
|
||||
-H "Content-Type: application/json"
|
||||
curl -X DELETE localhost:8080/apis/apps/v1/namespaces/default/replicasets/my-repset \
|
||||
-d '{"kind":"DeleteOptions","apiVersion":"v1","propagationPolicy":"Foreground"}' \
|
||||
-H "Content-Type: application/json"
|
||||
```
|
||||
|
||||
<!--
|
||||
Here's an example that orphans dependents:
|
||||
-->
|
||||
|
||||
下面是一个孤儿 Dependent 的例子:
|
||||
这里是一个孤儿附属的例子:
|
||||
|
||||
```shell
|
||||
kubectl proxy --port=8080
|
||||
curl -X DELETE localhost:8080/apis/extensions/v1beta1/namespaces/default/replicasets/my-repset \
|
||||
-d '{"kind":"DeleteOptions","apiVersion":"v1","propagationPolicy":"Orphan"}' \
|
||||
-H "Content-Type: application/json"
|
||||
curl -X DELETE localhost:8080/apis/apps/v1/namespaces/default/replicasets/my-repset \
|
||||
-d '{"kind":"DeleteOptions","apiVersion":"v1","propagationPolicy":"Orphan"}' \
|
||||
-H "Content-Type: application/json"
|
||||
```
|
||||
|
||||
<!--
|
||||
kubectl also supports cascading deletion.
|
||||
To delete dependents automatically using kubectl, set `--cascade` to true. To
|
||||
orphan dependents, set `--cascade` to false. The default value for `--cascade`
|
||||
is true.
|
||||
|
||||
Here's an example that orphans the dependents of a ReplicaSet:
|
||||
-->
|
||||
|
||||
kubectl 也支持级联删除。
|
||||
通过设置 `--cascade` 为 true,可以使用 kubectl 自动删除 Dependent 对象。
|
||||
设置 `--cascade` 为 false,会使 Dependent 对象成为孤儿 Dependent 对象。
|
||||
`--cascade` 的默认值是 true。
|
||||
|
||||
下面是一个例子,使一个 ReplicaSet 的 Dependent 对象成为孤儿 Dependent:
|
||||
通过设置 `--cascade` 为 `true`,可以使用 kubectl 自动删除附属对象。设置 `--cascade` 为 `false`,会使附属对象成为孤儿附属对象。`--cascade` 的默认值是 true。
|
||||
|
||||
下面是一个例子,使一个 ReplicaSet 的附属对象成为孤儿附属:
|
||||
|
||||
```shell
|
||||
kubectl delete replicaset my-repset --cascade=false
|
||||
```
|
||||
|
||||
<!--
|
||||
### Additional note on Deployments
|
||||
|
||||
Prior to 1.7, When using cascading deletes with Deployments you *must* use `propagationPolicy: Foreground`
|
||||
to delete not only the ReplicaSets created, but also their Pods. If this type of _propagationPolicy_
|
||||
is not used, only the ReplicaSets will be deleted, and the Pods will be orphaned.
|
||||
See [kubeadm/#149](https://github.com/kubernetes/kubeadm/issues/149#issuecomment-284766613) for more information.
|
||||
-->
|
||||
|
||||
### Deployment 的其他说明
|
||||
|
||||
在 1.7 之前的版本中,当在 Deployment 中使用级联删除时,您必须*使用* `propagationPolicy:Foreground`。这样不仅删除所创建的 ReplicaSet,还删除其 Pod。如果不使用这种类型的 `propagationPolicy`,则将只删除 ReplicaSet,而 Pod 被孤立。
|
||||
|
||||
更多信息,请参考 [kubeadm/#149](https://github.com/kubernetes/kubeadm/issues/149#issuecomment-284766613)。
|
||||
|
||||
<!--
|
||||
## Known issues
|
||||
|
||||
Tracked at [#26120](https://github.com/kubernetes/kubernetes/issues/26120)
|
||||
-->
|
||||
|
||||
## 已知的问题
|
||||
* 1.7 版本,垃圾收集不支持 [自定义资源](/docs/concepts/api-extension/custom-resources/),比如那些通过 CustomResourceDefinition 新增,或者通过 API server 聚集而成的资源对象。
|
||||
|
||||
[其它已知的问题](https://github.com/kubernetes/kubernetes/issues/26120)
|
||||
跟踪 [#26120](https://github.com/kubernetes/kubernetes/issues/26120)
|
||||
|
||||
{{% /capture %}}
|
||||
|
||||
@@ -169,9 +301,10 @@ kubectl delete replicaset my-repset --cascade=false
|
||||
{{% capture whatsnext %}}
|
||||
|
||||
|
||||
## 控制垃圾收集器删除附属者
|
||||
[设计文档 1](https://git.k8s.io/community/contributors/design-proposals/api-machinery/garbage-collection.md)
|
||||
|
||||
[设计文档 1](https://git.k8s.io/community/contributors/design-proposals/garbage-collection.md)
|
||||
[设计文档 2](https://git.k8s.io/community/contributors/design-proposals/synchronous-garbage-collection.md)
|
||||
[设计文档 2](https://git.k8s.io/community/contributors/design-proposals/api-machinery/synchronous-garbage-collection.md)
|
||||
|
||||
{{% /capture %}}
|
||||
|
||||
|
||||
@@ -0,0 +1,868 @@
|
||||
---
|
||||
title: Job 从运行到完成
|
||||
content_template: templates/concept
|
||||
feature:
|
||||
title: Batch execution
|
||||
description: >
|
||||
In addition to services, Kubernetes can manage your batch and CI workloads, replacing containers that fail, if desired.
|
||||
weight: 70
|
||||
---
|
||||
|
||||
<!--
|
||||
---
|
||||
reviewers:
|
||||
- erictune
|
||||
- soltysh
|
||||
title: Jobs - Run to Completion
|
||||
content_template: templates/concept
|
||||
feature:
|
||||
title: Batch execution
|
||||
description: >
|
||||
In addition to services, Kubernetes can manage your batch and CI workloads, replacing containers that fail, if desired.
|
||||
weight: 70
|
||||
---
|
||||
-->
|
||||
|
||||
{{% capture overview %}}
|
||||
|
||||
<!--
|
||||
A Job creates one or more Pods and ensures that a specified number of them successfully terminate.
|
||||
As pods successfully complete, the Job tracks the successful completions. When a specified number
|
||||
of successful completions is reached, the task (ie, Job) is complete. Deleting a Job will clean up
|
||||
the Pods it created.
|
||||
-->
|
||||
|
||||
Job 创建一个或多个 pod,并且确保指定数量的 pod 成功终止。Pod 成功完成后,Job 将跟踪成功完成的情况。当达到指定的成功完成次数时,任务(即 Job)就完成了。删除 Job 将清除其创建的 pod。
|
||||
|
||||
<!--
|
||||
A simple case is to create one Job object in order to reliably run one Pod to completion.
|
||||
The Job object will start a new Pod if the first Pod fails or is deleted (for example
|
||||
due to a node hardware failure or a node reboot).
|
||||
-->
|
||||
|
||||
一种简单的情况时创建一个 Job 对象,以便可靠地运行一个 Pod 来完成。如果第一个 pod 失败了或被删除了(例如,由于节点硬件故障或节点重启),则 Job 对象将启动一个新的 pod。
|
||||
|
||||
<!--
|
||||
You can also use a Job to run multiple Pods in parallel.
|
||||
-->
|
||||
|
||||
也可以使用 Job 去并行运行多个 pod。
|
||||
|
||||
{{% /capture %}}
|
||||
|
||||
|
||||
{{% capture body %}}
|
||||
|
||||
<!--
|
||||
## Running an example Job
|
||||
-->
|
||||
|
||||
## 运行一个 Job 示例
|
||||
|
||||
<!--
|
||||
Here is an example Job config. It computes π to 2000 places and prints it out.
|
||||
It takes around 10s to complete.
|
||||
-->
|
||||
|
||||
下面是一个 Job 配置样例。它计算 π 到2000位并将其打印出来。大约需要 10 秒钟才能完成。
|
||||
|
||||
{{< codenew file="controllers/job.yaml" >}}
|
||||
|
||||
<!--
|
||||
You can run the example with this command:
|
||||
-->
|
||||
|
||||
可以使用以下命令运行示例:
|
||||
|
||||
```shell
|
||||
kubectl apply -f https://k8s.io/examples/controllers/job.yaml
|
||||
```
|
||||
```
|
||||
job "pi" created
|
||||
```
|
||||
|
||||
<!--
|
||||
Check on the status of the Job with `kubectl`:
|
||||
-->
|
||||
|
||||
使用 `kubectl` 命令检查 Job 的状态:
|
||||
|
||||
```shell
|
||||
kubectl describe jobs/pi
|
||||
```
|
||||
```
|
||||
Name: pi
|
||||
Namespace: default
|
||||
Selector: controller-uid=b1db589a-2c8d-11e6-b324-0209dc45a495
|
||||
Labels: controller-uid=b1db589a-2c8d-11e6-b324-0209dc45a495
|
||||
job-name=pi
|
||||
Annotations: <none>
|
||||
Parallelism: 1
|
||||
Completions: 1
|
||||
Start Time: Tue, 07 Jun 2016 10:56:16 +0200
|
||||
Pods Statuses: 0 Running / 1 Succeeded / 0 Failed
|
||||
Pod Template:
|
||||
Labels: controller-uid=b1db589a-2c8d-11e6-b324-0209dc45a495
|
||||
job-name=pi
|
||||
Containers:
|
||||
pi:
|
||||
Image: perl
|
||||
Port:
|
||||
Command:
|
||||
perl
|
||||
-Mbignum=bpi
|
||||
-wle
|
||||
print bpi(2000)
|
||||
Environment: <none>
|
||||
Mounts: <none>
|
||||
Volumes: <none>
|
||||
Events:
|
||||
FirstSeen LastSeen Count From SubobjectPath Type Reason Message
|
||||
--------- -------- ----- ---- ------------- -------- ------ -------
|
||||
1m 1m 1 {job-controller } Normal SuccessfulCreate Created pod: pi-dtn4q
|
||||
```
|
||||
|
||||
<!--
|
||||
To view completed Pods of a Job, use `kubectl get pods`.
|
||||
-->
|
||||
|
||||
要查看 Job 的已完成 pod,可以使用 `kubectl get pods` 命令。
|
||||
|
||||
<!--
|
||||
To list all the Pods that belong to a Job in a machine readable form, you can use a command like this:
|
||||
-->
|
||||
|
||||
要以机器可读的形式列出属于 Job 的所有 pod,可以使用以下命令:
|
||||
|
||||
```shell
|
||||
pods=$(kubectl get pods --selector=job-name=pi --output=jsonpath='{.items[*].metadata.name}')
|
||||
echo $pods
|
||||
```
|
||||
```
|
||||
pi-aiw0a
|
||||
```
|
||||
|
||||
<!--
|
||||
Here, the selector is the same as the selector for the Job. The `--output=jsonpath` option specifies an expression
|
||||
that just gets the name from each Pod in the returned list.
|
||||
-->
|
||||
|
||||
这里,选择器与 Job 的选择器相同。`--output=jsonpath` 选项指定一个表达式来从 pod 返回列表中获取每个 pod 的名称。
|
||||
|
||||
<!--
|
||||
View the standard output of one of the pods:
|
||||
-->
|
||||
|
||||
查看其中一个 pod 的标准输出:
|
||||
|
||||
```shell
|
||||
kubectl logs $pods
|
||||
```
|
||||
The output is similar to this:
|
||||
```shell
|
||||
3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821480865132823066470938446095505822317253594081284811174502841027019385211055596446229489549303819644288109756659334461284756482337867831652712019091456485669234603486104543266482133936072602491412737245870066063155881748815209209628292540917153643678925903600113305305488204665213841469519415116094330572703657595919530921861173819326117931051185480744623799627495673518857527248912279381830119491298336733624406566430860213949463952247371907021798609437027705392171762931767523846748184676694051320005681271452635608277857713427577896091736371787214684409012249534301465495853710507922796892589235420199561121290219608640344181598136297747713099605187072113499999983729780499510597317328160963185950244594553469083026425223082533446850352619311881710100031378387528865875332083814206171776691473035982534904287554687311595628638823537875937519577818577805321712268066130019278766111959092164201989380952572010654858632788659361533818279682303019520353018529689957736225994138912497217752834791315155748572424541506959508295331168617278558890750983817546374649393192550604009277016711390098488240128583616035637076601047101819429555961989467678374494482553797747268471040475346462080466842590694912933136770289891521047521620569660240580381501935112533824300355876402474964732639141992726042699227967823547816360093417216412199245863150302861829745557067498385054945885869269956909272107975093029553211653449872027559602364806654991198818347977535663698074265425278625518184175746728909777727938000816470600161452491921732172147723501414419735685481613611573525521334757418494684385233239073941433345477624168625189835694855620992192221842725502542568876717904946016534668049886272327917860857843838279679766814541009538837863609506800642251252051173929848960841284886269456042419652850222106611863067442786220391949450471237137869609563643719172874677646575739624138908658326459958133904780275901
|
||||
```
|
||||
|
||||
<!--
|
||||
## Writing a Job Spec
|
||||
-->
|
||||
|
||||
## 编写 Job 规范
|
||||
|
||||
<!--
|
||||
As with all other Kubernetes config, a Job needs `apiVersion`, `kind`, and `metadata` fields.
|
||||
-->
|
||||
|
||||
和其他 Kubernetes 配置一样,Job 需要 `apiVersion`,`kind` 和 `metadata` 字段。
|
||||
|
||||
<!--
|
||||
A Job also needs a [`.spec` section](https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status).
|
||||
-->
|
||||
|
||||
Job 也需要 [`.spec` 部分](https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status)。
|
||||
|
||||
<!--
|
||||
### Pod Template
|
||||
-->
|
||||
|
||||
### Pod 模板
|
||||
|
||||
<!--
|
||||
The `.spec.template` is the only required field of the `.spec`.
|
||||
-->
|
||||
|
||||
`.spec.template` 是 `.spec` 中唯一必填字段。
|
||||
|
||||
<!--
|
||||
The `.spec.template` is a [pod template](/docs/concepts/workloads/pods/pod-overview/#pod-templates). It has exactly the same schema as a [pod](/docs/user-guide/pods), except it is nested and does not have an `apiVersion` or `kind`.
|
||||
-->
|
||||
|
||||
`.spec.template` 是 [pod 模板](/docs/concepts/workloads/pods/pod-overview/#pod-templates)。它具有与 [pod](/docs/user-guide/pods) 完全相同的架构,只是它是嵌套的并且没有 `apiVersion` 或 `kind`。
|
||||
|
||||
<!--
|
||||
In addition to required fields for a Pod, a pod template in a Job must specify appropriate
|
||||
labels (see [pod selector](#pod-selector)) and an appropriate restart policy.
|
||||
-->
|
||||
|
||||
除了 pod 的必填字段,Job 中的 pod 模板还必须指定合适的标签(参考 [pod 选择器](#pod-selector))和适当的重启策略。
|
||||
|
||||
<!--
|
||||
Only a [`RestartPolicy`](/docs/concepts/workloads/pods/pod-lifecycle/#restart-policy) equal to `Never` or `OnFailure` is allowed.
|
||||
-->
|
||||
|
||||
[`RestartPolicy`](/docs/concepts/workloads/pods/pod-lifecycle/#restart-policy) 只能等于 `Never` 或 `OnFailure`。
|
||||
|
||||
<!--
|
||||
### Pod Selector
|
||||
-->
|
||||
|
||||
### Pod 选择器
|
||||
|
||||
<!--
|
||||
The `.spec.selector` field is optional. In almost all cases you should not specify it.
|
||||
See section [specifying your own pod selector](#specifying-your-own-pod-selector).
|
||||
-->
|
||||
|
||||
`.spec.selector` 字段是可选的。在大多数场景下不必指定它。请参阅[指定自己的 pod 选择器](#specifying-your-own-pod-selector)。
|
||||
|
||||
<!--
|
||||
### Parallel Jobs
|
||||
-->
|
||||
|
||||
### 并行 Job
|
||||
|
||||
<!--
|
||||
There are three main types of task suitable to run as a Job:
|
||||
-->
|
||||
|
||||
下面是适合作为 Job 运行的三种主要任务类型:
|
||||
|
||||
<!--
|
||||
1. Non-parallel Jobs
|
||||
- normally, only one Pod is started, unless the Pod fails.
|
||||
- the Job is complete as soon as its Pod terminates successfully.
|
||||
1. Parallel Jobs with a *fixed completion count*:
|
||||
- specify a non-zero positive value for `.spec.completions`.
|
||||
- the Job represents the overall task, and is complete when there is one successful Pod for each value in the range 1 to `.spec.completions`.
|
||||
- **not implemented yet:** Each Pod is passed a different index in the range 1 to `.spec.completions`.
|
||||
1. Parallel Jobs with a *work queue*:
|
||||
- do not specify `.spec.completions`, default to `.spec.parallelism`.
|
||||
- the Pods must coordinate amongst themselves or an external service to determine what each should work on. For example, a Pod might fetch a batch of up to N items from the work queue.
|
||||
- each Pod is independently capable of determining whether or not all its peers are done, and thus that the entire Job is done.
|
||||
- when _any_ Pod from the Job terminates with success, no new Pods are created.
|
||||
- once at least one Pod has terminated with success and all Pods are terminated, then the Job is completed with success.
|
||||
- once any Pod has exited with success, no other Pod should still be doing any work for this task or writing any output. They should all be in the process of exiting.
|
||||
-->
|
||||
|
||||
1. 非并行 Job
|
||||
- 通常,除非 pod 发生故障,否则仅启动一个 pod。
|
||||
- 一旦 pod 成功终止,Job 即完成。
|
||||
1. 配置了*固定完成计数*的并行 Job:
|
||||
- 为 `.spec.completions` 指定一个非零正数值。
|
||||
- Job 代表整体任务,并且在 1 到 `.spec.completions` 范围内都有一个 pod 成功完成时,Job 才算完成。
|
||||
- **尚未实现:** 每个 pod 都会被传递一个从 1 到 `.spec.completions` 之间的索引值。
|
||||
1. 具有*工作队列*的并行 Job:
|
||||
- 不指定 `.spec.completions` 的话, 默认为 `.spec.parallelism`。
|
||||
- Pod 必须在彼此之间或外部服务之间进行协调,来确定每个 pod 该处理什么任务。例如,一个 pod 可以从工作队列中获取一批任务(最多 N 个)。
|
||||
- 每个 pod 都可以独立确定其所有对端是否完成,从而确定整个 Job 完成。
|
||||
- 当 Job 中的_任何_ pod 成功结束后,不会再创建新的 pod。
|
||||
- 一旦至少一个 pod 成功终止并且所有的 pod 都终止了,则 Job 就成功完成了。
|
||||
- 一旦 任何 pod 成功退出,其他 pod 都不应该为此任务做任务工作或编写任何输出。它们都应该处在退出过程中。
|
||||
|
||||
<!--
|
||||
For a _non-parallel_ Job, you can leave both `.spec.completions` and `.spec.parallelism` unset. When both are
|
||||
unset, both are defaulted to 1.
|
||||
-->
|
||||
|
||||
对于_非并行_ Job,可以不设置 `.spec.completions` 和 `.spec.parallelism`。两者均未设置时,默认值为 1。
|
||||
|
||||
<!--
|
||||
For a _fixed completion count_ Job, you should set `.spec.completions` to the number of completions needed.
|
||||
You can set `.spec.parallelism`, or leave it unset and it will default to 1.
|
||||
-->
|
||||
|
||||
对于一个_固定完成计数_ Job,应该将 `.spec.completions` 设置为所需的完成数量。`.spec.parallelism` 可以设置,也可以不设置,默认值为 1。
|
||||
|
||||
<!--
|
||||
For a _work queue_ Job, you must leave `.spec.completions` unset, and set `.spec.parallelism` to
|
||||
a non-negative integer.
|
||||
-->
|
||||
|
||||
对于一个_工作队列_ Job,不要设置 `.spec.completions`,并且将 `.spec.parallelism` 设置一个非负整数。
|
||||
|
||||
<!--
|
||||
For more information about how to make use of the different types of job, see the [job patterns](#job-patterns) section.
|
||||
-->
|
||||
|
||||
有关如何使用不同类型 Job 的更多信息,请参考 [Job 模式](#job-patterns)部分。
|
||||
|
||||
|
||||
<!--
|
||||
#### Controlling Parallelism
|
||||
-->
|
||||
|
||||
#### 控制并行
|
||||
|
||||
<!--
|
||||
The requested parallelism (`.spec.parallelism`) can be set to any non-negative value.
|
||||
If it is unspecified, it defaults to 1.
|
||||
If it is specified as 0, then the Job is effectively paused until it is increased.
|
||||
-->
|
||||
|
||||
请求的并发数(`.spec.parallelism`)可以设置为任何非负的整数。如果未指定,默认值为 1。如果指定为 0,则 Job 就被有效地暂停直到该配置值增加。
|
||||
|
||||
<!--
|
||||
Actual parallelism (number of pods running at any instant) may be more or less than requested
|
||||
parallelism, for a variety of reasons:
|
||||
-->
|
||||
|
||||
实际的并发数(在任何时刻运行着的 pod 数量)由于下面的一些原因,可能大于或小于请求的并发数:
|
||||
|
||||
<!--
|
||||
- For _fixed completion count_ Jobs, the actual number of pods running in parallel will not exceed the number of
|
||||
remaining completions. Higher values of `.spec.parallelism` are effectively ignored.
|
||||
- For _work queue_ Jobs, no new Pods are started after any Pod has succeeded -- remaining Pods are allowed to complete, however.
|
||||
- If the controller has not had time to react.
|
||||
- If the controller failed to create Pods for any reason (lack of `ResourceQuota`, lack of permission, etc.),
|
||||
then there may be fewer pods than requested.
|
||||
- The controller may throttle new Pod creation due to excessive previous pod failures in the same Job.
|
||||
- When a Pod is gracefully shut down, it takes time to stop.
|
||||
-->
|
||||
|
||||
- 对于_固定完成计数_ Job,实际上并行运行的 pod 数量不会超过剩余的完成数。更高的 `.spec.parallelism` 值将被优先忽略。
|
||||
- 对于_工作队列_ Job,任何 pod 成功之后都不会启动新的 pod。然而,剩余的 pod 可以完成。
|
||||
- 如果控制器还没来得及反应。
|
||||
- 如果控制器由于任何原因(缺少 `ResourceQuota`,缺少权限等)未能创建 pod,则 pod 数量将少于请求数。
|
||||
- 控制器可能会因为同一 Job 中有过多之前失败的 pod,从而限制新的 pod 的创建。
|
||||
- 当 pod 优雅关闭时,需要花费一些时间才能停止。
|
||||
|
||||
<!--
|
||||
## Handling Pod and Container Failures
|
||||
-->
|
||||
|
||||
## 处理 Pod 和容器失败
|
||||
|
||||
<!--
|
||||
A container in a Pod may fail for a number of reasons, such as because the process in it exited with
|
||||
a non-zero exit code, or the container was killed for exceeding a memory limit, etc. If this
|
||||
happens, and the `.spec.template.spec.restartPolicy = "OnFailure"`, then the Pod stays
|
||||
on the node, but the container is re-run. Therefore, your program needs to handle the case when it is
|
||||
restarted locally, or else specify `.spec.template.spec.restartPolicy = "Never"`.
|
||||
See [pod lifecycle](/docs/concepts/workloads/pods/pod-lifecycle/#example-states) for more information on `restartPolicy`.
|
||||
-->
|
||||
|
||||
Pod 中的容器可能由于多种原因而失败,例如,由于容器中的进程以非零退出码退出,或者容器由于超过内存限制而被杀掉等。如果容器失败发生,并且 `.spec.template.spec.restartPolicy = "OnFailure"`,则 pod 停留在节点上,但是容器会重新运行。因此,你的程序需要处理本地重启的情况,或者指定 `.spec.template.spec.restartPolicy = "Never"`。参阅 [pod 生命周期](/docs/concepts/workloads/pods/pod-lifecycle/#example-states)获取更多关于 `restartPolicy` 的信息。
|
||||
|
||||
<!--
|
||||
An entire Pod can also fail, for a number of reasons, such as when the pod is kicked off the node
|
||||
(node is upgraded, rebooted, deleted, etc.), or if a container of the Pod fails and the
|
||||
`.spec.template.spec.restartPolicy = "Never"`. When a Pod fails, then the Job controller
|
||||
starts a new Pod. This means that your application needs to handle the case when it is restarted in a new
|
||||
pod. In particular, it needs to handle temporary files, locks, incomplete output and the like
|
||||
caused by previous runs.
|
||||
-->
|
||||
|
||||
由于多种原因,整个 pod 也可能失败,比如,当 pod 从节点上被踢走(节点在升级,重启,被删除等),或者 pod 中的容器失败且设置了 `.spec.template.spec.restartPolicy = "Never"`。当 pod 失败后,Job 控制器将启动一个新的 pod。这意味着你的应用程序需要处理这种情况(应用程序在新的 pod 中重启)。特别是,它需要处理由先前运行引起的临时文件,锁,不完整输出等等。
|
||||
|
||||
<!--
|
||||
Note that even if you specify `.spec.parallelism = 1` and `.spec.completions = 1` and
|
||||
`.spec.template.spec.restartPolicy = "Never"`, the same program may
|
||||
sometimes be started twice.
|
||||
-->
|
||||
|
||||
请注意,即使你指定了 `.spec.parallelism = 1`,`.spec.completions = 1` 和 `.spec.template.spec.restartPolicy = "Never"`,统一程序有时也会启动两次。
|
||||
|
||||
<!--
|
||||
If you do specify `.spec.parallelism` and `.spec.completions` both greater than 1, then there may be
|
||||
multiple pods running at once. Therefore, your pods must also be tolerant of concurrency.
|
||||
-->
|
||||
|
||||
如果你指定 `.spec.parallelism` 和 `.spec.completions` 配置都大于 1,则可能同时有多个 pod 运行。因此,你的 pod 必须容忍并发。
|
||||
|
||||
<!--
|
||||
### Pod backoff failure policy
|
||||
-->
|
||||
|
||||
### Pod 的退避失败策略
|
||||
|
||||
<!--
|
||||
There are situations where you want to fail a Job after some amount of retries
|
||||
due to a logical error in configuration etc.
|
||||
To do so, set `.spec.backoffLimit` to specify the number of retries before
|
||||
considering a Job as failed. The back-off limit is set by default to 6. Failed
|
||||
Pods associated with the Job are recreated by the Job controller with an
|
||||
exponential back-off delay (10s, 20s, 40s ...) capped at six minutes. The
|
||||
back-off count is reset if no new failed Pods appear before the Job's next
|
||||
status check.
|
||||
-->
|
||||
|
||||
在某些情况下(配置中的逻辑错误等),你需要在重试一定次数后才使 Job 失败。为此需要设置 `.spec.backoffLimit` 配置值为判断 Job 失败前的重试次数。 退避限制默认设置为 6。与 Job 相关的 pod在失败后,经过一个指数级退避延迟(10 秒,20 秒,40 秒,上限为 6 分钟),由 Job 控制器重新创建。 如果在 Job 的下一次状态检查之前未出现新的失败 pod,则会重置退避计数。
|
||||
|
||||
{{< note >}}
|
||||
<!--
|
||||
Issue [#54870](https://github.com/kubernetes/kubernetes/issues/54870) still exists for versions of Kubernetes prior to version 1.12
|
||||
-->
|
||||
|
||||
1.12 之前的 Kubernetes 版本仍然存在问题 [#54870](https://github.com/kubernetes/kubernetes/issues/54870)
|
||||
|
||||
{{< /note >}}
|
||||
{{< note >}}
|
||||
<!--
|
||||
If your job has `restartPolicy = "OnFailure"`, keep in mind that your container running the Job
|
||||
will be terminated once the job backoff limit has been reached. This can make debugging the Job's executable more difficult. We suggest setting
|
||||
`restartPolicy = "Never"` when debugging the Job or using a logging system to ensure output
|
||||
from failed Jobs is not lost inadvertently.
|
||||
-->
|
||||
|
||||
如果你的 Job 外配置了 `restartPolicy = "OnFailure"`,请记住,一旦 Job 达到退避限制,运行在该 Job 的容器将被终止。这会使得调试 Job 的可执行将变得更加困难。我们建议在调试 Job 或使用日志系统时设置 `restartPolicy = "Never"`,以确保失败 Job 的输出不会在不经意间丢失。
|
||||
{{< /note >}}
|
||||
|
||||
<!--
|
||||
## Job Termination and Cleanup
|
||||
-->
|
||||
|
||||
## Job 终止和清理
|
||||
|
||||
<!--
|
||||
When a Job completes, no more Pods are created, but the Pods are not deleted either. Keeping them around
|
||||
allows you to still view the logs of completed pods to check for errors, warnings, or other diagnostic output.
|
||||
The job object also remains after it is completed so that you can view its status. It is up to the user to delete
|
||||
old jobs after noting their status. Delete the job with `kubectl` (e.g. `kubectl delete jobs/pi` or `kubectl delete -f ./job.yaml`). When you delete the job using `kubectl`, all the pods it created are deleted too.
|
||||
-->
|
||||
|
||||
当 Job 完成后,不会再创建 pod,但是 pod 也不会被删除。将这些 pod 保留,使你仍然可以查看已完成 pod 的日志来检查错误,警告或其他诊断输出。Job 对象在完成后也同样保留下来,以便你可以查看它的状态。由用户来决定在查看完状态后删除旧的 Job。使用 `kubectl`(例如 `kubectl delete jobs/pi` 或 `kubectl delete -f ./job.yaml` )来删除 Job。当你使用 `kubectl` 删除 Job 后,它所创建的所有 pod 也会被删除。
|
||||
|
||||
<!--
|
||||
By default, a Job will run uninterrupted unless a Pod fails (`restartPolicy=Never`) or a Container exits in error (`restartPolicy=OnFailure`), at which point the Job defers to the
|
||||
`.spec.backoffLimit` described above. Once `.spec.backoffLimit` has been reached the Job will be marked as failed and any running Pods will be terminated.
|
||||
-->
|
||||
|
||||
默认情况下,除非 pod 失败(`restartPolicy=Never`)或容器错误退出(`restartPolicy=OnFailure`),否则 Job 将不会被中断运行。Job 中断将遵循上面介绍的 `.spec.backoffLimit`。一旦 `.spec.backoffLimit` 达到,Job 将被标记为失败,企鹅别所有正运行的 pod 将被终止。
|
||||
|
||||
<!--
|
||||
Another way to terminate a Job is by setting an active deadline.
|
||||
Do this by setting the `.spec.activeDeadlineSeconds` field of the Job to a number of seconds.
|
||||
The `activeDeadlineSeconds` applies to the duration of the job, no matter how many Pods are created.
|
||||
Once a Job reaches `activeDeadlineSeconds`, all of its running Pods are terminated and the Job status will become `type: Failed` with `reason: DeadlineExceeded`.
|
||||
-->
|
||||
|
||||
终止 Job 的另一种方式是设置有限期限。通过设置 Job 对象的 `.spec.activeDeadlineSeconds` 字段为秒数来达到。`activeDeadlineSeconds` 适用于 Job 存在期间,不管有多少 pod 被创建。一旦 Job 达到 `activeDeadlineSeconds`,所有运行中的 pod将被终止,并且 Job 的状态将变成 `type: Failed` 与 `reason: DeadlineExceeded`。
|
||||
|
||||
<!--
|
||||
Note that a Job's `.spec.activeDeadlineSeconds` takes precedence over its `.spec.backoffLimit`. Therefore, a Job that is retrying one or more failed Pods will not deploy additional Pods once it reaches the time limit specified by `activeDeadlineSeconds`, even if the `backoffLimit` is not yet reached.
|
||||
-->
|
||||
|
||||
请注意,Job 的 `.spec.activeDeadlineSeconds` 配置优先于 `.spec.backoffLimit` 配置。因此,重试一个或多个失败 pod 的 Job 在达到 `activeDeadlineSeconds` 指定的时间限制前,不会部署其他的 pod,即使 `backoffLimit` 尚未达到。
|
||||
|
||||
<!--
|
||||
Example:
|
||||
-->
|
||||
|
||||
例子:
|
||||
|
||||
```yaml
|
||||
apiVersion: batch/v1
|
||||
kind: Job
|
||||
metadata:
|
||||
name: pi-with-timeout
|
||||
spec:
|
||||
backoffLimit: 5
|
||||
activeDeadlineSeconds: 100
|
||||
template:
|
||||
spec:
|
||||
containers:
|
||||
- name: pi
|
||||
image: perl
|
||||
command: ["perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"]
|
||||
restartPolicy: Never
|
||||
```
|
||||
|
||||
<!--
|
||||
Note that both the Job spec and the [Pod template spec](/docs/concepts/workloads/pods/init-containers/#detailed-behavior) within the Job have an `activeDeadlineSeconds` field. Ensure that you set this field at the proper level.
|
||||
-->
|
||||
|
||||
请注意,Job 对象中的 Job 规范和 [Pod 模板规范](/docs/concepts/workloads/pods/init-containers/#detailed-behavior)都有 `activeDeadlineSeconds` 字段。确保将此字段设置在适当的层级。
|
||||
|
||||
<!--
|
||||
## Clean Up Finished Jobs Automatically
|
||||
-->
|
||||
|
||||
## 自动清理已完成的 Job
|
||||
|
||||
<!--
|
||||
Finished Jobs are usually no longer needed in the system. Keeping them around in
|
||||
the system will put pressure on the API server. If the Jobs are managed directly
|
||||
by a higher level controller, such as
|
||||
[CronJobs](/docs/concepts/workloads/controllers/cron-jobs/), the Jobs can be
|
||||
cleaned up by CronJobs based on the specified capacity-based cleanup policy.
|
||||
-->
|
||||
|
||||
系统中已完成的 Job 通常不再需要。将它们保留在系统中将会给 API 服务器带来压力。如果 Job 由更高级别的控制器管理,比如 [CronJobs](/docs/concepts/workloads/controllers/cron-jobs/),则 Job 可以由 CronJobs 基于指定的基于容量的清理策略来进行清除。
|
||||
|
||||
<!--
|
||||
### TTL Mechanism for Finished Jobs
|
||||
-->
|
||||
|
||||
### 已完成 Job 的 TTL 机制
|
||||
|
||||
{{< feature-state for_k8s_version="v1.12" state="alpha" >}}
|
||||
|
||||
<!--
|
||||
Another way to clean up finished Jobs (either `Complete` or `Failed`)
|
||||
automatically is to use a TTL mechanism provided by a
|
||||
[TTL controller](/docs/concepts/workloads/controllers/ttlafterfinished/) for
|
||||
finished resources, by specifying the `.spec.ttlSecondsAfterFinished` field of
|
||||
the Job.
|
||||
-->
|
||||
|
||||
清理已完成 Job(`Complete` 或 `Failed`)的另一个方式是通过使用 [TTL 控制器](/docs/concepts/workloads/controllers/ttlafterfinished/)提供的 TTL 机制,TTL 通过指定 Job 的 `.spec.ttlSecondsAfterFinished` 字段来清理已完成资源。
|
||||
|
||||
<!--
|
||||
When the TTL controller cleans up the Job, it will delete the Job cascadingly,
|
||||
i.e. delete its dependent objects, such as Pods, together with the Job. Note
|
||||
that when the Job is deleted, its lifecycle guarantees, such as finalizers, will
|
||||
be honored.
|
||||
-->
|
||||
|
||||
当 TTL 控制器清理 Job 时,它将级联删除 Job,即删除它的依赖对象,比如 pod 将和 Job 一起被删除。请注意,当 Job 被删除后,它的生命周期保证,如终结者,将被触发。
|
||||
|
||||
<!--
|
||||
For example:
|
||||
-->
|
||||
|
||||
例如:
|
||||
|
||||
```yaml
|
||||
apiVersion: batch/v1
|
||||
kind: Job
|
||||
metadata:
|
||||
name: pi-with-ttl
|
||||
spec:
|
||||
ttlSecondsAfterFinished: 100
|
||||
template:
|
||||
spec:
|
||||
containers:
|
||||
- name: pi
|
||||
image: perl
|
||||
command: ["perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"]
|
||||
restartPolicy: Never
|
||||
```
|
||||
|
||||
<!--
|
||||
The Job `pi-with-ttl` will be eligible to be automatically deleted, `100`
|
||||
seconds after it finishes.
|
||||
-->
|
||||
|
||||
`pi-with-ttl` Job 在完成后 100 秒就会自动删除掉。
|
||||
|
||||
<!--
|
||||
If the field is set to `0`, the Job will be eligible to be automatically deleted
|
||||
immediately after it finishes. If the field is unset, this Job won't be cleaned
|
||||
up by the TTL controller after it finishes.
|
||||
-->
|
||||
|
||||
如果该字段设为为 `0`,那么 Job 将在完成后立即被自动删除掉。如果该字段未设置,则 Job 在完成后将不会被 TTL 控制器清理掉。
|
||||
|
||||
<!--
|
||||
Note that this TTL mechanism is alpha, with feature gate `TTLAfterFinished`. For
|
||||
more information, see the documentation for
|
||||
[TTL controller](/docs/concepts/workloads/controllers/ttlafterfinished/) for
|
||||
finished resources.
|
||||
-->
|
||||
|
||||
请注意,此 TTL 机制处于 alpha 阶段,由 `TTLAfterFinished` 功能门控制是否启动。有关详细信息,请参阅 [TTL 控制器](/docs/concepts/workloads/controllers/ttlafterfinished/)中关于已完成资源的处理。
|
||||
|
||||
<!--
|
||||
## Job Patterns
|
||||
-->
|
||||
|
||||
## Job 模式
|
||||
|
||||
<!--
|
||||
The Job object can be used to support reliable parallel execution of Pods. The Job object is not
|
||||
designed to support closely-communicating parallel processes, as commonly found in scientific
|
||||
computing. It does support parallel processing of a set of independent but related *work items*.
|
||||
These might be emails to be sent, frames to be rendered, files to be transcoded, ranges of keys in a
|
||||
NoSQL database to scan, and so on.
|
||||
-->
|
||||
|
||||
Job 对象可用于支持 pod 的可靠并行执行。Job 对象并非设计为支持紧密通信的并行过程(常见于科学计算领域)。它被用于支持一组独立但相关的*工作项*的并行处理。这些可能是要发送的电子邮件,要渲染的帧,要编码转换的文件,要扫描的 NoSQL 数据库中一段范围内的键等等。
|
||||
|
||||
<!--
|
||||
In a complex system, there may be multiple different sets of work items. Here we are just
|
||||
considering one set of work items that the user wants to manage together — a *batch job*.
|
||||
-->
|
||||
|
||||
在复杂的系统中,可能会有多个不同的工作项集。这里我们只考虑用户想要一起管理一组工作项 — *批处理任务*。
|
||||
|
||||
<!--
|
||||
There are several different patterns for parallel computation, each with strengths and weaknesses.
|
||||
The tradeoffs are:
|
||||
-->
|
||||
|
||||
并行计算有几种不同的模式,每种都有各自的优缺点。权衡点如下:
|
||||
|
||||
<!--
|
||||
- One Job object for each work item, vs. a single Job object for all work items. The latter is
|
||||
better for large numbers of work items. The former creates some overhead for the user and for the
|
||||
system to manage large numbers of Job objects.
|
||||
- Number of pods created equals number of work items, vs. each Pod can process multiple work items.
|
||||
The former typically requires less modification to existing code and containers. The latter
|
||||
is better for large numbers of work items, for similar reasons to the previous bullet.
|
||||
- Several approaches use a work queue. This requires running a queue service,
|
||||
and modifications to the existing program or container to make it use the work queue.
|
||||
Other approaches are easier to adapt to an existing containerised application.
|
||||
-->
|
||||
|
||||
- 一个 Job 对象处理一个工作项,还是一个 Job 对象处理所有的工作项。后者适用于有大量工作项的场景。前者在管理大量 Job 对象时会对用户和系统带来一些开销。
|
||||
- 创建和工作项数量一样多的 pod,还是一个 pod 处理多个工作项。前者通常对现有代码和容器进行较少的修改。后者更适用于处理大量工作项(理由和前一条的相似)。
|
||||
- 几种方法使用工作队列。这需要运行一个队列服务,并对现有的程序和容器进行修改以使其能够使用工作队列。其他方法更容易适应现有的容器化应用程序。
|
||||
|
||||
|
||||
<!--
|
||||
The tradeoffs are summarized here, with columns 2 to 4 corresponding to the above tradeoffs.
|
||||
The pattern names are also links to examples and more detailed description.
|
||||
-->
|
||||
|
||||
权衡总结如下表,第 2 至 4 列对应上面的权衡点。模式名称也是样例和详细描述的链接。
|
||||
|
||||
<!--
|
||||
| Pattern | Single Job object | Fewer pods than work items? | Use app unmodified? | Works in Kube 1.1? |
|
||||
| -------------------------------------------------------------------- |:-----------------:|:---------------------------:|:-------------------:|:-------------------:|
|
||||
| [Job Template Expansion](/docs/tasks/job/parallel-processing-expansion/) | | | ✓ | ✓ |
|
||||
| [Queue with Pod Per Work Item](/docs/tasks/job/coarse-parallel-processing-work-queue/) | ✓ | | sometimes | ✓ |
|
||||
| [Queue with Variable Pod Count](/docs/tasks/job/fine-parallel-processing-work-queue/) | ✓ | ✓ | | ✓ |
|
||||
| Single Job with Static Work Assignment | ✓ | | ✓ |
|
||||
|
|
||||
-->
|
||||
|
||||
| 模式 | 单个 Job 对象 | 比工作项更少的 pod? | 使用未修改的 app? | Kube 1.1 中生效? |
|
||||
| -------------------------------------------------------------------- |:-----------------:|:---------------------------:|:-------------------:|:-------------------:|
|
||||
| [Job 模板扩展](/docs/tasks/job/parallel-processing-expansion/) | | | ✓ | ✓ |
|
||||
| [一个项对应一个 pod 的队列](/docs/tasks/job/coarse-parallel-processing-work-queue/) | ✓ | | 有时 | ✓ |
|
||||
| [具有可变 pod 数量的队列](/docs/tasks/job/fine-parallel-processing-work-queue/) | ✓ | ✓ | | ✓ |
|
||||
| 具有静态工作分配的单个 Job | ✓ | | ✓ | |
|
||||
|
||||
<!--
|
||||
When you specify completions with `.spec.completions`, each Pod created by the Job controller
|
||||
has an identical [`spec`](https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status). This means that
|
||||
all pods for a task will have the same command line and the same
|
||||
image, the same volumes, and (almost) the same environment variables. These patterns
|
||||
are different ways to arrange for pods to work on different things.
|
||||
-->
|
||||
|
||||
当使用 `.spec.completions` 指定完成数时,由 Job 控制器创建的每个 pod 都有一个相同的 [`规范`](https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status)。这意味着一个任务的所有 pod 将有相同的命令行和镜像,相同的卷以及(几乎)相同的环境变量。这些模式通过不同的方式安排 pod 去处理不同的任务。
|
||||
|
||||
<!--
|
||||
This table shows the required settings for `.spec.parallelism` and `.spec.completions` for each of the patterns.
|
||||
Here, `W` is the number of work items.
|
||||
-->
|
||||
|
||||
下表列出了每种模式下对 `.spec.parallelism` 和 `.spec.completions` 需要做的设置。
|
||||
|
||||
<!--
|
||||
| Pattern | `.spec.completions` | `.spec.parallelism` |
|
||||
| -------------------------------------------------------------------- |:-------------------:|:--------------------:|
|
||||
| [Job Template Expansion](/docs/tasks/job/parallel-processing-expansion/) | 1 | should be 1 |
|
||||
| [Queue with Pod Per Work Item](/docs/tasks/job/coarse-parallel-processing-work-queue/) | W | any |
|
||||
| [Queue with Variable Pod Count](/docs/tasks/job/fine-parallel-processing-work-queue/) | 1 | any |
|
||||
| Single Job with Static Work Assignment | W | any |
|
||||
-->
|
||||
|
||||
|
||||
| 模式 | `.spec.completions` | `.spec.parallelism` |
|
||||
| -------------------------------------------------------------------- |:-------------------:|:--------------------:|
|
||||
| [Job 模板扩展](/docs/tasks/job/parallel-processing-expansion/) | 1 | 应该为 1 |
|
||||
| [一个项对应一个 pod 的队列](/docs/tasks/job/coarse-parallel-processing-work-queue/) | W | 任意 |
|
||||
| [具有可变 pod 数量的队列](/docs/tasks/job/fine-parallel-processing-work-queue/) | 1 | 任意 |
|
||||
| 具有静态工作分配的单个 Job | W | 任意 |
|
||||
|
||||
<!--
|
||||
## Advanced Usage
|
||||
-->
|
||||
|
||||
## 高级用法
|
||||
|
||||
<!--
|
||||
### Specifying your own pod selector
|
||||
-->
|
||||
|
||||
### 指定你的 pod 选择器
|
||||
|
||||
<!--
|
||||
Normally, when you create a Job object, you do not specify `.spec.selector`.
|
||||
The system defaulting logic adds this field when the Job is created.
|
||||
It picks a selector value that will not overlap with any other jobs.
|
||||
-->
|
||||
|
||||
通常,在创建 Job 对象时,不用指定 `.spec.selector`。系统的默认逻辑会在创建 Job 时添加这个字段。它会选择一个不会和其他 pod 重叠的选择器。
|
||||
|
||||
<!--
|
||||
However, in some cases, you might need to override this automatically set selector.
|
||||
To do this, you can specify the `.spec.selector` of the Job.
|
||||
-->
|
||||
|
||||
但是,在某些情况下,你可能需要去覆盖默认设置的选择器。为此,你需要指定 Job 的 `.spec.selector`。
|
||||
|
||||
<!--
|
||||
Be very careful when doing this. If you specify a label selector which is not
|
||||
unique to the pods of that Job, and which matches unrelated Pods, then pods of the unrelated
|
||||
job may be deleted, or this Job may count other Pods as completing it, or one or both
|
||||
Jobs may refuse to create Pods or run to completion. If a non-unique selector is
|
||||
chosen, then other controllers (e.g. ReplicationController) and their Pods may behave
|
||||
in unpredictable ways too. Kubernetes will not stop you from making a mistake when
|
||||
specifying `.spec.selector`.
|
||||
-->
|
||||
|
||||
当设置时需要特别小心。如果你指定的标签选择器不是 Job 的 pod 所独有的,并且匹配到了不相关的 pod,那么不相关 Job 的 pod 可能会被删除,或此 Job 可能将其他 pod 统计为已完成,或者其中一个或两个 Job 可能拒绝创建 pod 或运行完成。如果一个选择了非唯一的选择器,则其他的控制器(比如 ReplicationController)和它的 pod 的行为也将是不可预测的。当指定了 `.spec.selector`,Kubernetes将不会阻止你产生错误。
|
||||
|
||||
<!--
|
||||
Here is an example of a case when you might want to use this feature.
|
||||
-->
|
||||
|
||||
下面的例子描述了你想要使用该功能的场景。
|
||||
|
||||
<!--
|
||||
Say Job `old` is already running. You want existing Pods
|
||||
to keep running, but you want the rest of the Pods it creates
|
||||
to use a different pod template and for the Job to have a new name.
|
||||
You cannot update the Job because these fields are not updatable.
|
||||
Therefore, you delete Job `old` but _leave its pods
|
||||
running_, using `kubectl delete jobs/old --cascade=false`.
|
||||
Before deleting it, you make a note of what selector it uses:
|
||||
-->
|
||||
|
||||
假设 `old` Job 已经在运行了。你想要运行中的 pod 保持运行,但是你想 Job 创建的其他 pod 使用不同的 pod 模板,并使 Job 具有一个新的名称。你不能更新 Job 对象,因为这些字段是不可更新的。因此,你需要删除 `old` 但是_让它的 pod 运行_,可以使用 `kubectl delete jobs/old --cascade=false` 命令。在删除之前,你需要记下它所使用的选择器:
|
||||
|
||||
```
|
||||
kubectl get job old -o yaml
|
||||
```
|
||||
```
|
||||
kind: Job
|
||||
metadata:
|
||||
name: old
|
||||
...
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
controller-uid: a8f3d00d-c6d2-11e5-9f87-42010af00002
|
||||
...
|
||||
```
|
||||
|
||||
<!--
|
||||
Then you create a new Job with name `new` and you explicitly specify the same selector.
|
||||
Since the existing Pods have label `controller-uid=a8f3d00d-c6d2-11e5-9f87-42010af00002`,
|
||||
they are controlled by Job `new` as well.
|
||||
-->
|
||||
|
||||
然后使用新名称 `new` 创建一个新的 Job ,并且显示指定相同的选择器。由于现有的 pod 具有 `controller-uid=a8f3d00d-c6d2-11e5-9f87-42010af00002` 标签,它们也受 `new` Job 的控制。
|
||||
|
||||
<!--
|
||||
You need to specify `manualSelector: true` in the new Job since you are not using
|
||||
the selector that the system normally generates for you automatically.
|
||||
-->
|
||||
|
||||
由于你不再使用系统通常为你自动生成的选择器,你需要在新的 Job 中指定 `manualSelector: true`。
|
||||
|
||||
```
|
||||
kind: Job
|
||||
metadata:
|
||||
name: new
|
||||
...
|
||||
spec:
|
||||
manualSelector: true
|
||||
selector:
|
||||
matchLabels:
|
||||
controller-uid: a8f3d00d-c6d2-11e5-9f87-42010af00002
|
||||
...
|
||||
```
|
||||
|
||||
<!--
|
||||
The new Job itself will have a different uid from `a8f3d00d-c6d2-11e5-9f87-42010af00002`. Setting
|
||||
`manualSelector: true` tells the system to that you know what you are doing and to allow this
|
||||
mismatch.
|
||||
-->
|
||||
|
||||
新的 Job 本身将具有一个与 `a8f3d00d-c6d2-11e5-9f87-42010af00002` 不通的 uid。设置 `manualSelector: true` 来告诉系统你知道自己在做什么,并使其允许这种不匹配。
|
||||
|
||||
<!--
|
||||
## Alternatives
|
||||
-->
|
||||
|
||||
## 备选方案
|
||||
|
||||
<!--
|
||||
### Bare Pods
|
||||
-->
|
||||
|
||||
### 裸 pod
|
||||
|
||||
<!--
|
||||
When the node that a Pod is running on reboots or fails, the pod is terminated
|
||||
and will not be restarted. However, a Job will create new Pods to replace terminated ones.
|
||||
For this reason, we recommend that you use a Job rather than a bare Pod, even if your application
|
||||
requires only a single Pod.
|
||||
-->
|
||||
|
||||
当 pod 所在节点重启或发生故障时,pod 将终止并且不会重启。然后,Job 将创建新的 pod 替换终止的 pod。因此,即使你的应用仅需要一个 pod,我们还是推荐使用 Job 而不是裸 pod。
|
||||
|
||||
<!--
|
||||
### Replication Controller
|
||||
-->
|
||||
|
||||
### 副本控制器
|
||||
|
||||
<!--
|
||||
Jobs are complementary to [Replication Controllers](/docs/user-guide/replication-controller).
|
||||
A Replication Controller manages Pods which are not expected to terminate (e.g. web servers), and a Job
|
||||
manages Pods that are expected to terminate (e.g. batch tasks).
|
||||
-->
|
||||
|
||||
Job 是[副本控制器](/docs/user-guide/replication-controller)的补充。副本控制器管理预期不会终止的 pod(比如 web 服务器),而 Job 管理预期将会终止的 pod(比如批处理任务)。
|
||||
|
||||
<!--
|
||||
As discussed in [Pod Lifecycle](/docs/concepts/workloads/pods/pod-lifecycle/), `Job` is *only* appropriate
|
||||
for pods with `RestartPolicy` equal to `OnFailure` or `Never`.
|
||||
(Note: If `RestartPolicy` is not set, the default value is `Always`.)
|
||||
-->
|
||||
|
||||
正如在 [Pod 生命周期](/docs/concepts/workloads/pods/pod-lifecycle/)中所讨论的,`Job` *仅*适用于具有 `RestartPolicy` 值为 `OnFailure` 或 `Never` 的 pod。(注意:如果 `RestartPolicy` 未指定,默认值为 `Always`。)
|
||||
|
||||
<!--
|
||||
### Single Job starts Controller Pod
|
||||
-->
|
||||
|
||||
### 单 Job 启动控制 pod
|
||||
|
||||
<!--
|
||||
Another pattern is for a single Job to create a Pod which then creates other Pods, acting as a sort
|
||||
of custom controller for those Pods. This allows the most flexibility, but may be somewhat
|
||||
complicated to get started with and offers less integration with Kubernetes.
|
||||
-->
|
||||
|
||||
单个 Job 的另一种模式是创建一个创建其他 pod 的 pod,充当这些 pod 的一种自定义控制器。这提供了更大的灵活性,但是入门起来可能有点复杂,并且与 Kubernetes 的集成较少。
|
||||
|
||||
<!--
|
||||
One example of this pattern would be a Job which starts a Pod which runs a script that in turn
|
||||
starts a Spark master controller (see [spark example](https://github.com/kubernetes/examples/tree/{{< param "githubbranch" >}}/staging/spark/README.md)), runs a spark
|
||||
driver, and then cleans up.
|
||||
-->
|
||||
|
||||
这种模式的一个样例是:一个 Job 启动一个 pod 来运行一个脚本,该脚本依次启动 Spark 主控制器(参阅 [spark 例子](https://github.com/kubernetes/examples/tree/{{< param "githubbranch" >}}/staging/spark/README.md)),并运行 spark 驱动,然后进行清理。
|
||||
|
||||
<!--
|
||||
An advantage of this approach is that the overall process gets the completion guarantee of a Job
|
||||
object, but complete control over what Pods are created and how work is assigned to them.
|
||||
-->
|
||||
|
||||
这种方法的优点是整个过程可以获取 Job 对象的完成保证,不是完全控制 pod 的创建以及如何将工作分配给 pod。
|
||||
|
||||
## Cron Jobs {#cron-jobs}
|
||||
|
||||
<!--
|
||||
You can use a [`CronJob`](/docs/concepts/workloads/controllers/cron-jobs/) to create a Job that will run at specified times/dates, similar to the Unix tool `cron`.
|
||||
-->
|
||||
|
||||
你可以使用 [`CronJob`](/docs/concepts/workloads/controllers/cron-jobs/) 来创建一个会在指定的时间/日期执行的 Job,类似于 Unix 工具 `cron`。
|
||||
|
||||
{{% /capture %}}
|
||||
@@ -0,0 +1,416 @@
|
||||
---
|
||||
reviewers:
|
||||
- Kashomon
|
||||
- bprashanth
|
||||
- madhusudancs
|
||||
title: ReplicaSet
|
||||
content_template: templates/concept
|
||||
weight: 10
|
||||
---
|
||||
|
||||
{{% capture overview %}}
|
||||
|
||||
<!--
|
||||
ReplicaSet is the next-generation Replication Controller. The only difference
|
||||
between a _ReplicaSet_ and a
|
||||
[_Replication Controller_](/docs/concepts/workloads/controllers/replicationcontroller/) right now is
|
||||
the selector support. ReplicaSet supports the new set-based selector requirements
|
||||
as described in the [labels user guide](/docs/concepts/overview/working-with-objects/labels/#label-selectors)
|
||||
whereas a Replication Controller only supports equality-based selector requirements.
|
||||
-->
|
||||
|
||||
ReplicaSet 是下一代的 Replication Controller。 _ReplicaSet_ 和 [_Replication Controller_](/docs/concepts/workloads/controllers/replicationcontroller/) 的唯一区别是选择器的支持。ReplicaSet 支持新的基于集合的选择器需求,这在[标签用户指南](/docs/concepts/overview/working-with-objects/labels/#label-selectors)中有描述。而 Replication Controller 仅支持基于相等选择器的需求。
|
||||
|
||||
{{% /capture %}}
|
||||
|
||||
{{% capture body %}}
|
||||
|
||||
<!--
|
||||
## How to use a ReplicaSet
|
||||
|
||||
Most [`kubectl`](/docs/user-guide/kubectl/) commands that support
|
||||
Replication Controllers also support ReplicaSets. One exception is the
|
||||
[`rolling-update`](/docs/reference/generated/kubectl/kubectl-commands#rolling-update) command. If
|
||||
you want the rolling update functionality please consider using Deployments
|
||||
instead. Also, the
|
||||
[`rolling-update`](/docs/reference/generated/kubectl/kubectl-commands#rolling-update) command is
|
||||
imperative whereas Deployments are declarative, so we recommend using Deployments
|
||||
through the [`rollout`](/docs/reference/generated/kubectl/kubectl-commands#rollout) command.
|
||||
|
||||
While ReplicaSets can be used independently, today it's mainly used by
|
||||
[Deployments](/docs/concepts/workloads/controllers/deployment/) as a mechanism to orchestrate pod
|
||||
creation, deletion and updates. When you use Deployments you don't have to worry
|
||||
about managing the ReplicaSets that they create. Deployments own and manage
|
||||
their ReplicaSets.
|
||||
-->
|
||||
|
||||
## 怎样使用 ReplicaSet
|
||||
|
||||
大多数支持 Replication Controllers 的[`kubectl`](/docs/user-guide/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](/docs/concepts/workloads/controllers/deployment/) 用作协调 Pod 创建、删除和更新的机制。
|
||||
当您使用 Deployment 时,您不必担心还要管理它们创建的 ReplicaSet。Deployment 会拥有并管理它们的 ReplicaSet。
|
||||
|
||||
<!--
|
||||
## When to use a ReplicaSet
|
||||
|
||||
A ReplicaSet ensures that a specified number of pod replicas are running at any given
|
||||
time. However, a Deployment is a higher-level concept that manages ReplicaSets and
|
||||
provides declarative updates to pods along with a lot of other useful features.
|
||||
Therefore, we recommend using Deployments instead of directly using ReplicaSets, unless
|
||||
you require custom update orchestration or don't require updates at all.
|
||||
|
||||
This actually means that you may never need to manipulate ReplicaSet objects:
|
||||
use a Deployment instead, and define your application in the spec section.
|
||||
-->
|
||||
|
||||
## 什么时候使用 ReplicaSet
|
||||
|
||||
ReplicaSet 确保任何时间都有指定数量的 Pod 副本在运行。
|
||||
然而,Deployment 是一个更高级的概念,它管理 ReplicaSet,并向 Pod 提供声明式的更新以及许多其他有用的功能。
|
||||
因此,我们建议使用 Deployment 而不是直接使用 ReplicaSet,除非您需要自定义更新业务流程或根本不需要更新。
|
||||
|
||||
这实际上意味着,您可能永远不需要操作 ReplicaSet 对象:而是使用 Deployment,并在 spec 部分定义您的应用。
|
||||
|
||||
<!--
|
||||
## Example
|
||||
-->
|
||||
## 示例
|
||||
|
||||
{{< codenew file="controllers/frontend.yaml" >}}
|
||||
|
||||
<!--
|
||||
Saving this manifest into `frontend.yaml` and submitting it to a Kubernetes cluster should
|
||||
create the defined ReplicaSet and the pods that it manages.
|
||||
-->
|
||||
|
||||
将此清单保存到 `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
|
||||
Name: frontend
|
||||
Namespace: default
|
||||
Selector: tier=frontend,tier in (frontend)
|
||||
Labels: app=guestbook
|
||||
tier=frontend
|
||||
Annotations: <none>
|
||||
Replicas: 3 current / 3 desired
|
||||
Pods Status: 3 Running / 0 Waiting / 0 Succeeded / 0 Failed
|
||||
Pod Template:
|
||||
Labels: app=guestbook
|
||||
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
|
||||
Mounts: <none>
|
||||
Volumes: <none>
|
||||
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
|
||||
```
|
||||
|
||||
<!--
|
||||
## Writing a ReplicaSet Spec
|
||||
|
||||
As with all other Kubernetes API objects, a ReplicaSet needs the `apiVersion`, `kind`, and `metadata` fields. For
|
||||
general information about working with manifests, see [object management using kubectl](/docs/concepts/overview/object-management-kubectl/overview/).
|
||||
|
||||
A ReplicaSet also needs a [`.spec` section](https://git.k8s.io/community/contributors/devel/api-conventions.md#spec-and-status).
|
||||
-->
|
||||
|
||||
## 编写 ReplicaSet Spec
|
||||
|
||||
与所有其他 Kubernetes API 对象一样,ReplicaSet 也需要 `apiVersion`、`kind`、和 `metadata` 字段。有关使用清单的一般信息,请参见 [使用 kubectl 管理对象](/docs/concepts/overview/object-management-kubectl/overview/)。
|
||||
|
||||
ReplicaSet 也需要 [`.spec`](https://git.k8s.io/community/contributors/devel/api-conventions.md#spec-and-status) 部分。
|
||||
|
||||
<!--
|
||||
### Pod Template
|
||||
|
||||
The `.spec.template` is the only required field of the `.spec`. The `.spec.template` is a
|
||||
[pod template](/docs/concepts/workloads/pods/pod-overview/#pod-templates). It has exactly the same schema as a
|
||||
[pod](/docs/concepts/workloads/pods/pod/), except that it is nested and does not have an `apiVersion` or `kind`.
|
||||
|
||||
In addition to required fields of a pod, a pod template in a ReplicaSet must specify appropriate
|
||||
labels and an appropriate restart policy.
|
||||
|
||||
For labels, make sure to not overlap with other controllers. For more information, see [pod selector](#pod-selector).
|
||||
|
||||
For [restart policy](/docs/concepts/workloads/pods/pod-lifecycle/#restart-policy), the only allowed value for `.spec.template.spec.restartPolicy` is `Always`, which is the default.
|
||||
|
||||
For local container restarts, ReplicaSet delegates to an agent on the node,
|
||||
for example the [Kubelet](/docs/admin/kubelet/) or Docker.
|
||||
-->
|
||||
|
||||
### Pod 模版
|
||||
|
||||
`.spec.template` 是 `.spec` 唯一需要的字段。`.spec.template` 是 [Pod 模版](/docs/concepts/workloads/pods/pod-overview/#pod-templates)。它和 [Pod](/docs/concepts/workloads/pods/pod/) 的语法几乎完全一样,除了它是嵌套的并没有 `apiVersion` 和 `kind`。
|
||||
|
||||
除了所需的 Pod 字段之外,ReplicaSet 中的 Pod 模板必须指定适当的标签和适当的重启策略。
|
||||
|
||||
对于标签,请确保不要与其他控制器重叠。更多信息请参考 [Pod 选择器](#pod-selector)。
|
||||
|
||||
对于 [重启策略](/docs/concepts/workloads/pods/pod-lifecycle/#restart-policy),`.spec.template.spec.restartPolicy` 唯一允许的取值是 `Always`,这也是默认值.
|
||||
|
||||
对于本地容器重新启动,ReplicaSet 委托给了节点上的代理去执行,例如[Kubelet](/docs/admin/kubelet/) 或 Docker 去执行。
|
||||
|
||||
<!--
|
||||
### Pod Selector
|
||||
|
||||
The `.spec.selector` field is a [label selector](/docs/concepts/overview/working-with-objects/labels/). A ReplicaSet
|
||||
manages all the pods with labels that match the selector. It does not distinguish
|
||||
between pods that it created or deleted and pods that another person or process created or
|
||||
deleted. This allows the ReplicaSet to be replaced without affecting the running pods.
|
||||
|
||||
The `.spec.template.metadata.labels` must match the `.spec.selector`, or it will
|
||||
be rejected by the API.
|
||||
|
||||
In Kubernetes 1.9 the API version `apps/v1` on the ReplicaSet kind is the current version and is enabled by default. The API version `apps/v1beta2` is deprecated.
|
||||
-->
|
||||
|
||||
### Pod 选择器
|
||||
|
||||
`.spec.selector` 字段是[标签选择器](/docs/concepts/overview/working-with-objects/labels/)。ReplicaSet 管理所有标签匹配与标签选择器的 Pod。它不区分自己创建或删除的 Pod 和其他人或进程创建或删除的pod。这允许在不影响运行中的 Pod 的情况下替换副本集。
|
||||
|
||||
`.spec.template.metadata.labels` 必须匹配 `.spec.selector`,否则它将被 API 拒绝。
|
||||
|
||||
Kubernetes 1.9 版本中,API 版本 `apps/v1` 中的 ReplicaSet 类型的版本是当前版本并默认开启。API 版本 `apps/v1beta2` 被弃用。
|
||||
|
||||
<!--
|
||||
Also you should not normally create any pods whose labels match this selector, either directly, with
|
||||
another ReplicaSet, or with another controller such as a Deployment. If you do so, the ReplicaSet thinks that it
|
||||
created the other pods. Kubernetes does not stop you from doing this.
|
||||
|
||||
If you do end up with multiple controllers that have overlapping selectors, you
|
||||
will have to manage the deletion yourself.
|
||||
-->
|
||||
|
||||
另外,通常您不应该创建标签与此选择器匹配的任何 Pod,或者直接与另一个 ReplicaSet 或另一个控制器(如 Deployment)标签匹配的任何 Pod。
|
||||
如果你这样做,ReplicaSet 会认为它创造了其他 Pod。Kubernetes 并不会阻止您这样做。
|
||||
|
||||
如果您最终使用了多个具有重叠选择器的控制器,则必须自己负责删除。
|
||||
|
||||
<!--
|
||||
### Labels on a ReplicaSet
|
||||
|
||||
The ReplicaSet can itself have labels (`.metadata.labels`). Typically, you
|
||||
would set these the same as the `.spec.template.metadata.labels`. However, they are allowed to be
|
||||
different, and the `.metadata.labels` do not affect the behavior of the ReplicaSet.
|
||||
|
||||
### Replicas
|
||||
|
||||
You can specify how many pods should run concurrently by setting `.spec.replicas`. The number running at any time may be higher
|
||||
or lower, such as if the replicas were just increased or decreased, or if a pod is gracefully
|
||||
shut down, and a replacement starts early.
|
||||
|
||||
If you do not specify `.spec.replicas`, then it defaults to 1.
|
||||
-->
|
||||
|
||||
### Replicas
|
||||
|
||||
通过设置 `.spec.replicas` 您可以指定要同时运行多少个 Pod。
|
||||
在任何时间运行的 Pod 数量可能高于或低于 `.spec.replicas` 指定的数量,例如在副本刚刚被增加或减少后、或者 Pod 正在被优雅地关闭、以及替换提前开始。
|
||||
|
||||
如果您没有指定 `.spec.replicas`, 那么默认值为 1。
|
||||
|
||||
<!--
|
||||
## Working with ReplicaSets
|
||||
|
||||
### Deleting a ReplicaSet and its Pods
|
||||
|
||||
To delete a ReplicaSet and all of its Pods, use [`kubectl delete`](/docs/reference/generated/kubectl/kubectl-commands#delete). The [Garbage collector](/docs/concepts/workloads/controllers/garbage-collection/) automatically deletes all of the dependent Pods by default.
|
||||
|
||||
When using the REST API or the `client-go` library, you must set `propagationPolicy` to `Background` or `Foreground` in delete option. e.g. :
|
||||
-->
|
||||
|
||||
## 使用 ReplicaSets 的具体方法
|
||||
|
||||
### 删除 ReplicaSet 和它的 Pod
|
||||
|
||||
要删除 ReplicaSet 和它的所有 Pod,使用[`kubectl delete`](/docs/reference/generated/kubectl/kubectl-commands#delete) 命令。
|
||||
默认情况下,[垃圾收集器](/docs/concepts/workloads/controllers/garbage-collection/) 自动删除所有依赖的 Pod。
|
||||
|
||||
当使用 REST API 或 `client-go` 库时,您必须在删除选项中将 `propagationPolicy` 设置为 `Background` 或 `Foreground`。例如:
|
||||
|
||||
```shell
|
||||
kubectl proxy --port=8080
|
||||
curl -X DELETE 'localhost:8080/apis/extensions/v1beta1/namespaces/default/replicasets/frontend' \
|
||||
> -d '{"kind":"DeleteOptions","apiVersion":"v1","propagationPolicy":"Foreground"}' \
|
||||
> -H "Content-Type: application/json"
|
||||
```
|
||||
|
||||
<!--
|
||||
### Deleting just a ReplicaSet
|
||||
|
||||
You can delete a ReplicaSet without affecting any of its pods using [`kubectl delete`](/docs/reference/generated/kubectl/kubectl-commands#delete) with the `--cascade=false` option.
|
||||
When using the REST API or the `client-go` library, you must set `propagationPolicy` to `Orphan`, e.g. :
|
||||
-->
|
||||
|
||||
### 只删除 ReplicaSet
|
||||
|
||||
您可以只删除 ReplicaSet 而不影响它的 Pod,方法是使用[`kubectl delete`](/docs/reference/generated/kubectl/kubectl-commands#delete) 命令并设置 `--cascade=false` 选项。
|
||||
|
||||
当使用 REST API 或 `client-go` 库时,您必须将 `propagationPolicy` 设置为 `Orphan`。例如:
|
||||
|
||||
```shell
|
||||
kubectl proxy --port=8080
|
||||
curl -X DELETE 'localhost:8080/apis/extensions/v1beta1/namespaces/default/replicasets/frontend' \
|
||||
> -d '{"kind":"DeleteOptions","apiVersion":"v1","propagationPolicy":"Orphan"}' \
|
||||
> -H "Content-Type: application/json"
|
||||
```
|
||||
|
||||
<!--
|
||||
Once the original is deleted, you can create a new ReplicaSet to replace it. As long
|
||||
as the old and new `.spec.selector` are the same, then the new one will adopt the old pods.
|
||||
However, it will not make any effort to make existing pods match a new, different pod template.
|
||||
To update pods to a new spec in a controlled way, use a [rolling update](#rolling-updates).
|
||||
-->
|
||||
|
||||
一旦删除了原来的 ReplicaSet,就可以创建一个新的来替换它。
|
||||
由于新旧 ReplicaSet 的 `.spec.selector` 是相同的,新的 ReplicaSet 将接管老的 Pod。
|
||||
但是,它不会努力使现有的 Pod 与新的、不同的 Pod 模板匹配。
|
||||
若想要以可控的方式将 Pod 更新到新的 spec,就要使用 [滚动更新](#rolling-updates)的方式。
|
||||
|
||||
|
||||
<!--
|
||||
|
||||
### Isolating pods from a ReplicaSet
|
||||
|
||||
Pods may be removed from a ReplicaSet's target set by changing their labels. This technique may be used to remove pods
|
||||
from service for debugging, data recovery, etc. Pods that are removed in this way will be replaced automatically (
|
||||
assuming that the number of replicas is not also changed).
|
||||
|
||||
-->
|
||||
|
||||
### 将 Pod 从 ReplicaSet 中隔离
|
||||
|
||||
可以通过改变标签来从 ReplicaSet 的目标集中移除 Pod。这种技术可以用来从服务中去除 Pod,以便进行排错、数据恢复等。
|
||||
以这种方式移除的 Pod 将被自动替换(假设副本的数量没有改变)。
|
||||
|
||||
<!--
|
||||
### Scaling a ReplicaSet
|
||||
|
||||
A ReplicaSet can be easily scaled up or down by simply updating the `.spec.replicas` field. The ReplicaSet controller
|
||||
ensures that a desired number of pods with a matching label selector are available and operational.
|
||||
-->
|
||||
|
||||
### 缩放 RepliaSet
|
||||
|
||||
通过更新 `.spec.replicas` 字段,ReplicaSet 可以被轻松的进行缩放。ReplicaSet 控制器能确保匹配标签选择器的数量的 Pod 是可用的和可操作的。
|
||||
|
||||
<!--
|
||||
### ReplicaSet as an Horizontal Pod Autoscaler Target
|
||||
|
||||
A ReplicaSet can also be a target for
|
||||
[Horizontal Pod Autoscalers (HPA)](/docs/tasks/run-application/horizontal-pod-autoscale/). That is,
|
||||
a ReplicaSet can be auto-scaled by an HPA. Here is an example HPA targeting
|
||||
the ReplicaSet we created in the previous example.
|
||||
-->
|
||||
|
||||
### ReplicaSet 作为水平的 Pod 自动缩放器目标
|
||||
|
||||
ReplicaSet 也可以作为 [水平的 Pod 缩放器 (HPA)](/docs/tasks/run-application/horizontal-pod-autoscale/) 的目标。也就是说,ReplicaSet 可以被 HPA 自动缩放。
|
||||
以下是 HPA 以我们在前一个示例中创建的副本集为目标的示例。
|
||||
|
||||
|
||||
{{< codenew file="controllers/hpa-rs.yaml" >}}
|
||||
|
||||
<!--
|
||||
Saving this manifest into `hpa-rs.yaml` and submitting it to a Kubernetes cluster should
|
||||
create the defined HPA that autoscales the target ReplicaSet depending on the CPU usage
|
||||
of the replicated pods.
|
||||
-->
|
||||
|
||||
将这个列表保存到 `hpa-rs.yaml` 并提交到 Kubernetes 集群,就能创建它所定义的 HPA,进而就能根据复制的 Pod 的 CPU 利用率对目标 ReplicaSet进行自动缩放。
|
||||
|
||||
```shell
|
||||
kubectl create -f https://k8s.io/examples/controllers/hpa-rs.yaml
|
||||
```
|
||||
|
||||
<!--
|
||||
Alternatively, you can use the `kubectl autoscale` command to accomplish the same
|
||||
(and it's easier!)
|
||||
-->
|
||||
|
||||
或者,可以使用 `kubectl autoscale` 命令完成相同的操作。
|
||||
(而且它更简单!)
|
||||
|
||||
```shell
|
||||
kubectl autoscale rs frontend
|
||||
```
|
||||
|
||||
<!--
|
||||
## Alternatives to ReplicaSet
|
||||
|
||||
### Deployment (Recommended)
|
||||
|
||||
[`Deployment`](/docs/concepts/workloads/controllers/deployment/) is a higher-level API object that updates its underlying ReplicaSets and their Pods
|
||||
in a similar fashion as `kubectl rolling-update`. Deployments are recommended if you want this rolling update functionality,
|
||||
because unlike `kubectl rolling-update`, they are declarative, server-side, and have additional features. For more information on running a stateless
|
||||
application using a Deployment, please read [Run a Stateless Application Using a Deployment](/docs/tasks/run-application/run-stateless-application-deployment/).
|
||||
-->
|
||||
|
||||
## ReplicaSet 的替代方案
|
||||
|
||||
### Deployment (推荐)
|
||||
|
||||
[`Deployment`](/docs/concepts/workloads/controllers/deployment/) 是一个高级 API 对象,它以 `kubectl rolling-update` 的方式更新其底层副本集及其Pod。
|
||||
如果您需要滚动更新功能,建议使用 Deployment,因为 Deployment 与 `kubectl rolling-update` 不同的是:它是声明式的、服务器端的、并且具有其他特性。
|
||||
有关使用 Deployment 来运行无状态应用的更多信息,请参阅 [使用 Deployment 运行无状态应用](/docs/tasks/run-application/run-stateless-application-deployment/)。
|
||||
|
||||
<!--
|
||||
### Bare Pods
|
||||
|
||||
Unlike the case where a user directly created pods, a ReplicaSet replaces pods that are deleted or terminated for any reason, such as in the case of node failure or disruptive node maintenance, such as a kernel upgrade. For this reason, we recommend that you use a ReplicaSet even if your application requires only a single pod. Think of it similarly to a process supervisor, only it supervises multiple pods across multiple nodes instead of individual processes on a single node. A ReplicaSet delegates local container restarts to some agent on the node (for example, Kubelet or Docker).
|
||||
-->
|
||||
|
||||
### 裸 Pod
|
||||
|
||||
与用户直接创建 Pod 的情况不同,ReplicaSet 会替换那些由于某些原因被删除或被终止的 Pod,例如在节点故障或破坏性的节点维护(如内核升级)的情况下。
|
||||
因为这个好处,我们建议您使用 ReplicaSet,即使应用程序只需要一个 Pod。
|
||||
想像一下,ReplicaSet 类似于进程监视器,只不过它在多个节点上监视多个 Pod,而不是在单个节点上监视单个进程。
|
||||
ReplicaSet 将本地容器重启的任务委托给了节点上的某个代理(例如,Kubelet 或 Docker)去完成。
|
||||
|
||||
<!--
|
||||
### Job
|
||||
|
||||
Use a [`Job`](/docs/concepts/jobs/run-to-completion-finite-workloads/) instead of a ReplicaSet for pods that are expected to terminate on their own
|
||||
(that is, batch jobs).
|
||||
-->
|
||||
|
||||
### Job
|
||||
|
||||
使用[`Job`](/docs/concepts/jobs/run-to-completion-finite-workloads/) 代替ReplicaSet,可以用于那些期望自行终止的 Pod。
|
||||
|
||||
<!--
|
||||
### DaemonSet
|
||||
|
||||
Use a [`DaemonSet`](/docs/concepts/workloads/controllers/daemonset/) instead of a ReplicaSet for pods that provide a
|
||||
machine-level function, such as machine monitoring or machine logging. These pods have a lifetime that is tied
|
||||
to a machine lifetime: the pod needs to be running on the machine before other pods start, and are
|
||||
safe to terminate when the machine is otherwise ready to be rebooted/shutdown.
|
||||
-->
|
||||
|
||||
### DaemonSet
|
||||
|
||||
对于管理那些提供主机级别功能(如主机监控和主机日志)的容器,就要用[`DaemonSet`](/docs/concepts/workloads/controllers/daemonset/) 而不用 ReplicaSet。
|
||||
这些 Pod 的寿命与主机寿命有关:这些 Pod 需要先于主机上的其他 Pod 运行,并且在机器准备重新启动/关闭时安全地终止。
|
||||
|
||||
{{% /capture %}}
|
||||
|
||||
@@ -0,0 +1,546 @@
|
||||
---
|
||||
title: ReplicationController
|
||||
feature:
|
||||
title: 自我修复
|
||||
anchor: ReplicationController 如何工作
|
||||
description: >
|
||||
重新启动失败的容器,在节点死亡时替换并重新调度容器,杀死不响应用户定义的健康检查的容器,并且在它们准备好服务之前不会它们公布给客户端。
|
||||
|
||||
content_template: templates/concept
|
||||
weight: 20
|
||||
---
|
||||
<!--
|
||||
title: ReplicationController
|
||||
feature:
|
||||
title: Self-healing
|
||||
anchor: How a ReplicationController Works
|
||||
description: >
|
||||
Restarts containers that fail, replaces and reschedules containers when nodes die, kills containers that don't respond to your user-defined health check, and doesn't advertise them to clients until they are ready to serve.
|
||||
|
||||
content_template: templates/concept
|
||||
weight: 20
|
||||
-->
|
||||
|
||||
{{% capture overview %}}
|
||||
|
||||
{{< note >}}
|
||||
<!--
|
||||
A [`Deployment`](/docs/concepts/workloads/controllers/deployment/) that configures a [`ReplicaSet`](/docs/concepts/workloads/controllers/replicaset/) is now the recommended way to set up replication.
|
||||
-->
|
||||
现在推荐使用配置 [`ReplicaSet`](/docs/concepts/workloads/controllers/replicaset/) 的 [`Deployment`](/docs/concepts/workloads/controllers/deployment/) 来建立副本管理机制。
|
||||
{{< /note >}}
|
||||
|
||||
<!--
|
||||
A _ReplicationController_ ensures that a specified number of pod replicas are running at any one
|
||||
time. In other words, a ReplicationController makes sure that a pod or a homogeneous set of pods is
|
||||
always up and available.
|
||||
-->
|
||||
_ReplicationController_ 确保在任何时候都有特定数量的 pod 副本处于运行状态。
|
||||
换句话说,ReplicationController 确保一个 pod 或一组同类的 pod 总是可用的。
|
||||
{{% /capture %}}
|
||||
|
||||
|
||||
{{% capture body %}}
|
||||
|
||||
<!--
|
||||
## How a ReplicationController Works
|
||||
|
||||
If there are too many pods, the ReplicationController terminates the extra pods. If there are too few, the
|
||||
ReplicationController starts more pods. Unlike manually created pods, the pods maintained by a
|
||||
ReplicationController are automatically replaced if they fail, are deleted, or are terminated.
|
||||
For example, your pods are re-created on a node after disruptive maintenance such as a kernel upgrade.
|
||||
For this reason, you should use a ReplicationController even if your application requires
|
||||
only a single pod. A ReplicationController is similar to a process supervisor,
|
||||
but instead of supervising individual processes on a single node, the ReplicationController supervises multiple pods
|
||||
across multiple nodes.
|
||||
|
||||
ReplicationController is often abbreviated to "rc" or "rcs" in discussion, and as a shortcut in
|
||||
kubectl commands.
|
||||
|
||||
A simple case is to create one ReplicationController object to reliably run one instance of
|
||||
a Pod indefinitely. A more complex use case is to run several identical replicas of a replicated
|
||||
service, such as web servers.
|
||||
-->
|
||||
## ReplicationController 如何工作
|
||||
|
||||
当 pods 数量过多时,ReplicationController 会终止多余的 pods。当 pods 数量太少时,ReplicationController 将会启动新的 pods。
|
||||
与手动创建的 pod 不同,由 ReplicationController 创建的 pods 在失败、被删除或被终止时会被自动替换。
|
||||
例如,在中断性维护(如内核升级)之后,您的 pod 会在节点上重新创建。
|
||||
因此,即使您的应用程序只需要一个 pod,您也应该使用一个 ReplicationController。
|
||||
ReplicationController 类似于进程管理器,但是 ReplicationController 不是监控单个节点上的单个进程,而是监控跨多个节点的多个 pods。
|
||||
|
||||
在讨论中,ReplicationController 通常缩写为 "rc" 或 "rcs",并作为 kubectl 命令的快捷方式。
|
||||
|
||||
一个简单的例子是创建一个 ReplicationController 对象来可靠地无限期地运行 Pod 的一个实例。
|
||||
更复杂的用例是运行一个多副本服务(如 web 服务器)的若干相同副本。
|
||||
|
||||
<!--
|
||||
## Running an example ReplicationController
|
||||
|
||||
This example ReplicationController config runs three copies of the nginx web server.
|
||||
-->
|
||||
## 运行一个示例 ReplicationController
|
||||
|
||||
这个示例 ReplicationController 配置运行 nginx web 服务器的三个副本。
|
||||
|
||||
{{< codenew file="controllers/replication.yaml" >}}
|
||||
|
||||
<!--
|
||||
Run the example job by downloading the example file and then running this command:
|
||||
-->
|
||||
通过下载示例文件并运行以下命令来运行示例任务:
|
||||
|
||||
```shell
|
||||
kubectl apply -f https://k8s.io/examples/controllers/replication.yaml
|
||||
```
|
||||
```
|
||||
replicationcontroller/nginx created
|
||||
```
|
||||
|
||||
<!--
|
||||
Check on the status of the ReplicationController using this command:
|
||||
-->
|
||||
使用以下命令检查 ReplicationController 的状态:
|
||||
|
||||
```shell
|
||||
kubectl describe replicationcontrollers/nginx
|
||||
```
|
||||
```
|
||||
Name: nginx
|
||||
Namespace: default
|
||||
Selector: app=nginx
|
||||
Labels: app=nginx
|
||||
Annotations: <none>
|
||||
Replicas: 3 current / 3 desired
|
||||
Pods Status: 0 Running / 3 Waiting / 0 Succeeded / 0 Failed
|
||||
Pod Template:
|
||||
Labels: app=nginx
|
||||
Containers:
|
||||
nginx:
|
||||
Image: nginx
|
||||
Port: 80/TCP
|
||||
Environment: <none>
|
||||
Mounts: <none>
|
||||
Volumes: <none>
|
||||
Events:
|
||||
FirstSeen LastSeen Count From SubobjectPath Type Reason Message
|
||||
--------- -------- ----- ---- ------------- ---- ------ -------
|
||||
20s 20s 1 {replication-controller } Normal SuccessfulCreate Created pod: nginx-qrm3m
|
||||
20s 20s 1 {replication-controller } Normal SuccessfulCreate Created pod: nginx-3ntk0
|
||||
20s 20s 1 {replication-controller } Normal SuccessfulCreate Created pod: nginx-4ok8v
|
||||
```
|
||||
|
||||
<!--
|
||||
Here, three pods are created, but none is running yet, perhaps because the image is being pulled.
|
||||
A little later, the same command may show:
|
||||
-->
|
||||
此时,创建了三个 pod,但是还没有运行,可能正在拉取镜像。
|
||||
稍后,相同的命令可能显示:
|
||||
|
||||
```shell
|
||||
Pods Status: 3 Running / 0 Waiting / 0 Succeeded / 0 Failed
|
||||
```
|
||||
|
||||
<!--
|
||||
To list all the pods that belong to the ReplicationController in a machine readable form, you can use a command like this:
|
||||
-->
|
||||
要以机器可读的形式列出属于 ReplicationController 的所有 pod,可以使用如下命令:
|
||||
|
||||
```shell
|
||||
pods=$(kubectl get pods --selector=app=nginx --output=jsonpath={.items..metadata.name})
|
||||
echo $pods
|
||||
```
|
||||
```
|
||||
nginx-3ntk0 nginx-4ok8v nginx-qrm3m
|
||||
```
|
||||
|
||||
<!--
|
||||
Here, the selector is the same as the selector for the ReplicationController (seen in the
|
||||
`kubectl describe` output, and in a different form in `replication.yaml`. The `--output=jsonpath` option
|
||||
specifies an expression that just gets the name from each pod in the returned list.
|
||||
-->
|
||||
这里,选择器与 ReplicationController 的选择器相同(参见 `kubectl describe` 输出),并以不同的形式出现在 `replication.yaml` 中。
|
||||
`--output=jsonpath` 选项指定了一个表达式,只从返回列表中的每个 pod 中获取名称。
|
||||
|
||||
<!--
|
||||
## Writing a ReplicationController Spec
|
||||
|
||||
As with all other Kubernetes config, a ReplicationController needs `apiVersion`, `kind`, and `metadata` fields.
|
||||
For general information about working with config files, see [object management ](/docs/concepts/overview/working-with-objects/object-management/).
|
||||
|
||||
A ReplicationController also needs a [`.spec` section](https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status).
|
||||
-->
|
||||
## 编写一个 ReplicationController Spec
|
||||
|
||||
与所有其它 Kubernetes 配置一样,ReplicationController 需要 `apiVersion` ,`kind` 和 `metadata` 字段。
|
||||
有关使用配置文件的常规信息,参考[对象管理](/docs/concepts/overview/working-with-objects/object-management/)。
|
||||
|
||||
ReplicationController 也需要一个 [`.spec` 部分](https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status)。
|
||||
|
||||
<!--
|
||||
### Pod Template
|
||||
|
||||
The `.spec.template` is the only required field of the `.spec`.
|
||||
|
||||
The `.spec.template` is a [pod template](/docs/concepts/workloads/pods/pod-overview/#pod-templates). It has exactly the same schema as a [pod](/docs/concepts/workloads/pods/pod/), except it is nested and does not have an `apiVersion` or `kind`.
|
||||
|
||||
In addition to required fields for a Pod, a pod template in a ReplicationController must specify appropriate
|
||||
labels and an appropriate restart policy. For labels, make sure not to overlap with other controllers. See [pod selector](#pod-selector).
|
||||
|
||||
Only a [`.spec.template.spec.restartPolicy`](/docs/concepts/workloads/pods/pod-lifecycle/#restart-policy) equal to `Always` is allowed, which is the default if not specified.
|
||||
|
||||
For local container restarts, ReplicationControllers delegate to an agent on the node,
|
||||
for example the [Kubelet](/docs/admin/kubelet/) or Docker.
|
||||
-->
|
||||
### Pod 模板
|
||||
|
||||
`.spec.template` 是 `.spec` 的唯一必需字段。
|
||||
|
||||
`.spec.template` 是一个 [pod 模板](/docs/concepts/workloads/pods/pod-overview/#pod-templates)。它的模式与 [pod](/docs/concepts/workloads/pods/pod/) 完全相同,只是它是嵌套的,并且没有 `apiVersion` 或 `kind`。
|
||||
|
||||
除了 Pod 所需的字段外,ReplicationController 中的 pod 模板必须指定适当的标签和适当的重新启动策略。
|
||||
对于标签,请确保不与其他控制器重叠。参考 [pod 选择器](#pod-选择器)。
|
||||
|
||||
只允许 [`.spec.template.spec.restartPolicy`](/docs/concepts/workloads/pods/pod-lifecycle/#restart-policy) 等于 `Always`,如果没有指定,这是默认值。
|
||||
|
||||
对于本地容器重启,ReplicationController 委托给节点上的代理,
|
||||
例如 [Kubelet](/docs/admin/kubelet/) 或 Docker。
|
||||
|
||||
<!--
|
||||
### Labels on the ReplicationController
|
||||
|
||||
The ReplicationController can itself have labels (`.metadata.labels`). Typically, you
|
||||
would set these the same as the `.spec.template.metadata.labels`; if `.metadata.labels` is not specified
|
||||
then it defaults to `.spec.template.metadata.labels`. However, they are allowed to be
|
||||
different, and the `.metadata.labels` do not affect the behavior of the ReplicationController.
|
||||
-->
|
||||
### ReplicationController 上的标签
|
||||
|
||||
ReplicationController 本身可以有标签 (`.metadata.labels`)。
|
||||
通常,您可以将这些设置为 `.spec.template.metadata.labels`;
|
||||
如果没有指定 `.metadata.labels` 那么它默认为 `.spec.template.metadata.labels`。
|
||||
但是,Kubernetes 允许它们是不同的,`.metadata.labels` 不会影响 ReplicationController 的行为。
|
||||
|
||||
<!--
|
||||
### Pod Selector
|
||||
|
||||
The `.spec.selector` field is a [label selector](/docs/concepts/overview/working-with-objects/labels/#label-selectors). A ReplicationController
|
||||
manages all the pods with labels that match the selector. It does not distinguish
|
||||
between pods that it created or deleted and pods that another person or process created or
|
||||
deleted. This allows the ReplicationController to be replaced without affecting the running pods.
|
||||
|
||||
If specified, the `.spec.template.metadata.labels` must be equal to the `.spec.selector`, or it will
|
||||
be rejected by the API. If `.spec.selector` is unspecified, it will be defaulted to
|
||||
`.spec.template.metadata.labels`.
|
||||
|
||||
Also you should not normally create any pods whose labels match this selector, either directly, with
|
||||
another ReplicationController, or with another controller such as Job. If you do so, the
|
||||
ReplicationController thinks that it created the other pods. Kubernetes does not stop you
|
||||
from doing this.
|
||||
|
||||
If you do end up with multiple controllers that have overlapping selectors, you
|
||||
will have to manage the deletion yourself (see [below](#working-with-replicationcontrollers)).
|
||||
-->
|
||||
### Pod 选择器
|
||||
|
||||
`.spec.selector` 字段是一个[标签选择器](/docs/concepts/overview/working-with-objects/labels/#label-selectors)。
|
||||
ReplicationController 管理标签与选择器匹配的所有 Pods。
|
||||
它不区分它创建或删除的 pod 以及另一个人或进程创建或删除的 pod。
|
||||
这允许在不影响正在运行的 pod 的情况下替换 ReplicationController。
|
||||
|
||||
如果指定了 `.spec.template.metadata.labels`,它必须和 `.spec.selector` 相同,否则它将被 API 拒绝。
|
||||
如果没有指定 `.spec.selector`,它将默认为 `.spec.template.metadata.labels`。
|
||||
|
||||
此外,用户通常不应创建标签与此选择器匹配的任何其他 Pods,无论是直接创建、使用另一个 ReplicationController 来创建或者别的控制器(如 Job )来创建,都是不允许的。
|
||||
如果这样做, ReplicationController 会认为这些 Pods 是由它自己创建的。
|
||||
Kubernetes 并没有阻止你这样做。
|
||||
|
||||
如果您的确创建了多个控制器并且其选择器之间存在重叠,那么您将不得不自己管理删除操作(参考[后文](#使用-replicationcontrollers))。
|
||||
|
||||
<!--
|
||||
### Multiple Replicas
|
||||
|
||||
You can specify how many pods should run concurrently by setting `.spec.replicas` to the number
|
||||
of pods you would like to have running concurrently. The number running at any time may be higher
|
||||
or lower, such as if the replicas were just increased or decreased, or if a pod is gracefully
|
||||
shutdown, and a replacement starts early.
|
||||
|
||||
If you do not specify `.spec.replicas`, then it defaults to 1.
|
||||
-->
|
||||
### 多个副本
|
||||
|
||||
你可以通过设置 `.spec.replicas` 来指定应该同时运行多少个 Pods。
|
||||
在任何时候,处于运行状态的 Pods 个数都可能高于或者低于设定值。例如,副本个数刚刚被增加或减少时,或者一个 pod 处于体面终止过程中而其替代副本已经提前开始创建时。
|
||||
|
||||
如果你没有指定 `.spec.replicas` ,那么它默认是1。
|
||||
|
||||
<!--
|
||||
## Working with ReplicationControllers
|
||||
-->
|
||||
## 使用 ReplicationController
|
||||
|
||||
<!--
|
||||
### Deleting a ReplicationController and its Pods
|
||||
|
||||
To delete a ReplicationController and all its pods, use [`kubectl
|
||||
delete`](/docs/reference/generated/kubectl/kubectl-commands#delete). Kubectl will scale the ReplicationController to zero and wait
|
||||
for it to delete each pod before deleting the ReplicationController itself. If this kubectl
|
||||
command is interrupted, it can be restarted.
|
||||
|
||||
When using the REST API or go client library, you need to do the steps explicitly (scale replicas to
|
||||
0, wait for pod deletions, then delete the ReplicationController).
|
||||
-->
|
||||
### 删除一个 ReplicationController 以及它的 Pod
|
||||
|
||||
要删除一个 ReplicationController 以及它的 Pod,使用 [`kubectl delete`](/docs/reference/generated/kubectl/kubectl-commands#delete)。
|
||||
Kubectl 将 ReplicationController 缩放为0并等待以便在删除 ReplicationController 本身之前删除每个 pod。
|
||||
如果这个 kubectl 命令被中断,可以重新启动它。
|
||||
|
||||
当使用 REST API 或 go 客户端库时,您需要明确地执行这些步骤(缩放副本为0、 等待 Pod 删除,之后删除 ReplicationController 资源)。
|
||||
|
||||
<!--
|
||||
### Deleting just a ReplicationController
|
||||
|
||||
You can delete a ReplicationController without affecting any of its pods.
|
||||
|
||||
Using kubectl, specify the `--cascade=false` option to [`kubectl delete`](/docs/reference/generated/kubectl/kubectl-commands#delete).
|
||||
|
||||
When using the REST API or go client library, simply delete the ReplicationController object.
|
||||
|
||||
Once the original is deleted, you can create a new ReplicationController to replace it. As long
|
||||
as the old and new `.spec.selector` are the same, then the new one will adopt the old pods.
|
||||
However, it will not make any effort to make existing pods match a new, different pod template.
|
||||
To update pods to a new spec in a controlled way, use a [rolling update](#rolling-updates).
|
||||
-->
|
||||
### 只删除 ReplicationController
|
||||
|
||||
你可以删除一个 ReplicationController 而不影响它的任何 pod。
|
||||
|
||||
使用 kubectl ,为 [`kubectl delete`](/docs/reference/generated/kubectl/kubectl-commands#delete) 指定 `--cascade=false` 选项。
|
||||
|
||||
当使用 REST API 或 go 客户端库时, 只需删除 ReplicationController 对象。
|
||||
|
||||
一旦原始对象被删除,你可以创建一个新的 ReplicationController 来替换它。
|
||||
只要新的和旧的 `.spec.selector` 相同,那么新的控制器将领养旧的 Pods。
|
||||
但是,它不会做出任何努力使现有的 pod 匹配新的、不同的 pod 模板。
|
||||
如果希望以受控方式更新 Pods 以使用新的 spec,请执行[滚动更新](#滚动更新)操作。
|
||||
|
||||
<!--
|
||||
### Isolating pods from a ReplicationController
|
||||
|
||||
Pods may be removed from a ReplicationController's target set by changing their labels. This technique may be used to remove pods from service for debugging, data recovery, etc. Pods that are removed in this way will be replaced automatically (assuming that the number of replicas is not also changed).
|
||||
-->
|
||||
### 从 ReplicationController 中隔离 pod
|
||||
|
||||
通过更改 Pod 的标签,可以从 ReplicationController 的目标中删除 pod。
|
||||
此技术可用于从服务中删除 pod 以进行调试、数据恢复等。以这种方式删除的 pod 将自动替换(假设复制副本的数量也没有更改)。
|
||||
|
||||
<!--
|
||||
## Common usage patterns
|
||||
-->
|
||||
## 常见的使用模式
|
||||
|
||||
<!--
|
||||
### Rescheduling
|
||||
|
||||
As mentioned above, whether you have 1 pod you want to keep running, or 1000, a ReplicationController will ensure that the specified number of pods exists, even in the event of node failure or pod termination (for example, due to an action by another control agent).
|
||||
-->
|
||||
### 重新调度
|
||||
|
||||
如上所述,无论您想要继续运行1个 pod 还是1000个,一个 ReplicationController 都将确保存在指定数量的 pod,即使在节点故障或 pod 终止(例如,由于另一个控制代理的操作)的情况下也是如此。
|
||||
<!--
|
||||
### Scaling
|
||||
|
||||
The ReplicationController makes it easy to scale the number of replicas up or down, either manually or by an auto-scaling control agent, by simply updating the `replicas` field.
|
||||
-->
|
||||
### 扩缩容
|
||||
|
||||
通过简单地更新 `replicas` 字段,ReplicationController 可以方便地横向扩容或缩容副本的数量,或手动或通过自动缩放控制代理。
|
||||
|
||||
<!--
|
||||
### Rolling updates
|
||||
|
||||
The ReplicationController is designed to facilitate rolling updates to a service by replacing pods one-by-one.
|
||||
|
||||
As explained in [#1353](http://issue.k8s.io/1353), the recommended approach is to create a new ReplicationController with 1 replica, scale the new (+1) and old (-1) controllers one by one, and then delete the old controller after it reaches 0 replicas. This predictably updates the set of pods regardless of unexpected failures.
|
||||
|
||||
Ideally, the rolling update controller would take application readiness into account, and would ensure that a sufficient number of pods were productively serving at any given time.
|
||||
|
||||
The two ReplicationControllers would need to create pods with at least one differentiating label, such as the image tag of the primary container of the pod, since it is typically image updates that motivate rolling updates.
|
||||
|
||||
Rolling update is implemented in the client tool
|
||||
[`kubectl rolling-update`](/docs/reference/generated/kubectl/kubectl-commands#rolling-update). Visit [`kubectl rolling-update` task](/docs/tasks/run-application/rolling-update-replication-controller/) for more concrete examples.
|
||||
-->
|
||||
### 滚动更新
|
||||
|
||||
ReplicationController 的设计目的是通过逐个替换 pod 以方便滚动更新服务。
|
||||
|
||||
如[#1353](http://issue.k8s.io/1353)所述,建议的方法是使用1个副本创建一个新的 ReplicationController,逐个缩放新的(+1)和旧的(-1)控制器,然后在旧的控制器达到0个副本后将其删除。这一方法能够实现可控的 Pods 集合更新,即使存在意外失效的状况。
|
||||
|
||||
理想情况下,滚动更新控制器将考虑应用程序的就绪情况,并确保在任何给定时间都有足够数量的 Pods 有效地提供服务。
|
||||
|
||||
这两个 ReplicationController 将需要创建至少具有一个不同标签的 pod,比如 pod 主要容器的镜像标签,因为通常是镜像更新触发滚动更新。
|
||||
|
||||
滚动更新是在客户端工具
|
||||
[`kubectl rolling-update`](/docs/reference/generated/kubectl/kubectl-commands#rolling-update)中实现的。 访问 [`kubectl rolling-update` 任务](/docs/tasks/run-application/rolling-update-replication-controller/)以获得更多的具体示例。
|
||||
|
||||
<!--
|
||||
### Multiple release tracks
|
||||
|
||||
In addition to running multiple releases of an application while a rolling update is in progress, it's common to run multiple releases for an extended period of time, or even continuously, using multiple release tracks. The tracks would be differentiated by labels.
|
||||
|
||||
For instance, a service might target all pods with `tier in (frontend), environment in (prod)`. Now say you have 10 replicated pods that make up this tier. But you want to be able to 'canary' a new version of this component. You could set up a ReplicationController with `replicas` set to 9 for the bulk of the replicas, with labels `tier=frontend, environment=prod, track=stable`, and another ReplicationController with `replicas` set to 1 for the canary, with labels `tier=frontend, environment=prod, track=canary`. Now the service is covering both the canary and non-canary pods. But you can mess with the ReplicationControllers separately to test things out, monitor the results, etc.
|
||||
-->
|
||||
### 多个版本跟踪
|
||||
|
||||
除了在滚动更新过程中运行应用程序的多个版本之外,通常还会使用多个版本跟踪来长时间,甚至持续运行多个版本。这些跟踪将根据标签加以区分。
|
||||
|
||||
例如,一个服务可能把具有 `tier in (frontend), environment in (prod)` 的所有 pod 作为目标。
|
||||
现在假设您有10个副本的 pod 组成了这个层。但是你希望能够'金丝雀部署'这个组件的新版本。
|
||||
您可以为大部分副本设置一个 ReplicationController,其中 `replicas` 设置为9,标签为 `tier=frontend, environment=prod, track=stable` 而为 canary 设置另一个 ReplicationController,其中 `replicas` 设置为1,标签为 `tier=frontend, environment=prod, track=canary`。
|
||||
现在这个服务覆盖了 canary 和非 canary pod。但您可以单独处理 ReplicationController,以测试、监控结果等。
|
||||
|
||||
<!--
|
||||
### Using ReplicationControllers with Services
|
||||
|
||||
Multiple ReplicationControllers can sit behind a single service, so that, for example, some traffic
|
||||
goes to the old version, and some goes to the new version.
|
||||
|
||||
A ReplicationController will never terminate on its own, but it isn't expected to be as long-lived as services. Services may be composed of pods controlled by multiple ReplicationControllers, and it is expected that many ReplicationControllers may be created and destroyed over the lifetime of a service (for instance, to perform an update of pods that run the service). Both services themselves and their clients should remain oblivious to the ReplicationControllers that maintain the pods of the services.
|
||||
-->
|
||||
### 和服务一起使用 ReplicationController
|
||||
|
||||
多个 ReplicationController 可以位于一个服务的后面,例如,一部分流量流向旧版本,一部分流量流向新版本。
|
||||
|
||||
一个 ReplicationController 永远不会自行终止,但它不会像服务那样长寿。
|
||||
服务可以由多个 ReplicationController 控制的 pod 组成,并且在服务的生命周期内(例如,为了执行 pod 更新而运行服务),可以创建和销毁许多 ReplicationController。
|
||||
服务本身和它们的客户端都应该忽略负责维护服务 Pod 的 ReplicationController 的存在。
|
||||
|
||||
<!--
|
||||
## Writing programs for Replication
|
||||
|
||||
Pods created by a ReplicationController are intended to be fungible and semantically identical, though their configurations may become heterogeneous over time. This is an obvious fit for replicated stateless servers, but ReplicationControllers can also be used to maintain availability of master-elected, sharded, and worker-pool applications. Such applications should use dynamic work assignment mechanisms, such as the [RabbitMQ work queues](https://www.rabbitmq.com/tutorials/tutorial-two-python.html), as opposed to static/one-time customization of the configuration of each pod, which is considered an anti-pattern. Any pod customization performed, such as vertical auto-sizing of resources (for example, cpu or memory), should be performed by another online controller process, not unlike the ReplicationController itself.
|
||||
-->
|
||||
## 编写多副本的应用
|
||||
|
||||
由 ReplicationController 创建的 Pod 是可替换的,语义上是相同的,尽管随着时间的推移,它们的配置可能会变得异构。
|
||||
这显然适合于多副本的无状态服务器,但是 ReplicationController 也可以用于维护主选、分片和工作池应用程序的可用性。
|
||||
这样的应用程序应该使用动态的工作分配机制,例如 [RabbitMQ工作队列](https://www.rabbitmq.com/tutorials/tutorial-two-python.html),而不是静态的/一次性定制每个 pod 的配置,这被认为是一种反模式。
|
||||
执行的任何 pod 定制,例如资源的垂直自动调整大小(例如,cpu 或内存),都应该由另一个在线控制器进程执行,这与 ReplicationController 本身没什么不同。
|
||||
|
||||
<!--
|
||||
## Responsibilities of the ReplicationController
|
||||
|
||||
The ReplicationController simply ensures that the desired number of pods matches its label selector and are operational. Currently, only terminated pods are excluded from its count. In the future, [readiness](http://issue.k8s.io/620) and other information available from the system may be taken into account, we may add more controls over the replacement policy, and we plan to emit events that could be used by external clients to implement arbitrarily sophisticated replacement and/or scale-down policies.
|
||||
|
||||
The ReplicationController is forever constrained to this narrow responsibility. It itself will not perform readiness nor liveness probes. Rather than performing auto-scaling, it is intended to be controlled by an external auto-scaler (as discussed in [#492](http://issue.k8s.io/492)), which would change its `replicas` field. We will not add scheduling policies (for example, [spreading](http://issue.k8s.io/367#issuecomment-48428019)) to the ReplicationController. Nor should it verify that the pods controlled match the currently specified template, as that would obstruct auto-sizing and other automated processes. Similarly, completion deadlines, ordering dependencies, configuration expansion, and other features belong elsewhere. We even plan to factor out the mechanism for bulk pod creation ([#170](http://issue.k8s.io/170)).
|
||||
|
||||
The ReplicationController is intended to be a composable building-block primitive. We expect higher-level APIs and/or tools to be built on top of it and other complementary primitives for user convenience in the future. The "macro" operations currently supported by kubectl (run, scale, rolling-update) are proof-of-concept examples of this. For instance, we could imagine something like [Asgard](http://techblog.netflix.com/2012/06/asgard-web-based-cloud-management-and.html) managing ReplicationControllers, auto-scalers, services, scheduling policies, canaries, etc.
|
||||
-->
|
||||
## ReplicationController 的职责
|
||||
|
||||
ReplicationController 只需确保所需的 pod 数量与其标签选择器匹配,并且是可操作的。
|
||||
目前,它的计数中只排除终止的 pod。
|
||||
未来,可能会考虑系统提供的[就绪状态](http://issue.k8s.io/620)和其他信息,我们可能会对替换策略添加更多控制,我们计划发出事件,这些事件可以被外部客户端用来实现任意复杂的替换和/或缩减策略。
|
||||
|
||||
ReplicationController 永远被限制在这个狭隘的职责范围内。
|
||||
它本身既不执行就绪态探测,也不执行活跃性探测。
|
||||
它不负责执行自动缩放,而是由外部自动缩放器控制(如[#492](http://issue.k8s.io/492)中所述),后者负责更改其 `replicas` 字段取值。
|
||||
我们不会向 ReplicationController 添加调度策略(例如,[spreading](http://issue.k8s.io/367#issuecomment-48428019))。
|
||||
它也不应该验证所控制的 pod 是否与当前指定的模板匹配,因为这会阻碍自动调整大小和其他自动化过程。
|
||||
类似地,完成期限、整理依赖关系、配置扩展和其他特性也属于其他地方。
|
||||
我们甚至计划考虑批量创建 pod 的机制([#170](http://issue.k8s.io/170))。
|
||||
|
||||
ReplicationController 旨在成为可组合的构建基元。
|
||||
我们希望在它和其他补充原语的基础上构建更高级别的 API 和/或工具,以便于将来的用户使用。
|
||||
Kubectl 目前支持的“宏”操作(运行、缩放、滚动更新)就是这方面的概念示例。
|
||||
例如,我们可以想象类似于 [Asgard](http://techblog.netflix.com/2012/06/asgaard-web-based-cloud-management-and.html) 的东西管理 ReplicationController、自动定标器、服务、调度策略、 canary 等。
|
||||
|
||||
<!--
|
||||
## API Object
|
||||
|
||||
Replication controller is a top-level resource in the Kubernetes REST API. More details about the
|
||||
API object can be found at:
|
||||
[ReplicationController API object](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#replicationcontroller-v1-core).
|
||||
-->
|
||||
## API 对象
|
||||
|
||||
在 Kubernetes REST API 中 Replication controller 是顶级资源。
|
||||
更多关于 API 对象的详细信息可以在
|
||||
[ReplicationController API 对象](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#replicationcontroller-v1-core)找到。
|
||||
|
||||
<!--
|
||||
## Alternatives to ReplicationController
|
||||
-->
|
||||
## ReplicationController 的替代方案
|
||||
|
||||
<!--
|
||||
### 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.
|
||||
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.
|
||||
-->
|
||||
### ReplicaSet
|
||||
|
||||
[`ReplicaSet`](/docs/concepts/workloads/controllers/replicaset/) 是下一代 ReplicationController ,支持新的[基于集合的标签选择器](/docs/concepts/overview/working-with-objects/labels/#set-based-requirement)。
|
||||
它主要被 [`Deployment`](/docs/concepts/workloads/controllers/deployment/) 用来作为一种编排 pod 创建、删除及更新的机制。
|
||||
请注意,我们推荐使用 Deployment 而不是直接使用 ReplicaSet,除非您需要自定义更新编排或根本不需要更新。
|
||||
|
||||
<!--
|
||||
### Deployment (Recommended)
|
||||
|
||||
[`Deployment`](/docs/concepts/workloads/controllers/deployment/) is a higher-level API object that updates its underlying Replica Sets and their Pods
|
||||
in a similar fashion as `kubectl rolling-update`. Deployments are recommended if you want this rolling update functionality,
|
||||
because unlike `kubectl rolling-update`, they are declarative, server-side, and have additional features.
|
||||
-->
|
||||
### Deployment (推荐)
|
||||
|
||||
[`Deployment`](/docs/concepts/workloads/controllers/deployment/) 是一种更高级别的 API 对象,它以类似于 `kubectl rolling-update` 的方式更新其底层 ReplicaSet 及其 Pod。
|
||||
如果您想要这种滚动更新功能,那么推荐使用 Deployment,因为与 `kubectl rolling-update` 不同,它们是声明式的、服务端的,并且具有其它特性。
|
||||
|
||||
<!--
|
||||
### Bare Pods
|
||||
|
||||
Unlike in the case where a user directly created pods, a ReplicationController replaces pods that are deleted or terminated for any reason, such as in the case of node failure or disruptive node maintenance, such as a kernel upgrade. For this reason, we recommend that you use a ReplicationController even if your application requires only a single pod. Think of it similarly to a process supervisor, only it supervises multiple pods across multiple nodes instead of individual processes on a single node. A ReplicationController delegates local container restarts to some agent on the node (for example, Kubelet or Docker).
|
||||
-->
|
||||
### 裸 Pods
|
||||
|
||||
与用户直接创建 pod 的情况不同,ReplicationController 能够替换因某些原因被删除或被终止的 pod ,例如在节点故障或中断节点维护的情况下,例如内核升级。
|
||||
因此,我们建议您使用 ReplicationController,即使您的应用程序只需要一个 pod。
|
||||
可以将其看作类似于进程管理器,它只管理跨多个节点的多个 pod ,而不是单个节点上的单个进程。
|
||||
ReplicationController 将本地容器重启委托给节点上的某个代理(例如,Kubelet 或 Docker)。
|
||||
|
||||
<!--
|
||||
### Job
|
||||
|
||||
Use a [`Job`](/docs/concepts/jobs/run-to-completion-finite-workloads/) instead of a ReplicationController for pods that are expected to terminate on their own
|
||||
(that is, batch jobs).
|
||||
-->
|
||||
### Job
|
||||
|
||||
对于预期会自行终止的 pod (即批处理任务),使用 [`Job`](/docs/concepts/jobs/run-to-completion-finite-workloads/) 而不是 ReplicationController。
|
||||
|
||||
<!--
|
||||
### DaemonSet
|
||||
|
||||
Use a [`DaemonSet`](/docs/concepts/workloads/controllers/daemonset/) instead of a ReplicationController for pods that provide a
|
||||
machine-level function, such as machine monitoring or machine logging. These pods have a lifetime that is tied
|
||||
to a machine lifetime: the pod needs to be running on the machine before other pods start, and are
|
||||
safe to terminate when the machine is otherwise ready to be rebooted/shutdown.
|
||||
-->
|
||||
### DaemonSet
|
||||
|
||||
对于提供机器级功能(例如机器监控或机器日志记录)的 pod ,使用 [`DaemonSet`](/docs/concepts/workloads/controllers/daemonset/) 而不是 ReplicationController。
|
||||
这些 pod 的生命期与机器的生命期绑定:它们需要在其他 pod 启动之前在机器上运行,并且在机器准备重新启动/关闭时安全地终止。
|
||||
|
||||
<!--
|
||||
## For more information
|
||||
|
||||
Read [Run Stateless AP Replication Controller](/docs/tutorials/stateless-application/run-stateless-ap-replication-controller/).
|
||||
-->
|
||||
## 更多信息
|
||||
|
||||
请阅读[运行无状态的 Replication Controller](/docs/tutorials/stateless-application/run-stateless-ap-replication-controller/)。
|
||||
|
||||
{{% /capture %}}
|
||||
@@ -0,0 +1,457 @@
|
||||
---
|
||||
reviewers:
|
||||
- enisoc
|
||||
- erictune
|
||||
- foxish
|
||||
- janetkuo
|
||||
- kow3ns
|
||||
- smarterclayton
|
||||
title: StatefulSets
|
||||
content_template: templates/concept
|
||||
weight: 40
|
||||
---
|
||||
|
||||
<!--
|
||||
---
|
||||
reviewers:
|
||||
- enisoc
|
||||
- erictune
|
||||
- foxish
|
||||
- janetkuo
|
||||
- kow3ns
|
||||
- smarterclayton
|
||||
title: StatefulSets
|
||||
content_template: templates/concept
|
||||
weight: 40
|
||||
---
|
||||
-->
|
||||
|
||||
{{% capture overview %}}
|
||||
|
||||
<!--
|
||||
StatefulSet is the workload API object used to manage stateful applications.
|
||||
-->
|
||||
|
||||
StatefulSet 是用来管理有状态应用的工作负载 API 对象。
|
||||
|
||||
{{< note >}}
|
||||
|
||||
<!--**Note:** StatefulSets are stable (GA) in 1.9.-->
|
||||
**注意** StatefulSets 是在 1.9 版本中正式发布的。
|
||||
|
||||
{{< /note >}}
|
||||
|
||||
{{< glossary_definition term_id="statefulset" length="all" >}}
|
||||
{{% /capture %}}
|
||||
|
||||
{{% capture body %}}
|
||||
|
||||
<!--
|
||||
## Using StatefulSets
|
||||
|
||||
StatefulSets are valuable for applications that require one or more of the
|
||||
following.
|
||||
|
||||
* Stable, unique network identifiers.
|
||||
* Stable, persistent storage.
|
||||
* Ordered, graceful deployment and scaling.
|
||||
* Ordered, automated rolling updates.
|
||||
|
||||
In the above, stable is synonymous with persistence across Pod (re)scheduling.
|
||||
If an application doesn't require any stable identifiers or ordered deployment,
|
||||
deletion, or scaling, you should deploy your application using a workload object
|
||||
that provides a set of stateless replicas.
|
||||
[Deployment](/docs/concepts/workloads/controllers/deployment/) or
|
||||
[ReplicaSet](/docs/concepts/workloads/controllers/replicaset/) may be better suited to your stateless needs.
|
||||
-->
|
||||
|
||||
## 使用 StatefulSets
|
||||
|
||||
StatefulSets 对于需要满足以下一个或多个需求的应用程序很有价值:
|
||||
|
||||
* 稳定的、唯一的网络标识符。
|
||||
* 稳定的、持久的存储。
|
||||
* 有序的、优雅的部署和缩放。
|
||||
* 有序的、自动的滚动更新。
|
||||
|
||||
在上面,稳定意味着 Pod 调度或重调度的整个过程是有持久性的。如果应用程序不需要任何稳定的标识符或有序的部署、删除或伸缩,则应该使用由一组无状态的副本控制器提供的工作负载来部署应用程序,比如 [Deployment](/docs/concepts/workloads/controllers/deployment/) 或者 [ReplicaSet](/docs/concepts/workloads/controllers/replicaset/) 可能更适用于您的无状态需要。
|
||||
|
||||
<!--
|
||||
## Limitations
|
||||
|
||||
* The storage for a given Pod must either be provisioned by a [PersistentVolume Provisioner](https://github.com/kubernetes/examples/tree/{{< param "githubbranch" >}}/staging/persistent-volume-provisioning/README.md) based on the requested `storage class`, or pre-provisioned by an admin.
|
||||
* Deleting and/or scaling a StatefulSet down will *not* delete the volumes associated with the StatefulSet. This is done to ensure data safety, which is generally more valuable than an automatic purge of all related StatefulSet resources.
|
||||
* StatefulSets currently require a [Headless Service](/docs/concepts/services-networking/service/#headless-services) to be responsible for the network identity of the Pods. You are responsible for creating this Service.
|
||||
* StatefulSets do not provide any guarantees on the termination of pods when a StatefulSet is deleted. To achieve ordered and graceful termination of the pods in the StatefulSet, it is possible to scale the StatefulSet down to 0 prior to deletion.
|
||||
* When using [Rolling Updates](#rolling-updates) with the default
|
||||
[Pod Management Policy](#pod-management-policies) (`OrderedReady`),
|
||||
it's possible to get into a broken state that requires
|
||||
[manual intervention to repair](#forced-rollback).
|
||||
|
||||
-->
|
||||
|
||||
## 限制
|
||||
|
||||
* 给定 Pod 的存储必须由 [PersistentVolume 驱动](https://github.com/kubernetes/examples/tree/{{< param "githubbranch" >}}/staging/persistent-volume-provisioning/README.md) 基于所请求的 `storage class` 来提供,或者由管理员预先提供。
|
||||
* 删除和/或收缩 StatefulSet 并*不会*删除它关联的存储卷。这样做是为了保证数据安全,它通常比自动清除 StatefulSet 所有相关的资源更有价值。
|
||||
* StatefulSet 当前需要 [headless 服务](/docs/concepts/services-networking/service/#headless-services) 来负责 Pod 的网络标识。您需要负责创建此服务。
|
||||
* 当删除 StatefulSets 时,StatefulSet 不提供任何终止 Pod 的保证。为了实现 StatefulSet 中的 Pod 可以有序和优雅的终止,可以在删除之前将 StatefulSet 缩放为 0。
|
||||
* 在默认 [Pod 管理策略](#pod-management-policies)(`OrderedReady`) 时使用 [滚动更新](#rolling-updates),可能进入需要 [人工干预](#forced-rollback) 才能修复的损坏状态。
|
||||
|
||||
<!--
|
||||
## Components
|
||||
The example below demonstrates the components of a StatefulSet.
|
||||
|
||||
* A Headless Service, named nginx, is used to control the network domain.
|
||||
* The StatefulSet, named web, has a Spec that indicates that 3 replicas of the nginx container will be launched in unique Pods.
|
||||
* The volumeClaimTemplates will provide stable storage using [PersistentVolumes](/docs/concepts/storage/persistent-volumes/) provisioned by a PersistentVolume Provisioner.
|
||||
-->
|
||||
|
||||
## 组件
|
||||
下面的示例演示了 StatefulSet 的组件。
|
||||
|
||||
* 名为 nginx 的无头服务用来控制网络域。
|
||||
* 名为 web 的 StatefulSet 有一个 Spec,它表明将在单个 Pod 中启动 nginx 容器的 3 个副本。
|
||||
* volumeClaimTemplates 将通过 [PersistentVolumes](/docs/concepts/storage/persistent-volumes/) 驱动提供的 PersistentVolume 来提供稳定的存储。
|
||||
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: nginx
|
||||
labels:
|
||||
app: nginx
|
||||
spec:
|
||||
ports:
|
||||
- port: 80
|
||||
name: web
|
||||
clusterIP: None
|
||||
selector:
|
||||
app: nginx
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: StatefulSet
|
||||
metadata:
|
||||
name: web
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
app: nginx # has to match .spec.template.metadata.labels
|
||||
serviceName: "nginx"
|
||||
replicas: 3 # by default is 1
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: nginx # has to match .spec.selector.matchLabels
|
||||
spec:
|
||||
terminationGracePeriodSeconds: 10
|
||||
containers:
|
||||
- name: nginx
|
||||
image: k8s.gcr.io/nginx-slim:0.8
|
||||
ports:
|
||||
- containerPort: 80
|
||||
name: web
|
||||
volumeMounts:
|
||||
- name: www
|
||||
mountPath: /usr/share/nginx/html
|
||||
volumeClaimTemplates:
|
||||
- metadata:
|
||||
name: www
|
||||
spec:
|
||||
accessModes: [ "ReadWriteOnce" ]
|
||||
storageClassName: "my-storage-class"
|
||||
resources:
|
||||
requests:
|
||||
storage: 1Gi
|
||||
```
|
||||
|
||||
<!--
|
||||
## Pod Selector
|
||||
You must set the `.spec.selector` field of a StatefulSet to match the labels of its `.spec.template.metadata.labels`. Prior to Kubernetes 1.8, the `.spec.selector` field was defaulted when omitted. In 1.8 and later versions, failing to specify a matching Pod Selector will result in a validation error during StatefulSet creation.
|
||||
-->
|
||||
|
||||
## Pod 选择器
|
||||
您必须设置 StatefulSet 的 `.spec.selector` 字段来匹配它的`.spec.template.metadata.labels`标签。在 Kubernetes 1.8 版本之前,忽略`.spec.selector` 字段会提供默认设置。在 1.8 和以后的版本中,指定的 Pod 选择器匹配失败将在创建 StatefulSet 期间导致验证错误。
|
||||
|
||||
<!--
|
||||
## Pod Identity
|
||||
StatefulSet Pods have a unique identity that is comprised of an ordinal, a
|
||||
stable network identity, and stable storage. The identity sticks to the Pod,
|
||||
regardless of which node it's (re)scheduled on.
|
||||
-->
|
||||
|
||||
## Pod 的身份
|
||||
|
||||
StatefulSet Pod 具有唯一的标识,该标识包括顺序标识、稳定的网络标识和稳定的存储。该标识和 Pod 是绑定的,不管它被调度在哪个节点上。
|
||||
|
||||
<!--
|
||||
### Ordinal Index
|
||||
|
||||
For a StatefulSet with N replicas, each Pod in the StatefulSet will be
|
||||
assigned an integer ordinal, from 0 up through N-1, that is unique over the Set.
|
||||
-->
|
||||
|
||||
### 有序索引
|
||||
|
||||
对于具有 N 个副本的 StatefulSet,StatefulSet 中的每个 Pod 将被分配一个整数序号,从 0 到 N-1,该序号在 StatefulSet 上是唯一的。
|
||||
|
||||
<!--
|
||||
### Stable Network ID
|
||||
|
||||
Each Pod in a StatefulSet derives its hostname from the name of the StatefulSet
|
||||
and the ordinal of the Pod. The pattern for the constructed hostname
|
||||
is `$(statefulset name)-$(ordinal)`. The example above will create three Pods
|
||||
named `web-0,web-1,web-2`.
|
||||
A StatefulSet can use a [Headless Service](/docs/concepts/services-networking/service/#headless-services)
|
||||
to control the domain of its Pods. The domain managed by this Service takes the form:
|
||||
`$(service name).$(namespace).svc.cluster.local`, where "cluster.local" is the
|
||||
cluster domain.
|
||||
As each Pod is created, it gets a matching DNS subdomain, taking the form:
|
||||
`$(podname).$(governing service domain)`, where the governing service is defined
|
||||
by the `serviceName` field on the StatefulSet.
|
||||
-->
|
||||
|
||||
### 稳定的网络 ID
|
||||
|
||||
StatefulSet 中的每个 Pod 根据 StatefulSet 的名称和 Pod 的序号派生出它的主机名。组合主机名的格式为`$(statefulset name)-$(ordinal)`。上例将会创建三个名称为`web-0,web-1,web-2`的三个 Pod。
|
||||
StatefulSet 可以使用 [headless 服务](/docs/concepts/services-networking/service/#headless-services) 控制它的 Pod 的网络域。管理域的这个服务的格式为:
|
||||
`$(service name).$(namespace).svc.cluster.local`,其中`cluster.local`是集群域。
|
||||
一旦每个 Pod 创建成功,就会得到一个匹配的 DNS 子域,格式为:`$(podname).$(governing service domain)`,其中管理服务由 StatefulSet 的 `serviceName` 域来定义。
|
||||
|
||||
|
||||
<!--
|
||||
Here are some examples of choices for Cluster Domain, Service name,
|
||||
StatefulSet name, and how that affects the DNS names for the StatefulSet's Pods.
|
||||
-->
|
||||
|
||||
下面给出一些选择集群域、服务名、StatefulSet 名、及其怎样影响 StatefulSet 的 Pod 上的 DNS 名称的示例:
|
||||
|
||||
Cluster Domain | Service (ns/name) | StatefulSet (ns/name) | StatefulSet Domain | Pod DNS | Pod Hostname |
|
||||
-------------- | ----------------- | ----------------- | -------------- | ------- | ------------ |
|
||||
cluster.local | default/nginx | default/web | nginx.default.svc.cluster.local | web-{0..N-1}.nginx.default.svc.cluster.local | web-{0..N-1} |
|
||||
cluster.local | foo/nginx | foo/web | nginx.foo.svc.cluster.local | web-{0..N-1}.nginx.foo.svc.cluster.local | web-{0..N-1} |
|
||||
kube.local | foo/nginx | foo/web | nginx.foo.svc.kube.local | web-{0..N-1}.nginx.foo.svc.kube.local | web-{0..N-1} |
|
||||
|
||||
{{< note >}}
|
||||
|
||||
<!--
|
||||
**Note:** Cluster Domain will be set to `cluster.local` unless
|
||||
[otherwise configured](/docs/concepts/services-networking/dns-pod-service/#how-it-works).
|
||||
-->
|
||||
**注意** 集群域会被设置为 `cluster.local` 除非有[其他配置](/docs/concepts/services-networking/dns-pod-service/#how-it-works)。
|
||||
|
||||
{{< /note >}}
|
||||
|
||||
<!--
|
||||
### Stable Storage
|
||||
|
||||
Kubernetes creates one [PersistentVolume](/docs/concepts/storage/persistent-volumes/) for each
|
||||
VolumeClaimTemplate. In the nginx example above, each Pod will receive a single PersistentVolume
|
||||
with a StorageClass of `my-storage-class` and 1 Gib of provisioned storage. If no StorageClass
|
||||
is specified, then the default StorageClass will be used. When a Pod is (re)scheduled
|
||||
onto a node, its `volumeMounts` mount the PersistentVolumes associated with its
|
||||
PersistentVolume Claims. Note that, the PersistentVolumes associated with the
|
||||
Pods' PersistentVolume Claims are not deleted when the Pods, or StatefulSet are deleted.
|
||||
This must be done manually.
|
||||
-->
|
||||
|
||||
### 稳定的存储
|
||||
|
||||
Kubernetes 为每个 VolumeClaimTemplate 创建一个 [PersistentVolume](/docs/concepts/storage/persistent-volumes/)。在上面的 nginx 示例中,每个 Pod 将会得到基于 StorageClass `my-storage-class` 提供的 1 Gib 的 PersistentVolume。如果没有声明 StorageClass,就会使用默认的 StorageClass。当一个 Pod 被安排到节点上时,它的 `volumeMounts` 挂载了与其 PersistentVolumeClaims 相关联的 PersistentVolume。请注意,当 Pod 或者 StatefulSet 被删除时,与 PersistentVolumeClaims 相关联的 PersistentVolume 并不会被删除。要删除它必须通过手动方式来完成。
|
||||
|
||||
|
||||
<!--
|
||||
### Pod Name Label
|
||||
|
||||
When the StatefulSet {{< glossary_tooltip term_id="controller" >}} creates a Pod,
|
||||
it adds a label, `statefulset.kubernetes.io/pod-name`, that is set to the name of
|
||||
the Pod. This label allows you to attach a Service to a specific Pod in
|
||||
the StatefulSet.
|
||||
-->
|
||||
|
||||
### Pod 名称标签
|
||||
|
||||
当 StatefulSet {{< glossary_tooltip term_id="controller" >}} 创建 Pod 时,它会添加一个标签 `statefulset.kubernetes.io/pod-name`,该标签设置为 Pod 名称。这个标签允许您给 StatefulSet 中的特定 Pod 绑定一个 Service。
|
||||
|
||||
<!--
|
||||
## Deployment and Scaling Guarantees
|
||||
|
||||
* For a StatefulSet with N replicas, when Pods are being deployed, they are created sequentially, in order from {0..N-1}.
|
||||
* When Pods are being deleted, they are terminated in reverse order, from {N-1..0}.
|
||||
* Before a scaling operation is applied to a Pod, all of its predecessors must be Running and Ready.
|
||||
* Before a Pod is terminated, all of its successors must be completely shutdown.
|
||||
-->
|
||||
|
||||
## 部署和伸缩保证
|
||||
|
||||
* 对于包含 N 个 副本的 StatefulSet,当部署 Pod 时,它们是依次创建的,顺序为`0..N-1`。
|
||||
* 当删除 Pod 时,它们是逆序终止的,顺序为`N-1..0`。
|
||||
* 在将缩放操作应用到 Pod 之前,它前面的所有 Pod 必须是 Running 和 Ready 状态。
|
||||
* 在 Pod 终止之前,所有的继任者必须完全关闭。
|
||||
|
||||
<!--
|
||||
The StatefulSet should not specify a `pod.Spec.TerminationGracePeriodSeconds` of 0. This practice is unsafe and strongly discouraged. For further explanation, please refer to [force deleting StatefulSet Pods](/docs/tasks/run-application/force-delete-stateful-set-pod/).
|
||||
-->
|
||||
|
||||
StatefulSet 不应该声明 `pod.Spec.TerminationGracePeriodSeconds` 为 0。这种做法是不安全的,要强烈阻止。更多的解释请参考 [强制删除 StatefulSet Pods](/docs/tasks/run-application/force-delete-stateful-set-pod/)。
|
||||
|
||||
<!--
|
||||
When the nginx example above is created, three Pods will be deployed in the order
|
||||
web-0, web-1, web-2. web-1 will not be deployed before web-0 is
|
||||
[Running and Ready](/docs/user-guide/pod-states/), and web-2 will not be deployed until
|
||||
web-1 is Running and Ready. If web-0 should fail, after web-1 is Running and Ready, but before
|
||||
web-2 is launched, web-2 will not be launched until web-0 is successfully relaunched and
|
||||
becomes Running and Ready.
|
||||
-->
|
||||
|
||||
在上面的 nginx 示例被创建后,会按照 web-0、web-1、web-2 的顺序部署三个 Pod。在 web-0 进入 [Running 和 Ready](/docs/user-guide/pod-states/) 状态前不会部署 web-1。在 web-1 进入 Running 和 Ready 状态前不会部署 web-2。如果 web-1 已经处于 Running 和 Ready 状态,而 web-2 尚未部署,在此期间发生了 web-0 运行失败,那么 web-2 将不会被部署,要等到 web-0 部署完成并进入 Running 和 Ready 状态后,才会部署 web-2。
|
||||
|
||||
<!--
|
||||
If a user were to scale the deployed example by patching the StatefulSet such that
|
||||
`replicas=1`, web-2 would be terminated first. web-1 would not be terminated until web-2
|
||||
is fully shutdown and deleted. If web-0 were to fail after web-2 has been terminated and
|
||||
is completely shutdown, but prior to web-1's termination, web-1 would not be terminated
|
||||
until web-0 is Running and Ready.
|
||||
-->
|
||||
|
||||
如果用户想将示例中的 StatefulSet 收缩为 `replicas=1`,首先被终止的是 web-2。在 web-2 没有被完全停止和删除前,web-1 不会被终止。当 web-2 已被终止和删除、web-1 尚未被终止,如果在此期间发生 web-0 运行失败,那么就不会终止 web-1,必须等到 web-0 进入 Running 和 Ready 状态后才会终止 web-1。
|
||||
|
||||
<!--
|
||||
### Pod Management Policies
|
||||
In Kubernetes 1.7 and later, StatefulSet allows you to relax its ordering guarantees while
|
||||
preserving its uniqueness and identity guarantees via its `.spec.podManagementPolicy` field.
|
||||
|
||||
#### OrderedReady Pod Management
|
||||
|
||||
`OrderedReady` pod management is the default for StatefulSets. It implements the behavior
|
||||
described [above](#deployment-and-scaling-guarantees).
|
||||
|
||||
#### Parallel Pod Management
|
||||
|
||||
`Parallel` pod management tells the StatefulSet controller to launch or
|
||||
terminate all Pods in parallel, and to not wait for Pods to become Running
|
||||
and Ready or completely terminated prior to launching or terminating another
|
||||
Pod.
|
||||
-->
|
||||
|
||||
### Pod 管理策略 {#pod-management-policies}
|
||||
在 Kubernetes 1.7 及以后的版本中,StatefulSet 允许您放松其排序保证,同时通过它的 `.spec.podManagementPolicy` 域保持其唯一性和身份保证。
|
||||
|
||||
#### 有序的 Pod 管理
|
||||
|
||||
`有序的` Pod 管理是 StatefulSet 的默认功能。它实现了 [上面](#deployment-and-scaling-guarantees)描述的行为。
|
||||
|
||||
#### 并行的 Pod 管理
|
||||
|
||||
`并行` Pod 管理让 StatefulSet 控制器并行的启动或终止所有的 Pod,启动或者终止其他 Pod 前,无需等待 Pod 进入 Running 和 ready 或者完全停止状态。
|
||||
|
||||
<!--
|
||||
## Update Strategies
|
||||
|
||||
In Kubernetes 1.7 and later, StatefulSet's `.spec.updateStrategy` field allows you to configure
|
||||
and disable automated rolling updates for containers, labels, resource request/limits, and
|
||||
annotations for the Pods in a StatefulSet.
|
||||
-->
|
||||
|
||||
## 更新策略
|
||||
|
||||
在 Kubernetes 1.7 及以后的版本中,StatefulSet 的 `.spec.updateStrategy` 字段让您可以配置和禁用掉自动滚动更新 Pod 的容器、标签、资源请求/限制、以及注解。
|
||||
|
||||
|
||||
<!--
|
||||
### On Delete
|
||||
|
||||
The `OnDelete` update strategy implements the legacy (1.6 and prior) behavior. When a StatefulSet's
|
||||
`.spec.updateStrategy.type` is set to `OnDelete`, the StatefulSet controller will not automatically
|
||||
update the Pods in a StatefulSet. Users must manually delete Pods to cause the controller to
|
||||
create new Pods that reflect modifications made to a StatefulSet's `.spec.template`.
|
||||
-->
|
||||
|
||||
### On Delete
|
||||
|
||||
`OnDelete` 更新策略实现了 1.6 及以前版本的历史遗留行为。当 StatefulSet 的 `.spec.updateStrategy.type` 设置为 `OnDelete` 时,它的控制器将不会自动更新 StatefulSet 中的 Pod。用户必须手动删除 Pod 以便让控制器创建新的 Pod,以此来对 StatefulSet 的 `.spec.template` 的变动作出反应。
|
||||
|
||||
|
||||
<!--
|
||||
### Rolling Updates
|
||||
|
||||
The `RollingUpdate` update strategy implements automated, rolling update for the Pods in a
|
||||
StatefulSet. It is the default strategy when `.spec.updateStrategy` is left unspecified. When a StatefulSet's `.spec.updateStrategy.type` is set to `RollingUpdate`, the
|
||||
StatefulSet controller will delete and recreate each Pod in the StatefulSet. It will proceed
|
||||
in the same order as Pod termination (from the largest ordinal to the smallest), updating
|
||||
each Pod one at a time. It will wait until an updated Pod is Running and Ready prior to
|
||||
updating its predecessor.
|
||||
-->
|
||||
|
||||
### 滚动更新 {#rolling-updates}
|
||||
|
||||
`RollingUpdate` 更新策略对 StatefulSet 中的 Pod 执行自动的滚动更新。在没有声明`.spec.updateStrategy`时,`RollingUpdate`是默认配置。
|
||||
当 StatefulSet 的 `.spec.updateStrategy.type` 被设置为 `RollingUpdate` 时,StatefulSet 控制器会删除和重建 StatefulSet 中的每个 Pod。
|
||||
它将按照与 Pod 终止相同的顺序(从最大序号到最小序号)进行,每次更新一个 Pod。它会等到被更新的 Pod 进入 Running 和 Ready 状态,然后再更新其前身。
|
||||
|
||||
<!--
|
||||
#### Partitions
|
||||
|
||||
The `RollingUpdate` update strategy can be partitioned, by specifying a
|
||||
`.spec.updateStrategy.rollingUpdate.partition`. If a partition is specified, all Pods with an
|
||||
ordinal that is greater than or equal to the partition will be updated when the StatefulSet's
|
||||
`.spec.template` is updated. All Pods with an ordinal that is less than the partition will not
|
||||
be updated, and, even if they are deleted, they will be recreated at the previous version. If a
|
||||
StatefulSet's `.spec.updateStrategy.rollingUpdate.partition` is greater than its `.spec.replicas`,
|
||||
updates to its `.spec.template` will not be propagated to its Pods.
|
||||
In most cases you will not need to use a partition, but they are useful if you want to stage an
|
||||
update, roll out a canary, or perform a phased roll out.
|
||||
-->
|
||||
|
||||
#### 分区
|
||||
|
||||
通过声明 `.spec.updateStrategy.rollingUpdate.partition`的方式,`RollingUpdate`更新策略可以实现分区。如果声明了一个分区,当 StatefulSet 的`.spec.template` 被更新时,所有序号大于等于该分区序号的 Pod 都会被更新。所有序号小于该分区序号的 Pod 都不会被更新,并且,即使他们被删除也会依据之前的版本进行重建。如果 StatefulSet 的 `.spec.updateStrategy.rollingUpdate.partition` 大于它的 `.spec.replicas`,对它的 `.spec.template` 的更新将不会传递到它的 Pod。
|
||||
在大多数情况下,您不需要使用分区,但如果您希望进行阶段更新、执行金丝雀或执行分阶段展开,则这些分区会非常有用。
|
||||
|
||||
<!--
|
||||
#### Forced Rollback
|
||||
|
||||
When using [Rolling Updates](#rolling-updates) with the default
|
||||
[Pod Management Policy](#pod-management-policies) (`OrderedReady`),
|
||||
it's possible to get into a broken state that requires manual intervention to repair.
|
||||
|
||||
If you update the Pod template to a configuration that never becomes Running and
|
||||
Ready (for example, due to a bad binary or application-level configuration error),
|
||||
StatefulSet will stop the rollout and wait.
|
||||
|
||||
In this state, it's not enough to revert the Pod template to a good configuration.
|
||||
Due to a [known issue](https://github.com/kubernetes/kubernetes/issues/67250),
|
||||
StatefulSet will continue to wait for the broken Pod to become Ready
|
||||
(which never happens) before it will attempt to revert it back to the working
|
||||
configuration.
|
||||
|
||||
After reverting the template, you must also delete any Pods that StatefulSet had
|
||||
already attempted to run with the bad configuration.
|
||||
StatefulSet will then begin to recreate the Pods using the reverted template.
|
||||
-->
|
||||
#### 强制回滚 {#forced-rollback}
|
||||
|
||||
在默认 [Pod 管理策略](#pod-management-policies)(`OrderedReady`) 时使用 [滚动更新](#rolling-updates) ,可能进入需要人工干预才能修复的损坏状态。
|
||||
|
||||
如果更新后 Pod 模板配置进入无法运行或就绪的状态(例如,由于错误的二进制文件或应用程序级配置错误),StatefulSet 将停止回滚并等待。
|
||||
|
||||
在这种状态下,仅将 Pod 模板还原为正确的配置是不够的。由于 [已知问题](https://github.com/kubernetes/kubernetes/issues/67250),
|
||||
StatefulSet 将继续等待损坏状态的 Pod 准备就绪(永远不会发生),然后再尝试将其恢复为正常工作配置。
|
||||
|
||||
恢复模板后,还必须删除 StatefulSet 尝试使用错误的配置来运行的 Pod。这样,StatefulSet 才会开始使用被还原的模板来重新创建 Pod。
|
||||
|
||||
{{% /capture %}}
|
||||
{{% capture whatsnext %}}
|
||||
|
||||
<!--
|
||||
* Follow an example of [deploying a stateful application](/docs/tutorials/stateful-application/basic-stateful-set/).
|
||||
* Follow an example of [deploying Cassandra with Stateful Sets](/docs/tutorials/stateful-application/cassandra/).
|
||||
-->
|
||||
|
||||
* 示例一:[部署有状态应用](/docs/tutorials/stateful-application/basic-stateful-set/)。
|
||||
* 示例二:[使用 StatefulSet 部署 Cassandra](/docs/tutorials/stateful-application/cassandra/)。
|
||||
|
||||
|
||||
{{% /capture %}}
|
||||
|
||||
@@ -0,0 +1,120 @@
|
||||
---
|
||||
reviewers:
|
||||
- janetkuo
|
||||
title: 已完成资源的 TTL 控制器
|
||||
content_template: templates/concept
|
||||
weight: 65
|
||||
---
|
||||
<!--
|
||||
---
|
||||
reviewers:
|
||||
- janetkuo
|
||||
title: TTL Controller for Finished Resources
|
||||
content_template: templates/concept
|
||||
weight: 65
|
||||
---
|
||||
-->
|
||||
|
||||
{{% capture overview %}}
|
||||
|
||||
{{< feature-state for_k8s_version="v1.12" state="alpha" >}}
|
||||
|
||||
<!--
|
||||
The TTL controller provides a TTL mechanism to limit the lifetime of resource objects that have finished execution. TTL controller only handles[Jobs](/docs/concepts/workloads/controllers/jobs-run-to-completion/) for now, and may be expanded to handle other resources that will finish execution,such as Pods and custom resources.
|
||||
-->
|
||||
TTL 控制器提供了一种 TTL 机制来限制已完成执行的资源对象的生命周期。TTL 控制器目前只处理[作业](/docs/concepts/workloads/controllers/jobs-run-to-completion/),可能以后会扩展以处理将完成执行的其他资源,例如 Pod 和自定义资源。
|
||||
|
||||
<!--
|
||||
Alpha Disclaimer: this feature is currently alpha, and can be enabled with[feature gate](/docs/reference/command-line-tools-reference/feature-gates/)`TTLAfterFinished`.
|
||||
-->
|
||||
Alpha 免责声明:此功能目前是 alpha 版,可以通过[feature gate](/docs/reference/command-line-tools-reference/feature-gates/) `TTLAfterFinished` 启用。
|
||||
|
||||
|
||||
{{% /capture %}}
|
||||
|
||||
|
||||
{{% capture body %}}
|
||||
|
||||
<!--
|
||||
## TTL Controller
|
||||
-->
|
||||
## TTL 控制器
|
||||
|
||||
<!--
|
||||
The TTL controller only supports Jobs for now. A cluster operator can use this feature to cleanup finished Jobs (either `Complete` or `Failed`) automatically by specifying the`.spec.ttlSecondsAfterFinished` field of a Job, as in this[example](/docs/concepts/workloads/controllers/jobs-run-to-completion/#clean-up-finished-jobs-automatically).
|
||||
-->
|
||||
TTL 控制器现在只支持 Jobs。集群操作员可以通过指定 Job 的 `.spec.ttlSecondsAfterFinished` 字段来自动清理已结束的作业(“完成”或“失败”),就像下边的[示例](/docs/concepts/workloads/controllers/jobs-run-to-completion/#clean-up-finished-jobs-automatically)。
|
||||
<!--
|
||||
The TTL controller will assume that a resource is eligible to be cleaned upTTL seconds after the resource has finished, in other words, when the TTL has expired. When the TTL controller cleans up a resource, it will delete it cascadingly, i.e. delete its dependent objects together with it. Note that when the resource is deleted,its lifecycle guarantees, such as finalizers, will be honored.
|
||||
-->
|
||||
TTL 控制器假设资源能在执行完成后的 TTL 秒内被清理,也就是当 TTL 过期后。当 TTL 控制器清理资源时,它将做级联删除,即删除资源对象的同时也删除其依赖对象。注意,当资源被删除时,由该资源的生命周期保证其终结器(finalizers)等被执行。
|
||||
|
||||
<!--
|
||||
The TTL seconds can be set at any time. Here are some examples for setting the`.spec.ttlSecondsAfterFinished` field of a Job:
|
||||
-->
|
||||
可以随时设置 TTL 秒。以下是设置 Job 的 `.spec.ttlSecondsAfterFinished` 字段的一些示例:
|
||||
|
||||
<!--
|
||||
* Specify this field in the resource manifest, so that a Job can be cleaned up
|
||||
automatically some time after it finishes.
|
||||
* Set this field of existing, already finished resources, to adopt this new
|
||||
feature.
|
||||
* Use a
|
||||
[mutating admission webhook](/docs/reference/access-authn-authz/extensible-admission-controllers/#admission-webhooks)
|
||||
to set this field dynamically at resource creation time. Cluster administrators can
|
||||
use this to enforce a TTL policy for finished resources.
|
||||
* Use a
|
||||
[mutating admission webhook](/docs/reference/access-authn-authz/extensible-admission-controllers/#admission-webhooks)
|
||||
to set this field dynamically after the resource has finished, and choose
|
||||
different TTL values based on resource status, labels, etc.
|
||||
-->
|
||||
* 在资源清单(manifest)中指定此字段,以便作业在完成后的某个时间被自动清除。
|
||||
* 将此字段设置为存在的、已完成的资源,以采用此新功能。
|
||||
* 在资源创建时使用 [mutating admission webhook](/docs/reference/access-authn-authz/extensible-admission-controllers/#admission-webhooks) 动态设置该字段。集群管理员可以使用它对完成的资源强制执行 TTL 策略。
|
||||
* 使用 [mutating admission webhook](/docs/reference/access-authn-authz/extensible-admission-controllers/#admission-webhooks) 在资源完成后动态设置该字段,并根据资源状态、标签等选择不同的 TTL 值。
|
||||
|
||||
<!--
|
||||
## Caveat
|
||||
-->
|
||||
## 警告
|
||||
|
||||
<!--
|
||||
### Updating TTL Seconds
|
||||
-->
|
||||
### 更新 TTL 秒
|
||||
|
||||
<!--
|
||||
Note that the TTL period, e.g. `.spec.ttlSecondsAfterFinished` field of Jobs,can be modified after the resource is created or has finished. However, once the Job becomes eligible to be deleted (when the TTL has expired), the system won't guarantee that the Jobs will be kept, even if an update to extend the TTL returns a successful API response.
|
||||
-->
|
||||
请注意,在创建资源后或已经执行结束后,仍可以修改其 TTL 周期,例如作业的 `.spec.ttlSecondsAfterFinished` 字段。但是,一旦作业变为可被删除状态(当其 TTL 已过期时),即使您通过 API 扩展其 TTL 时长得到了成功的响应,系统也不保证作业将被保留。
|
||||
|
||||
<!--
|
||||
### Time Skew
|
||||
-->
|
||||
### 时间偏差
|
||||
|
||||
<!--
|
||||
Because TTL controller uses timestamps stored in the Kubernetes resources to determine whether the TTL has expired or not, this feature is sensitive to time skew in the cluster, which may cause TTL controller to clean up resource objects at the wrong time.
|
||||
-->
|
||||
由于 TTL 控制器使用存储在 Kubernetes 资源中的时间戳来确定 TTL 是否已过期,因此该功能对集群中的时间偏差很敏感,这可能导致 TTL 控制器在错误的时间清理资源对象。
|
||||
|
||||
<!--
|
||||
In Kubernetes, it's required to run NTP on all nodes(see [#6159](https://github.com/kubernetes/kubernetes/issues/6159#issuecomment-93844058))to avoid time skew. Clocks aren't always correct, but the difference should bevery small. Please be aware of this risk when setting a non-zero TTL.
|
||||
-->
|
||||
在 Kubernetes 中,需要在所有节点上运行 NTP(参见[#6159](https://github.com/kubernetes/kubernetes/issues/6159#issuecomment-93844058))以避免时间偏差。时钟并不总是如此正确,但差异应该很小。设置非零 TTL 时请注意这种风险。
|
||||
|
||||
{{% /capture %}}
|
||||
|
||||
{{% capture whatsnext %}}
|
||||
|
||||
<!--
|
||||
[Clean up Jobs automatically](/docs/concepts/workloads/controllers/jobs-run-to-completion/#clean-up-finished-jobs-automatically)
|
||||
-->
|
||||
[自动清理作业](/docs/concepts/workloads/controllers/jobs-run-to-completion/#clean-up-finished-jobs-automatically)
|
||||
|
||||
<!--
|
||||
[Design doc](https://github.com/kubernetes/enhancements/blob/master/keps/sig-apps/0026-ttl-after-finish.md)
|
||||
-->
|
||||
[设计文档](https://github.com/kubernetes/enhancements/blob/master/keps/sig-apps/0026-ttl-after-finish.md)
|
||||
|
||||
{{% /capture %}}
|
||||
@@ -1,12 +1,11 @@
|
||||
---
|
||||
title: "Pods"
|
||||
weight: 10
|
||||
---
|
||||
|
||||
<!--
|
||||
---
|
||||
title: "Pods"
|
||||
weight: 10
|
||||
---
|
||||
-->
|
||||
|
||||
---
|
||||
title: "Pods"
|
||||
weight: 10
|
||||
---
|
||||
|
||||
|
||||
@@ -0,0 +1,533 @@
|
||||
---
|
||||
title: 干扰
|
||||
content_template: templates/concept
|
||||
weight: 60
|
||||
---
|
||||
|
||||
<!--
|
||||
---
|
||||
reviewers:
|
||||
- erictune
|
||||
- foxish
|
||||
- davidopp
|
||||
title: Disruptions
|
||||
content_template: templates/concept
|
||||
weight: 60
|
||||
---
|
||||
-->
|
||||
|
||||
{{% capture overview %}}
|
||||
<!--
|
||||
This guide is for application owners who want to build
|
||||
highly available applications, and thus need to understand
|
||||
what types of Disruptions can happen to Pods.
|
||||
-->
|
||||
|
||||
本指南针对的是希望构建高可用性应用程序的应用所有者,他们有必要了解可能发生在 pod 上的干扰类型。
|
||||
|
||||
<!--
|
||||
It is also for Cluster Administrators who want to perform automated
|
||||
cluster actions, like upgrading and autoscaling clusters.
|
||||
-->
|
||||
|
||||
文档同样适用于想要执行自动化集群操作(例如升级和自动扩展集群)的集群管理员。
|
||||
|
||||
{{% /capture %}}
|
||||
|
||||
|
||||
{{% capture body %}}
|
||||
|
||||
<!--
|
||||
## Voluntary and Involuntary Disruptions
|
||||
-->
|
||||
|
||||
## 自愿干扰和非自愿干扰
|
||||
|
||||
<!--
|
||||
Pods do not disappear until someone (a person or a controller) destroys them, or
|
||||
there is an unavoidable hardware or system software error.
|
||||
-->
|
||||
|
||||
Pod 不会消失,除非有人(用户或控制器)将其销毁,或者出现了不可避免的硬件或软件系统错误。
|
||||
|
||||
<!--
|
||||
We call these unavoidable cases *involuntary disruptions* to
|
||||
an application. Examples are:
|
||||
-->
|
||||
|
||||
我们把这些不可避免的情况称为应用的*非自愿干扰*。例如:
|
||||
|
||||
<!--
|
||||
- a hardware failure of the physical machine backing the node
|
||||
- cluster administrator deletes VM (instance) by mistake
|
||||
- cloud provider or hypervisor failure makes VM disappear
|
||||
- a kernel panic
|
||||
- the node disappears from the cluster due to cluster network partition
|
||||
- eviction of a pod due to the node being [out-of-resources](/docs/tasks/administer-cluster/out-of-resource/).
|
||||
-->
|
||||
|
||||
- 节点下层物理机的硬件故障
|
||||
- 集群管理员错误地删除虚拟机(实例)
|
||||
- 云提供商或虚拟机管理程序中的故障导致的虚拟机消失
|
||||
- 内核错误
|
||||
- 节点由于集群网络隔离从集群中消失
|
||||
- 由于节点[资源不足](/docs/tasks/administer-cluster/out-of-resource/)导致 pod 被驱逐。
|
||||
|
||||
<!--
|
||||
Except for the out-of-resources condition, all these conditions
|
||||
should be familiar to most users; they are not specific
|
||||
to Kubernetes.
|
||||
-->
|
||||
|
||||
除了资源不足的情况,大多数用户应该都熟悉这些情况;它们不是特定于 Kubernetes 的。
|
||||
|
||||
<!--
|
||||
We call other cases *voluntary disruptions*. These include both
|
||||
actions initiated by the application owner and those initiated by a Cluster
|
||||
Administrator. Typical application owner actions include:
|
||||
-->
|
||||
|
||||
我们称其他情况为*自愿干扰*。包括由应用程序所有者发起的操作和由集群管理员发起的操作。典型的应用程序所有者的
|
||||
作包括:
|
||||
|
||||
<!--
|
||||
- deleting the deployment or other controller that manages the pod
|
||||
- updating a deployment's pod template causing a restart
|
||||
- directly deleting a pod (e.g. by accident)
|
||||
-->
|
||||
|
||||
- 删除 deployment 或其他管理 pod 的控制器
|
||||
- 更新了 deployment 的 pod 模板导致 pod 重启
|
||||
- 直接删除 pod(例如,因为误操作)
|
||||
|
||||
<!--
|
||||
Cluster Administrator actions include:
|
||||
-->
|
||||
|
||||
集群管理员操作包括:
|
||||
|
||||
<!--
|
||||
- [Draining a node](/docs/tasks/administer-cluster/safely-drain-node/) for repair or upgrade.
|
||||
- Draining a node from a cluster to scale the cluster down (learn about
|
||||
[Cluster Autoscaling](/docs/tasks/administer-cluster/cluster-management/#cluster-autoscaler)
|
||||
).
|
||||
- Removing a pod from a node to permit something else to fit on that node.
|
||||
-->
|
||||
|
||||
- [排空(drain)节点](/docs/tasks/administer-cluster/safely-drain-node/)进行修复或升级。
|
||||
- 从集群中排空节点以缩小集群(了解[集群自动扩缩](/docs/tasks/administer-cluster/cluster-management/#cluster-autoscaler))。
|
||||
- 从节点中移除一个 pod,以允许其他 pod 使用该节点。
|
||||
|
||||
<!--
|
||||
These actions might be taken directly by the cluster administrator, or by automation
|
||||
run by the cluster administrator, or by your cluster hosting provider.
|
||||
-->
|
||||
|
||||
这些操作可能由集群管理员直接执行,也可能由集群管理员所使用的自动化工具执行,或者由集群托管提供商自动执行。
|
||||
|
||||
<!--
|
||||
Ask your cluster administrator or consult your cloud provider or distribution documentation
|
||||
to determine if any sources of voluntary disruptions are enabled for your cluster.
|
||||
If none are enabled, you can skip creating Pod Disruption Budgets.
|
||||
-->
|
||||
|
||||
咨询集群管理员或联系云提供商,或者查询发布文档,以确定是否为集群启用了任何资源干扰源。如果没有启用,可以不用创建 Pod Disruption Budgets(Pod 干扰预算)
|
||||
|
||||
{{< caution >}}
|
||||
|
||||
<!--
|
||||
Not all voluntary disruptions are constrained by Pod Disruption Budgets. For example,
|
||||
deleting deployments or pods bypasses Pod Disruption Budgets.
|
||||
-->
|
||||
|
||||
并非所有的自愿干扰都会受到 pod 干扰预算的限制。例如,删除 deployment 或 pod 的删除操作就会跳过 pod 干扰预算检查。
|
||||
|
||||
{{< /caution >}}
|
||||
|
||||
<!--
|
||||
## Dealing with Disruptions
|
||||
-->
|
||||
|
||||
## 处理干扰
|
||||
|
||||
<!--
|
||||
Here are some ways to mitigate involuntary disruptions:
|
||||
-->
|
||||
|
||||
以下是减轻非自愿干扰的一些方法:
|
||||
|
||||
<!--
|
||||
- Ensure your pod [requests the resources](/docs/tasks/configure-pod-container/assign-cpu-ram-container) it needs.
|
||||
- Replicate your application if you need higher availability. (Learn about running replicated
|
||||
[stateless](/docs/tasks/run-application/run-stateless-application-deployment/)
|
||||
and [stateful](/docs/tasks/run-application/run-replicated-stateful-application/) applications.)
|
||||
- For even higher availability when running replicated applications,
|
||||
spread applications across racks (using
|
||||
[anti-affinity](/docs/user-guide/node-selection/#inter-pod-affinity-and-anti-affinity-beta-feature))
|
||||
or across zones (if using a
|
||||
[multi-zone cluster](/docs/setup/multiple-zones).)
|
||||
-->
|
||||
|
||||
- 确保 pod[请求所需资源](/docs/tasks/configure-pod-container/assign-cpu-ram-container)。
|
||||
- 如果需要更高的可用性,请复制应用程序。(了解有关运行多副本的[无状态](/docs/tasks/run-application/run-stateless-application-deployment/)和[有状态](/docs/tasks/run-application/run-replicated-stateful-application/)应用程序的信息。)
|
||||
- 为了在运行复制应用程序时获得更高的可用性,请跨机架(使用[反亲和性](/docs/user-guide/node-selection/#inter-pod-affinity-and-anti-affinity-beta-feature))或跨区域(如果使用[多区域集群](/docs/setup/multiple-zones))扩展应用程序。
|
||||
|
||||
<!--
|
||||
The frequency of voluntary disruptions varies. On a basic Kubernetes cluster, there are
|
||||
no voluntary disruptions at all. However, your cluster administrator or hosting provider
|
||||
may run some additional services which cause voluntary disruptions. For example,
|
||||
rolling out node software updates can cause voluntary disruptions. Also, some implementations
|
||||
of cluster (node) autoscaling may cause voluntary disruptions to defragment and compact nodes.
|
||||
Your cluster administrator or hosting provider should have documented what level of voluntary
|
||||
disruptions, if any, to expect.
|
||||
-->
|
||||
|
||||
自愿干扰的频率各不相同。在一个基本的 Kubernetes 集群中,根本没有自愿干扰。然而,集群管理
|
||||
或托管提供商可能运行一些可能导致自愿干扰的额外服务。例如,节点软
|
||||
更新可能导致自愿干扰。另外,集群(节点)自动缩放的某些
|
||||
现可能导致碎片整理和紧缩节点的自愿干扰。集群
|
||||
理员或托管提供商应该已经记录了各级别的自愿干扰(如果有的话)。
|
||||
|
||||
<!--
|
||||
Kubernetes offers features to help run highly available applications at the same
|
||||
time as frequent voluntary disruptions. We call this set of features
|
||||
*Disruption Budgets*.
|
||||
-->
|
||||
|
||||
Kubernetes 提供特性来满足在出现频繁自愿干扰的同时运行高可用的应用程序。我们称这些特性为*干扰预算*
|
||||
|
||||
<!--
|
||||
## How Disruption Budgets Work
|
||||
-->
|
||||
|
||||
## 干扰预算工作原理
|
||||
|
||||
<!--
|
||||
An Application Owner can create a `PodDisruptionBudget` object (PDB) for each application.
|
||||
A PDB limits the number of pods of a replicated application that are down simultaneously from
|
||||
voluntary disruptions. For example, a quorum-based application would
|
||||
like to ensure that the number of replicas running is never brought below the
|
||||
number needed for a quorum. A web front end might want to
|
||||
ensure that the number of replicas serving load never falls below a certain
|
||||
percentage of the total.
|
||||
-->
|
||||
|
||||
应用程序所有者可以为每个应用程序创建 `PodDisruptionBudget` 对象(PDB)。PDB 将限制在同一时间因自愿干扰导致的复制应用程序中宕机的 pod 数量。例如,基于定额的应用程序希望确保运行的副本数
|
||||
永远不会低于仲裁所需的数量。Web 前端可能希望确保提供负载的副本数量永远不会低于总数的某个百分比。
|
||||
|
||||
<!--
|
||||
Cluster managers and hosting providers should use tools which
|
||||
respect Pod Disruption Budgets by calling the [Eviction API](/docs/tasks/administer-cluster/safely-drain-node/#the-eviction-api)
|
||||
instead of directly deleting pods or deployments. Examples are the `kubectl drain` command
|
||||
and the Kubernetes-on-GCE cluster upgrade script (`cluster/gce/upgrade.sh`).
|
||||
-->
|
||||
|
||||
集群管理员和托管提供商应该使用遵循 Pod Disruption Budgets 的接口(通过调用[驱逐 API](/docs/tasks/administer-cluster/safely-drain-node/#the-eviction-api)),而不是直接删除 pod 或 deployment。示例包括 `kubectl drain` 命令和 Kubernetes-on-GCE 集群升级脚本(`cluster/gce/upgrade.sh`)。
|
||||
|
||||
<!--
|
||||
When a cluster administrator wants to drain a node
|
||||
they use the `kubectl drain` command. That tool tries to evict all
|
||||
the pods on the machine. The eviction request may be temporarily rejected,
|
||||
and the tool periodically retries all failed requests until all pods
|
||||
are terminated, or until a configurable timeout is reached.
|
||||
-->
|
||||
|
||||
当集群管理员想排空一个节点时,可以使用 `kubectl drain` 命令。该命令试图驱逐机器上的所有 pod。驱逐请求可能会暂时被拒绝,且该工具定时重试失败的请求直到所有的 pod 都被终止,或者达到配置的超时时间。
|
||||
|
||||
<!--
|
||||
A PDB specifies the number of replicas that an application can tolerate having, relative to how
|
||||
many it is intended to have. For example, a Deployment which has a `.spec.replicas: 5` is
|
||||
supposed to have 5 pods at any given time. If its PDB allows for there to be 4 at a time,
|
||||
then the Eviction API will allow voluntary disruption of one, but not two pods, at a time.
|
||||
-->
|
||||
|
||||
PDB 指定应用程序可以容忍的副本数量(相当于应该有多少副本)。例如,具有 `.spec.replicas: 5` 的 deployment 在任何时间都应该有 5 个 pod。如果 PDB 允许其在某一时刻有 4 个副本,那么驱逐 API 将允许同一时刻仅有一个而不是两个 pod 自愿干扰。
|
||||
|
||||
<!--
|
||||
The group of pods that comprise the application is specified using a label selector, the same
|
||||
as the one used by the application's controller (deployment, stateful-set, etc).
|
||||
-->
|
||||
|
||||
使用标签选择器来指定构成应用程序的一组 pod,这与应用程序的控制器(deployment,stateful-set 等)选择 pod 的逻辑一样。
|
||||
|
||||
<!--
|
||||
The "intended" number of pods is computed from the `.spec.replicas` of the pods controller.
|
||||
The controller is discovered from the pods using the `.metadata.ownerReferences` of the object.
|
||||
-->
|
||||
|
||||
Pod 控制器的 `.spec.replicas` 计算“预期的” pod 数量。根据 pod 对象的 `.metadata.ownerReferences` 字段来发现控制器。
|
||||
|
||||
<!--
|
||||
PDBs cannot prevent [involuntary disruptions](#voluntary-and-involuntary-disruptions) from
|
||||
occurring, but they do count against the budget.
|
||||
-->
|
||||
|
||||
PDB 不能阻止[非自愿干扰](#voluntary-and-involuntary-disruptions)的发生,但是确实会计入
|
||||
算。
|
||||
|
||||
<!--
|
||||
Pods which are deleted or unavailable due to a rolling upgrade to an application do count
|
||||
against the disruption budget, but controllers (like deployment and stateful-set)
|
||||
are not limited by PDBs when doing rolling upgrades -- the handling of failures
|
||||
during application updates is configured in the controller spec.
|
||||
(Learn about [updating a deployment](/docs/concepts/workloads/controllers/deployment/#updating-a-deployment).)
|
||||
-->
|
||||
|
||||
由于应用程序的滚动升级而被删除或不可用的 pod 确实会计入干扰预算,但是控制器(如 deployment 和 stateful-set)在进行滚动升级时不受 PDB
|
||||
的限制。应用程序更新期间的故障处理是在控制器的 spec 中配置的。(了解[更新 deployment](/docs/concepts/workloads/controllers/deployment/#updating-a-deployment)。)
|
||||
|
||||
<!--
|
||||
When a pod is evicted using the eviction API, it is gracefully terminated (see
|
||||
`terminationGracePeriodSeconds` in [PodSpec](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#podspec-v1-core).)
|
||||
-->
|
||||
|
||||
当使用驱逐 API 驱逐 pod 时,pod 会被优雅地终止(参考 [PodSpec](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#podspec-v1-core) 中的 `terminationGracePeriodSeconds`)。
|
||||
|
||||
<!--
|
||||
## PDB Example
|
||||
-->
|
||||
|
||||
## PDB 例子
|
||||
|
||||
<!--
|
||||
Consider a cluster with 3 nodes, `node-1` through `node-3`.
|
||||
The cluster is running several applications. One of them has 3 replicas initially called
|
||||
`pod-a`, `pod-b`, and `pod-c`. Another, unrelated pod without a PDB, called `pod-x`, is also shown.
|
||||
Initially, the pods are laid out as follows:
|
||||
-->
|
||||
|
||||
假设集群有 3 个节点,`node-1` 到 `node-3`。集群上运行了一些应用。其中一个应用有 3 个副本,分别是 `pod-a`,`pod-b` 和 `pod-c`。另外,还有一个不带 PDB 的无关 pod `pod-x` 也同样显示。最初,所有的 pod 分布如下:
|
||||
|
||||
|
||||
| node-1 | node-2 | node-3 |
|
||||
|:--------------------:|:-------------------:|:------------------:|
|
||||
| pod-a *available* | pod-b *available* | pod-c *available* |
|
||||
| pod-x *available* | | |
|
||||
|
||||
<!--
|
||||
All 3 pods are part of a deployment, and they collectively have a PDB which requires
|
||||
there be at least 2 of the 3 pods to be available at all times.
|
||||
-->
|
||||
|
||||
3 个 pod 都是 deployment 的一部分,并且共同拥有同一个 PDB,要求 3 个 pod 中至少有 2 个 pod 始终处于可用状态。
|
||||
|
||||
<!--
|
||||
For example, assume the cluster administrator wants to reboot into a new kernel version to fix a bug in the kernel.
|
||||
The cluster administrator first tries to drain `node-1` using the `kubectl drain` command.
|
||||
That tool tries to evict `pod-a` and `pod-x`. This succeeds immediately.
|
||||
Both pods go into the `terminating` state at the same time.
|
||||
This puts the cluster in this state:
|
||||
-->
|
||||
|
||||
例如,假设集群管理员想要重启系统,升级内核版本来修复内核中的 bug。集群管理员首先使用 `kubectl drain` 命令尝试排空 `node-1` 节点。命令尝试驱逐 `pod-a` 和 `pod-x`。操作立即就成功了。两个 pod 同时进入 `terminating` 状态。这时的集群处于下面的状态:
|
||||
|
||||
| node-1 *draining* | node-2 | node-3 |
|
||||
|:--------------------:|:-------------------:|:------------------:|
|
||||
| pod-a *terminating* | pod-b *available* | pod-c *available* |
|
||||
| pod-x *terminating* | | |
|
||||
|
||||
<!--
|
||||
The deployment notices that one of the pods is terminating, so it creates a replacement
|
||||
called `pod-d`. Since `node-1` is cordoned, it lands on another node. Something has
|
||||
also created `pod-y` as a replacement for `pod-x`.
|
||||
-->
|
||||
|
||||
Deployment 控制器观察到其中一个 pod 正在终止,因此它创建了一个替代 pod `pod-d`。由于 `node-1` 被封锁(cordon),`pod-d` 落在另一个节点上。同样其他控制器也创建了 `pod-y` 作为 `pod-x` 的替代品。
|
||||
|
||||
<!--
|
||||
(Note: for a StatefulSet, `pod-a`, which would be called something like `pod-0`, would need
|
||||
to terminate completely before its replacement, which is also called `pod-0` but has a
|
||||
different UID, could be created. Otherwise, the example applies to a StatefulSet as well.)
|
||||
-->
|
||||
|
||||
(注意:对于 StatefulSet 来说,`pod-a`(也称为 `pod-0`)需要在替换 pod 创建之前完全终止,替代它的也称为 `pod-0`,但是具有不同的 UID。反之,样例也适用于 StatefulSet。)
|
||||
|
||||
<!--
|
||||
Now the cluster is in this state:
|
||||
-->
|
||||
|
||||
当前集群的状态如下:
|
||||
|
||||
| node-1 *draining* | node-2 | node-3 |
|
||||
|:--------------------:|:-------------------:|:------------------:|
|
||||
| pod-a *terminating* | pod-b *available* | pod-c *available* |
|
||||
| pod-x *terminating* | pod-d *starting* | pod-y |
|
||||
|
||||
<!--
|
||||
At some point, the pods terminate, and the cluster looks like this:
|
||||
-->
|
||||
|
||||
在某一时刻,pod 被终止,集群如下所示:
|
||||
|
||||
| node-1 *drained* | node-2 | node-3 |
|
||||
|:--------------------:|:-------------------:|:------------------:|
|
||||
| | pod-b *available* | pod-c *available* |
|
||||
| | pod-d *starting* | pod-y |
|
||||
|
||||
<!--
|
||||
At this point, if an impatient cluster administrator tries to drain `node-2` or
|
||||
`node-3`, the drain command will block, because there are only 2 available
|
||||
pods for the deployment, and its PDB requires at least 2. After some time passes, `pod-d` becomes available.
|
||||
-->
|
||||
|
||||
此时,如果一个急躁的集群管理员试图排空(drain)`node-2` 或 `node-3`,drain 命令将被阻塞,因为对于 deployment 来说只有 2 个可用的 pod,并且它的 PDB 至少需要 2 个。经过一段时间,`pod-d` 变得可用。
|
||||
|
||||
<!--
|
||||
The cluster state now looks like this:
|
||||
-->
|
||||
|
||||
集群状态如下所示:
|
||||
|
||||
| node-1 *drained* | node-2 | node-3 |
|
||||
|:--------------------:|:-------------------:|:------------------:|
|
||||
| | pod-b *available* | pod-c *available* |
|
||||
| | pod-d *available* | pod-y |
|
||||
|
||||
<!--
|
||||
Now, the cluster administrator tries to drain `node-2`.
|
||||
The drain command will try to evict the two pods in some order, say
|
||||
`pod-b` first and then `pod-d`. It will succeed at evicting `pod-b`.
|
||||
But, when it tries to evict `pod-d`, it will be refused because that would leave only
|
||||
one pod available for the deployment.
|
||||
-->
|
||||
|
||||
现在,集群管理员试图排空(drain)`node-2`。drain 命令将尝试按照某种顺序驱逐两个 pod,假设先是 `pod-b`,然后是 `pod-d`。命令成功驱逐 `pod-b`,但是当它尝试驱逐 `pod-d`时将被拒绝,因为对于 deployment 来说只剩一个可用的 pod 了。
|
||||
|
||||
<!--
|
||||
The deployment creates a replacement for `pod-b` called `pod-e`.
|
||||
Because there are not enough resources in the cluster to schedule
|
||||
`pod-e` the drain will again block. The cluster may end up in this
|
||||
state:
|
||||
-->
|
||||
|
||||
Deployment 创建 `pod-b` 的替代 pod `pod-e`。因为集群中没有足够的资源来调度 `pod-e`,drain 命令再次阻塞。集群最终将是下面这种状态:
|
||||
|
||||
| node-1 *drained* | node-2 | node-3 | *no node* |
|
||||
|:--------------------:|:-------------------:|:------------------:|:------------------:|
|
||||
| | pod-b *available* | pod-c *available* | pod-e *pending* |
|
||||
| | pod-d *available* | pod-y | |
|
||||
|
||||
<!--
|
||||
At this point, the cluster administrator needs to
|
||||
add a node back to the cluster to proceed with the upgrade.
|
||||
-->
|
||||
|
||||
此时,集群管理员需要增加一个节点到集群中以继续升级操作。
|
||||
|
||||
<!--
|
||||
You can see how Kubernetes varies the rate at which disruptions
|
||||
can happen, according to:
|
||||
-->
|
||||
|
||||
可以看到 Kubernetes 如何改变干扰发生的速率,根据:
|
||||
|
||||
<!--
|
||||
- how many replicas an application needs
|
||||
- how long it takes to gracefully shutdown an instance
|
||||
- how long it takes a new instance to start up
|
||||
- the type of controller
|
||||
- the cluster's resource capacity
|
||||
-->
|
||||
|
||||
- 应用程序需要多少个副本
|
||||
- 优雅关闭应用实例需要多长时间
|
||||
- 启动应用新实例需要多长时间
|
||||
- 控制器的类型
|
||||
- 集群的资源能力
|
||||
|
||||
<!--
|
||||
## Separating Cluster Owner and Application Owner Roles
|
||||
-->
|
||||
|
||||
## 分离集群所有者和应用所有者角色
|
||||
|
||||
<!--
|
||||
Often, it is useful to think of the Cluster Manager
|
||||
and Application Owner as separate roles with limited knowledge
|
||||
of each other. This separation of responsibilities
|
||||
may make sense in these scenarios:
|
||||
-->
|
||||
|
||||
通常,将集群管理者和应用所有者视为彼此了解有限的独立角色是很有用的。这种责任分离在下面这些场景下是有意义的:
|
||||
|
||||
<!--
|
||||
- when there are many application teams sharing a Kubernetes cluster, and
|
||||
there is natural specialization of roles
|
||||
- when third-party tools or services are used to automate cluster management
|
||||
-->
|
||||
|
||||
- 当有许多应用程序团队共用一个 Kubernetes 集群,并且有自然的专业角色
|
||||
- 当第三方工具或服务用于集群自动化管理
|
||||
|
||||
<!--
|
||||
Pod Disruption Budgets support this separation of roles by providing an
|
||||
interface between the roles.
|
||||
-->
|
||||
|
||||
Pod 干扰预算通过在角色之间提供接口来支持这种分离。
|
||||
|
||||
<!--
|
||||
If you do not have such a separation of responsibilities in your organization,
|
||||
you may not need to use Pod Disruption Budgets.
|
||||
-->
|
||||
|
||||
如果你的组织中没有这样的责任分离,则可能不需要使用 Pod 干扰预算。
|
||||
|
||||
<!--
|
||||
## How to perform Disruptive Actions on your Cluster
|
||||
-->
|
||||
|
||||
## 如何在集群上执行干扰操作
|
||||
|
||||
<!--
|
||||
If you are a Cluster Administrator, and you need to perform a disruptive action on all
|
||||
the nodes in your cluster, such as a node or system software upgrade, here are some options:
|
||||
-->
|
||||
|
||||
如果你是集群管理员,并且需要对集群中的所有节点执行干扰操作,例如节点或系统软件升级,则可以使用以下选项
|
||||
|
||||
|
||||
<!--
|
||||
- Accept downtime during the upgrade.
|
||||
- Failover to another complete replica cluster.
|
||||
- No downtime, but may be costly both for the duplicated nodes
|
||||
and for human effort to orchestrate the switchover.
|
||||
- Write disruption tolerant applications and use PDBs.
|
||||
- No downtime.
|
||||
- Minimal resource duplication.
|
||||
- Allows more automation of cluster administration.
|
||||
- Writing disruption-tolerant applications is tricky, but the work to tolerate voluntary
|
||||
disruptions largely overlaps with work to support autoscaling and tolerating
|
||||
involuntary disruptions.
|
||||
-->
|
||||
|
||||
- 接受升级期间的停机时间。
|
||||
- 故障转移到另一个完整的副本集群。
|
||||
- 没有停机时间,但是对于重复的节点和人工协调成本可能是昂贵的。
|
||||
- 编写可容忍干扰的应用程序和使用 PDB。
|
||||
- 没有停机
|
||||
间。
|
||||
- 最小的资源重复。
|
||||
- 允许更多的集群管理自动化。
|
||||
- 编写可容忍干扰的应用程序是棘手的,但对于支持容忍自愿干扰所做的工作,和支持自动扩缩和容忍非
|
||||
愿干扰所做工作相比,有大量的重叠
|
||||
|
||||
{{% /capture %}}
|
||||
|
||||
|
||||
{{% capture whatsnext %}}
|
||||
|
||||
<!--
|
||||
* Follow steps to protect your application by [configuring a Pod Disruption Budget](/docs/tasks/run-application/configure-pdb/).
|
||||
-->
|
||||
|
||||
* 参考[配置 Pod 干扰预算](/docs/tasks/run-application/configure-pdb/)中的方法来保护你的
|
||||
用。
|
||||
|
||||
<!--
|
||||
* Learn more about [draining nodes](/docs/tasks/administer-cluster/safely-drain-node/)
|
||||
-->
|
||||
|
||||
* 了解更多关于[排空节点](/docs/tasks/administer-cluster/safely-drain-node/)的信息。
|
||||
|
||||
{{% /capture %}}
|
||||
@@ -0,0 +1,313 @@
|
||||
---
|
||||
title: 临时容器
|
||||
content_template: templates/concept
|
||||
weight: 80
|
||||
---
|
||||
|
||||
<!--
|
||||
---
|
||||
reviewers:
|
||||
- verb
|
||||
- yujuhong
|
||||
title: Ephemeral Containers
|
||||
content_template: templates/concept
|
||||
weight: 80
|
||||
---
|
||||
-->
|
||||
|
||||
{{% capture overview %}}
|
||||
|
||||
{{< feature-state state="alpha" >}}
|
||||
|
||||
<!--
|
||||
This page provides an overview of ephemeral containers: a special type of container
|
||||
that runs temporarily in an existing {{< glossary_tooltip term_id="pod" >}} to accomplish user-initiated actions such
|
||||
as troubleshooting. You use ephemeral containers to inspect services rather than
|
||||
to build applications.
|
||||
-->
|
||||
|
||||
此页面概述了临时容器:一种特殊的容器,该容器在现有 {{< glossary_tooltip term_id="pod" >}} 中临时运行,为了完成用户启动的操作,例如故障排查。使用临时容器来检查服务,而不是构建应用程序。
|
||||
|
||||
<!--
|
||||
Ephemeral containers are in early alpha state and are not suitable for production
|
||||
clusters. You should expect the feature not to work in some situations, such as
|
||||
when targeting the namespaces of a container. In accordance with the [Kubernetes
|
||||
Deprecation Policy](/docs/reference/using-api/deprecation-policy/), this alpha
|
||||
feature could change significantly in the future or be removed entirely.
|
||||
-->
|
||||
|
||||
{{< warning >}}
|
||||
临时容器处于早期的 alpha 阶段,不适用于生成环境集群。应该预料到临时容器在某些情况下不起作用,例如在定位容器的名称命名空间。根据 [Kubernetes
|
||||
弃用政策](/docs/reference/using-api/deprecation-policy/),该 alpha 功能将来可能发生重大变化或完全删除。
|
||||
{{< /warning >}}
|
||||
|
||||
{{% /capture %}}
|
||||
|
||||
{{% capture body %}}
|
||||
|
||||
<!--
|
||||
## Understanding ephemeral containers
|
||||
-->
|
||||
|
||||
## 了解临时容器
|
||||
|
||||
<!--
|
||||
{{< glossary_tooltip text="Pods" term_id="pod" >}} are the fundamental building
|
||||
block of Kubernetes applications. Since Pods are intended to be disposable and
|
||||
replaceable, you cannot add a container to a Pod once it has been created.
|
||||
Instead, you usually delete and replace Pods in a controlled fashion using
|
||||
{{< glossary_tooltip text="deployments" term_id="deployment" >}}.
|
||||
-->
|
||||
|
||||
{{< glossary_tooltip text="Pods" term_id="pod" >}} 是 Kubernetes 应用程序的基本构建块。由于 pod 是一次性且可替换的,因此一旦 Pod 创建,就无法将容器加入到 Pod 中。取而代之的是,通常使用 {{< glossary_tooltip text="deployments" term_id="deployment" >}} 以受控的方式来删除并替换 Pod。
|
||||
|
||||
<!--
|
||||
Sometimes it's necessary to inspect the state of an existing Pod, however, for
|
||||
example to troubleshoot a hard-to-reproduce bug. In these cases you can run
|
||||
an ephemeral container in an existing Pod to inspect its state and run
|
||||
arbitrary commands.
|
||||
-->
|
||||
|
||||
有时有必要检查现有 Pod 的状态,例如,对于难以复现的故障进行排查。在这些场景中,可以在现有 Pod 中运行临时容器来检查其状态并运行任意命令。
|
||||
|
||||
<!--
|
||||
### What is an ephemeral container?
|
||||
-->
|
||||
|
||||
### 什么是临时容器?
|
||||
|
||||
<!--
|
||||
Ephemeral containers differ from other containers in that they lack guarantees
|
||||
for resources or execution, and they will never be automatically restarted, so
|
||||
they are not appropriate for building applications. Ephemeral containers are
|
||||
described using the same `ContainerSpec` as regular containers, but many fields
|
||||
are incompatible and disallowed for ephemeral containers.
|
||||
-->
|
||||
|
||||
临时容器与其他容器的不同之处在于,它们缺少对资源或执行的保证,并且永远不会自动重启,因此不适用于构建应用程序。临时容器使用与常规容器相同的 `ContainerSpec` 段进行描述,但许多字段是不相容且不允许的。
|
||||
|
||||
<!--
|
||||
- Ephemeral containers may not have ports, so fields such as `ports`,
|
||||
`livenessProbe`, `readinessProbe` are disallowed.
|
||||
- Pod resource allocations are immutable, so setting `resources` is disallowed.
|
||||
- For a complete list of allowed fields, see the [EphemeralContainer reference
|
||||
documentation](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#ephemeralcontainer-v1-core).
|
||||
-->
|
||||
|
||||
- 临时容器没有端口配置,因此像 `ports`,`livenessProbe`,`readinessProbe` 这样的字段是不允许的。
|
||||
- Pod 资源分配是不可变的,因此 `resources` 配置是不允许的。
|
||||
- 有关允许字段的完整列表,请参见[临时容器参考文档](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#ephemeralcontainer-v1-core)。
|
||||
|
||||
<!--
|
||||
Ephemeral containers are created using a special `ephemeralcontainers` handler
|
||||
in the API rather than by adding them directly to `pod.spec`, so it's not
|
||||
possible to add an ephemeral container using `kubectl edit`.
|
||||
-->
|
||||
|
||||
临时容器是使用 API 中的一种特殊的 `ephemeralcontainers` 处理器进行创建的,而不是直接添加到 `pod.spec` 段,因此无法使用 `kubectl edit` 来添加一个临时容器。
|
||||
|
||||
<!--
|
||||
Like regular containers, you may not change or remove an ephemeral container
|
||||
after you have added it to a Pod.
|
||||
-->
|
||||
|
||||
与常规容器一样,将临时容器添加到 Pod 后,将不能更改或删除临时容器。
|
||||
|
||||
<!--
|
||||
## Uses for ephemeral containers
|
||||
-->
|
||||
|
||||
## 临时容器的用途
|
||||
|
||||
<!--
|
||||
Ephemeral containers are useful for interactive troubleshooting when `kubectl
|
||||
exec` is insufficient because a container has crashed or a container image
|
||||
doesn't include debugging utilities.
|
||||
-->
|
||||
|
||||
当容器崩溃或容器镜像中不包含调试工具时,使用 `kubectl
|
||||
exec` 命令进行故障排查不足,临时容器对于交互式故障处理很有用。
|
||||
|
||||
<!--
|
||||
In particular, [distroless images](https://github.com/GoogleContainerTools/distroless)
|
||||
enable you to deploy minimal container images that reduce attack surface
|
||||
and exposure to bugs and vulnerabilities. Since distroless images do not include a
|
||||
shell or any debugging utilities, it's difficult to troubleshoot distroless
|
||||
images using `kubectl exec` alone.
|
||||
-->
|
||||
|
||||
尤其是,[distroless 镜像](https://github.com/GoogleContainerTools/distroless)能够使得部署最小的容器镜像,从而减少攻击面并减少故障和漏洞的暴露。由于 distroless 镜像不包含 shell 或任何的调试工具,因此很难单独使用 `kubectl exec` 命令进行故障排查。
|
||||
|
||||
<!--
|
||||
When using ephemeral containers, it's helpful to enable [process namespace
|
||||
sharing](/docs/tasks/configure-pod-container/share-process-namespace/) so
|
||||
you can view processes in other containers.
|
||||
-->
|
||||
|
||||
使用临时容器时,启用[进程命名空间共享](/docs/tasks/configure-pod-container/share-process-namespace/)很有帮助,可以查看其他容器中的进程。
|
||||
|
||||
<!--
|
||||
### Examples
|
||||
-->
|
||||
|
||||
### 例子
|
||||
|
||||
<!--
|
||||
The examples in this section require the `EphemeralContainers` [feature
|
||||
gate](/docs/reference/command-line-tools-reference/feature-gates/) to be
|
||||
enabled and kubernetes client and server version v1.16 or later.
|
||||
-->
|
||||
|
||||
{{< note >}}
|
||||
本节中的示例要求启用 `EphemeralContainers` [特性](/docs/reference/command-line-tools-reference/feature-gates/),并且 kubernetes 客户端和服务端版本要求为 v1.16 或更高版本。
|
||||
{{< /note >}}
|
||||
|
||||
<!--
|
||||
The examples in this section demonstrate how ephemeral containers appear in
|
||||
the API. Users would normally use a `kubectl` plugin for troubleshooting that
|
||||
would automate these steps.
|
||||
-->
|
||||
|
||||
本节中的示例演示了临时容器如何在 API 中出现。用户通常会使用 `kubectl` 插件来进行故障排查,从而自动化执行这些步骤。
|
||||
|
||||
<!--
|
||||
Ephemeral containers are created using the `ephemeralcontainers` subresource
|
||||
of Pod, which can be demonstrated using `kubectl --raw`. First describe
|
||||
the ephemeral container to add as an `EphemeralContainers` list:
|
||||
-->
|
||||
|
||||
临时容器是使用 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"
|
||||
}]
|
||||
}
|
||||
```
|
||||
|
||||
<!--
|
||||
To update the ephemeral containers of the already running `example-pod`:
|
||||
-->
|
||||
|
||||
使用如下命令更新已运行的临时容器 `example-pod`:
|
||||
|
||||
```shell
|
||||
kubectl replace --raw /api/v1/namespaces/default/pods/example-pod/ephemeralcontainers -f ec.json
|
||||
```
|
||||
|
||||
<!--
|
||||
This will return the new list of ephemeral containers:
|
||||
-->
|
||||
|
||||
这将返回临时容器的新列表:
|
||||
|
||||
```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
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
<!--
|
||||
You can view the state of the newly created ephemeral container using `kubectl describe`:
|
||||
-->
|
||||
|
||||
可以使用以下命令查看新创建的临时容器的状态:
|
||||
|
||||
```shell
|
||||
kubectl describe pod example-pod
|
||||
```
|
||||
|
||||
```
|
||||
...
|
||||
Ephemeral Containers:
|
||||
debugger:
|
||||
Container ID: docker://cf81908f149e7e9213d3c3644eda55c72efaff67652a2685c1146f0ce151e80f
|
||||
Image: busybox
|
||||
Image ID: docker-pullable://busybox@sha256:9f1003c480699be56815db0f8146ad2e22efea85129b5b5983d0e0fb52d9ab70
|
||||
Port: <none>
|
||||
Host Port: <none>
|
||||
Command:
|
||||
sh
|
||||
State: Running
|
||||
Started: Thu, 29 Aug 2019 06:42:21 +0000
|
||||
Ready: False
|
||||
Restart Count: 0
|
||||
Environment: <none>
|
||||
Mounts: <none>
|
||||
...
|
||||
```
|
||||
|
||||
<!--
|
||||
You can attach to the new ephemeral container using `kubectl attach`:
|
||||
-->
|
||||
|
||||
可以使用以下命令连接到新的临时容器:
|
||||
|
||||
```shell
|
||||
kubectl attach -it example-pod -c debugger
|
||||
```
|
||||
|
||||
<!--
|
||||
If process namespace sharing is enabled, you can see processes from all the containers in that Pod. For example:
|
||||
-->
|
||||
|
||||
如果启用了进程命名空间共享,则可以从该 Pod 的所有容器中查看进程。如下所示:
|
||||
|
||||
```shell
|
||||
/ # ps auxww
|
||||
PID USER TIME COMMAND
|
||||
1 root 0:00 /pause
|
||||
6 root 0:00 nginx: master process nginx -g daemon off;
|
||||
11 101 0:00 nginx: worker process
|
||||
12 101 0:00 nginx: worker process
|
||||
13 101 0:00 nginx: worker process
|
||||
14 101 0:00 nginx: worker process
|
||||
15 101 0:00 nginx: worker process
|
||||
16 101 0:00 nginx: worker process
|
||||
17 101 0:00 nginx: worker process
|
||||
18 101 0:00 nginx: worker process
|
||||
19 root 0:00 /pause
|
||||
24 root 0:00 sh
|
||||
29 root 0:00 ps auxww
|
||||
```
|
||||
|
||||
{{% /capture %}}
|
||||
@@ -12,63 +12,119 @@ content_template: templates/concept
|
||||
|
||||
{{% capture overview %}}
|
||||
|
||||
本页提供了 Init 容器的概览,它是一种专用的容器,在应用容器启动之前运行,并包括一些应用镜像中不存在的实用工具和安装脚本。
|
||||
<!--
|
||||
This page provides an overview of init containers: specialized containers that run before app containers in a {{< glossary_tooltip text="Pod" term_id="pod" >}}.
|
||||
Init containers can contain utilities or setup scripts not present in an app image.
|
||||
-->
|
||||
|
||||
本页提供了 Init 容器的概览,它是一种专用的容器,在{{< glossary_tooltip text="Pod" term_id="pod" >}}内的应用容器启动之前运行,并包括一些应用镜像中不存在的实用工具和安装脚本。
|
||||
{{% /capture %}}
|
||||
|
||||
{{< toc >}}
|
||||
|
||||
|
||||
这个特性在 1.6 版本已经退出 beta 版本。Init 容器可以在 PodSpec 中有效 QoS 层同应用的 `containers` 数组一起来指定。
|
||||
beta 注解的值将仍然需要保留,并覆盖 PodSpec 字段值。
|
||||
|
||||
<!--
|
||||
You can specify init containers in the Pod specification alongside the `containers` array (which describes app containers).
|
||||
-->
|
||||
你可以在Pod的规格信息中与containers数组同级的位置指定 Init 容器。
|
||||
{{% capture body %}}
|
||||
|
||||
|
||||
<!--
|
||||
## Understanding init containers
|
||||
|
||||
A {{< glossary_tooltip text="Pod" term_id="pod" >}} can have multiple containers running apps within it, but it can also have one or more init containers, which are run before the app containers are started.
|
||||
|
||||
-->
|
||||
|
||||
## 理解 Init 容器
|
||||
|
||||
|
||||
|
||||
[Pod](/docs/concepts/abstractions/pod/) 能够具有多个容器,应用运行在容器里面,但是它也可能有一个或多个先于应用容器启动的 Init 容器。
|
||||
{{< glossary_tooltip text="Pod" term_id="pod" >}} 可以包含多个容器,应用运行在这些容器里面,同时 Pod 也可以有一个或多个先于应用容器启动的 Init 容器。
|
||||
|
||||
|
||||
<!--
|
||||
Init containers are exactly like regular containers, except:
|
||||
* Init containers always run to completion.
|
||||
* Each init container must complete successfully before the next one starts.
|
||||
-->
|
||||
Init 容器与普通的容器非常像,除了如下两点:
|
||||
|
||||
|
||||
|
||||
* 它们总是运行到完成。
|
||||
* 每个都必须在下一个启动之前成功完成。
|
||||
|
||||
|
||||
|
||||
<!--
|
||||
If a Pod's init container fails, Kubernetes repeatedly restarts the Pod until the init container succeeds. However, if the Pod has a `restartPolicy` of Never, Kubernetes does not restart the Pod.
|
||||
-->
|
||||
如果 Pod 的 Init 容器失败,Kubernetes 会不断地重启该 Pod,直到 Init 容器成功为止。然而,如果 Pod 对应的 `restartPolicy` 值为 Never,它不会重新启动。
|
||||
|
||||
指定容器为 Init 容器,需要在 PodSpec 中添加 `initContainers` 字段,以 [Container](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#container-v1-core) 类型对象的 JSON 数组的形式,还有 app 的 `containers` 数组。
|
||||
|
||||
<!--
|
||||
To specify an init container for a Pod, add the `initContainers` field into the Pod specification, as an array of objects of type [Container](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#container-v1-core), alongside the app `containers` array.
|
||||
|
||||
The status of the init containers is returned in `.status.initContainerStatuses` field as an array of the container statuses (similar to the `.status.containerStatuses` field).
|
||||
-->
|
||||
指定容器为 Init 容器,需要在 Pod 的 spec 中添加 `initContainers` 字段, 该字段內以[Container](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#container-v1-core) 类型对象数组的形式组织,和应用的 `containers` 数组同级相邻。
|
||||
Init 容器的状态在 `status.initContainerStatuses` 字段中以容器状态数组的格式返回(类似 `status.containerStatuses` 字段)。
|
||||
|
||||
|
||||
<!--
|
||||
### Differences from regular containers
|
||||
Init containers support all the fields and features of app containers, including resource limits, volumes, and security settings. However, the resource requests and limits for an init container are handled differently, as documented in [Resources](#resources).
|
||||
Also, init containers do not support readiness probes because they must run to completion before the Pod can be ready.
|
||||
If you specify multiple init containers for a Pod, Kubelet runs each init container sequentially. Each init container must succeed before the next can run. When all of the init containers have run to completion, Kubelet initializes the application containers for the Pod and runs them as usual.
|
||||
-->
|
||||
|
||||
### 与普通容器的不同之处
|
||||
|
||||
Init 容器支持应用容器的全部字段和特性,包括资源限制、数据卷和安全设置。
|
||||
然而,Init 容器对资源请求和限制的处理稍有不同,在下面 [资源](#资源) 处有说明。
|
||||
而且 Init 容器不支持 Readiness Probe,因为它们必须在 Pod 就绪之前运行完成。
|
||||
|
||||
如果为一个 Pod 指定了多个 Init 容器,那些容器会按顺序一次运行一个。
|
||||
每个 Init 容器必须运行成功,下一个才能够运行。
|
||||
当所有的 Init 容器运行完成时,Kubernetes 初始化 Pod 并像平常一样运行应用容器。
|
||||
Init 容器支持应用容器的全部字段和特性,包括资源限制、数据卷和安全设置。 然而,Init 容器对资源请求和限制的处理稍有不同,在下面 [资源](#资源) 处有说明。
|
||||
|
||||
同时 Init 容器不支持 Readiness Probe,因为它们必须在 Pod 就绪之前运行完成。
|
||||
|
||||
如果为一个 Pod 指定了多个 Init 容器,这些容器会按顺序逐个运行。每个 Init 容器必须运行成功,下一个才能够运行。当所有的 Init 容器运行完成时,Kubernetes 才会为 Pod 初始化应用容器并像平常一样运行。
|
||||
|
||||
|
||||
<!--
|
||||
## Using init containers
|
||||
Because init containers have separate images from app containers, they have some advantages for start-up related code:
|
||||
* Init containers can contain utilities or custom code for setup that are not present in an app image. For example, there is no need to make an image `FROM` another image just to use a tool like `sed`, `awk`, `python`, or `dig` during setup.
|
||||
* Init containers can securely run utilities that would make an app container image less secure.
|
||||
* The application image builder and deployer roles can work independently without the need to jointly build a single app image.
|
||||
* Init containers can run with a different view of the filesystem than app containers in the same Pod. Consequently, they can be given access to {{< glossary_tooltip text="Secrets" term_id="secret" >}} that app containers cannot access.
|
||||
* Because init containers run to completion before any app containers start, init containers offer a mechanism to block or delay app container startup until a set of preconditions are met. Once preconditions are met, all of the app containers in a Pod can start in parallel.
|
||||
-->
|
||||
## Init 容器能做什么?
|
||||
|
||||
因为 Init 容器具有与应用容器分离的单独镜像,它们的启动相关代码具有如下优势:
|
||||
因为 Init 容器具有与应用容器分离的单独镜像,其启动相关代码具有如下优势:
|
||||
|
||||
* 它们可以包含并运行实用工具,出于安全考虑,是不建议在应用容器镜像中包含这些实用工具的。
|
||||
* 它们可以包含用于安装的工具和定制化代码,这些都是在应用镜像中没有的。例如,创建镜像没必要 `FROM` 另一个镜像,只需要在安装过程中使用类似 `sed`、 `awk`、 `python` 或 `dig` 这样的工具。
|
||||
* 应用镜像可以分离出创建和部署的角色,而没有必要联合它们构建一个单独的镜像。
|
||||
* 它们使用 Linux Namespace,所以对应用容器具有不同的文件系统视图。因此,它们能够具有访问 Secret 的权限,而应用容器不能够访问。
|
||||
* 它们在应用容器启动之前运行完成,然而应用容器并行运行,所以 Init 容器提供了一种简单的方式来阻塞或延迟应用容器的启动,直到满足了一组先决条件。
|
||||
* Init 容器可以包含一些安装过程中应用容器中不存在的实用工具或个性化代码。例如,没有必要仅为了在安装过程中使用类似 `sed`、 `awk`、 `python` 或 `dig` 这样的工具而去`FROM` 一个镜像来生成一个新的镜像。
|
||||
* Init 容器可以安全地运行这些工具,避免这些工具导致应用镜像的安全性降低。
|
||||
* 应用镜像的创建者和部署者可以各自独立工作,而没有必要联合构建一个单独的应用镜像。
|
||||
* Init 容器能以不同于Pod内应用容器的文件系统视图运行。因此,Init容器可具有访问 {{< glossary_tooltip text="Secrets" term_id="secret" >}} 的权限,而应用容器不能够访问。
|
||||
* 由于 Init 容器必须在应用容器启动之前运行完成,因此 Init 容器提供了一种机制来阻塞或延迟应用容器的启动,直到满足了一组先决条件。一旦前置条件满足,Pod内的所有的应用容器会并行启动。
|
||||
|
||||
|
||||
<!--
|
||||
### Examples
|
||||
Here are some ideas for how to use init containers:
|
||||
* Wait for a {{< glossary_tooltip text="Service" term_id="service">}} to
|
||||
be created, using a shell one-line command like:
|
||||
```shell
|
||||
for i in {1..100}; do sleep 1; if dig myservice; then exit 0; fi; done; exit 1
|
||||
```
|
||||
* Register this Pod with a remote server from the downward API with a command like:
|
||||
```shell
|
||||
curl -X POST http://$MANAGEMENT_SERVICE_HOST:$MANAGEMENT_SERVICE_PORT/register -d 'instance=$(<POD_NAME>)&ip=$(<POD_IP>)'
|
||||
```
|
||||
* Wait for some time before starting the app container with a command like
|
||||
```shell
|
||||
sleep 60
|
||||
```
|
||||
|
||||
* Clone a Git repository into a {{< glossary_tooltip text="Volume" term_id="volume" >}}
|
||||
* Place values into a configuration file and run a template tool to dynamically generate a configuration file for the main app container. For example, place the `POD_IP` value in a configuration and generate the main app configuration file using Jinja.
|
||||
|
||||
-->
|
||||
|
||||
### 示例
|
||||
|
||||
@@ -82,50 +138,38 @@ Init 容器支持应用容器的全部字段和特性,包括资源限制、数
|
||||
|
||||
curl -X POST http://$MANAGEMENT_SERVICE_HOST:$MANAGEMENT_SERVICE_PORT/register -d 'instance=$(<POD_NAME>)&ip=$(<POD_IP>)'
|
||||
|
||||
* 在启动应用容器之前等一段时间,使用类似 `sleep 60` 的命令。
|
||||
* 克隆 Git 仓库到数据卷。
|
||||
* 在启动应用容器之前等一段时间,使用类似命令:
|
||||
|
||||
`sleep 60`
|
||||
|
||||
* 克隆 Git 仓库到 {{< glossary_tooltip text="Volume" term_id="volume" >}}。
|
||||
* 将配置值放到配置文件中,运行模板工具为主应用容器动态地生成配置文件。例如,在配置文件中存放 POD_IP 值,并使用 Jinja 生成主应用配置文件。
|
||||
|
||||
更多详细用法示例,可以在 [StatefulSet 文档](/docs/concepts/abstractions/controllers/statefulsets/) 和 [Pod 初始化](/docs/tasks/configure-pod-container/configure-pod-initialization) 中找到。
|
||||
|
||||
|
||||
|
||||
### 使用 Init 容器
|
||||
|
||||
下面是 Kubernetes 1.5 版本 yaml 文件,展示了一个具有 2 个 Init 容器的简单 Pod。
|
||||
第一个等待 `myservice` 启动,第二个等待 `mydb` 启动。
|
||||
一旦这两个 Service 都启动完成,Pod 将开始启动。
|
||||
|
||||
<!--
|
||||
#### Init containers in use
|
||||
This example defines a simple Pod that has two init containers. The first waits for `myservice`, and the second waits for `mydb`. Once both init containers complete, the Pod runs the app container from its `spec` section.
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: myapp-pod
|
||||
labels:
|
||||
app: myapp
|
||||
annotations:
|
||||
pod.beta.kubernetes.io/init-containers: '[
|
||||
{
|
||||
"name": "init-myservice",
|
||||
"image": "busybox",
|
||||
"command": ["sh", "-c", "until nslookup myservice; do echo waiting for myservice; sleep 2; done;"]
|
||||
},
|
||||
{
|
||||
"name": "init-mydb",
|
||||
"image": "busybox",
|
||||
"command": ["sh", "-c", "until nslookup mydb; do echo waiting for mydb; sleep 2; done;"]
|
||||
}
|
||||
]'
|
||||
spec:
|
||||
containers:
|
||||
- name: myapp-container
|
||||
image: busybox
|
||||
command: ['sh', '-c', 'echo The app is running! && sleep 3600']
|
||||
|
||||
```
|
||||
|
||||
The following YAML file outlines the `mydb` and `myservice` services:
|
||||
```yaml
|
||||
|
||||
```
|
||||
|
||||
|
||||
You can start this Pod by running:
|
||||
```shell
|
||||
```
|
||||
|
||||
这是 Kubernetes 1.6 版本的新语法,尽管老的 annotation 语法仍然可以使用。我们已经把 Init 容器的声明移到 `spec` 中:
|
||||
And check on its status with:
|
||||
```shell
|
||||
```
|
||||
-->
|
||||
### 使用 Init 容器
|
||||
|
||||
下面的例子定义了一个具有 2 个 Init 容器的简单 Pod。 第一个等待 `myservice` 启动,第二个等待 `mydb` 启动。 一旦这两个 Init容器 都启动完成,Pod 将启动`spec`区域中的应用容器。
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
@@ -137,23 +181,17 @@ metadata:
|
||||
spec:
|
||||
containers:
|
||||
- name: myapp-container
|
||||
image: busybox
|
||||
image: busybox:1.28
|
||||
command: ['sh', '-c', 'echo The app is running! && sleep 3600']
|
||||
initContainers:
|
||||
- name: init-myservice
|
||||
image: busybox
|
||||
image: busybox:1.28
|
||||
command: ['sh', '-c', 'until nslookup myservice; do echo waiting for myservice; sleep 2; done;']
|
||||
- name: init-mydb
|
||||
image: busybox
|
||||
image: busybox:1.28
|
||||
command: ['sh', '-c', 'until nslookup mydb; do echo waiting for mydb; sleep 2; done;']
|
||||
```
|
||||
|
||||
|
||||
|
||||
1.5 版本的语法在 1.6 版本仍然可以使用,但是我们推荐使用 1.6 版本的新语法。
|
||||
在 Kubernetes 1.6 版本中,Init 容器在 API 中新建了一个字段。
|
||||
虽然期望使用 beta 版本的 annotation,但在未来发行版将会被废弃掉。
|
||||
|
||||
下面的 yaml 文件展示了 `mydb` 和 `myservice` 两个 Service:
|
||||
|
||||
```
|
||||
@@ -179,16 +217,35 @@ spec:
|
||||
```
|
||||
|
||||
|
||||
|
||||
这个 Pod 可以使用下面的命令进行启动和调试:
|
||||
要启动这个 Pod,可以执行如下命令:
|
||||
|
||||
```
|
||||
kubectl apply -f myapp.yaml
|
||||
```
|
||||
|
||||
```
|
||||
pod/myapp-pod created
|
||||
```
|
||||
|
||||
|
||||
|
||||
要检查其状态:
|
||||
```
|
||||
kubectl get -f myapp.yaml
|
||||
```
|
||||
|
||||
```
|
||||
$ kubectl create -f myapp.yaml
|
||||
pod "myapp-pod" created
|
||||
$ kubectl get -f myapp.yaml
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
myapp-pod 0/1 Init:0/2 0 6m
|
||||
$ kubectl describe -f myapp.yaml
|
||||
```
|
||||
|
||||
如需更详细的信息:
|
||||
|
||||
```
|
||||
kubectl describe -f myapp.yaml
|
||||
```
|
||||
|
||||
```
|
||||
Name: myapp-pod
|
||||
Namespace: default
|
||||
[...]
|
||||
@@ -221,111 +278,175 @@ Events:
|
||||
13s 13s 1 {kubelet 172.17.4.201} spec.initContainers{init-myservice} Normal Pulled Successfully pulled image "busybox"
|
||||
13s 13s 1 {kubelet 172.17.4.201} spec.initContainers{init-myservice} Normal Created Created container with docker id 5ced34a04634; Security:[seccomp=unconfined]
|
||||
13s 13s 1 {kubelet 172.17.4.201} spec.initContainers{init-myservice} Normal Started Started container with docker id 5ced34a04634
|
||||
```
|
||||
|
||||
如需查看Pod内 Init 容器的日志,请执行:
|
||||
|
||||
```
|
||||
$ kubectl logs myapp-pod -c init-myservice # Inspect the first init container
|
||||
$ kubectl logs myapp-pod -c init-mydb # Inspect the second init container
|
||||
```
|
||||
|
||||
<!--
|
||||
At this point, those init containers will be waiting to discover Services named `mydb` and `myservice`.
|
||||
|
||||
Here's a configuration you can use to make those Services appear:
|
||||
-->
|
||||
|
||||
一旦我们启动了 `mydb` 和 `myservice` 这两个 Service,我们能够看到 Init 容器完成,并且 `myapp-pod` 被创建:
|
||||
在这一刻,Init 容器将会等待至发现名称为`mydb`和`myservice`的 Service。
|
||||
|
||||
如下为创建这些 Service 的配置文件:
|
||||
|
||||
```
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: myservice
|
||||
spec:
|
||||
ports:
|
||||
- protocol: TCP
|
||||
port: 80
|
||||
targetPort: 9376
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: mydb
|
||||
spec:
|
||||
ports:
|
||||
- protocol: TCP
|
||||
port: 80
|
||||
targetPort: 9377
|
||||
```
|
||||
|
||||
|
||||
创建`mydb`和`myservice`的 service 命令:
|
||||
|
||||
```shell
|
||||
$ kubectl create -f services.yaml
|
||||
```
|
||||
|
||||
```
|
||||
service "myservice" created
|
||||
service "mydb" created
|
||||
```
|
||||
|
||||
这样你将能看到这些 Init容器 执行完毕,随后`my-app`的Pod转移进入 Running 状态:
|
||||
```shell
|
||||
$ kubectl get -f myapp.yaml
|
||||
```
|
||||
```shell
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
myapp-pod 1/1 Running 0 9m
|
||||
```
|
||||
|
||||
一旦我们启动了 `mydb` 和 `myservice` 这两个 Service,我们能够看到 Init 容器完成,并且 `myapp-pod` 被创建:
|
||||
|
||||
|
||||
这个例子非常简单,但是应该能够为创建自己的 Init 容器提供一些启发。
|
||||
<!--
|
||||
This simple example should provide some inspiration for you to create your own init containers. [What's next](#what-s-next) contains a link to a more detailed example.
|
||||
-->
|
||||
这个简单的例子应该能为你创建自己的 Init 容器提供一些启发。 [What's next](#what-s-next) 部分提供了更详细例子的链接。
|
||||
|
||||
|
||||
<!--
|
||||
During the startup of a Pod, each init container starts in order, after the network and volumes are initialized. Each container must exit successfully before the next container starts. If a container fails to start due to the runtime or exits with failure, it is retried according to the Pod `restartPolicy`. However, if the Pod `restartPolicy` is set to Always, the init containers use `restartPolicy` OnFailure.
|
||||
|
||||
A Pod cannot be `Ready` until all init containers have succeeded. The ports on an init container are not aggregated under a Service. A Pod that is initializing
|
||||
is in the `Pending` state but should have a condition `Initializing` set to true.
|
||||
|
||||
If the Pod [restarts](#pod-restart-reasons), or is restarted, all init containers must execute again.
|
||||
|
||||
Changes to the init container spec are limited to the container image field. Altering an init container image field is equivalent to restarting the Pod.
|
||||
|
||||
Because init containers can be restarted, retried, or re-executed, init container code should be idempotent. In particular, code that writes to files on `EmptyDirs` should be prepared for the possibility that an output file already exists.
|
||||
|
||||
Init containers have all of the fields of an app container. However, Kubernetes prohibits `readinessProbe` from being used because init containers cannot define readiness distinct from completion. This is enforced during validation.
|
||||
|
||||
Use `activeDeadlineSeconds` on the Pod and `livenessProbe` on the container to prevent init containers from failing forever. The active deadline includes init containers.
|
||||
|
||||
The name of each app and init container in a Pod must be unique; avalidation error is thrown for any container sharing a name with another.
|
||||
|
||||
-->
|
||||
|
||||
## 具体行为
|
||||
|
||||
在 Pod 启动过程中,Init 容器会按顺序在网络和数据卷初始化之后启动。
|
||||
每个容器必须在下一个容器启动之前成功退出。
|
||||
如果由于运行时或失败退出,导致容器启动失败,它会根据 Pod 的 `restartPolicy` 指定的策略进行重试。
|
||||
然而,如果 Pod 的 `restartPolicy` 设置为 Always,Init 容器失败时会使用 `RestartPolicy` 策略。
|
||||
在 Pod 启动过程中,每个Init 容器在网络和数据卷初始化之后会按顺序启动。每个 Init容器 成功退出后才会启动下一个 Init容器。 如果因为运行或退出时失败引发容器启动失败,它会根据 Pod 的 `restartPolicy` 策略进行重试。
|
||||
然而,如果 Pod 的 `restartPolicy` 设置为 Always,Init 容器失败时会使用 `restartPolicy` 的 OnFailure 策略。
|
||||
|
||||
|
||||
|
||||
在所有的 Init 容器没有成功之前,Pod 将不会变成 `Ready` 状态。
|
||||
Init 容器的端口将不会在 Service 中进行聚集。
|
||||
正在初始化中的 Pod 处于 `Pending` 状态,但应该会将条件 `Initialized` 设置为 true。
|
||||
在所有的 Init 容器没有成功之前,Pod 将不会变成 `Ready` 状态。 Init 容器的端口将不会在 Service 中进行聚集。 正在初始化中的 Pod 处于 `Pending` 状态,但会将条件 `Initializing` 设置为 true。
|
||||
|
||||
如果 Pod [重启](#pod-restart-reasons),所有 Init 容器必须重新执行。
|
||||
|
||||
对 Init 容器 spec 的修改,被限制在容器 image 字段中。
|
||||
更改 Init 容器的 image 字段,等价于重启该 Pod。
|
||||
对 Init 容器 spec 的修改仅限于容器的 image 字段。 更改 Init 容器的 image 字段,等同于重启该 Pod。
|
||||
|
||||
因为 Init 容器可能会被重启、重试或者重新执行,所以 Init 容器的代码应该是幂等的。 特别地,基于 `EmptyDirs` 写文件的代码,应该对输出文件可能已经存在做好准备。
|
||||
|
||||
Init 容器具有应用容器的所有字段。 然而 Kubernetes 禁止使用 `readinessProbe`,因为 Init 容器不能定义不同于完成(completion)的就绪(readiness)。 这一点会在校验时强制执行。
|
||||
|
||||
在 Pod 上使用 `activeDeadlineSeconds`和在容器上使用 `livenessProbe` 可以避免 Init 容器一直重复失败。 `activeDeadlineSeconds` 时间包含了 Init 容器启动的时间。
|
||||
|
||||
在 Pod 中的每个应用容器和 Init 容器的名称必须唯一;与任何其它容器共享同一个名称,会在校验时抛出错误。
|
||||
|
||||
|
||||
<!--
|
||||
### Resources
|
||||
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*
|
||||
* 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
|
||||
* Scheduling is done based on effective requests/limits, which means init containers can reserve resources for initialization that are not used during the life of the Pod.
|
||||
* The QoS (quality of service) tier of the Pod's *effective QoS tier* is the QoS tier for init containers and app containers alike.
|
||||
|
||||
因为 Init 容器可能会被重启、重试或者重新执行,所以 Init 容器的代码应该是幂等的。
|
||||
特别地,被写到 `EmptyDirs` 中文件的代码,应该对输出文件可能已经存在做好准备。
|
||||
|
||||
Init 容器具有应用容器的所有字段。
|
||||
然而 Kubernetes 禁止使用 `readinessProbe`,因为 Init 容器不能够定义不同于完成(completion)的就绪(readiness)。
|
||||
这会在验证过程中强制执行。
|
||||
|
||||
|
||||
|
||||
在 Pod 上使用 `activeDeadlineSeconds`,在容器上使用 `livenessProbe`,这样能够避免 Init 容器一直失败。
|
||||
这就为 Init 容器活跃设置了一个期限。
|
||||
|
||||
在 Pod 中的每个 app 和 Init 容器的名称必须唯一;与任何其它容器共享同一个名称,会在验证时抛出错误。
|
||||
|
||||
|
||||
Quota and limits are applied based on the effective Pod request and limit.
|
||||
Pod level control groups (cgroups) are based on the effective Pod request and limit, the same as the scheduler.
|
||||
-->
|
||||
|
||||
### 资源
|
||||
|
||||
为 Init 容器指定顺序和执行逻辑,下面对资源使用的规则将被应用:
|
||||
给定Init 容器的执行顺序下,资源使用适用于如下规则:
|
||||
|
||||
* 所有 Init 容器上定义的任何特定资源的 limit 或 request 的最大值,作为 Pod *有效初始 request/limit*
|
||||
* Pod 对资源的 *有效 limit/request * 是如下两者的较大者:
|
||||
* 所有应用容器对某个资源的 limit/request 之和
|
||||
* 对某个资源的有效初始 limit/request
|
||||
* 基于有效 limit/request 完成调度,这意味着 Init 容器能够为初始化过程预留资源,这些资源在 Pod 生命周期过程中并没有被使用。
|
||||
* Pod 的 *有效 QoS 层* ,与 Init 容器和应用容器的一样。
|
||||
|
||||
配额和限制适用于有效 Pod的 limit/request。
|
||||
Pod 级别的 cgroups 是基于有效 Pod 的 limit/request,和调度器相同。
|
||||
|
||||
|
||||
|
||||
* 在所有 Init 容器上定义的,任何特殊资源请求或限制的最大值,是 *有效初始请求/限制*
|
||||
* Pod 对资源的 *有效请求/限制* 要高于:
|
||||
* 所有应用容器对某个资源的请求/限制之和
|
||||
* 对某个资源的有效初始请求/限制
|
||||
* 基于有效请求/限制完成调度,这意味着 Init 容器能够为初始化预留资源,这些资源在 Pod 生命周期过程中并没有被使用。
|
||||
* Pod 的 *有效 QoS 层* ,是 Init 容器和应用容器相同的 QoS 层。
|
||||
|
||||
|
||||
|
||||
基于有效 Pod 请求和限制来应用配额和限制。
|
||||
Pod 级别的 cgroups 是基于有效 Pod 请求和限制,和调度器相同。
|
||||
|
||||
<!--
|
||||
### Pod restart reasons
|
||||
A Pod can restart, causing re-execution of init containers, for the following reasons:
|
||||
* A user updates the Pod specification, causing the init container image to change. Any changes to the init container image restarts the Pod. App container image changes only restart the app container.
|
||||
* The Pod infrastructure container is restarted. This is uncommon and would have to be done by someone with root access to nodes.
|
||||
* All containers in a Pod are terminated while `restartPolicy` is set to Always, forcing a restart, and the init container completion record has been lost due to garbage collection.
|
||||
|
||||
|
||||
-->
|
||||
### Pod 重启的原因
|
||||
|
||||
Pod 能够重启,会导致 Init 容器重新执行,主要有如下几个原因:
|
||||
Pod重启导致 Init 容器重新执行,主要有如下几个原因:
|
||||
|
||||
* 用户更新 PodSpec 导致 Init 容器镜像发生改变。应用容器镜像的变更只会重启应用容器。
|
||||
* Pod 基础设施容器被重启。这不多见,但某些具有 root 权限可访问 Node 的人可能会这样做。
|
||||
* 当 `restartPolicy` 设置为 Always,Pod 中所有容器会终止,强制重启,由于垃圾收集导致 Init 容器完成的记录丢失。
|
||||
* 用户更新 Pod 的 Spec 导致 Init 容器镜像发生改变。Init 容器镜像的变更会引起 Pod 重启. 应用容器镜像的变更仅会重启应用容器。
|
||||
* Pod 的基础设施容器 (译者注:如 pause 容器) 被重启。 这种情况不多见,必须由具备 root 权限访问 Node 的人员来完成。
|
||||
* 当 `restartPolicy` 设置为 Always,Pod 中所有容器会终止而强制重启,由于垃圾收集导致 Init 容器的完成记录丢失。
|
||||
|
||||
|
||||
|
||||
## 支持与兼容性
|
||||
|
||||
Apiserver 版本为 1.6 或更高版本的集群,通过使用 `spec.initContainers` 字段来支持 Init 容器。
|
||||
之前的版本可以使用 alpha 和 beta 注解支持 Init 容器。
|
||||
`spec.initContainers` 字段也被加入到 alpha 和 beta 注解中,所以 Kubernetes 1.3.0 版本或更高版本可以执行 Init 容器,并且 1.6 版本的 apiserver 能够安全的回退到 1.5.x 版本,而不会使存在的已创建 Pod 失去 Init 容器的功能。
|
||||
|
||||
{{% /capture %}}
|
||||
|
||||
|
||||
{{% capture whatsnext %}}
|
||||
|
||||
<!--
|
||||
* Read about [creating a Pod that has an init container](/docs/tasks/configure-pod-container/configure-pod-initialization/#creating-a-pod-that-has-an-init-container)
|
||||
* Learn how to [debug init containers](/docs/tasks/debug-application-cluster/debug-init-containers/)
|
||||
-->
|
||||
|
||||
|
||||
* [创建具有 Init 容器的 Pod](/docs/tasks/configure-pod-container/configure-pod-initialization/#creating-a-pod-that-has-an-init-container)
|
||||
|
||||
* 阅读[创建包含 Init 容器的 Pod](/docs/tasks/configure-pod-container/configure-pod-initialization/#creating-a-pod-that-has-an-init-container)
|
||||
* 学习如何[调测 Init 容器](/docs/tasks/debug-application-cluster/debug-init-containers/)
|
||||
{{% /capture %}}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,256 @@
|
||||
---
|
||||
reviewers:
|
||||
- erictune
|
||||
title: Pod 概览
|
||||
content_template: templates/concept
|
||||
weight: 10
|
||||
---
|
||||
|
||||
<!--
|
||||
---
|
||||
reviewers:
|
||||
- erictune
|
||||
title: Pod Overview
|
||||
content_template: templates/concept
|
||||
weight: 10
|
||||
---
|
||||
-->
|
||||
|
||||
{{% capture overview %}}
|
||||
<!--
|
||||
This page provides an overview of `Pod`, the smallest deployable object in the Kubernetes object model.
|
||||
-->
|
||||
本节提供了 `Pod` 的概览信息,`Pod` 是最小可部署的 Kubernetes 对象模型。
|
||||
{{% /capture %}}
|
||||
|
||||
|
||||
{{% capture body %}}
|
||||
|
||||
<!--
|
||||
## Understanding Pods
|
||||
|
||||
A *Pod* is the basic building block of Kubernetes--the smallest and simplest unit in the Kubernetes object model that you create or deploy. A Pod represents a running process on your cluster.
|
||||
-->
|
||||
|
||||
## 理解 Pod
|
||||
|
||||
*Pod* 是 Kubernetes 的基本构建块,它是 Kubernetes 对象模型中创建或部署的最小和最简单的单元。
|
||||
Pod 表示集群上正在运行的进程。
|
||||
|
||||
<!--
|
||||
A Pod encapsulates an application container (or, in some cases, multiple containers), storage resources, a unique network IP, and options that govern how the container(s) should run. A Pod represents a unit of deployment: *a single instance of an application in Kubernetes*, which might consist of either a single container or a small number of containers that are tightly coupled and that share resources.
|
||||
-->
|
||||
|
||||
Pod 封装了应用程序容器(或者在某些情况下封装多个容器)、存储资源、唯一网络 IP 以及控制容器应该如何运行的选项。
|
||||
Pod 表示部署单元:*Kubernetes 中应用程序的单个实例*,它可能由单个容器或少量紧密耦合并共享资源的容器组成。
|
||||
|
||||
<!--
|
||||
> [Docker](https://www.docker.com) is the most common container runtime used in a Kubernetes Pod, but Pods support other [container runtimes](https://kubernetes.io/docs/setup/production-environment/container-runtimes/) as well.
|
||||
|
||||
Pods in a Kubernetes cluster can be used in two main ways:
|
||||
-->
|
||||
[Docker](https://www.docker.com) 是 Kubernetes Pod 中最常用的容器运行时,但 Pod 也能支持其他的[容器运行时](https://kubernetes.io/docs/setup/production-environment/container-runtimes/)。
|
||||
|
||||
Kubernetes 集群中的 Pod 可被用于以下两个主要用途:
|
||||
|
||||
<!--
|
||||
* **Pods that run a single container**. The "one-container-per-Pod" model is the most common Kubernetes use case; in this case, you can think of a Pod as a wrapper around a single container, and Kubernetes manages the Pods rather than the containers directly.
|
||||
* **Pods that run multiple containers that need to work together**. A Pod might encapsulate an application composed of multiple co-located containers that are tightly coupled and need to share resources. These co-located containers might form a single cohesive unit of service--one container serving files from a shared volume to the public, while a separate "sidecar" container refreshes or updates those files. The Pod wraps these containers and storage resources together as a single manageable entity.
|
||||
-->
|
||||
|
||||
* **运行单个容器的 Pod**。"每个 Pod 一个容器"模型是最常见的 Kubernetes 用例;在这种情况下,可以将 Pod 看作单个容器的包装器,并且 Kubernetes 直接管理 Pod,而不是容器。
|
||||
* **运行多个协同工作的容器的 Pod**。
|
||||
Pod 可能封装由多个紧密耦合且需要共享资源的共处容器组成的应用程序。
|
||||
这些位于同一位置的容器可能形成单个内聚的服务单元——一个容器将文件从共享卷提供给公众,而另一个单独的“挂斗”容器则刷新或更新这些文件。
|
||||
Pod 将这些容器和存储资源打包为一个可管理的实体。
|
||||
|
||||
<!--
|
||||
The [Kubernetes Blog](http://kubernetes.io/blog) has some additional information on Pod use cases. For more information, see:
|
||||
|
||||
* [The Distributed System Toolkit: Patterns for Composite Containers](https://kubernetes.io/blog/2015/06/the-distributed-system-toolkit-patterns)
|
||||
* [Container Design Patterns](https://kubernetes.io/blog/2016/06/container-design-patterns)
|
||||
-->
|
||||
|
||||
[Kubernetes 博客](http://kubernetes.io/blog) 上有一些其他的 Pod 用例信息。更多信息请参考:
|
||||
|
||||
* [分布式系统工具包:复合容器的模式](https://kubernetes.io/blog/2015/06/the-distributed-system-toolkit-patterns)
|
||||
* [容器设计模式](https://kubernetes.io/blog/2016/06/container-design-patterns)
|
||||
|
||||
<!--
|
||||
Each Pod is meant to run a single instance of a given application. If you want to scale your application horizontally (e.g., run multiple instances), you should use multiple Pods, one for each instance. In Kubernetes, this is generally referred to as _replication_. Replicated Pods are usually created and managed as a group by an abstraction called a Controller. See [Pods and Controllers](#pods-and-controllers) for more information.
|
||||
-->
|
||||
|
||||
每个 Pod 表示运行给定应用程序的单个实例。如果希望横向扩展应用程序(例如,运行多个实例),则应该使用多个 Pod,每个实例使用一个。
|
||||
在 Kubernetes 中,这通常被称为 _副本_。
|
||||
通常使用一个称为控制器的抽象来创建和管理一组被复制的 Pod。
|
||||
更多信息请参见 [POD 和控制器](#pods-and-controllers)。
|
||||
|
||||
<!--
|
||||
### How Pods manage multiple Containers
|
||||
|
||||
Pods are designed to support multiple cooperating processes (as containers) that form a cohesive unit of service. The containers in a Pod are automatically co-located and co-scheduled on the same physical or virtual machine in the cluster. The containers can share resources and dependencies, communicate with one another, and coordinate when and how they are terminated.
|
||||
-->
|
||||
|
||||
### Pod 怎样管理多个容器
|
||||
|
||||
Pod 被设计成支持形成内聚服务单元的多个协作过程(作为容器)。
|
||||
Pod 中的容器被自动的安排到集群中的同一物理或虚拟机上,并可以一起进行调度。
|
||||
容器可以共享资源和依赖、彼此通信、协调何时以及何种方式终止它们。
|
||||
|
||||
<!--
|
||||
Note that grouping multiple co-located and co-managed containers in a single Pod is a relatively advanced use case. You should use this pattern only in specific instances in which your containers are tightly coupled. For example, you might have a container that acts as a web server for files in a shared volume, and a separate "sidecar" container that updates those files from a remote source, as in the following diagram:
|
||||
-->
|
||||
|
||||
注意,在单个 Pod 中将多个并置和共同管理的容器分组是一个相对高级的使用方式。
|
||||
只在容器紧密耦合的特定实例中使用此模式。
|
||||
例如,您可能有个充当共享卷中文件的 Web 服务器的容器,以及从远程源更新这些文件的单独的"挂斗"容器,如下图所示:
|
||||
|
||||
|
||||
{{< figure src="/images/docs/pod.svg" title="pod diagram" width="50%" >}}
|
||||
|
||||
<!--
|
||||
Pods provide two kinds of shared resources for their constituent containers: *networking* and *storage*.
|
||||
-->
|
||||
|
||||
Pod 为其组成容器提供了两种共享资源:*网络* 和 *存储*。
|
||||
|
||||
<!--
|
||||
#### Networking
|
||||
|
||||
Each Pod is assigned a unique IP address. Every container in a Pod shares the network namespace, including the IP address and network ports. Containers *inside a Pod* can communicate with one another using `localhost`. When containers in a Pod communicate with entities *outside the Pod*, they must coordinate how they use the shared network resources (such as ports).
|
||||
-->
|
||||
|
||||
#### 联网
|
||||
|
||||
每个 Pod 分配一个唯一的 IP 地址。
|
||||
Pod 中的每个容器共享网络命名空间,包括 IP 地址和网络端口。
|
||||
*Pod 内的容器* 可以使用 `localhost` 互相通信。
|
||||
当 Pod 中的容器与 *Pod 之外* 的实体通信时,它们必须协调如何使用共享的网络资源(例如端口)。
|
||||
|
||||
<!--
|
||||
#### Storage
|
||||
|
||||
A Pod can specify a set of shared storage *volumes*. All containers in the Pod can access the shared volumes, allowing those containers to share data. Volumes also allow persistent data in a Pod to survive in case one of the containers within needs to be restarted. See [Volumes](/docs/concepts/storage/volumes/) for more information on how Kubernetes implements shared storage in a Pod.
|
||||
-->
|
||||
|
||||
#### 存储
|
||||
|
||||
一个 Pod 可以指定一组共享存储 *卷*。
|
||||
Pod 中的所有容器都可以访问共享卷,允许这些容器共享数据。
|
||||
卷还允许 Pod 中的持久数据在重启 Pod 中的某个容器时存活。
|
||||
有关 Kubernetes 如何在 Pod 中实现共享存储的更多信息,请参考 [卷](/docs/concepts/storage/volumes/)。
|
||||
|
||||
<!--
|
||||
## Working with Pods
|
||||
|
||||
You'll rarely create individual Pods directly in Kubernetes--even singleton Pods. This is because Pods are designed as relatively ephemeral, disposable entities. When a Pod gets created (directly by you, or indirectly by a Controller), it is scheduled to run on a Node in your cluster. The Pod remains on that Node until the process is terminated, the pod object is deleted, the pod is *evicted* for lack of resources, or the Node fails.
|
||||
-->
|
||||
|
||||
## 使用 Pod
|
||||
|
||||
你很少在 Kubernetes 中直接创建单独的 Pod,甚至是单个存在的 Pod。
|
||||
这是因为 Pod 被设计成了相对短暂的一次性的实体。
|
||||
当 Pod 由您创建或者间接地由控制器创建时,它被调度在集群中的节点上运行。
|
||||
Pod 会保持在该节点上运行,直到进程被终止、Pod 对象被删除、Pod 因资源不足而被 *驱逐* 或者节点失效为止。
|
||||
{{< note >}}
|
||||
<!--
|
||||
Restarting a container in a Pod should not be confused with restarting the Pod. The Pod itself does not run, but is an environment the containers run in and persists until it is deleted.
|
||||
-->
|
||||
重启 Pod 中的容器不应与重启 Pod 混淆。Pod 本身不运行,而是作为容器运行的环境,并且一直保持到被删除为止。
|
||||
{{< /note >}}
|
||||
|
||||
<!--
|
||||
Pods do not, by themselves, self-heal. If a Pod is scheduled to a Node that fails, or if the scheduling operation itself fails, the Pod is deleted; likewise, a Pod won't survive an eviction due to a lack of resources or Node maintenance. Kubernetes uses a higher-level abstraction, called a *Controller*, that handles the work of managing the relatively disposable Pod instances. Thus, while it is possible to use Pod directly, it's far more common in Kubernetes to manage your pods using a Controller. See [Pods and Controllers](#pods-and-controllers) for more information on how Kubernetes uses Controllers to implement Pod scaling and healing.
|
||||
-->
|
||||
|
||||
Pod 本身并不能自愈。
|
||||
如果 Pod 被调度到失败的节点,或者如果调度操作本身失败,则删除该 Pod;同样,由于缺乏资源或进行节点维护,Pod 在被驱逐后将不再生存。
|
||||
Kubernetes 使用了一个更高级的称为 *控制器* 的抽象,由它处理相对可丢弃的 Pod 实例的管理工作。
|
||||
因此,虽然可以直接使用 Pod,但在 Kubernetes 中,更为常见的是使用控制器管理 Pod。
|
||||
有关 Kubernetes 如何使用控制器实现 Pod 伸缩和愈合的更多信息,请参考 [Pod 和控制器](#pods-and-controllers)。
|
||||
|
||||
<!--
|
||||
### Pods and Controllers
|
||||
|
||||
A Controller can create and manage multiple Pods for you, handling replication and rollout and providing self-healing capabilities at cluster scope. For example, if a Node fails, the Controller might automatically replace the Pod by scheduling an identical replacement on a different Node.
|
||||
-->
|
||||
|
||||
### Pod 和控制器
|
||||
|
||||
控制器可以为您创建和管理多个 Pod,管理副本和上线,并在集群范围内提供自修复能力。
|
||||
例如,如果一个节点失败,控制器可以在不同的节点上调度一样的替身来自动替换 Pod。
|
||||
|
||||
<!--
|
||||
Some examples of Controllers that contain one or more pods include:
|
||||
|
||||
* [Deployment](/docs/concepts/workloads/controllers/deployment/)
|
||||
* [StatefulSet](/docs/concepts/workloads/controllers/statefulset/)
|
||||
* [DaemonSet](/docs/concepts/workloads/controllers/daemonset/)
|
||||
|
||||
In general, Controllers use a Pod Template that you provide to create the Pods for which it is responsible.
|
||||
-->
|
||||
|
||||
包含一个或多个 Pod 的控制器一些示例包括:
|
||||
|
||||
* [Deployment](/docs/concepts/workloads/controllers/deployment/)
|
||||
* [StatefulSet](/docs/concepts/workloads/controllers/statefulset/)
|
||||
* [DaemonSet](/docs/concepts/workloads/controllers/daemonset/)
|
||||
|
||||
控制器通常使用您提供的 Pod 模板来创建它所负责的 Pod。
|
||||
|
||||
<!--
|
||||
## Pod Templates
|
||||
|
||||
Pod templates are pod specifications which are included in other objects, such as
|
||||
[Replication Controllers](/docs/concepts/workloads/controllers/replicationcontroller/), [Jobs](/docs/concepts/jobs/run-to-completion-finite-workloads/), and
|
||||
[DaemonSets](/docs/concepts/workloads/controllers/daemonset/). Controllers use Pod Templates to make actual pods.
|
||||
The sample below is a simple manifest for a Pod which contains a container that prints
|
||||
a message.
|
||||
-->
|
||||
|
||||
## Pod 模板
|
||||
|
||||
Pod 模板是包含在其他对象中的 Pod 规范,例如
|
||||
[Replication Controllers](/docs/concepts/workloads/controllers/replicationcontroller/)、 [Jobs](/docs/concepts/jobs/run-to-completion-finite-workloads/)、和
|
||||
[DaemonSets](/docs/concepts/workloads/controllers/daemonset/)。
|
||||
控制器使用 Pod 模板来制作实际使用的 Pod。
|
||||
下面的示例是一个简单的 Pod 清单,它包含一个打印消息的容器。
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: myapp-pod
|
||||
labels:
|
||||
app: myapp
|
||||
spec:
|
||||
containers:
|
||||
- name: myapp-container
|
||||
image: busybox
|
||||
command: ['sh', '-c', 'echo Hello Kubernetes! && sleep 3600']
|
||||
```
|
||||
|
||||
<!--
|
||||
Rather than specifying the current desired state of all replicas, pod templates are like cookie cutters. Once a cookie has been cut, the cookie has no relationship to the cutter. There is no "quantum entanglement". Subsequent changes to the template or even switching to a new template has no direct effect on the pods already created. Similarly, pods created by a replication controller may subsequently be updated directly. This is in deliberate contrast to pods, which do specify the current desired state of all containers belonging to the pod. This approach radically simplifies system semantics and increases the flexibility of the primitive.
|
||||
-->
|
||||
|
||||
Pod 模板就像饼干切割器,而不是指定所有副本的当前期望状态。
|
||||
一旦饼干被切掉,饼干就与切割器没有关系。
|
||||
没有“量子纠缠”。
|
||||
随后对模板的更改或甚至切换到新的模板对已经创建的 Pod 没有直接影响。
|
||||
类似地,由副本控制器创建的 Pod 随后可以被直接更新。
|
||||
这与 Pod 形成有意的对比,Pod 指定了属于 Pod 的所有容器的当前期望状态。
|
||||
这种方法从根本上简化了系统语义,增加了原语的灵活性。
|
||||
|
||||
{{% /capture %}}
|
||||
|
||||
{{% capture whatsnext %}}
|
||||
<!--
|
||||
* Learn more about Pod behavior:
|
||||
* [Pod Termination](/docs/concepts/workloads/pods/pod/#termination-of-pods)
|
||||
* Other Pod Topics
|
||||
-->
|
||||
* 进一步了解 Pod 的行为:
|
||||
* [Pod 的终止](/docs/concepts/workloads/pods/pod/#termination-of-pods)
|
||||
* 其他 Pod 话题
|
||||
{{% /capture %}}
|
||||
@@ -0,0 +1,402 @@
|
||||
---
|
||||
title: Pod 拓扑扩展约束
|
||||
content_template: templates/concept
|
||||
weight: 50
|
||||
---
|
||||
|
||||
<!--
|
||||
---
|
||||
title: Pod Topology Spread Constraints
|
||||
content_template: templates/concept
|
||||
weight: 50
|
||||
---
|
||||
-->
|
||||
|
||||
|
||||
{{% capture overview %}}
|
||||
|
||||
{{< feature-state for_k8s_version="v1.16" state="alpha" >}}
|
||||
|
||||
<!--
|
||||
You can use _topology spread constraints_ to control how {{< glossary_tooltip text="Pods" term_id="Pod" >}} are spread across your cluster among failure-domains such as regions, zones, nodes, and other user-defined topology domains. This can help to achieve high availability as well as efficient resource utilization.
|
||||
-->
|
||||
|
||||
可以使用_拓扑扩展约束_来控制 {{< glossary_tooltip text="Pods" term_id="Pod" >}} 在集群内故障域(例如地区,区域,节点和其他用户自定义拓扑域)之间的分布。这可以帮助实现高可用以及提升资源利用率。
|
||||
|
||||
{{% /capture %}}
|
||||
|
||||
{{% capture body %}}
|
||||
|
||||
<!--
|
||||
## Prerequisites
|
||||
-->
|
||||
|
||||
## 先决条件
|
||||
|
||||
<!--
|
||||
### Enable Feature Gate
|
||||
-->
|
||||
|
||||
### 启用功能
|
||||
|
||||
<!--
|
||||
Ensure the `EvenPodsSpread` feature gate is enabled (it is disabled by default
|
||||
in 1.16). See [Feature Gates](/docs/reference/command-line-tools-reference/feature-gates/)
|
||||
for an explanation of enabling feature gates. The `EvenPodsSpread` feature gate must be enabled for the
|
||||
{{< glossary_tooltip text="API Server" term_id="kube-apiserver" >}} **and**
|
||||
{{< glossary_tooltip text="scheduler" term_id="kube-scheduler" >}}.
|
||||
-->
|
||||
|
||||
确保 `EvenPodsSpread` 功能已开启(在 1.16 版本中该功能默认关闭)。阅读[功能选项](/docs/reference/command-line-tools-reference/feature-gates/)了解如何开启该功能。`EvenPodsSpread` 必须在 {{< glossary_tooltip text="API Server" term_id="kube-apiserver" >}} **和** {{< glossary_tooltip text="scheduler" term_id="kube-scheduler" >}} 中都要开启。
|
||||
|
||||
<!--
|
||||
### Node Labels
|
||||
-->
|
||||
|
||||
### 节点标签
|
||||
|
||||
<!--
|
||||
Topology spread constraints rely on node labels to identify the topology domain(s) that each Node is in. For example, a Node might have labels: `node=node1,zone=us-east-1a,region=us-east-1`
|
||||
-->
|
||||
|
||||
拓扑扩展约束依赖于节点标签来标识每个节点所在的拓扑域。例如,一个节点可能具有标签:`node=node1,zone=us-east-1a,region=us-east-1`
|
||||
|
||||
<!--
|
||||
Suppose you have a 4-node cluster with the following labels:
|
||||
-->
|
||||
|
||||
假设你拥有一个具有以下标签的 4 节点集群:
|
||||
|
||||
```
|
||||
NAME STATUS ROLES AGE VERSION LABELS
|
||||
node1 Ready <none> 4m26s v1.16.0 node=node1,zone=zoneA
|
||||
node2 Ready <none> 3m58s v1.16.0 node=node2,zone=zoneA
|
||||
node3 Ready <none> 3m17s v1.16.0 node=node3,zone=zoneB
|
||||
node4 Ready <none> 2m43s v1.16.0 node=node4,zone=zoneB
|
||||
```
|
||||
|
||||
<!--
|
||||
Then the cluster is logically viewed as below:
|
||||
-->
|
||||
|
||||
然后从逻辑上看集群如下:
|
||||
|
||||
```
|
||||
+---------------+---------------+
|
||||
| zoneA | zoneB |
|
||||
+-------+-------+-------+-------+
|
||||
| node1 | node2 | node3 | node4 |
|
||||
+-------+-------+-------+-------+
|
||||
```
|
||||
|
||||
<!--
|
||||
Instead of manually applying labels, you can also reuse the [well-known labels](/docs/reference/kubernetes-api/labels-annotations-taints/) that are created and populated automatically on most clusters.
|
||||
-->
|
||||
|
||||
可以复用在大多数集群上自动创建和填充的[知名标签](/docs/reference/kubernetes-api/labels-annotations-taints/),而不是手动添加标签。
|
||||
|
||||
<!--
|
||||
## Spread Constraints for Pods
|
||||
-->
|
||||
|
||||
## Pod 的拓扑约束
|
||||
|
||||
### API
|
||||
|
||||
<!--
|
||||
The field `pod.spec.topologySpreadConstraints` is introduced in 1.16 as below:
|
||||
-->
|
||||
|
||||
`pod.spec.topologySpreadConstraints` 字段定义如下所示:
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: mypod
|
||||
spec:
|
||||
topologySpreadConstraints:
|
||||
- maxSkew: <integer>
|
||||
topologyKey: <string>
|
||||
whenUnsatisfiable: <string>
|
||||
labelSelector: <object>
|
||||
```
|
||||
|
||||
<!--
|
||||
You can define one or multiple `topologySpreadConstraint` to instruct the kube-scheduler how to place each incoming Pod in relation to the existing Pods across your cluster. The fields are:
|
||||
-->
|
||||
|
||||
可以定义一个或多个 `topologySpreadConstraint` 来指示 kube-scheduler 如何将每个传入的 Pod 根据与现有的 Pod 的关联关系在集群中部署。字段包括:
|
||||
|
||||
<!--
|
||||
- **maxSkew** describes the degree to which Pods may be unevenly distributed. It's the maximum permitted difference between the number of matching Pods in any two topology domains of a given topology type. It must be greater than zero.
|
||||
- **topologyKey** is the key of node labels. If two Nodes are labelled with this key and have identical values for that label, the scheduler treats both Nodes as being in the same topology. The scheduler tries to place a balanced number of Pods into each topology domain.
|
||||
- **whenUnsatisfiable** indicates how to deal with a Pod if it doesn't satisfy the spread constraint:
|
||||
- `DoNotSchedule` (default) tells the scheduler not to schedule it.
|
||||
- `ScheduleAnyway` tells the scheduler to still schedule it while prioritizing nodes that minimize the skew.
|
||||
- **labelSelector** is used to find matching Pods. Pods that match this label selector are counted to determine the number of Pods in their corresponding topology domain. See [Label Selectors](/docs/concepts/overview/working-with-objects/labels/#label-selectors) for more details.
|
||||
-->
|
||||
|
||||
- **maxSkew** 描述 pod 分布不均的程度。这是给定拓扑类型中任意两个拓扑域中匹配的 pod 之间的最大允许差值。它必须大于零。
|
||||
- **topologyKey** 是节点标签的键。如果两个节点使用此键标记并且具有相同的标签值,则调度器会将这两个节点视为处于同一拓扑中。调度器试图在每个拓扑域中放置数量均衡的 pod。
|
||||
- **whenUnsatisfiable** 指示如果 pod 不满足扩展约束时如何处理:
|
||||
- `DoNotSchedule`(默认)告诉调度器不用进行调度。
|
||||
- `ScheduleAnyway` 告诉调度器在对最小化倾斜的节点进行优先级排序时仍对其进行调度。
|
||||
- **labelSelector** 用于查找匹配的 pod。匹配此标签的 pod 将被统计,以确定相应拓扑域中 pod 的数量。有关详细信息,请参考[标签选择器](/docs/concepts/overview/working-with-objects/labels/#label-selectors)。
|
||||
|
||||
<!--
|
||||
You can read more about this field by running `kubectl explain Pod.spec.topologySpreadConstraints`.
|
||||
-->
|
||||
|
||||
执行 `kubectl explain Pod.spec.topologySpreadConstraints` 命令了解更多关于 topologySpreadConstraints 的信息。
|
||||
|
||||
<!--
|
||||
### Example: One TopologySpreadConstraint
|
||||
-->
|
||||
|
||||
### 例子:单个拓扑扩展约束
|
||||
|
||||
<!--
|
||||
Suppose you have a 4-node cluster where 3 Pods labeled `foo:bar` are located in node1, node2 and node3 respectively (`P` represents Pod):
|
||||
-->
|
||||
|
||||
假设你拥有一个 4 节点集群,其中标记为 `foo:bar` 的 3 个 pod 分别位于 node1,node2 和 node3 中(`P` 表示 pod):
|
||||
|
||||
```
|
||||
+---------------+---------------+
|
||||
| zoneA | zoneB |
|
||||
+-------+-------+-------+-------+
|
||||
| node1 | node2 | node3 | node4 |
|
||||
+-------+-------+-------+-------+
|
||||
| P | P | P | |
|
||||
+-------+-------+-------+-------+
|
||||
```
|
||||
|
||||
<!--
|
||||
If we want an incoming Pod to be evenly spread with existing Pods across zones, the spec can be given as:
|
||||
-->
|
||||
|
||||
如果希望传入的 pod 均匀散布在现有的 pod 区域,则可以指定字段如下:
|
||||
|
||||
{{< codenew file="pods/topology-spread-constraints/one-constraint.yaml" >}}
|
||||
|
||||
<!--
|
||||
`topologyKey: zone` implies the even distribution will only be applied to the nodes which have label pair "zone:<any value>" present. `whenUnsatisfiable: DoNotSchedule` tells the scheduler to let it stay pending if the incoming Pod can’t satisfy the constraint.
|
||||
-->
|
||||
|
||||
`topologyKey: zone` 意味着均匀分布将只应用于存在标签对为 "zone:<any value>" 的节点上。`whenUnsatisfiable: DoNotSchedule` 告诉调度器,如果传入的 pod 不满足约束,则让它保持挂起状态。
|
||||
|
||||
<!--
|
||||
If the scheduler placed this incoming Pod into "zoneA", the Pods distribution would become [3, 1], hence the actual skew is 2 (3 - 1) - which violates `maxSkew: 1`. In this example, the incoming Pod can only be placed onto "zoneB":
|
||||
-->
|
||||
|
||||
如果调度器将传入的 pod 放入 "zoneA",pod 分布将变为 [3, 1],因此实际的倾斜为 2(3 - 1)。这违反了 `maxSkew: 1`。此示例中,传入的 pod 只能放置在 "zoneB" 上:
|
||||
|
||||
```
|
||||
+---------------+---------------+ +---------------+---------------+
|
||||
| zoneA | zoneB | | zoneA | zoneB |
|
||||
+-------+-------+-------+-------+ +-------+-------+-------+-------+
|
||||
| node1 | node2 | node3 | node4 | OR | node1 | node2 | node3 | node4 |
|
||||
+-------+-------+-------+-------+ +-------+-------+-------+-------+
|
||||
| P | P | P | P | | P | P | P P | |
|
||||
+-------+-------+-------+-------+ +-------+-------+-------+-------+
|
||||
```
|
||||
|
||||
<!--
|
||||
You can tweak the Pod spec to meet various kinds of requirements:
|
||||
-->
|
||||
|
||||
可以调整 pod 规格以满足各种要求:
|
||||
|
||||
<!--
|
||||
- Change `maxSkew` to a bigger value like "2" so that the incoming Pod can be placed onto "zoneA" as well.
|
||||
- Change `topologyKey` to "node" so as to distribute the Pods evenly across nodes instead of zones. In the above example, if `maxSkew` remains "1", the incoming Pod can only be placed onto "node4".
|
||||
- Change `whenUnsatisfiable: DoNotSchedule` to `whenUnsatisfiable: ScheduleAnyway` to ensure the incoming Pod to be always schedulable (suppose other scheduling APIs are satisfied). However, it’s preferred to be placed onto the topology domain which has fewer matching Pods. (Be aware that this preferability is jointly normalized with other internal scheduling priorities like resource usage ratio, etc.)
|
||||
-->
|
||||
|
||||
- 将 `maxSkew` 更改为更大的值,比如 "2",这样传入的 pod 也可以放在 "zoneA" 上。
|
||||
- 将 `topologyKey` 更改为 "node",以便将 pod 均匀分布在节点上而不是区域中。在上面的例子中,如果 `maxSkew` 保持为 "1",那么传入的 pod 只能放在 "node4" 上。
|
||||
- 将 `whenUnsatisfiable: DoNotSchedule` 更改为 `whenUnsatisfiable: ScheduleAnyway`,以确保传入的 pod 始终可以调度(假设满足其他的调度 API)。但是,最好将其放置在具有较少匹配 pod 的拓扑域中。(请注意,此优先性与其他内部调度优先级(如资源使用率等)一起进行标准化。)
|
||||
|
||||
<!--
|
||||
### Example: Multiple TopologySpreadConstraints
|
||||
-->
|
||||
|
||||
### 例子:多个拓扑扩展约束
|
||||
|
||||
<!--
|
||||
This builds upon the previous example. Suppose you have a 4-node cluster where 3 Pods labeled `foo:bar` are located in node1, node2 and node3 respectively (`P` represents Pod):
|
||||
-->
|
||||
|
||||
下面的例子建立在前面例子的基础上。假设你拥有一个 4 节点集群,其中 3 个标记为 `foo:bar` 的 pod 分别位于 node1,node2 和 node3 上(`P` 表示 pod):
|
||||
|
||||
```
|
||||
+---------------+---------------+
|
||||
| zoneA | zoneB |
|
||||
+-------+-------+-------+-------+
|
||||
| node1 | node2 | node3 | node4 |
|
||||
+-------+-------+-------+-------+
|
||||
| P | P | P | |
|
||||
+-------+-------+-------+-------+
|
||||
```
|
||||
|
||||
<!--
|
||||
You can use 2 TopologySpreadConstraints to control the Pods spreading on both zone and node:
|
||||
-->
|
||||
|
||||
可以使用 2 个拓扑扩展约束来控制 pod 在 区域和节点两个维度上进行分布:
|
||||
|
||||
{{< codenew file="pods/topology-spread-constraints/two-constraints.yaml" >}}
|
||||
|
||||
<!--
|
||||
In this case, to match the first constraint, the incoming Pod can only be placed onto "zoneB"; while in terms of the second constraint, the incoming Pod can only be placed onto "node4". Then the results of 2 constraints are ANDed, so the only viable option is to place on "node4".
|
||||
-->
|
||||
|
||||
在这种情况下,为了匹配第一个约束,传入的 pod 只能放置在 "zoneB" 中;而在第二个约束中,传入的 pod 只能放置在 "node4" 上。然后两个约束的结果加在一起,因此唯一可行的选择是放置在 "node4" 上。
|
||||
|
||||
<!--
|
||||
Multiple constraints can lead to conflicts. Suppose you have a 3-node cluster across 2 zones:
|
||||
-->
|
||||
|
||||
多个约束可能导致冲突。假设有一个跨越 2 个区域的 3 节点集群:
|
||||
|
||||
```
|
||||
+---------------+-------+
|
||||
| zoneA | zoneB |
|
||||
+-------+-------+-------+
|
||||
| node1 | node2 | nod3 |
|
||||
+-------+-------+-------+
|
||||
| P P | P | P P |
|
||||
+-------+-------+-------+
|
||||
```
|
||||
|
||||
<!--
|
||||
If you apply "two-constraints.yaml" to this cluster, you will notice "mypod" stays in `Pending` state. This is because: to satisfy the first constraint, "mypod" can only be put to "zoneB"; while in terms of the second constraint, "mypod" can only put to "node2". Then a joint result of "zoneB" and "node2" returns nothing.
|
||||
-->
|
||||
|
||||
如果对集群应用 "two-constraints.yaml",会发现 "mypod" 处于 `Pending` 状态。这是因为:为了满足第一个约束,"mypod" 只能放在 "zoneB" 中,而第二个约束要求 "mypod" 只能放在 "node2" 上。pod 调度无法满足两种约束。
|
||||
|
||||
<!--
|
||||
To overcome this situation, you can either increase the `maxSkew` or modify one of the constraints to use `whenUnsatisfiable: ScheduleAnyway`.
|
||||
-->
|
||||
|
||||
为了克服这种情况,可以增加 `maxSkew` 或修改其中一个约束,让其使用 `whenUnsatisfiable: ScheduleAnyway`。
|
||||
|
||||
<!--
|
||||
### Conventions
|
||||
-->
|
||||
|
||||
### 约定
|
||||
|
||||
<!--
|
||||
There are some implicit conventions worth noting here:
|
||||
-->
|
||||
|
||||
这里有一些值得注意的隐式约定:
|
||||
|
||||
<!--
|
||||
- Only the Pods holding the same namespace as the incoming Pod can be matching candidates.
|
||||
-->
|
||||
|
||||
- 只有与传入 pod 具有相同命名空间的 pod 才能作为匹配候选者。
|
||||
|
||||
<!--
|
||||
- Nodes without `topologySpreadConstraints[*].topologyKey` present will be bypassed. It implies that:
|
||||
1. the Pods located on those nodes do not impact `maxSkew` calculation - in the above example, suppose "node1" does not have label "zone", then the 2 Pods will be disregarded, hence the incomingPod will be scheduled into "zoneA".
|
||||
2. the incoming Pod has no chances to be scheduled onto this kind of nodes - in the above example, suppose a "node5" carrying label `{zone-typo: zoneC}` joins the cluster, it will be bypassed due to the absence of label key "zone".
|
||||
-->
|
||||
|
||||
- 没有 `topologySpreadConstraints[*].topologyKey` 的节点将被忽略。这意味着:
|
||||
1. 位于这些节点上的 pod 不影响 `maxSkew` 的计算。在上面的例子中,假设 "node1" 没有标签 "zone",那么 2 个 pod 将被忽略,因此传入的 pod 将被调度到 "zoneA" 中。
|
||||
2. 传入的 pod 没有机会被调度到这类节点上。在上面的例子中,假设一个带有标签 `{zone-typo: zoneC}` 的 "node5" 加入到集群,它将由于没有标签键 "zone" 而被忽略。
|
||||
|
||||
<!--
|
||||
- Be aware of what will happen if the incomingPod’s `topologySpreadConstraints[*].labelSelector` doesn’t match its own labels. In the above example, if we remove the incoming Pod’s labels, it can still be placed onto "zoneB" since the constraints are still satisfied. However, after the placement, the degree of imbalance of the cluster remains unchanged - it’s still zoneA having 2 Pods which hold label {foo:bar}, and zoneB having 1 Pod which holds label {foo:bar}. So if this is not what you expect, we recommend the workload’s `topologySpreadConstraints[*].labelSelector` to match its own labels.
|
||||
-->
|
||||
|
||||
注意,如果传入 pod 的 `topologySpreadConstraints[*].labelSelector` 与自身的标签不匹配,将会发生什么。在上面的例子中,如果移除传入 pod 的标签,pod 仍然可以调度到 "zoneB",因为约束仍然满足。然而,在调度之后,集群的不平衡程度保持不变。zoneA 仍然有 2 个带有 {foo:bar} 标签的 pod,zoneB 有 1 个带有 {foo:bar} 标签的 pod。因此,如果这不是你所期望的,建议工作负载的 `topologySpreadConstraints[*].labelSelector` 与其自身的标签匹配。
|
||||
|
||||
<!--
|
||||
- If the incoming Pod has `spec.nodeSelector` or `spec.affinity.nodeAffinity` defined, nodes not matching them will be bypassed.
|
||||
-->
|
||||
|
||||
- 如果传入的 pod 定义了 `spec.nodeSelector` 或 `spec.affinity.nodeAffinity`,则将忽略不匹配的节点。
|
||||
|
||||
<!--
|
||||
Suppose you have a 5-node cluster ranging from zoneA to zoneC:
|
||||
-->
|
||||
|
||||
假设有一个从 zonea 到 zonec 的 5 节点集群:
|
||||
|
||||
|
||||
```
|
||||
+---------------+---------------+-------+
|
||||
| zoneA | zoneB | zoneC |
|
||||
+-------+-------+-------+-------+-------+
|
||||
| node1 | node2 | node3 | node4 | node5 |
|
||||
+-------+-------+-------+-------+-------+
|
||||
| P | P | P | | |
|
||||
+-------+-------+-------+-------+-------+
|
||||
```
|
||||
|
||||
<!--
|
||||
and you know that "zoneC" must be excluded. In this case, you can compose the yaml as below, so that "mypod" will be placed onto "zoneB" instead of "zoneC". Similarly `spec.nodeSelector` is also respected.
|
||||
-->
|
||||
|
||||
你知道 "zoneC" 必须被排除在外。在这种情况下,可以按如下方式编写 yaml,以便将 "mypod" 放置在 "zoneB" 上,而不是 "zoneC" 上。同样,`spec.nodeSelector` 也要一样处理。
|
||||
|
||||
{{< codenew file="pods/topology-spread-constraints/one-constraint-with-nodeaffinity.yaml" >}}
|
||||
|
||||
<!--
|
||||
## Comparison with PodAffinity/PodAntiAffinity
|
||||
-->
|
||||
|
||||
## 与 PodAffinity/PodAntiAffinity 相比较
|
||||
|
||||
<!--
|
||||
In Kubernetes, directives related to "Affinity" control how Pods are
|
||||
scheduled - more packed or more scattered.
|
||||
-->
|
||||
|
||||
在 Kubernetes 中,与 "Affinity" 相关的指令控制 pod 的调度方式(更密集或更分散)。
|
||||
|
||||
<!--
|
||||
- For `PodAffinity`, you can try to pack any number of Pods into qualifying
|
||||
topology domain(s)
|
||||
- For `PodAntiAffinity`, only one Pod can be scheduled into a
|
||||
single topology domain.
|
||||
-->
|
||||
|
||||
- 对于 `PodAffinity`,可以尝试将任意数量的 pod 打包到符合条件的拓扑域中。
|
||||
- 对于 `PodAntiAffinity`,只能将一个 pod 调度到单个拓扑域中。
|
||||
|
||||
<!--
|
||||
The "EvenPodsSpread" feature provides flexible options to distribute Pods evenly across different
|
||||
topology domains - to achieve high availability or cost-saving. This can also help on rolling update
|
||||
workloads and scaling out replicas smoothly.
|
||||
See [Motivation](https://github.com/kubernetes/enhancements/blob/master/keps/sig-scheduling/20190221-even-pods-spreading.md#motivation) for more details.
|
||||
-->
|
||||
|
||||
"EvenPodsSpread" 功能提供灵活的选项来将 pod 均匀分布到不同的拓扑域中,以实现高可用性或节省成本。这也有助于滚动更新工作负载和平滑扩展副本。有关详细信息,请参考[动机](https://github.com/kubernetes/enhancements/blob/master/keps/sig-scheduling/20190221-even-pods-spreading.md#motivation)。
|
||||
|
||||
<!--
|
||||
## Known Limitations
|
||||
-->
|
||||
|
||||
## 已知局限性
|
||||
|
||||
<!--
|
||||
As of 1.16, at which this feature is Alpha, there are some known limitations:
|
||||
-->
|
||||
|
||||
1.16 版本(此功能为 alpha)存在下面的一些限制:
|
||||
|
||||
<!--
|
||||
- Scaling down a `Deployment` may result in imbalanced Pods distribution.
|
||||
- Pods matched on tainted nodes are respected. See [Issue 80921](https://github.com/kubernetes/kubernetes/issues/80921)
|
||||
-->
|
||||
|
||||
- `Deployment` 的缩容可能导致 pod 分布不平衡。
|
||||
- pod 匹配到污点节点是允许的。参考 [Issue 80921](https://github.com/kubernetes/kubernetes/issues/80921)。
|
||||
|
||||
{{% /capture %}}
|
||||
@@ -0,0 +1,399 @@
|
||||
---
|
||||
reviewers:
|
||||
title: Pods
|
||||
content_template: templates/concept
|
||||
weight: 20
|
||||
---
|
||||
|
||||
<!--
|
||||
---
|
||||
reviewers:
|
||||
title: Pods
|
||||
content_template: templates/concept
|
||||
weight: 20
|
||||
---
|
||||
-->
|
||||
|
||||
{{% capture overview %}}
|
||||
|
||||
<!--
|
||||
_Pods_ are the smallest deployable units of computing that can be created and
|
||||
managed in Kubernetes.
|
||||
-->
|
||||
|
||||
_Pods_ 是可以在 Kubernetes 中创建和管理的、最小的可部署的计算单元。
|
||||
|
||||
{{% /capture %}}
|
||||
|
||||
|
||||
{{% capture body %}}
|
||||
|
||||
<!--
|
||||
## What is a Pod?
|
||||
|
||||
A _pod_ (as in a pod of whales or pea pod) is a group of one or more containers
|
||||
(such as Docker containers), with shared storage/network, and a specification
|
||||
for how to run the containers. A pod's contents are always co-located and
|
||||
co-scheduled, and run in a shared context. A pod models an
|
||||
application-specific "logical host" - it contains one or more application
|
||||
containers which are relatively tightly coupled — in a pre-container
|
||||
world, being executed on the same physical or virtual machine would mean being
|
||||
executed on the same logical host.
|
||||
-->
|
||||
|
||||
## Pod 是什么?
|
||||
|
||||
_pod_ (就像在鲸鱼荚或者豌豆荚中)是一组(一个或多个)容器(例如 Docker 容器),这些容器有共享存储、网络、以及怎样运行这些容器的声明。Pod 的内容总是共同定位和共同调度,并且在共享的上下文中运行。
|
||||
Pod 以特定于应用的“逻辑主机”为模型,它包含一个或多个应用容器,这些容器是相对紧密的耦合在一起;在容器出现之前,在相同的物理机或虚拟机上运行意味着在相同的逻辑主机上运行。
|
||||
|
||||
<!--
|
||||
While Kubernetes supports more container runtimes than just Docker, Docker is
|
||||
the most commonly known runtime, and it helps to describe pods in Docker terms.
|
||||
|
||||
The shared context of a pod is a set of Linux namespaces, cgroups, and
|
||||
potentially other facets of isolation - the same things that isolate a Docker
|
||||
container. Within a pod's context, the individual applications may have
|
||||
further sub-isolations applied.
|
||||
-->
|
||||
|
||||
虽然 Kubernetes 支持多种容器运行时,但 Docker 是最常见的一种运行时,它有助于描述 Docker 术语中的 Pod。
|
||||
|
||||
Pod 的共享上下文是一组 Linux 命名空间、cgroups、以及其他潜在的资源隔离相关的因素,这些相同的东西也隔离了 Docker 容器。在 Pod 的上下文中,单个应用程序可能还会应用进一步的子隔离。
|
||||
|
||||
<!--
|
||||
Containers within a pod share an IP address and port space, and
|
||||
can find each other via `localhost`. They can also communicate with each
|
||||
other using standard inter-process communications like SystemV semaphores 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/).
|
||||
These containers usually communicate with each other via Pod IP addresses.
|
||||
|
||||
Applications within a pod also have access to shared volumes, which are defined
|
||||
as part of a pod and are made available to be mounted into each application's
|
||||
filesystem.
|
||||
-->
|
||||
|
||||
Pod 中的所有容器共享一个 IP 地址和端口空间,并且可以通过 `localhost` 互相发现。他们也能通过标准的进程间通信(如 SystemV 信号量或 POSIX 共享内存)方式进行互相通信。不同 Pod 中的容器的 IP 地址互不相同,没有 [特殊配置](/docs/concepts/policy/pod-security-policy/) 就不能使用 IPC 进行通信。这些容器之间经常通过 Pod IP 地址进行通信。
|
||||
|
||||
Pod 中的应用也能访问共享卷,共享卷是 Pod 定义的一部分,可被用来挂载到每个应用的文件系统上。
|
||||
|
||||
<!--
|
||||
In terms of [Docker](https://www.docker.com/) constructs, a pod is modelled as
|
||||
a group of Docker containers with shared namespaces and shared
|
||||
[volumes](/docs/concepts/storage/volumes/).
|
||||
|
||||
Like individual application containers, pods are considered to be relatively
|
||||
ephemeral (rather than durable) entities. As discussed in [life of a
|
||||
pod](/docs/concepts/workloads/pods/pod-lifecycle/), pods are created, assigned a unique ID (UID), and
|
||||
scheduled to nodes where they remain until termination (according to restart
|
||||
policy) or deletion. If a node dies, the pods scheduled to that node are
|
||||
scheduled for deletion, after a timeout period. A given pod (as defined by a UID) is not
|
||||
"rescheduled" to a new node; instead, it can be replaced by an identical pod,
|
||||
with even the same name if desired, but with a new UID (see [replication
|
||||
controller](/docs/concepts/workloads/controllers/replicationcontroller/) for more details).
|
||||
-->
|
||||
|
||||
在 [Docker](https://www.docker.com/) 体系的术语中,Pod 被建模为一组具有共享命名空间和共享 [卷](/docs/concepts/storage/volumes/) 的 Docker 容器。
|
||||
|
||||
与单个应用程序容器一样,Pod被认为是相对短暂的(而不是持久的)实体。如 [Pod 的生命](/docs/concepts/workloads/pods/pod-lifecycle/) 所讨论的那样:Pod 被创建、给它指定一个唯一 ID (UID)、被调度到节点、在节点上存续直到终止(取决于重启策略)或被删除。如果节点宕机,调度到该节点上的 Pod 会在一个超时周期后被安排删除。给定 Pod (由 UID 定义)不会重新调度到新节点;相反,它会被一个完全相同的 Pod 替换掉,如果需要甚至连 Pod 名称都可以一样,除了 UID 是新的(更多信息请查阅 [副本控制器(replication
|
||||
controller)](/docs/concepts/workloads/controllers/replicationcontroller/))。
|
||||
|
||||
<!--
|
||||
When something is said to have the same lifetime as a pod, such as a volume,
|
||||
that means that it exists as long as that pod (with that UID) exists. If that
|
||||
pod is deleted for any reason, even if an identical replacement is created, the
|
||||
related thing (e.g. volume) is also destroyed and created anew.
|
||||
-->
|
||||
|
||||
当某些东西被说成与 Pod(如卷)具有相同的生存期时,这意味着只要pod(具有该UID)存在,它就存在。如果那个 Pod 因为某种原因被删除了,即使创建了相同的 Pod 做替换,Pod 的相关的资源(如卷等)也会被销毁进行重新创建。
|
||||
|
||||
{{< figure src="/images/docs/pod.svg" title="pod diagram" width="50%" >}}
|
||||
|
||||
<!--
|
||||
*A multi-container pod that contains a file puller and a
|
||||
web server that uses a persistent volume for shared storage between the containers.*
|
||||
-->
|
||||
|
||||
包含多个容器的 Pod 包含文件拉取器和 web 服务器,使用了持久卷在容器之间进行存储共享。
|
||||
|
||||
{{< figure src="/images/docs/pod.svg" title="pod diagram" width="50%" >}}
|
||||
|
||||
|
||||
<!--
|
||||
## Motivation for pods
|
||||
|
||||
### Management
|
||||
|
||||
Pods are a model of the pattern of multiple cooperating processes which form a
|
||||
cohesive unit of service. They simplify application deployment and management
|
||||
by providing a higher-level abstraction than the set of their constituent
|
||||
applications. Pods serve as unit of deployment, horizontal scaling, and
|
||||
replication. Colocation (co-scheduling), shared fate (e.g. termination),
|
||||
coordinated replication, resource sharing, and dependency management are
|
||||
handled automatically for containers in a pod.
|
||||
-->
|
||||
|
||||
## Pod 的动机
|
||||
|
||||
### 管理
|
||||
|
||||
Pod 是形成内聚服务单元的多个协作过程模式的模型。它们提供了一个比它们的应用组成集合更高级的抽象,从而简化了应用的部署和管理。Pod 可以用作部署单元、水平缩放和复制。在 Pod中,多个容器的共同定位(协同调度)、共享命运(例如,终止)、协调复制、资源共享和依赖项管理都是自动处理的。
|
||||
|
||||
|
||||
<!--
|
||||
### Resource sharing and communication
|
||||
|
||||
Pods enable data sharing and communication among their constituents.
|
||||
|
||||
The applications in a pod all use the same network namespace (same IP and port
|
||||
space), and can thus "find" each other and communicate using `localhost`.
|
||||
Because of this, applications in a pod must coordinate their usage of ports.
|
||||
Each pod has an IP address in a flat shared networking space that has full
|
||||
communication with other physical computers and pods across the network.
|
||||
-->
|
||||
|
||||
### 资源共享和通信
|
||||
|
||||
Pod 使它的组成容器间能够进行数据共享和通信。
|
||||
|
||||
Pod 中的应用都使用相同的网络命名空间(相同 IP 和 端口空间),而且能够互相“发现”并使用 `localhost` 进行通信。因此,在 Pod 中的应用必须协调它们的端口使用情况。每个 Pod 在扁平的共享网络空间中具有一个IP地址,该空间能与整个网络上的其他物理机或虚拟机进行完全通信。
|
||||
|
||||
<!--
|
||||
The hostname is set to the pod's Name for the application containers within the
|
||||
pod. [More details on networking](/docs/concepts/cluster-administration/networking/).
|
||||
|
||||
In addition to defining the application containers that run in the pod, the pod
|
||||
specifies a set of shared storage volumes. Volumes enable data to survive
|
||||
container restarts and to be shared among the applications within the pod.
|
||||
-->
|
||||
|
||||
主机名被设置为 Pod 内的应用程序容器的 Pod 名称。请参考[组网的更多信息](/docs/concepts/cluster-administration/networking/)。
|
||||
|
||||
Pod 除了定义了 Pod 中运行的应用程序容器之外,Pod 还指定了一组共享存储卷。该共享存储卷能使数据在容器重新启动后继续保留,并能在 Pod 内的应用程序之间共享。
|
||||
|
||||
<!--
|
||||
## Uses of pods
|
||||
|
||||
Pods can be used to host vertically integrated application stacks (e.g. LAMP),
|
||||
but their primary motivation is to support co-located, co-managed helper
|
||||
programs, such as:
|
||||
|
||||
* content management systems, file and data loaders, local cache managers, etc.
|
||||
* log and checkpoint backup, compression, rotation, snapshotting, etc.
|
||||
* data change watchers, log tailers, logging and monitoring adapters, event publishers, etc.
|
||||
* proxies, bridges, and adapters
|
||||
* controllers, managers, configurators, and updaters
|
||||
-->
|
||||
|
||||
## 使用 Pod
|
||||
|
||||
Pod 可以用于托管垂直集成的应用程序栈(例如,LAMP),但最主要的动机是支持位于同一位置的、共同管理的帮助程序,例如:
|
||||
|
||||
* 内容管理系统、文件和数据加载器、本地缓存管理器等。
|
||||
* 日志和检查点备份、压缩、旋转、快照等。
|
||||
* 数据更改监视器、日志跟踪器、日志和监视适配器、事件发布器等。
|
||||
* 代理、桥接器和适配器
|
||||
* 控制器、管理器、配置器和更新器
|
||||
|
||||
|
||||
<!--
|
||||
Individual pods are not intended to run multiple instances of the same
|
||||
application, in general.
|
||||
|
||||
For a longer explanation, see [The Distributed System ToolKit: Patterns for
|
||||
Composite
|
||||
Containers](https://kubernetes.io/blog/2015/06/the-distributed-system-toolkit-patterns).
|
||||
-->
|
||||
|
||||
通常,单个 Pod 并不打算运行同一应用程序的多个实例。
|
||||
|
||||
更多解释,请参考 [分布式系统工具包:复合容器的模式](https://kubernetes.io/blog/2015/06/the-distributed-system-toolkit-patterns)
|
||||
|
||||
<!--
|
||||
## Alternatives considered
|
||||
|
||||
_Why not just run multiple programs in a single (Docker) container?_
|
||||
|
||||
1. Transparency. Making the containers within the pod visible to the
|
||||
infrastructure enables the infrastructure to provide services to those
|
||||
containers, such as process management and resource monitoring. This
|
||||
facilitates a number of conveniences for users.
|
||||
1. Decoupling software dependencies. The individual containers may be
|
||||
versioned, rebuilt and redeployed independently. Kubernetes may even support
|
||||
live updates of individual containers someday.
|
||||
1. Ease of use. Users don't need to run their own process managers, worry about
|
||||
signal and exit-code propagation, etc.
|
||||
1. Efficiency. Because the infrastructure takes on more responsibility,
|
||||
containers can be lighter weight.
|
||||
-->
|
||||
|
||||
## 备选方案的思考
|
||||
|
||||
_为什么不在单个(Docker)容器中运行多个程序?_
|
||||
|
||||
1. 透明度。Pod 内的容器对基础设施可见,使得基础设施能够向这些容器提供服务,例如流程管理和资源监控。这为用户提供了许多便利。
|
||||
1. 解耦软件依赖关系。可以独立地对单个容器进行版本控制、重新构建和重新部署。Kubernetes 有一天甚至可能支持单个容器的实时更新。
|
||||
1. 易用性。用户不需要运行他们自己的进程管理器、也不用担心信号和退出代码传播等。
|
||||
1. 效率。因为基础结构承担了更多的责任,所以容器可以变得更加轻量化。
|
||||
|
||||
<!--
|
||||
_Why not support affinity-based co-scheduling of containers?_
|
||||
|
||||
That approach would provide co-location, but would not provide most of the
|
||||
benefits of pods, such as resource sharing, IPC, guaranteed fate sharing, and
|
||||
simplified management.
|
||||
-->
|
||||
|
||||
_为什么不支持基于亲和性的容器联合调度?_
|
||||
|
||||
这种处理方法尽管可以提供同址,但不能提供 Pod 的大部分好处,如资源共享、IPC、有保证的命运共享和简化的管理。
|
||||
|
||||
<!--
|
||||
## Durability of pods (or lack thereof)
|
||||
|
||||
Pods aren't intended to be treated as durable entities. They won't survive scheduling failures, node failures, or other evictions, such as due to lack of resources, or in the case of node maintenance.
|
||||
|
||||
In general, users shouldn't need to create pods directly. They should almost
|
||||
always use controllers even for singletons, for example,
|
||||
[Deployments](/docs/concepts/workloads/controllers/deployment/).
|
||||
Controllers provide self-healing with a cluster scope, as well as replication
|
||||
and rollout management.
|
||||
Controllers like [StatefulSet](/docs/concepts/workloads/controllers/statefulset.md)
|
||||
can also provide support to stateful pods.
|
||||
-->
|
||||
|
||||
## Pod 的持久性(或稀缺性)
|
||||
|
||||
Pod 并没想被视为持久的实体。它们无法在调度失败、节点故障或其他驱逐策略(例如由于缺乏资源或在节点维护的情况下)中生存。
|
||||
|
||||
一般来说,用户不需要直接创建 Pod。他们几乎都是使用控制器进行创建,即使对于单例的创建也一样使用控制器,例如 [Deployments](/docs/concepts/workloads/controllers/deployment/)。
|
||||
控制器提供集群范围的自修复以及复制和滚动管理。
|
||||
像 [StatefulSet](/docs/concepts/workloads/controllers/statefulset.md) 这样的控制器还可以提供支持有状态的 Pod。
|
||||
|
||||
<!--
|
||||
The use of collective APIs as the primary user-facing primitive is relatively common among cluster scheduling systems, including [Borg](https://research.google.com/pubs/pub43438.html), [Marathon](https://mesosphere.github.io/marathon/docs/rest-api.html), [Aurora](http://aurora.apache.org/documentation/latest/reference/configuration/#job-schema), and [Tupperware](https://www.slideshare.net/Docker/aravindnarayanan-facebook140613153626phpapp02-37588997).
|
||||
-->
|
||||
|
||||
在集群调度系统中,使用 API 合集作为面向用户的主要原语是比较常见的,包括 [Borg](https://research.google.com/pubs/pub43438.html)、[Marathon](https://mesosphere.github.io/marathon/docs/rest-api.html)、[Aurora](http://aurora.apache.org/documentation/latest/reference/configuration/#job-schema)、和 [Tupperware](https://www.slideshare.net/Docker/aravindnarayanan-facebook140613153626phpapp02-37588997)。
|
||||
|
||||
<!--
|
||||
Pod is exposed as a primitive in order to facilitate:
|
||||
d
|
||||
* scheduler and controller pluggability
|
||||
* support for pod-level operations without the need to "proxy" them via controller APIs
|
||||
* decoupling of pod lifetime from controller lifetime, such as for bootstrapping
|
||||
* decoupling of controllers and services — the endpoint controller just watches pods
|
||||
* clean composition of Kubelet-level functionality with cluster-level functionality — Kubelet is effectively the "pod controller"
|
||||
* high-availability applications, which will expect pods to be replaced in advance of their termination and certainly in advance of deletion, such as in the case of planned evictions or image prefetching.
|
||||
-->
|
||||
|
||||
Pod 暴露为原语是为了便于:
|
||||
|
||||
* 调度器和控制器可插拔性
|
||||
* 支持 Pod 级别的操作,而不需要通过控制器 API "代理" 它们
|
||||
* Pod 生命与控制器生命的解耦,如自举
|
||||
* 控制器和服务的解耦;端点控制器只监视 Pod
|
||||
* Kubelet 级别的功能与集群级别功能的清晰组合;Kubelet 实际上是 "Pod 控制器"
|
||||
* 高可用性应用程序期望在 Pod 终止之前并且肯定要在 Pod 被删除之前替换 Pod,例如在计划驱逐或镜像预先提取的情况下。
|
||||
|
||||
<!--
|
||||
## Termination of Pods
|
||||
|
||||
Because pods represent running processes on nodes in the cluster, it is important to allow those processes to gracefully terminate when they are no longer needed (vs being violently killed with a KILL signal and having no chance to clean up). Users should be able to request deletion and know when processes terminate, but also be able to ensure that deletes eventually complete. When a user requests deletion of a pod, the system records the intended grace period before the pod is allowed to be forcefully killed, and a TERM signal is sent to the main process in each container. Once the grace period has expired, the KILL signal is sent to those processes, and the pod is then deleted from the API server. If the Kubelet or the container manager is restarted while waiting for processes to terminate, the termination will be retried with the full grace period.
|
||||
-->
|
||||
|
||||
## Pod 的终止
|
||||
|
||||
因为 Pod 代表在集群中的节点上运行的进程,所以当不再需要这些进程时(与被 KILL 信号粗暴地杀死并且没有机会清理相比),允许这些进程优雅地终止是非常重要的。
|
||||
用户应该能够请求删除并且知道进程何时终止,但是也能够确保删除最终完成。当用户请求删除 Pod 时,系统会记录在允许强制删除 Pod 之前所期望的宽限期,并向每个容器中的主进程发送 TERM 信号。一旦过了宽限期,KILL 信号就发送到这些进程,然后就从 API 服务器上删除 Pod。如果 Kubelet 或容器管理器在等待进程终止时发生重启,则终止操作将以完整的宽限期进行重试。
|
||||
|
||||
|
||||
<!--
|
||||
An example flow:
|
||||
|
||||
1. User sends command to delete Pod, with default grace period (30s)
|
||||
1. The Pod in the API server is updated with the time beyond which the Pod is considered "dead" along with the grace period.
|
||||
1. Pod shows up as "Terminating" when listed in client commands
|
||||
1. (simultaneous with 3) When the Kubelet sees that a Pod has been marked as terminating because the time in 2 has been set, it begins the pod shutdown process.
|
||||
1. If the pod has defined a [preStop hook](/docs/concepts/containers/container-lifecycle-hooks/#hook-details), it is invoked inside of the pod. If the `preStop` hook is still running after the grace period expires, step 2 is then invoked with a small (2 second) extended grace period.
|
||||
1. The processes in the Pod are sent the TERM signal.
|
||||
1. (simultaneous with 3) Pod is removed from endpoints list for service, and are no longer considered part of the set of running pods for replication controllers. Pods that shutdown slowly cannot continue to serve traffic as load balancers (like the service proxy) remove them from their rotations.
|
||||
1. When the grace period expires, any processes still running in the Pod are killed with SIGKILL.
|
||||
1. The Kubelet will finish deleting the Pod on the API server by setting grace period 0 (immediate deletion). The Pod disappears from the API and is no longer visible from the client.
|
||||
-->
|
||||
|
||||
流程示例:
|
||||
|
||||
1. 用户发送命令删除 Pod,使用的是默认的宽限期(30秒)
|
||||
2. API 服务器中的 Pod 会随着宽限期规定的时间进行更新,过了这个时间 Pod 就会被认为已 "死亡"。
|
||||
3. 当使用客户端命令查询 Pod 状态时,Pod 显示为 "Terminating"。
|
||||
4. (和第3步同步进行)当 Kubelet 看到 Pod 由于步骤2中设置的时间而被标记为 terminating 状态时,它就开始执行关闭 Pod 流程。
|
||||
1. 如果 Pod 定义了 [preStop 钩子](/docs/concepts/containers/container-lifecycle-hooks/#hook-details),就在 Pod 内部调用它。如果宽限期结束了 `preStop` 钩子还在运行,那么就用小的(2秒)扩展宽限期调用步骤2。
|
||||
|
||||
2. 给 Pod 内的进程发送 TERM 信号。
|
||||
5. (和第3步同步进行)从服务的端点列表中删除 Pod,Pod也不再被视为副本控制器的运行状态的 Pod 集的一部分。当负载平衡器(如服务代理)将 Pod 从轮换中移除时,关闭迟缓的 Pod 将不能继续为流量服务。
|
||||
6. 当宽限期结束后,Pod 中运行的任何进程都将被用 SIGKILL 杀死。
|
||||
7. Kubelet 将通过设置宽限期为0(立即删除)来完成删除 API 服务器上的 Pod。Pod 从 API 中消失,从客户端也不再可见。
|
||||
|
||||
|
||||
<!--
|
||||
By default, all deletes are graceful within 30 seconds. The `kubectl delete` command supports the `--grace-period=<seconds>` option which allows a user to override the default and specify their own value. The value `0` [force deletes](/docs/concepts/workloads/pods/pod/#force-deletion-of-pods) the pod. In kubectl version >= 1.5, you must specify an additional flag `--force` along with `--grace-period=0` in order to perform force deletions.
|
||||
-->
|
||||
|
||||
默认情况下,所有删除在30秒内都是优雅的。`kubectl delete` 命令支持 `--grace-period=<seconds>` 选项,允许用户覆盖默认值并声明他们自己的宽限期。设置为 ‘0’ 会[强制删除](/docs/concepts/workloads/pods/pod/#force-deletion-of-pods) Pod。在 kubectl 1.5以后的版本(含1.5版本)中,为了执行强制删除,您还必须为 `--grace-period=0` 声明一个额外的 `--force` 标志。
|
||||
|
||||
<!--
|
||||
### Force deletion of pods
|
||||
|
||||
Force deletion of a Pod is defined as deletion of a Pod from the cluster state and etcd immediately. When a force deletion is performed, the API server does not wait for confirmation from the kubelet that the Pod has been terminated on the node it was running on. It removes the Pod in the API immediately so a new Pod can be created with the same name. On the node, Pods that are set to terminate immediately will still be given a small grace period before being force killed.
|
||||
|
||||
Force deletions can be potentially dangerous for some pods and should be performed with caution. In case of StatefulSet pods, please refer to the task documentation for [deleting Pods from a StatefulSet](/docs/tasks/run-application/force-delete-stateful-set-pod/).
|
||||
-->
|
||||
|
||||
### Pod 的强制删除
|
||||
|
||||
强制删除pod定义为从集群状态和 etcd 中立即删除 Pod。当执行强制删除时,apiserver 并不会等待 kubelet 的确认信息,该 Pod 已在所运行的节点上被终止了。强制删除操作从 API 中立即清除了 Pod, 因此可以用相同的名称创建一个新的 Pod。在节点上,设置为立即终止的 Pod 还是会在被强制删除前设置一个小的宽限期。
|
||||
|
||||
强制删除对某些 Pod 可能具有潜在危险,因此应该谨慎地执行。对于 StatefulSet 管理的 Pod,请参考 [从 StatefulSet 中删除 Pod](/docs/tasks/run-application/force-delete-stateful-set-pod/)的任务文档。
|
||||
|
||||
<!--
|
||||
## Privileged mode for pod containers
|
||||
|
||||
From Kubernetes v1.1, any container in a pod can enable privileged mode, using the `privileged` flag on the `SecurityContext` of the container spec. This is useful for containers that want to use linux capabilities like manipulating the network stack and accessing devices. Processes within the container get almost the same privileges that are available to processes outside a container. With privileged mode, it should be easier to write network and volume plugins as separate pods that don't need to be compiled into the kubelet.
|
||||
|
||||
If the master is running Kubernetes v1.1 or higher, and the nodes are running a version lower than v1.1, then new privileged pods will be accepted by api-server, but will not be launched. They will be pending state.
|
||||
If user calls `kubectl describe pod FooPodName`, user can see the reason why the pod is in pending state. The events table in the describe command output will say:
|
||||
`Error validating pod "FooPodName"."FooPodNamespace" from api, ignoring: spec.containers[0].securityContext.privileged: forbidden '<*>(0xc2089d3248)true'`
|
||||
-->
|
||||
|
||||
## Pod 容器的特权模式
|
||||
|
||||
从 Kubernetes v1.1 开始,Pod 内的任何容器都可以开启特权模式,开启的方法是在容器声明中的 `SecurityContext` 域使用 `privileged` 标志。这对于希望使用linux功能(如操作网络堆栈和访问设备)的容器非常有用。容器内的进程获得的特权与容器外的进程几乎相同。使用特权模式,将网络和卷插件编写为不需要编译到 kubelet 中的独立的 Pod 应该更容易。
|
||||
|
||||
如果主节点的 Kubernetes 版本是 v1.1 或更高,而工作节点的版本低于 v1.1,新的特权 Pod 将被 API 服务器接受,但不会被启动。它们将处于 pending 状态。如果用户使用命令 `kubectl describe pod FooPodName`,就可以看到 Pod 处于 pending 状态的原因。`describe` 命令的输出事件列表将显示:
|
||||
`Error validating pod "FooPodName"."FooPodNamespace" from api, ignoring: spec.containers[0].securityContext.privileged: forbidden '<*>(0xc2089d3248)true'`
|
||||
|
||||
<!--
|
||||
If the master is running a version lower than v1.1, then privileged pods cannot be created. If user attempts to create a pod, that has a privileged container, the user will get the following error:
|
||||
`The Pod "FooPodName" is invalid.
|
||||
spec.containers[0].securityContext.privileged: forbidden '<*>(0xc20b222db0)true'`
|
||||
-->
|
||||
|
||||
如果主节点的版本低于 v1.1,那么特权 Pod 就不能被创建。如果用户尝试创建有特权容器的 Pod,将会得到下面的错误信息:
|
||||
`The Pod "FooPodName" is invalid.
|
||||
spec.containers[0].securityContext.privileged: forbidden '<*>(0xc20b222db0)true'`
|
||||
|
||||
<!--
|
||||
## API Object
|
||||
|
||||
Pod is a top-level resource in the Kubernetes REST API. More details about the
|
||||
API object can be found at:
|
||||
[Pod API object](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#pod-v1-core).
|
||||
|
||||
{{% /capture %}}
|
||||
-->
|
||||
|
||||
## API 对象
|
||||
|
||||
Pod 是 Kubernetes REST API 中的顶级资源。关于该 API 对象的更详细信息请参考 [Pod API 对象](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#pod-v1-core)。
|
||||
@@ -1,72 +1,151 @@
|
||||
---
|
||||
approvers:
|
||||
reviewers:
|
||||
- jessfraz
|
||||
title: Pod Preset
|
||||
content_template: templates/concept
|
||||
weight: 50
|
||||
---
|
||||
|
||||
{{% capture overview %}}
|
||||
本文提供了 PodPreset 的概述。 在 pod 创建时,用户可以使用 `podpreset` 对象将特定信息注入
|
||||
pod 中,这些信息可以包括 secret、 卷、卷挂载和环境变量。
|
||||
<!--
|
||||
This page provides an overview of PodPresets, which are objects for injecting
|
||||
certain information into pods at creation time. The information can include
|
||||
secrets, volumes, volume mounts, and environment variables.
|
||||
-->
|
||||
本文提供了 PodPreset 的概述。 在 Pod 创建时,用户可以使用 PodPreset 对象将特定信息注入 Pod 中,这些信息可以包括 secret、 卷、卷挂载和环境变量。
|
||||
{{% /capture %}}
|
||||
|
||||
{{< toc >}}
|
||||
|
||||
{{% capture body %}}
|
||||
|
||||
<!--
|
||||
## Understanding Pod Presets
|
||||
|
||||
A `Pod Preset` is an API resource for injecting additional runtime requirements
|
||||
into a Pod at creation time.
|
||||
You use [label selectors](/docs/concepts/overview/working-with-objects/labels/#label-selectors)
|
||||
to specify the Pods to which a given Pod Preset applies.
|
||||
-->
|
||||
|
||||
## 理解 Pod Preset
|
||||
|
||||
`Pod Preset` 是一种 API 资源,在 pod 创建时,用户可以用它将额外的运行时需求信息注入 pod。
|
||||
使用[标签选择器(label selector)](/docs/concepts/overview/working-with-objects/labels/#label-selectors)来指定 Pod Preset 所适用的 pod。
|
||||
`Pod Preset` 是一种 API 资源,在 Pod 创建时,用户可以用它将额外的运行时需求信息注入 Pod。
|
||||
使用[标签选择器(label selector)](/docs/concepts/overview/working-with-objects/labels/#label-selectors)来指定 Pod Preset 所适用的 Pod。
|
||||
|
||||
使用 Pod Preset 使得 pod 模板编写者不必显式地为每个 pod 设置信息。
|
||||
这样,使用特定服务的 pod 模板编写者不需要了解该服务的所有细节。
|
||||
<!--
|
||||
Using a Pod Preset allows pod template authors to not have to explicitly provide
|
||||
all information for every pod. This way, authors of pod templates consuming a
|
||||
specific service do not need to know all the details about that service.
|
||||
-->
|
||||
|
||||
使用 Pod Preset 使得 Pod 模板编写者不必显式地为每个 Pod 设置信息。
|
||||
这样,使用特定服务的 Pod 模板编写者不需要了解该服务的所有细节。
|
||||
|
||||
<!--
|
||||
For more information about the background, see the [design proposal for PodPreset](https://git.k8s.io/community/contributors/design-proposals/service-catalog/pod-preset.md).
|
||||
-->
|
||||
|
||||
了解更多的相关背景信息,请参考 [ PodPreset 设计提案](https://git.k8s.io/community/contributors/design-proposals/service-catalog/pod-preset.md)。
|
||||
|
||||
<!--
|
||||
## How It Works
|
||||
|
||||
Kubernetes provides an admission controller (`PodPreset`) which, when enabled,
|
||||
applies Pod Presets to incoming pod creation requests.
|
||||
When a pod creation request occurs, the system does the following:
|
||||
-->
|
||||
|
||||
## PodPreset 如何工作
|
||||
|
||||
Kubernetes 提供了准入控制器 (`PodPreset`),该控制器被启用时,会将 Pod Preset
|
||||
应用于接收到的 pod 创建请求中。
|
||||
当出现 pod 创建请求时,系统会执行以下操作:
|
||||
Kubernetes 提供了准入控制器 (`PodPreset`),该控制器被启用时,会将 Pod Preset
|
||||
应用于接收到的 Pod 创建请求中。
|
||||
当出现 Pod 创建请求时,系统会执行以下操作:
|
||||
|
||||
<!--
|
||||
1. Retrieve all `PodPresets` available for use.
|
||||
1. Check if the label selectors of any `PodPreset` matches the labels on the
|
||||
pod being created.
|
||||
1. Attempt to merge the various resources defined by the `PodPreset` into the
|
||||
Pod being created.
|
||||
1. On error, throw an event documenting the merge error on the pod, and create
|
||||
the pod _without_ any injected resources from the `PodPreset`.
|
||||
1. Annotate the resulting modified Pod spec to indicate that it has been
|
||||
modified by a `PodPreset`. The annotation is of the form
|
||||
`podpreset.admission.kubernetes.io/podpreset-<pod-preset name>: "<resource version>"`.
|
||||
-->
|
||||
|
||||
1. 检索所有可用 `PodPresets` 。
|
||||
1. 检查 `PodPreset` 的标签选择器与要创建的 pod 的标签是否匹配。
|
||||
1. 尝试合并 `PodPreset` 中定义的各种资源,并注入要创建的 pod。
|
||||
1. 发生错误时抛出事件,该事件记录了 pod 信息合并错误,同时在 _不注入_ `PodPreset` 信息的情况下创建 pod。
|
||||
1. 为改动的 pod spec 添加注解,来表明它被 `PodPreset` 所修改。 注解形如:
|
||||
1. 检查 `PodPreset` 的标签选择器与要创建的 Pod 的标签是否匹配。
|
||||
1. 尝试合并 `PodPreset` 中定义的各种资源,并注入要创建的 Pod。
|
||||
1. 发生错误时抛出事件,该事件记录了 pod 信息合并错误,同时在 _不注入_ `PodPreset` 信息的情况下创建 Pod。
|
||||
1. 为改动的 Pod spec 添加注解,来表明它被 `PodPreset` 所修改。 注解形如:
|
||||
`podpreset.admission.kubernetes.io/podpreset-<pod-preset name>": "<resource version>"`。
|
||||
|
||||
一个 Pod 可能不与任何 Pod Preset 匹配,也可能匹配多个 Pod Preset。 同时,一个 `PodPreset`
|
||||
<!--
|
||||
Each Pod can be matched by zero or more Pod Presets; and each `PodPreset` can be
|
||||
applied to zero or more pods. When a `PodPreset` is applied to one or more
|
||||
Pods, Kubernetes modifies the Pod Spec. For changes to `Env`, `EnvFrom`, and
|
||||
`VolumeMounts`, Kubernetes modifies the container spec for all containers in
|
||||
the Pod; for changes to `Volume`, Kubernetes modifies the Pod Spec.
|
||||
-->
|
||||
|
||||
一个 Pod 可能不与任何 Pod Preset 匹配,也可能匹配多个 Pod Preset。 同时,一个 `PodPreset`
|
||||
可能不应用于任何 Pod,也可能应用于多个 Pod。 当 `PodPreset` 应用于一个或多个 Pod 时,Kubernetes
|
||||
修改 pod spec。 对于 `Env`、 `EnvFrom` 和 `VolumeMounts` 的改动, Kubernetes 修改 pod
|
||||
中所有容器的规格,对于卷的改动,Kubernetes 修改 Pod spec。
|
||||
|
||||
|
||||
{{< note >}}
|
||||
**注意:** Pod Preset 能够在适当的时候修改 Pod spec 的 `spec.containers` 字段,
|
||||
但是不会应用于 `initContainers` 字段。
|
||||
<!--A Pod Preset is capable of modifying the `.spec.containers` field in a
|
||||
Pod spec when appropriate. *No* resource definition from the Pod Preset will be
|
||||
applied to the `initContainers` field.-->
|
||||
|
||||
Pod Preset 能够在适当的时候修改 Pod spec 的 `spec.containers` 字段,但是不会应用于 `initContainers` 字段。
|
||||
{{< /note >}}
|
||||
|
||||
<!--
|
||||
### Disable Pod Preset for a Specific Pod
|
||||
|
||||
There may be instances where you wish for a Pod to not be altered by any Pod
|
||||
Preset mutations. In these cases, you can add an annotation in the Pod Spec
|
||||
of the form: `podpreset.admission.kubernetes.io/exclude: "true"`.
|
||||
-->
|
||||
|
||||
### 为特定 Pod 禁用 Pod Preset
|
||||
|
||||
在一些情况下,用户不希望 pod 被 pod preset 所改动,这时,用户可以在 pod spec 中添加形如
|
||||
`podpreset.admission.kubernetes.io/exclude: "true"` 的注解。
|
||||
在一些情况下,用户不希望 Pod 被 Pod Preset 所改动,这时,用户可以在 Pod spec 中添加形如 `podpreset.admission.kubernetes.io/exclude: "true"` 的注解。
|
||||
|
||||
<!--
|
||||
## Enable Pod Preset
|
||||
|
||||
In order to use Pod Presets in your cluster you must ensure the following:
|
||||
-->
|
||||
|
||||
## 启用 Pod Preset
|
||||
|
||||
为了在集群中使用 Pod Preset,必须确保以下几点:
|
||||
|
||||
1. 已启用 api 类型 `settings.k8s.io/v1alpha1/podpreset`。 这可以通过在 API 服务器的
|
||||
`--runtime-config` 配置项中包含 `settings.k8s.io/v1alpha1=true` 来实现。
|
||||
1. 已启用准入控制器 `PodPreset`。 启用的一种方式是在 API 服务器的 `--admission-control`
|
||||
配置项中包含 `PodPreset` 。
|
||||
1. 已经通过在相应的名字空间中创建 `PodPreset` 对象,定义了 Pod preset。
|
||||
<!--
|
||||
1. You have enabled the API type `settings.k8s.io/v1alpha1/podpreset`. For
|
||||
example, this can be done by including `settings.k8s.io/v1alpha1=true` in
|
||||
the `--runtime-config` option for the API server.
|
||||
1. You have enabled the admission controller `PodPreset`. One way to doing this
|
||||
is to include `PodPreset` in the `--enable-admission-plugins` option value specified
|
||||
for the API server.
|
||||
1. You have defined your Pod Presets by creating `PodPreset` objects in the
|
||||
namespace you will use.
|
||||
-->
|
||||
|
||||
1. 已启用 API 类型 `settings.k8s.io/v1alpha1/podpreset`。 这可以通过在 API 服务器的 `--runtime-config` 配置项中包含 `settings.k8s.io/v1alpha1=true` 来实现。
|
||||
1. 已启用准入控制器 `PodPreset`。 启用的一种方式是在 API 服务器的 `--admission-control` 配置项中包含 `PodPreset` 。
|
||||
1. 已经通过在相应的命名空间中创建 `PodPreset` 对象,定义了 Pod Preset。
|
||||
|
||||
|
||||
{{% /capture %}}
|
||||
|
||||
{{% capture whatsnext %}}
|
||||
|
||||
* [使用 PodPreset 将信息注入 Pods](/docs/tasks/inject-data-application/podpreset/)
|
||||
|
||||
<!--
|
||||
* [Injecting data into a Pod using PodPreset](/docs/tasks/inject-data-application/podpreset/)
|
||||
-->
|
||||
* [使用 PodPreset 将信息注入 Pod](/docs/tasks/inject-data-application/podpreset/)
|
||||
{{% /capture %}}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user