配置最佳实践

本文档突出并整合了在用户指南、入门文档和示例中介绍的配置最佳实践。

这是一份不断更新的文档。如果你想到此列表中没有包含但对其他人可能有用的内容,请不要犹豫提交一个问题或拉取请求。

通用配置技巧

  • 在定义配置时,请指定最新的稳定 API 版本。

  • 配置文件在推送到集群之前应存储在版本控制系统中。这样可以在需要时快速回滚配置变更。这也有助于集群重建和恢复。

  • 使用 YAML 而不是 JSON 编写配置文件。虽然在几乎所有场景中这两种格式可以互换使用,但 YAML 通常更用户友好。

  • 如果合理,将相关的对象组合到一个文件中。一个文件通常比多个文件更容易管理。请参阅 guestbook-all-in-one.yaml 文件,它是一个关于此语法的示例。

  • 另请注意,许多 kubectl 命令可以作用于一个目录。例如,你可以对包含配置文件的目录运行 kubectl apply

  • 不必要时,不要指定默认值:简单、最小化的配置会减少出错的可能性。

  • 将对象描述放在注解中,以便更好地进行内省(introspection)。

"裸 Pod" vs ReplicaSet, Deployment, 和 Job

  • 如果可以避免,不要使用裸 Pod(即,不绑定到 ReplicaSetDeployment 的 Pod)。裸 Pod 在节点发生故障时不会被重新调度。

    Deployment 既会创建 ReplicaSet 以确保所需的 Pod 数量始终可用,又指定了替换 Pod 的策略(例如滚动更新),它几乎总是优于直接创建 Pod,除非是一些明确的 restartPolicy: Never 场景。Job 也可能适用。

Service

  • 在创建 Service 对应的后端工作负载(Deployment 或 ReplicaSet)之前,以及在需要访问该 Service 的任何工作负载之前,先创建 Service。当 Kubernetes 启动一个容器时,它会提供指向该容器启动时所有正在运行的 Service 的环境变量。例如,如果存在一个名为 foo 的 Service,所有容器在其初始环境中都会获得以下变量:

    FOO_SERVICE_HOST=<the host the Service is running on>
    FOO_SERVICE_PORT=<the port the Service is running on>
    

    这确实暗示了一个排序要求 - 任何 Pod 想要访问的 Service 都必须在 Pod 本身之前创建,否则环境变量将不会被填充。DNS 没有这个限制。

  • 一个可选的(强烈推荐的)集群插件是 DNS 服务器。DNS 服务器会监听 Kubernetes API 中新的 Service,并为每个 Service 创建一组 DNS 记录。如果整个集群中都启用了 DNS,那么所有 Pod 都应该能够自动进行 Service 的名称解析。

  • 除非绝对必要,否则不要为 Pod 指定 hostPort。当你将 Pod 绑定到 hostPort 时,这会限制 Pod 可以调度的位置数量,因为每个 <hostIP, hostPort, protocol> 组合都必须是唯一的。如果你不明确指定 hostIPprotocol,Kubernetes 将使用 0.0.0.0 作为默认的 hostIP,并使用 TCP 作为默认的 protocol

    如果你只需要为了调试目的访问端口,可以使用apiserver 代理kubectl port-forward

    如果你明确需要在节点上暴露 Pod 的端口,在诉诸于 hostPort 之前,考虑使用 NodePort 类型的 Service。

  • 避免使用 hostNetwork,原因与 hostPort 相同。

  • 当你不需要 kube-proxy 的负载均衡功能时,使用无头 Service(即 ClusterIPNone)进行服务发现。

使用标签

  • 定义和使用 标签来标识应用程序或 Deployment 的语义属性,例如 { app.kubernetes.io/name: MyApp, tier: frontend, phase: test, deployment: v3 }。你可以使用这些标签来为其他资源选择合适的 Pod;例如,一个选择所有 tier: frontend Pod 的 Service,或者所有 app.kubernetes.io/name: MyAppphase: test 组件。请参阅 guestbook 应用程序,了解此方法的示例。

    可以通过在其选择器中省略特定于发布的标签,使得一个 Service 能够跨越多个 Deployment。当需要在不停机的情况下更新正在运行的服务时,使用 Deployment

    一个对象的期望状态由 Deployment 描述,如果对其规范的更改被 应用,Deployment 控制器会以受控速率将实际状态更改为期望状态。

  • 使用Kubernetes 常用标签来表示常用用例。这些标准化标签以一种使工具(包括 kubectl仪表盘)能够互操作的方式丰富了元数据。

  • 你可以为了调试目的修改标签。由于 Kubernetes 控制器(如 ReplicaSet)和 Service 使用选择器标签匹配 Pod,移除 Pod 的相关标签会使其不再被控制器考虑,也不再由 Service 提供流量。如果你移除现有 Pod 的标签,其控制器将创建一个新的 Pod 来替代它。这是在“隔离”环境中调试之前“活跃”的 Pod 的一种有用方法。要交互式地移除或添加标签,请使用kubectl label

使用 kubectl

  • 使用 kubectl apply -f <directory>。这会在 <directory> 中查找所有 .yaml.yml.json 文件中的 Kubernetes 配置,并将其传递给 apply

  • 对于 getdelete 操作,使用标签选择器而不是特定的对象名称。请参阅关于标签选择器有效使用标签的部分。

  • 使用 kubectl create deploymentkubectl expose 快速创建单容器 Deployment 和 Service。有关示例,请参阅使用 Service 访问集群中的应用程序

最后修改于 2023 年 9 月 1 日下午 12:50 PST:将标签讨论移回其概念页面 (a84bdb6470)