Kubernetes - Kubernetes最佳实践
发布时间:2026-05-03 08:00
解决生产环境中Kubernetes集群Pod调度混乱、资源争抢、安全隐患等典型问题,提供可直接落地的配置方案与实战技巧。
一、前言
搞过K8s的人都清楚,生产集群跑起来容易,跑稳跑好难。Pod调度全靠默认策略,资源请求limit乱配,RBAC权限一团浆糊,etcd备份靠缘分……集群规模小的时候还能靠运气撑着,一旦上了规模,各种奇怪问题就冒出来了。本文不聊那些官方文档都写的泛泛之谈,直接给实战中踩出来的经验,覆盖命名空间规划、Pod资源配额、调度策略、安全加固、监控巡检5个核心维度。
二、操作步骤
步骤1:命名空间隔离与资源配额规划
生产集群必须按业务线或环境隔离命名空间,同时配合ResourceQuota限制总资源消耗,防止某个团队把整个集群资源吃光。
```bash
# 查看当前集群命名空间
kubectl get namespaces
```
预期输出:
```
NAME STATUS AGE
default Active 120d
kube-system Active 120d
kube-public Active 120d
production Active 45d
staging Active 60d
```
```bash
# 为生产环境创建专用的命名空间并配置资源配额(CentOS/RHEL/Ubuntu通用)
cat <
步骤2:Pod资源请求与限制配置
资源请求(request)决定调度位置,资源限制(limit)防止单个Pod失控。线上必须配置,内存limit建议比request高30%-50%,CPU limit可以设得更高或与request相同。
```bash
# 查看已部署Pod的资源配置情况
kubectl get pods -n production -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.spec.containers[0].resources.requests.cpu}{"\t"}{.spec.containers[0].resources.limits.cpu}{"\n"}{end}'
```
预期输出:
```
web-app-7d9f8b6c5-xk2p9 500m 1
api-gateway-5f4d7c9b8-3n7m 1 2
redis-master-0
```
```bash
# 创建带完整资源配额的Pod清单(CentOS/RHEL/Ubuntu通用)
cat <步骤3:Pod拓扑分布约束(反亲和性)
关键业务Pod不能全调度到同一节点,否则节点故障时服务全挂。通过podAntiAffinity确保Pod分散到不同可用区或节点。
```bash
# 部署高可用Pod分布配置(CentOS/RHEL/Ubuntu通用)
cat <步骤4:Taint与Toleration节点隔离控制
专用节点(比如存储节点、GPU节点)不能随便跑业务Pod,通过Taint污点隔离,确保专用负载调度到正确节点。
```bash
# 为专用存储节点添加污点(CentOS/RHEL/Ubuntu通用)
kubectl taint nodes storage-node-1 dedicated=storage:NoSchedule
```
预期输出:
```
node/storage-node-1 tainted
```
```bash
# 部署需要特殊节点的Pod,必须带Toleration(CentOS/RHEL/Ubuntu通用)
cat <步骤5:RBAC权限最小化配置
业务团队账户只能操作自己命名空间,禁止访问其他命名空间和集群级别资源。ServiceAccount+Role+RoleBinding实现最小权限。
```bash
# 为应用创建专用ServiceAccount(CentOS/RHEL/Ubuntu通用)
kubectl create serviceaccount app-reader -n production
```
预期输出:
```
serviceaccount/app-reader created
```
```bash
# 创建只读权限Role(CentOS/RHEL/Ubuntu通用)
cat <步骤6:使用LimitRange限制Pod/容器级别资源
ResourceQuota限制整个命名空间总量,LimitRange限制单个Pod/容器的资源上限,防止某个Pod申请无限资源。
```bash
# 创建LimitRange(CentOS/RHEL/Ubuntu通用)
cat <`看Events部分,如果是资源问题会写" insufficient cpu/memory",如果是污点问题会写"node(s) had taint that the pod didn't tolerate"。还有一个坑——LimitRange的max限制,有时候你Pod配置的资源请求超了命名空间上限,调度也会失败。
Q2:业务Pod重启频繁,日志显示OOMKilled,但内存监控还有余量?
这是K8s资源统计口径的问题。Linux会统计RSS+Cache+Swap,K8s的memory limit只看cgroup的memory.usage_in_bytes,包含所有内存开销。你看到的监控余量可能是页面缓存,不是真实可用内存。解法:把memory limit上调20%-30%,或者检查应用是否有内存泄漏。最靠谱的方式是本地压测时观察Pod实际内存消耗,再加10%作为buffer设limit。
Q3:同一个集群要跑有状态服务和无状态服务,怎么规划节点?
至少分三类节点池:通用节点跑无状态Deployment,存储节点跑有状态服务并加Taint隔离,性能节点跑计算密集型任务。节点池规划要在集群初始化时就定好,后期迁移成本高。云厂商直接用Node Pool功能,自建集群用标签+污点组合管理。注意存储节点SSD要选好,别用网络存储跑有状态数据库,延迟受不了。
Q4:ResourceQuota和LimitRange同时配置时,谁优先级更高?
两个都生效,取更严格的那个。ResourceQuota限制命名空间总配额,LimitRange限制单个Pod/Container的配额。比如命名空间总CPU限额32核,单个Container最大2核,如果你部署一个Pod申请4核,会被LimitRange直接拒绝,根本到不了ResourceQuota校验那步。生产环境建议两个都配,形成双重保险。
四、总结
K8s生产最佳实践核心就三句话:隔离要彻底,配额要精确,权限要最小。命名空间隔离配合ResourceQuota控制总量,LimitRange卡死单Pod上限,RBAC最小权限防止越权操作。调度层面善用反亲和性分散Pod,污点机制隔离专用节点。别小看这些配置,集群规模上50个节点以后,没规划的集群会变成灾难。延伸阅读建议:深入理解K8s调度器优先级与抢占机制,学习Vertical Pod Autoscaler实现更智能的资源推荐,掌握GPU节点调度与共享策略。