Administrator
Administrator
发布于 2026-10-28 / 0 阅读
0
0

Kubernetes 故障排查(05):CreateContainerConfigError:容器还没启动,先检查配置引用

面向初级运维,使用 Linux 节点和稳定 Kubernetes API。命令按 Bash 编写。本文为教学故障场景,日志及结果为示意,不冒充生产实测;执行前确认 context、命名空间和权限。

一、遭遇情况:Pod 已有节点,却一直起不来

发布后 Pod 分配到了节点,镜像也下载成功,但状态显示 CreateContainerConfigError。日志查询提示容器正在等待启动,没有业务日志可看。

本篇案例是 Deployment 从 ConfigMap 的 mode 键读取环境变量,但目标命名空间里没有这个 ConfigMap。业务进程根本还没启动,错误发生在容器运行配置准备阶段。

二、原因分析:对象存在、名字正确、键存在是三件事

ConfigMap 或 Secret 可能在别的命名空间,也可能名字正确但缺少目标 key。默认必需引用无法满足时,容器通常不能按预期创建。

这类错误与应用自行读取某个文件后报语法错误不同:后者往往已经有容器退出记录,应沿日志与 CrashLoopBackOff 排查。配置卷准备失败还可能表现为 ContainerCreating/FailedMount,展示状态不能替代完整事件。

配置引用故障的检查顺序

三、排查思路:从事件里找缺失对象

kubectl describe pod 目标Pod -n 目标命名空间
kubectl get deployment 目标部署 -n 目标命名空间 -o yaml
kubectl get configmap -n 目标命名空间
kubectl get secret -n 目标命名空间

将占位名称替换为实际值。Secret 列表不展示原始凭据,但整份 Deployment 也可能包含直接写入的敏感环境变量,只在受控终端查看并按需脱敏。

事件如果明确提示 configmap ... not found,先核对目标命名空间;若提示 key 不存在,则核对引用与配置的键名。配置内容不是本次排查必须公开的证据,尤其不要把 Secret 的 data 当作可随意分享的安全文本。

不要把必需凭据改成 optional: true 来绕过启动检查。这样可能把明确的配置错误推迟成应用连接失败,甚至让应用落入错误默认模式。

四、实践:引用一个尚未创建的 ConfigMap

保存 kt05-config.yaml:

apiVersion: v1
kind: Namespace
metadata:
  name: kt05
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: app
  namespace: kt05
spec:
  replicas: 1
  selector:
    matchLabels:
      app: config-demo
  template:
    metadata:
      labels:
        app: config-demo
    spec:
      containers:
        - name: app
          image: busybox:1.37
          command: ["sh", "-c"]
          args:
            - |
              printf 'mode=%s\n' "$APP_MODE"
              exec sleep 3600
          env:
            - name: APP_MODE
              valueFrom:
                configMapKeyRef:
                  name: app-settings
                  key: mode
kubectl apply -f kt05-config.yaml
kubectl describe pod -n kt05 -l app=config-demo
kubectl get pods -n kt05

在节点、镜像与准入检查通过的前提下,预期事件指出 app-settings 不存在。观察等待状态比反复执行 logs 更有用,因为这时还没有业务进程可产生日志。

五、修复实践:补齐原本要求的对象和键

kubectl create configmap app-settings -n kt05 --from-literal=mode=demo
kubectl rollout status deployment/app -n kt05 --timeout=120s
kubectl logs deployment/app -n kt05 --tail=20

预期日志出现 mode=demo。kubelet 会重试配置准备,不必为了让它“发现新配置”先删除整个 Deployment。恢复时间取决于重试和环境状态,不保证创建 ConfigMap 后下一毫秒就启动。

如果同名 ConfigMap 原来就存在,不要重复 create,也不要覆盖整份真实配置。检查其内容来源,按部署流程补齐正确键,保留其他必要配置。

六、配置改了,为什么应用还在用旧值

通过环境变量注入的配置在容器启动时确定,不会因为 ConfigMap 改动就自动刷新进程环境。对于 Deployment,通常需要完成一轮受控的新 Pod 发布,才能采用新的环境变量值。

普通挂载文件的更新行为不同,存在同步延迟;使用 subPath 的挂载不会获得同样的自动更新。即使文件已经变化,应用是否重新加载也取决于自身实现,不能把文件更新等同于业务配置已生效。

生产可通过版本化配置、Pod 模板变更或已有发布工具让变更可追踪。rollout restart 是一次发布动作,需要考虑副本与容量,不能为了每次试配置都对整个命名空间重启。

七、验证与总结

确认等待错误已消失、容器成功启动,并用应用可观测方式核对它真正采用的配置。验证应只暴露必要信息,例如运行模式或配置版本,不打印密码来证明 Secret “生效了”。

这类故障的闭环是:确定应用未启动 → 读缺失引用 → 核对 namespace/name/key → 修复配置来源 → 等待重试 → 验证最终运行值。配置错误应在依赖关系处修正,而不是靠放宽必需性掩盖。

官方参考


上一篇 · 系列目录 · 下一篇


评论