摘要:本文系统总结 Kubernetes 生产环境最佳实践:资源管理(requests/limits 策略、LimitRange、ResourceQuota、VPA)、高可用(多副本、PDB、topologySpread、Cluster Autoscaler)、安全加固(RBAC、Pod Security Context、镜像安全、etcd 加密)、发布策略(滚动更新、蓝绿、金丝雀)、GitOps 工作流、成本优化与故障排查 SOP。文末回顾全系列 20 篇要点。
一、资源管理最佳实践
1.1 requests/limits 设置策略
未设置 requests/limits 时,Pod 可能过度占用节点资源,导致其他 Pod 调度失败或 OOM 被随机驱逐。正确设置可保证调度公平性与资源可预测性。
yaml
resources:
requests: # 调度时的最小保障,影响调度决策
cpu: "100m" # 0.1 核
memory: "128Mi"
limits: # 运行时的硬限制,超限则 Throttling/OOM Kill
cpu: "500m"
memory: "256Mi"
设置策略:
| 场景 | CPU requests | CPU limits | 内存 requests | 内存 limits |
|---|---|---|---|---|
| 无状态 Web | 50-100m | 可等于或略高于 requests | 64-128Mi | 必须设置,避免 OOM |
| 有状态 DB | 250-500m | 2x requests | 512Mi-1Gi | 1.5-2x requests |
| 批处理 Job | 按任务特性 | 可放宽 | 按任务特性 | 必须设置 |
常见错误:不设置 limits 导致 OOM 随机杀人;limits 过低导致 Throttling;requests=limits 导致无法利用节点空闲资源。推荐 requests < limits,CPU limits 可适度放宽以减小限流影响。
推荐配置
requests < limits
正常运行与峰值
CPU limits 可放宽
避免限流影响
错误配置
不设置
资源抢占、OOM
limits 过低
Throttling/OOM Kill
requests=limits
无法利用空闲资源
1.2 LimitRange 与 ResourceQuota
LimitRange:为 Namespace 内无显式配置的容器设置默认的 requests/limits,并限制单容器/单 PVC 的资源上下限。适用于多租户或团队协作场景,避免单容器无上限占用资源。
应用 LimitRange:
bash
kubectl apply -f limitrange.yaml -n production
kubectl describe limitrange default-limits -n production
yaml
apiVersion: v1
kind: LimitRange
metadata:
name: default-limits
namespace: production
spec:
limits:
- type: Container
default:
cpu: "500m"
memory: "256Mi"
defaultRequest:
cpu: "100m"
memory: "128Mi"
max:
cpu: "4"
memory: "8Gi"
min:
cpu: "10m"
memory: "16Mi"
ResourceQuota:限制 Namespace 内资源总量,防止单租户占用过多集群资源。
yaml
apiVersion: v1
kind: ResourceQuota
metadata:
name: namespace-quota
namespace: production
spec:
hard:
pods: "50"
requests.cpu: "20"
requests.memory: "40Gi"
limits.cpu: "40"
limits.memory: "80Gi"
应用 ResourceQuota:
bash
kubectl apply -f resourcequota.yaml -n production
kubectl describe resourcequota namespace-quota -n production
LimitRange 与 ResourceQuota 字段说明:
| LimitRange 字段 | 含义 |
|---|---|
default |
未指定 limits 时的默认值 |
defaultRequest |
未指定 requests 时的默认值 |
max / min |
单容器资源上下限 |
| ResourceQuota 字段 | 含义 |
|---|---|
pods |
Namespace 内 Pod 数量上限 |
requests.cpu / requests.memory |
所有 Pod requests 总和上限 |
limits.cpu / limits.memory |
所有 Pod limits 总和上限 |
1.3 VPA(Vertical Pod Autoscaler)简介
VPA 根据 Pod 实际使用情况自动调整 requests/limits,适用于难以预估资源的工作负载。
VPA 模式 :Off(仅建议、不自动应用)、Initial(仅创建时应用)、Recreate(运行时也可调整,需重建 Pod)。
与 HPA 混用 :两者同时基于 CPU/内存时可能冲突。建议 HPA 负责横向扩缩容,VPA 使用 UpdateMode: Off 仅提供建议,人工评审后调整。
部署 VPA:
bash
# 安装 VPA 组件
kubectl apply -f https://raw.githubusercontent.com/kubernetes/autoscaler/master/vertical-pod-autoscaler/deploy/vpa-v1-crd.yaml
kubectl apply -f https://raw.githubusercontent.com/kubernetes/autoscaler/master/vertical-pod-autoscaler/deploy/recommender-deployment.yaml
kubectl apply -f https://raw.githubusercontent.com/kubernetes/autoscaler/master/vertical-pod-autoscaler/deploy/updater-deployment.yaml
二、高可用最佳实践
2.1 多维度高可用
生产环境需从控制平面、应用层、数据层三个维度保障高可用。
| 层级 | 要点 |
|---|---|
| 控制平面 | 至少 3 Master、etcd 奇数节点、API Server 前加 LB |
| 应用层 | 多副本、Pod 反亲和性、topologySpread、PDB |
| 数据层 | StatefulSet + PVC、主从/分片、定期备份 |
数据层
StatefulSet + PVC
定期备份
应用层
多副本
Pod Anti-Affinity
topologySpread
PDB
控制平面
3+ Master
etcd 奇数
API Server LB
2.2 PodDisruptionBudget(PDB)
PDB 确保在节点维护、驱逐或滚动更新时,至少保留指定数量的可用 Pod,避免业务中断。
yaml
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: app-pdb
spec:
minAvailable: 2 # 至少保持 2 个可用
# 或 maxUnavailable: 1
selector:
matchLabels:
app: my-app
2.3 topologySpreadConstraints
将 Pod 按可用区(zone)或节点均匀分布,单可用区故障时仍有副本可用。
yaml
spec:
topologySpreadConstraints:
- maxSkew: 1
topologyKey: topology.kubernetes.io/zone
whenUnsatisfiable: DoNotSchedule
labelSelector:
matchLabels:
app: my-app
说明 :maxSkew 为同一 topology 内最大数量差;whenUnsatisfiable: DoNotSchedule 表示不满足则不调度。
2.4 Cluster Autoscaler
Cluster Autoscaler 根据 Pod 的 Pending 状态与节点利用率,自动扩容或缩容节点。
工作原理:监听 Pending 且因资源不足无法调度的 Pod,触发节点组扩容;当节点上所有 Pod 可被调度到其他节点且节点利用率低于阈值时,触发缩容。
使用前提:需配合云厂商的节点组(如 AWS ASG、GCP MIG)使用;节点需支持缩容(无本地存储关键数据、DaemonSet 可容忍等)。
配置示例(需根据云厂商调整):
yaml
# cluster-autoscaler 启动参数示例
--scale-down-delay-after-add=10m
--scale-down-unneeded-time=10m
--skip-nodes-with-local-storage=false
三、安全加固
3.1 RBAC 最小权限
遵循最小权限原则,为不同角色创建 Role/ClusterRole,通过 RoleBinding/ClusterRoleBinding 绑定到 ServiceAccount 或用户。避免使用 cluster-admin 等宽泛权限。
最佳实践:
- 按 Namespace 创建 Role,仅授予该 Namespace 内资源权限。
- 需要集群级权限时使用 ClusterRole,谨慎绑定。
- 禁用 default ServiceAccount 的自动挂载:
automountServiceAccountToken: false。 - 启用审计日志,记录 API 访问行为。
yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: app-deployer
namespace: production
rules:
- apiGroups: ["apps"]
resources: ["deployments"]
verbs: ["get", "list", "create", "update", "patch"]
3.2 Pod Security Context
通过 securityContext 限制容器以非 root 运行、只读根文件系统、移除不必要的 Linux Capabilities,降低逃逸风险。
yaml
spec:
securityContext:
runAsNonRoot: true
runAsUser: 1000
fsGroup: 2000
containers:
- name: app
image: my-app:v1
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop:
- ALL
| 字段 | 含义 |
|---|---|
runAsNonRoot |
禁止 root 用户运行 |
readOnlyRootFilesystem |
根文件系统只读,需写目录用 emptyDir 挂载 |
capabilities.drop: ALL |
移除所有 Linux Capabilities |
3.3 镜像安全
- 使用私有仓库,避免依赖公共镜像稳定性。
- 固定 tag 或使用 digest,避免
latest。 - 镜像漏洞扫描(Trivy、 Clair),CI 中集成。
- 镜像签名与验证(Cosign、Notary)。
- 最小基础镜像(Alpine、Distroless)。
3.4 数据安全与 etcd 加密
- etcd 加密 :启用
EncryptionConfiguration对 Secret 等敏感资源静态加密。在 API Server 启动参数中配置--encryption-provider-config指向加密配置文件。 - Secret 外置:生产环境使用 Vault、Sealed Secrets 等外部密钥管理,避免 Secret 明文存储在 etcd。
- 定期备份:etcd 快照、应用数据备份,并定期演练恢复流程。
EncryptionConfiguration 示例:
yaml
apiVersion: apiserver.config.k8s.io/v1
kind: EncryptionConfiguration
resources:
- resources:
- secrets
providers:
- aescbc:
keys:
- name: key1
secret: <base64-encoded-32-byte-key>
- identity: {}
安全实践
镜像安全
运行时安全
网络安全
访问控制
数据安全
四、发布策略
4.1 滚动更新参数优化
yaml
spec:
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
| 参数 | 含义 | 建议 |
|---|---|---|
maxSurge |
可超出 desired 的最大 Pod 数 | 1 或 25% |
maxUnavailable |
更新过程中允许不可用的最大 Pod 数 | 0 保证全时可用 |
4.2 蓝绿部署
维护两套完全相同的环境(蓝、绿),发布时切换流量到新版本。
实现方式 :通过两套 Deployment(如 app-blue、app-green),Service 的 selector 指向当前活跃版本;切换时修改 Service selector 即可。或使用 Ingress 的 backend 切换。
优点 :切换迅速,回滚只需切回。缺点:需要双倍资源,需在发布窗口内完成。
4.3 金丝雀发布
将少量流量导入新版本,验证通过后逐步放量。
实现方式 :需配合 Istio、Flagger、Argo Rollouts 等工具。通过 VirtualService 按比例(如 10% 到 canary)或按请求头(如 x-canary: true)将流量路由到新版本;通过 Prometheus 指标判断成功或回滚。
| 策略 | 特点 | 适用场景 |
|---|---|---|
| 滚动更新 | 逐步替换,零停机,默认支持 | 常规发布 |
| 蓝绿 | 瞬时切换,快速回滚,双倍资源 | 重大变更 |
| 金丝雀 | 小流量验证,风险可控 | 需流量管理工具 |
4.4 优雅关闭
yaml
spec:
terminationGracePeriodSeconds: 60
containers:
- name: app
lifecycle:
preStop:
exec:
command: ["/bin/sh", "-c", "sleep 5"]
应用收到 SIGTERM 后应:停止接受新请求、完成正在处理的请求、关闭连接、退出进程。若应用不处理 SIGTERM,可配置 preStop 在发送 SIGTERM 前等待几秒,让 Ingress/Service 摘除端点。
五、GitOps 工作流
将 Git 作为唯一真相来源,通过 ArgoCD 或 FluxCD 监听变更并同步到集群,实现声明式、可审计、可自动部署的运维流程。
ArgoCD :提供 Web UI、多集群支持、同步状态监控,适合需要可视化的团队。安装:kubectl create namespace argocd && kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml。
FluxCD :轻量、GitOps 原生、与 CI 集成紧密,适合自动化优先的场景。通过 flux bootstrap 将 Git 仓库与集群关联。
工作流:开发者 Push 变更到 Git → GitOps 工具检测变更 → 计算 diff → 应用变更到集群 → 持续 reconcile 保持状态一致。
Push YAML
监听
同步
开发者
Git Repo
ArgoCD/FluxCD
K8s 集群
六、成本优化策略
| 层级 | 策略 |
|---|---|
| 资源 | 合理设置 requests/limits,避免过度预留;使用 VPA 建议 |
| 节点 | Spot/Preemptible 节点跑非关键负载;Cluster Autoscaler 缩容闲置节点 |
| 存储 | 按需选择 StorageClass(HDD/SSD);及时清理未使用 PVC |
| 镜像 | 多阶段构建、轻量基础镜像,减小拉取与存储成本 |
| 网络 | 同可用区部署减少跨区流量费用 |
| 监控 | 控制 Prometheus 保留期与 scrape 目标,避免冗余采集 |
资源利用率优化:
bash
# 查找低利用率 Pod(requests 远高于实际使用)
kubectl top pods -A
# 结合 VPA 建议调整 requests
闲置资源清理:
bash
# 查找未使用的 PVC
kubectl get pvc -A
# 查找 Pending 或 Failed 的 Pod
kubectl get pods -A | grep -E 'Pending|Error|CrashLoopBackOff'
性能优化要点:
| 层级 | 优化点 |
|---|---|
| 应用层 | 合理设置 JVM 堆大小、HPA 参数、readinessProbe 避免过早接收流量 |
| 镜像 | 多阶段构建、Alpine/Distroless 基础镜像、合理分层缓存 |
| 网络 | IPVS 模式、eBPF CNI(Cilium)、Pod 亲和性减少跨节点流量 |
| 存储 | SSD StorageClass、合理 PVC 大小、避免频繁扩容 |
| 集群 | etcd 使用 SSD、API Server 限流配置、合理设置 --max-requests-inflight |
kubectl 常用调试命令:
bash
# 查看某 Namespace 下所有资源
kubectl api-resources --verbs=list -o name | xargs -n 1 kubectl get -n <ns> 2>/dev/null
# 导出当前资源为 YAML(用于备份或迁移)
kubectl get deployment <name> -n <ns> -o yaml > backup.yaml
# 查看 Pod 调度失败原因
kubectl get events -n <ns> --field-selector reason=FailedScheduling
NetworkPolicy 排查 :若 Pod 间无法通信,检查是否有 NetworkPolicy 限制;kubectl get networkpolicy -A 列出所有策略;默认 deny-all 时需显式添加 allow 规则。
镜像拉取问题 :ImagePullBackOff 时查看 kubectl describe pod 的 Events;私有仓库需创建 imagePullSecrets 并挂载到 Pod;确认镜像 tag 存在且节点网络可访问仓库。
创建 imagePullSecrets:
bash
kubectl create secret docker-registry regcred \
--docker-server=<registry> \
--docker-username=<user> \
--docker-password=<pass> \
-n <namespace>
在 Pod spec 中引用:spec.imagePullSecrets: [{name: regcred}]。
七、故障排查 SOP
7.1 Pod 问题排查
Pending
CrashLoopBackOff
ImagePullBackOff
Running 但无 Ready
Pod 异常
状态?
describe 看 Events
logs --previous
检查镜像与 Secret
检查 readinessProbe
Pending :kubectl describe pod <pod> 查看 Events。常见原因:资源不足(扩容或减 requests)、节点污点(添加 tolerations)、无 PV(创建 StorageClass)、亲和性不满足(调整 affinity)。
CrashLoopBackOff :kubectl logs <pod> --previous 查看崩溃前日志。常见原因:应用启动失败、OOMKilled、Liveness Probe 失败、ConfigMap/Secret 缺失。
7.2 Service 问题排查
- 检查 Pod 是否 Running 且 Ready。
kubectl get endpoints <svc>确认有 Endpoints。- 在 Pod 内测试
curl svc-name:port。 - 确认 port、targetPort、containerPort 对应。
- 检查 NetworkPolicy 是否阻断流量。
7.3 Node 问题排查
bash
kubectl describe node <node>
kubectl get pods -A -o wide | grep <node>
kubectl get events -A --field-selector involvedObject.name=<node>
关注 Node 的 Conditions、资源压力(MemoryPressure、DiskPressure)、污点与调度状态。
Node 常见问题:
| 现象 | 可能原因 | 处理 |
|---|---|---|
| NotReady | kubelet 异常、网络分区 | 检查节点服务、网络 |
| MemoryPressure | 内存不足 | 扩容或驱逐低优先级 Pod |
| DiskPressure | 磁盘满 | 清理镜像、日志、PVC |
| 污点导致无法调度 | 节点有 NoSchedule 污点 | 添加 tolerations 或移除污点 |
7.4 故障排查速查表
bash
kubectl get pods -A
kubectl describe pod <pod>
kubectl logs <pod> --previous
kubectl exec -it <pod> -- sh
kubectl get events -A --sort-by='.lastTimestamp'
kubectl top pods -A
kubectl get endpoints <svc>
| 状态 | 排查方向 |
|---|---|
| Pending | 资源不足 / 调度失败 |
| CrashLoopBackOff | 应用崩溃 / 配置错误 |
| ImagePullBackOff | 镜像拉取失败 |
| CreateContainerErr | 容器创建失败(挂载、权限) |
| Evicted | 节点资源压力导致驱逐 |
| OOMKilled | 内存超限 |
八、总结表格
| 维度 | 要点 |
|---|---|
| 资源 | requests/limits、LimitRange、ResourceQuota、VPA |
| 高可用 | 多副本、PDB、topologySpread、Cluster Autoscaler |
| 安全 | RBAC、Pod Security Context、镜像扫描签名、etcd 加密 |
| 发布 | 滚动更新参数、蓝绿、金丝雀、优雅关闭 |
| 运维 | GitOps、成本优化、故障排查 SOP |
九、全系列 20 篇要点回顾
本系列从基础架构、核心资源、进阶主题到实战与最佳实践,覆盖 Kubernetes 运维的核心知识。
| 篇目 | 主题 |
|---|---|
| 01-04 | 容器演进、集群架构、控制平面、工作节点 |
| 05-10 | Pod、Deployment、Service、Namespace、ConfigMap/Secret、Volume |
| 11-15 | StatefulSet、DaemonSet/Job/CronJob、Ingress、网络模型、RBAC |
| 16-17 | 调度器、Helm |
| 18 | 可观测性:Prometheus、日志、tracing |
| 19 | 实战:微服务部署 |
| 20 | 生产最佳实践(本篇) |
学习建议:基础篇(01-04)建立架构认知;核心篇(05-10)掌握日常资源操作;进阶篇(11-15)覆盖有状态、网络与安全;高级篇(16-20)串联调度、包管理、可观测性与生产实践。建议配合 Minikube、Kind 等实验环境动手实践,每篇完成后用文中示例在集群中验证。
推荐资源:
| 类别 | 资源 |
|---|---|
| 官方文档 | https://kubernetes.io/docs/ |
| 互动学习 | killercoda.com、labs.play-with-k8s.com |
| 认证 | CKA、CKAD、CKS |
| 社区 | CNCF Slack、Kubernetes GitHub、KubeCon |
生产上线检查清单:① 资源 requests/limits 已设置;② 健康检查(liveness/readiness)已配置;③ 多副本 + PDB;④ 敏感信息使用 Secret;⑤ 数据持久化使用 PVC;⑥ 监控与告警已接入;⑦ 日志集中采集;⑧ RBAC 最小权限;⑨ 镜像非 root、只读根文件系统。
完成本系列 20 篇学习后,读者应能独立完成从集群规划、应用部署、监控告警到故障排查的全流程运维工作。
建议结合实际项目反复实践,并关注 Kubernetes 与 CNCF 生态的持续演进。
系列完结说明 :本系列 20 篇覆盖从入门到生产的完整路径。若需深入某专题,可参考各篇末尾推荐资源;若准备认证考试,建议重点复习 RBAC、调度、网络与故障排查章节。感谢阅读,祝你在 Kubernetes 运维之路上越走越远。如有疑问,欢迎通过 目录 回顾相关章节。
FAQ:
- Q:LimitRange 与 ResourceQuota 冲突怎么办? 二者可同时存在。LimitRange 约束单容器范围,ResourceQuota 约束 Namespace 总量。若 Pod 的 requests 超过 Quota 剩余额度,调度会失败。
- Q:PDB 导致滚动更新卡住? 当
minAvailable或maxUnavailable与当前副本数、更新策略不兼容时,会阻塞。可临时调整 PDB 或增大 Deployment 副本数。 - Q:如何选择蓝绿还是金丝雀? 蓝绿适合发布窗口明确、需快速回滚的场景;金丝雀适合需要渐进放量、观察指标的场景。
- Q:如何验证 RBAC 配置是否正确? 使用
kubectl auth can-i模拟:kubectl auth can-i create pods --as=system:serviceaccount:ns:sa-name -n ns。 - Q:Cluster Autoscaler 与 HPA 如何配合? HPA 先扩容 Pod,若节点资源不足导致 Pending,Cluster Autoscaler 再扩容节点;缩容时先缩 Pod 再缩节点。
- Q:如何快速回滚 Deployment?
kubectl rollout undo deployment/<name> -n <ns>;需回滚到指定版本时使用kubectl rollout history查看历史,再kubectl rollout undo deployment/<name> --to-revision=<n>。
高级 16-20
调度/Helm/监控/实战/最佳实践
进阶 11-15
StatefulSet/Ingress/RBAC
核心 05-10
Pod/Deployment/Service/Volume
基础 01-04
架构与控制平面