Kubernetes 常见问题与解决方案

devops进阶9 分钟阅读2026/8/12

这是一篇非常接地气的实战经验分享,翻译时我着重保留了原文那种“踩坑后痛定思痛”的口语化语气,同时确保技术术语的准确性和易读性。


Kubernetes 常见问题与解决方案:我用血泪换来的避坑指南

上周五晚上 10 点,我正准备关电脑享受周末,钉钉突然狂响——线上有个关键服务挂了。我打开终端一查,Pod 状态栏赫然显示着 OOMKilled。那一刻我立刻想起来:这个 Deployment 的 YAML 里,我压根没写 resources.limits

这是我玩 Kubernetes 以来踩得最痛的一个坑,但绝不是唯一一个。今天我想把这几年在 K8s 里摸爬滚打攒下的常见问题和解决方案整理出来,希望能帮你少走点弯路。

坑一:不设资源 requests 和 limits,等于埋雷

这是我最常犯、也见别人最常犯的错误。

Kubernetes 不强制要求你写 resources 字段,Pod 照样能跑。这就给人一种“没事,不写也行”的错觉。我早期在本地 minikube 上测试时从不写这玩意儿,一切正常。等部署到生产集群,问题全来了:

  • 没有 requests:调度器不知道 Pod 需要多少资源,可能把一堆 Pod 塞到同一个节点,导致 CPU 抢占、性能暴跌
  • 没有 limits:某个 Pod 内存泄漏,疯狂吃内存,把同节点其他 Pod 挤得被 OOMKilled 驱逐

我那次周五晚上的事故就是这么来的——一个 Java 应用了无限制的内存,把隔壁的关键 Go 服务给挤死了。

解决方案:从保守值开始,逐步调优。

resources:
  requests:
    cpu: "100m"    # 0.1 核
    memory: "128Mi"
  limits:
    cpu: "500m"    # 0.5 核
    memory: "512Mi"

然后用 kubectl top pods 观察实际用量,再调整。如果你用阿里云 ACK,控制台的监控图表更直观。配合 HPA(水平自动扩缩容),能根据指标自动增减 Pod 副本数。

我的教训:本地环境没问题不代表生产没问题。资源限制不是可选项,是必选项。

坑二:忽略存活探针和就绪探针

我第二个惨痛教训跟探针有关。

有次部署了一个 Spring Boot 应用,容器启动了,Kubernetes 认为它“运行中”——因为 JVM 进程没退出。但实际上 Spring 还在初始化,根本没准备好接请求。Service 已经把流量打进去了,用户看到的就是一堆 502 错误。更糟的是,有一次应用内部死锁了,进程还活着,K8s 也不知道该重启它。

解决方案:务必配置 livenessProbe 和 readinessProbe。

livenessProbe:
  httpGet:
    path: /healthz
    port: 8080
  initialDelaySeconds: 30   # 给应用启动时间
  periodSeconds: 10
readinessProbe:
  httpGet:
    path: /ready
    port: 8080
  initialDelaySeconds: 5
  periodSeconds: 5
  • livenessProbe(存活探针):检查失败就重启容器。救你于死锁、线程池耗尽等“进程在但应用死了”的场景
  • readinessProbe(就绪探针):检查失败就把 Pod 从 Service 端点摘除。防止流量打到还没准备好的 Pod

如果应用启动很慢(说的就是 Java),加个 startupProbe,给更长的初始宽限期,避免被误杀。

我的经验:一开始用简单的 TCP socket 探针也行,总比没有强。但最终要过渡到业务语义的 HTTP 端点。

坑三:镜像拉取慢或失败

这个问题我在阿里云 ACK 上踩过好几次。现象就是 Pod 一直 ImagePullBackOffErrImagePull

排查下来,常见原因有三类:

1. 公网访问没开或带宽太小

通过公网拉镜像时,集群需要公网访问能力。在 ACK 控制台检查是否开启了公网 API Server 访问,带宽峰值是否够用。

2. ACR 镜像密钥问题

从阿里云容器镜像服务 ACR 拉取私有镜像时,需要配置 imagePullSecret 或安装免密组件。我之前跨账号拉镜像时,免密组件配错了,折腾了两个小时。

解决方案:

  • 同账号:按照文档配置免密组件
  • 跨账号:正确配置跨账号免密,或手动创建 Secret
kubectl create secret docker-registry acr-secret \
  --docker-server=registry.cn-hangzhou.aliyuncs.com \
  --docker-username=your-username \
  --docker-password=your-password

然后在 Deployment 里引用:

imagePullSecrets:
  - name: acr-secret

3. Docker Hub 海外源网络不稳

