配置最佳实践
本文档重点介绍并整合了用户指南、入门文档和示例中介绍的配置最佳实践。
这是一份不断更新的文档。如果你想到一些不在列表上但可能对其他人有用的内容,请随时提交一个 issue 或 Pull Request。
通用配置技巧
定义配置时,请指定最新的稳定 API 版本。
配置文件在推送到集群之前应存储在版本控制中。这样可以在必要时快速回滚配置更改。它还有助于集群的重新创建和恢复。
使用 YAML 而不是 JSON 编写配置文件。尽管这些格式在几乎所有情况下都可以互换使用,但 YAML 通常更易于用户使用。
在合理的情况下,将相关对象分组到一个文件中。一个文件通常比多个文件更容易管理。请参阅 guestbook-all-in-one.yaml 文件,以获取此语法的示例。
还要注意,许多
kubectl
命令可以在目录上调用。例如,你可以在包含配置文件的目录上调用kubectl apply
。不要不必要地指定默认值:简单、最小的配置可以减少出错的可能性。
将对象描述放在注解中,以便更好地进行自省。
注意
YAML 1.2 布尔值规范相对于 YAML 1.1 引入了一项重大更改。这是 Kubernetes 中的一个已知 问题。YAML 1.2 只识别 **true** 和 **false** 为有效布尔值,而 YAML 1.1 还接受 **yes**、**no**、**on** 和 **off** 作为布尔值。然而,Kubernetes 使用的 YAML 解析器 大部分与 YAML 1.1 兼容,这意味着在 YAML 清单中使用 **yes** 或 **no** 而不是 **true** 或 **false** 可能会导致意外的错误或行为。为避免此问题,建议始终在 YAML 清单中使用 **true** 或 **false** 作为布尔值,并引用可能与布尔值混淆的任何字符串,例如 **"yes"** 或 **"no"**。
除了布尔值之外,YAML 版本之间还有额外的规范更改。请参阅 YAML 规范更改 文档以获取完整列表。
"裸" Pod 与 ReplicaSet、Deployment 和 Job
如果可以避免,请不要使用裸 Pod(即,未绑定到 ReplicaSet 或 Deployment 的 Pod)。裸 Pod 在节点发生故障时不会被重新调度。
除了某些明确的
restartPolicy: Never
场景外,Deployment 几乎总是优于直接创建 Pod,因为它既创建 ReplicaSet 以确保所需数量的 Pod 始终可用,又指定了替换 Pod 的策略(例如 RollingUpdate)。Job 也可能适用。
服务
在其对应的后端工作负载(Deployment 或 ReplicaSet)之前,以及在任何需要访问它的工作负载之前,创建 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
> 组合必须是唯一的。如果你不明确指定hostIP
和protocol
,Kubernetes 将使用0.0.0.0
作为默认hostIP
和TCP
作为默认protocol
。如果仅出于调试目的需要访问端口,可以使用 apiserver 代理 或
kubectl port-forward
。如果需要显式地在节点上暴露 Pod 的端口,请考虑使用 NodePort Service,然后再使用
hostPort
。避免使用
hostNetwork
,原因与hostPort
相同。当不需要
kube-proxy
负载均衡时,使用 无头 Service(其ClusterIP
为None
)进行服务发现。
使用标签
定义并使用标识应用程序或 Deployment 的 **语义属性** 的 标签,例如
{ app.kubernetes.io/name: MyApp, tier: frontend, phase: test, deployment: v3 }
。你可以使用这些标签为其他资源选择合适的 Pod;例如,一个 Service 选择所有tier: frontend
的 Pod,或者app.kubernetes.io/name: MyApp
的所有phase: test
组件。请参阅 guestbook 应用程序以获取此方法的示例。Service 可以通过从其选择器中省略特定于发布版本的标签来跨越多个 Deployment。当需要在不中断服务的情况下更新正在运行的服务时,请使用 Deployment。
对象的期望状态由 Deployment 描述,如果对该规范的更改被_应用_,Deployment 控制器将以受控的速度将实际状态更改为期望状态。
对于常见用例,请使用 Kubernetes 常用标签。这些标准化标签以一种方式丰富元数据,允许工具(包括
kubectl
和 dashboard)以可互操作的方式工作。你可以修改标签进行调试。由于 Kubernetes 控制器(如 ReplicaSet)和 Service 使用选择器标签来匹配 Pod,从 Pod 中删除相关标签将阻止控制器考虑它或 Service 为其提供流量。如果你删除现有 Pod 的标签,其控制器将创建一个新 Pod 来替换它。这是一种在"隔离"环境中调试先前"活动"Pod 的有用方法。要交互式地删除或添加标签,请使用
kubectl label
。
使用 kubectl
使用
kubectl apply -f <目录>
。这会在<目录>
中查找所有.yaml
、.yml
和.json
文件中的 Kubernetes 配置,并将其传递给apply
。对于
get
和delete
操作,请使用标签选择器而不是特定的对象名称。请参阅有关 标签选择器 和 有效使用标签 的部分。使用
kubectl create deployment
和kubectl expose
快速创建单容器 Deployment 和 Service。有关示例,请参阅 使用 Service 访问集群中的应用程序。