[转载] Kubernetes 配置最佳实践
本文为授权转载,非本账号原创。
原文:Kubernetes 配置最佳实践(参考地址:https://kubernetes.io/zh-cn/blog/2025/11/25/configuration-good-practices/)
原作者及译者:借由 Kirti Goyal | 译者 Wenjun Lou | 2025.11.25
来源:Kubernetes 官方中文博客;许可:CC BY 4.0(参考地址:https://creativecommons.org/licenses/by/4.0/)。保留原作者和译者署名,正文仅做适配博客编辑器的排版与链接格式转换,未改写技术内容。
内容不代表原作者或 Kubernetes 项目对本账号的认可或背书。
配置是 Kubernetes 中看似微不足道,实则关键的事情之一。 配置是每个 Kubernetes 工作负载的核心。 一个缺失的引号、错误的 API 版本或错位的 YAML 缩进都可能毁掉你的整个部署。
本博客汇集了经过验证的配置最佳实践。 这些小的习惯让你的 Kubernetes 设置更干净、一致且更易于管理。 无论你是刚刚开始还是已经在每天部署应用, 这些都是让你的集群保持稳定、让未来的你保持理智的小细节。
本博客的灵感源自最初的 Configuration Best Practices(配置最佳实践) 页面, 该页面由 Kubernetes 社区众多成员的贡献不断演进而来。
通用配置实践(参考地址:https://kubernetes.io/zh-cn/blog/2025/11/25/configuration-good-practices/#general-configuration-practices)
使用最新的稳定 API 版本(参考地址:https://kubernetes.io/zh-cn/blog/2025/11/25/configuration-good-practices/#use-the-latest-stable-api-version)
Kubernetes 发展很快。旧版 API 最终会被弃用并停止工作。 因此,在定义资源时,请确保使用最新的稳定 API 版本。 你可以随时使用以下命令检查:
kubectl api-resources
这个简单的步骤可以让你避免未来的兼容性问题。
将配置存储在版本控制中(参考地址:https://kubernetes.io/zh-cn/blog/2025/11/25/configuration-good-practices/#store-configuration-in-version-control)
永远不要直接从桌面应用清单文件。 始终将它们保存在像 Git 这样的版本控制系统中,这是你的安全网。 如果出现问题,你可以立即回滚到之前的提交、 比较更改或重新创建集群设置,而不会惊慌。
使用 YAML 而不是 JSON 编写配置(参考地址:https://kubernetes.io/zh-cn/blog/2025/11/25/configuration-good-practices/#write-configs-in-yaml-not-json)
使用 YAML 而不是 JSON 编写配置文件。 两者在技术上都可以工作,但 YAML 对人类来说更容易。 它更易读、更简洁,并在社区中广泛使用。
YAML 在布尔值方面有一些隐藏的陷阱:
只使用 true 或 false。
不要写 yes、no、on 或 off。
它们可能在同一个 YAML 版本中工作,但在另一个版本中会失败。
为了安全起见,请给任何看起来像布尔值的内容加引号(例如 "yes")。
保持配置简单和最小化(参考地址:https://kubernetes.io/zh-cn/blog/2025/11/25/configuration-good-practices/#keep-configuration-simple-and-minimal)
避免设置 Kubernetes 已经处理的默认值。 最小化的清单更容易调试、更易于审查,并且以后不太可能破坏东西。
将相关对象分组在一起(参考地址:https://kubernetes.io/zh-cn/blog/2025/11/25/configuration-good-practices/#group-related-objects-together)
如果你的 Deployment、Service 和 ConfigMap 都属于一个应用, 请将它们放在一个清单文件中。 这样更容易跟踪更改并将它们作为一个单元应用。 有关此语法的示例,请参阅 Guestbook all-in-one.yaml(参考地址:https://github.com/kubernetes/examples/blob/master/web/guestbook/all-in-one/guestbook-all-in-one.yaml) 文件。
你甚至可以使用以下命令应用整个目录:
kubectl apply -f configs/
只需一个命令,该文件夹中的所有内容都会被部署。
添加有用的注解(参考地址:https://kubernetes.io/zh-cn/blog/2025/11/25/configuration-good-practices/#add-helpful-annotations)
清单文件不仅是为机器准备的,也是为人类准备的。 使用注解来描述某些内容存在的原因或它的作用。 快速的一行注释可以在以后调试时节省数小时,并且还可以实现更好的协作。
最有用的注解是 kubernetes.io/description。
这就像使用注释一样,只是它会被复制到 API 中,
这样其他人在你部署后也能看到它。
管理工作负载:Pod、Deployment 和 Job(参考地址:https://kubernetes.io/zh-cn/blog/2025/11/25/configuration-good-practices/#managing-workloads-pods-deployments-and-jobs)
在 Kubernetes 中,一个常见的早期错误是直接创建 Pod。 Pod 可以工作,但如果出现问题,它们不会重新调度自己。
裸 Pod(不受控制器管理的 Pod,例如 Deployment(参考地址:https://kubernetes.io/zh-cn/docs/concepts/workloads/controllers/deployment/) 或 StatefulSet(参考地址:https://kubernetes.io/zh-cn/docs/concepts/workloads/controllers/statefulset/)) 用于测试是可以的,但在实际设置中,它们是有风险的。
为什么? 因为如果托管该 Pod 的节点死亡,Pod 也会随之死亡, Kubernetes 不会自动将其恢复。
对应该始终运行的应用使用 Deployment(参考地址:https://kubernetes.io/zh-cn/blog/2025/11/25/configuration-good-practices/#use-deployments-for-apps-that-should-always-be-running)
Deployment 既创建 ReplicaSet 以确保所需数量的 Pod 始终可用, 又指定替换 Pod 的策略(例如滚动更新(参考地址:https://kubernetes.io/zh-cn/docs/concepts/workloads/controllers/deployment/#rolling-update-deployment)), 几乎总是比直接创建 Pod 更可取。 你可以推出新版本,如果出现问题,可以立即回滚。
对应该完成的任务使用 Job(参考地址:https://kubernetes.io/zh-cn/blog/2025/11/25/configuration-good-practices/#use-jobs-for-tasks-that-should-finish)
当你需要某些东西运行一次然后停止时(如数据库迁移或批处理任务), Job(参考地址:https://kubernetes.io/zh-cn/docs/concepts/workloads/controllers/job/) 是完美的选择。 如果 Pod 失败,它会重试,并在完成时报告成功。
Service 配置和网络(参考地址:https://kubernetes.io/zh-cn/blog/2025/11/25/configuration-good-practices/#service-configuration-and-networking)
Service 是你的工作负载在集群内部(有时是外部)相互通信的方式。 没有它们,你的 Pod 存在但无法被任何人访问。让我们确保这种情况不会发生。
在使用它们的工作负载之前创建 Service(参考地址:https://kubernetes.io/zh-cn/blog/2025/11/25/configuration-good-practices/#create-services-before-workloads-that-use-them)
当 Kubernetes 启动 Pod 时,它会自动为现有 Service 注入环境变量。 因此,如果 Pod 依赖于 Service,请在其相应的后端工作负载(Deployment 或 StatefulSet) 以及任何需要访问它的工作负载之前创建 Service(参考地址:https://kubernetes.io/zh-cn/docs/concepts/services-networking/service/)。
例如,如果存在名为 foo 的 Service,所有容器将在其初始环境中获得以下变量:
FOO_SERVICE_HOST=<the host the Service runs on>
FOO_SERVICE_PORT=<the port the Service runs on>
基于 DNS 的发现没有这个问题,但无论如何遵循它是一个好习惯。
使用 DNS 进行 Service 发现(参考地址:https://kubernetes.io/zh-cn/blog/2025/11/25/configuration-good-practices/#use-dns-for-service-discovery)
如果你的集群有 DNS 安装扩展(Addon)(参考地址:https://kubernetes.io/zh-cn/docs/concepts/cluster-administration/addons/)(大多数都有), 每个 Service 都会自动获得一个 DNS 条目。 这意味着你可以通过名称而不是 IP 访问它:
curl http://my-service.default.svc.cluster.local
这是让 Kubernetes 网络感觉神奇的特性之一。
除非绝对必要,否则避免使用 hostPort 和 hostNetwork(参考地址:https://kubernetes.io/zh-cn/blog/2025/11/25/configuration-good-practices/#avoid-hostport-and-hostnetwork-unless-absolutely-necessary)
你有时会在清单中看到这些选项:
hostPort: 8080
hostNetwork: true
但问题是:
它们将你的 Pod 绑定到特定节点,使它们更难调度和扩缩容。
因为每个 <hostIP、hostPort、protocol> 组合必须是唯一的。
如果你没有明确指定 hostIP 和 protocol,
Kubernetes 将使用 0.0.0.0 作为默认 hostIP,使用 TCP 作为默认 protocol。
除非你在调试或构建网络插件之类的东西,否则请避免使用它们。
如果你只需要本地访问进行测试,请尝试 kubectl port-forward(参考地址:https://kubernetes.io/zh-cn/docs/reference/kubectl/generated/kubectl_port-forward/):
kubectl port-forward deployment/web 8080:80
有关更多信息,请参阅
使用端口转发访问集群中的应用程序(参考地址:https://kubernetes.io/zh-cn/docs/tasks/access-application-cluster/port-forward-access-application-cluster/)。
或者如果你真的需要外部访问,请使用 type: NodePort Service(参考地址:https://kubernetes.io/zh-cn/docs/concepts/services-networking/service/#type-nodeport)。
这是更安全、更符合 Kubernetes 原生方式的做法。
使用无头 Service 进行内部服务发现(参考地址:https://kubernetes.io/zh-cn/blog/2025/11/25/configuration-good-practices/#use-headless-services-for-internal-discovery)
有时,你不想让 Kubernetes 负载均衡流量。 你想直接与每个 Pod 通信。这就是无头 Service(参考地址:https://kubernetes.io/zh-cn/docs/concepts/services-networking/service/#headless-services) 的用武之地。
你通过设置 clusterIP: None 来创建一个。
DNS 不是给你一个 IP,而是给你所有 Pod IP 的列表,
这非常适合自己管理连接的应用程序。
有效使用标签(参考地址:https://kubernetes.io/zh-cn/blog/2025/11/25/configuration-good-practices/#working-with-labels-effectively)
标签(参考地址:https://kubernetes.io/zh-cn/docs/concepts/overview/working-with-objects/labels/)是附加到 Pod 等对象的键/值对。 标签帮助你组织、查询和分组资源。 它们本身不做任何事情,但它们使从 Service 到 Deployment 的所有其他内容都能顺利协同工作。
使用语义标签(参考地址:https://kubernetes.io/zh-cn/blog/2025/11/25/configuration-good-practices/#use-semantics-labels)
好的标签可以帮助你理解什么是什么,即使在几个月后也是如此。 定义并使用标签(参考地址:https://kubernetes.io/zh-cn/docs/concepts/overview/working-with-objects/labels/)来标识应用程序或 Deployment 的语义属性。 例如:
labels:
app.kubernetes.io/name: myapp
app.kubernetes.io/component: web
tier: frontend
phase: test
app.kubernetes.io/name:应用是什么tier:它属于哪一层(前端/后端)phase:它处于哪个阶段(测试/生产)
然后你可以使用这些标签来创建强大的选择算符。 例如:
kubectl get pods -l tier=frontend
这将列出集群中所有前端 Pod,无论它们来自哪个 Deployment。 基本上,你不需要手动列出 Pod 名称;你只是在描述你想要什么。 有关此方法的示例,请参阅 guestbook(参考地址:https://github.com/kubernetes/examples/tree/master/web/guestbook/) 应用。
使用常见的 Kubernetes 标签(参考地址:https://kubernetes.io/zh-cn/blog/2025/11/25/configuration-good-practices/#use-common-kubernetes-labels)
Kubernetes 实际上推荐一组常见标签(参考地址:https://kubernetes.io/zh-cn/docs/concepts/overview/working-with-objects/common-labels/)。 这是在你的不同工作负载或项目中命名事物的一种标准方式。 遵循此约定使你的清单更清晰,这意味着诸如 Headlamp(参考地址:https://headlamp.dev/)、 dashboard(参考地址:https://github.com/kubernetes/dashboard#introduction) 或第三方监控系统等工具 都可以自动理解正在运行的内容。
操作标签进行调试(参考地址:https://kubernetes.io/zh-cn/blog/2025/11/25/configuration-good-practices/#manipulate-labels-for-debugging)
由于控制器(如 ReplicaSet 或 Deployment)使用标签来管理 Pod, 你可以删除标签以临时 "分离" Pod。
示例:
kubectl label pod mypod app-
app- 部分会删除标签键 app。
一旦发生这种情况,控制器将不再管理该 Pod。
这就像将其隔离以进行检查,一种用于调试的"隔离模式"。
要交互式地删除或添加标签,请使用 kubectl label(参考地址:https://kubernetes.io/zh-cn/docs/reference/kubectl/generated/kubectl_label/)。
然后你可以检查 Pod 日志、exec 进入 Pod,完成后手动删除 Pod。 这是每个 Kubernetes 工程师都应该知道的超级被低估的技巧。
实用的 kubectl 技巧(参考地址:https://kubernetes.io/zh-cn/blog/2025/11/25/configuration-good-practices/#handy-kubectl-tips)
这些小技巧使你在处理多个清单文件或集群时生活变得更加轻松。
应用整个目录(参考地址:https://kubernetes.io/zh-cn/blog/2025/11/25/configuration-good-practices/#apply-entire-directories)
不要一次应用一个文件,而是应用整个文件夹:
# Using server-side apply is also a good practice
kubectl apply -f configs/ --server-side
此命令在该文件夹中查找 .yaml、.yml 和 .json 文件并将它们一起应用。
它更快、更清晰,并有助于按应用分组。
使用标签选择算符获取或删除资源(参考地址:https://kubernetes.io/zh-cn/blog/2025/11/25/configuration-good-practices/#use-label-selectors-to-get-or-delete-resources)
你不需要总是逐个输入资源名称。 相反,使用标签选择算符(参考地址:https://kubernetes.io/zh-cn/docs/concepts/overview/working-with-objects/labels/#label-selectors)一次对整个组进行操作:
kubectl get pods -l app=myapp
kubectl delete pod -l phase=test
这在 CI/CD 流水线中特别有用,你可以在其中动态清理测试资源。
快速创建 Deployment 和 Service(参考地址:https://kubernetes.io/zh-cn/blog/2025/11/25/configuration-good-practices/#quickly-create-deployments-and-services)
对于快速实验,你不需要总是编写清单。 你可以直接从 CLI 启动 Deployment:
kubectl create deployment webapp --image=nginx
然后将其公开为 Service:
kubectl expose deployment webapp --port=80
当你想在编写完整清单之前测试某些内容时,这非常有用。 另外,有关示例,请参阅 使用 Service 访问集群中的应用程序(参考地址:https://kubernetes.io/zh-cn/docs/tasks/access-application-cluster/service-access-application-cluster/)。
结论(参考地址:https://kubernetes.io/zh-cn/blog/2025/11/25/configuration-good-practices/#conclusion)
更清晰的配置可以让集群管理员更为泰然自若。 如果你坚持几个简单的习惯:保持配置简单和最小化、对所有内容进行版本控制、 使用一致的标签,并避免依赖裸 Pod,你将为自己节省数小时的调试时间。
最好的部分是什么? 清晰的配置保持可读性。即使在几个月后, 你或团队中的任何人都可以瞥一眼它们并确切知道发生了什么。
- ←上一页(参考地址:https://kubernetes.io/zh-cn/blog/2025/11/11/ingress-nginx-retirement/)
- 下一页→(参考地址:https://kubernetes.io/zh-cn/blog/2025/11/26/kubernetes-v1-35-sneak-peek/)
- 点赞
- 收藏
- 关注作者
评论(0)