这是国内用户的老大难问题。解决方案有两个:

  • 用 ACR 的制品订阅功能,把海外镜像同步到国内
  • 创建全球加速 GA 实例,加速拉取

我的建议:生产环境别直接依赖 Docker Hub。把镜像都同步到 ACR 或自建仓库,省心。

坑四:刚创建的集群就提示 Pod 数量不足

这个问题让我困惑了很久。明明买了 4 核 8G 的节点,怎么刚建好集群就说 Pod 不够用?

原因是:Kubernetes 自身组件(kube-proxy、CoreDNS、日志采集等)要占用资源,每个节点还要预留系统资源。阿里云文档里说得很清楚——购买后查看节点可用 CPU 和内存,比实例规格定义的少是正常的。

解决方案

  • 建集群时预留余量,别按“刚好够”来算
  • kubectl describe node <node-name>Allocatable 字段,这才是 Pod 真正能用的资源
  • 规划节点池时,把系统组件开销算进去

坑五:KubeConfig 证书过期导致连不上集群

某天早上 kubectl get pods 突然报 certificate is valid for 错误,我的心跳都漏了一拍。

ACK 托管集群的 KubeConfig 证书有有效期。解决方法:

  • 在 ACK 控制台重新下载 KubeConfig
  • 或用 aliyun CLI 更新证书

注意:KubeConfig 误删后可以从回收站恢复,但恢复按钮置灰说明有冲突——比如同一 RAM 用户在回收站有多条记录。这时需要根据集群 ID 和创建时间来识别正确的记录。

安全实践:别把 KubeConfig 长期存在跳板机上。用 RBAC 给不同团队配最小权限,定期轮换证书。

坑六:集群版本升级的恐惧

K8s 版本迭代快,旧版本终会被废弃。但升级集群这事儿,每次都让我紧张。

几个关键经验:

1. 不能永远不升级。过期版本的集群可能还能跑,但出了问题没人给你修,安全漏洞也没人补。

2. 不支持跨多个次版本升级。比如从 1.20 到 1.24,必须 1.20→1.21→1.22→1.23→1.24 一步步来。

3. 1.22 到 1.24 的 Docker→containerd 切换是大坑。提前在测试环境演练,确认镜像兼容性。

4. 升级前必须跑前置检查。常见报错及处理:

  • 废弃 API 报错:找到使用了废弃 API 的资源,改用新 API
  • 组件版本过低:先升级组件再升级集群
  • the aliyun service is not running:检查节点的 ECS 实例状态和阿里云插件
  • PLEG not healthy:通常是节点 Docker 或 containerd 异常,先修复节点

5. 升级不支持回退。所以一定要备份 etcd(托管集群阿里云帮你做了),在业务低峰期操作。

坑七:Pod 异常排查的通用思路

最后分享一个我总结的 Pod 故障排查流程,适用于大部分场景:

# 第一步:看 Pod 状态
kubectl get pods

# 第二步:看 Pod 事件,这步最关键
kubectl describe pod <pod-name>

# 第三步:看容器日志
kubectl logs <pod-name> [-c <container-name>]

# 第四步:如果是 CrashLoopBackOff,看上一次的日志
kubectl logs <pod-name> --previous

常见状态含义:

  • Pending:调度失败,通常是资源不足或 PVC 挂载问题
  • ImagePullBackOff:镜像拉取失败,参考坑三
  • CrashLoopBackOff:容器启动后崩溃,看日志找原因
  • OOMKilled:内存超限,参考坑一加 limits
  • Terminating:卡在删除,通常是有 finalizer 未完成或挂载点忙

在 ACK 控制台排查更方便——集群详情页有故障诊断功能,能自动分析常见问题。

写在最后

Kubernetes 的学习曲线确实陡,但大部分坑都有规律可循。总结一下我的核心建议:

  1. 资源限制必须写,从保守值开始,用监控调优
  2. 探针必须配,否则 K8s 就是个瞎子
  3. 镜像拉取提前规划,别依赖海外源
  4. 集群升级要趁早,别拖到过期才慌
  5. 排查问题有套路:先 describe 看事件,再 logs 看日志

老实说,K8s 的复杂性不会消失,但理解了这些常见问题的模式后,你至少能从“两眼一抹黑”变成“有方向地排查”。那些周五晚上的报警,也会少很多。

相关 Agent

D

Docker

Docker 是一个容器化平台,允许开发者将应用及其依赖项打包成轻量级、可移植的容器。它简化了跨环境的开发、测试和部署过程。该描述强调它最适合容器化和开发环境,提供免费方案和团队方案,团队方案从每用户每月5美元起。

了解更多 →