1. Helm 与 Kubernetes 镜像拉取基础
在优化镜像拉取重试机制之前,必须理解三个核心层次:Helm Chart 结构定义了镜像声明方式,Pod 生命周期决定了重试发生的阶段,kubelet 镜像拉取流程则是重试逻辑的实际执行引擎。本节从这三层逐级深入,为后续参数调优建立完整知识基线。
1.1 Helm Chart 结构中的镜像声明
Helm Chart 通过 values.yaml 和模板文件共同管理镜像配置。标准结构如下:
mychart/
├── Chart.yaml # 元数据:名称、版本、依赖
├── values.yaml # 默认配置值(含镜像仓库、标签、拉取策略)
├── templates/
│ ├── deployment.yaml # 引用 .Values.image 的模板
│ └── _helpers.tpl # 镜像全路径拼接函数
└── charts/ # 子依赖 Chart
镜像声明三要素在 values.yaml 中集中定义:
| 参数 | 示例值 | 说明 |
|---|---|---|
image.repository |
nginx |
镜像仓库地址(不含标签) |
image.tag |
1.25.3 |
镜像版本标签,推荐显式指定而非 latest |
image.pullPolicy |
IfNotPresent |
拉取策略:Always / IfNotPresent / Never |
最佳实践:在 Helm Chart 中始终将
image.pullPolicy 暴露为可配置参数,而非硬编码在 Deployment 模板中。这样在升级时可通过 --set 临时切换策略,无需修改 Chart 源码。
Deployment 模板中引用镜像的典型写法:
spec:
template:
spec:
containers:
- name: {{ .Chart.Name }}
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
1.2 Pod 生命周期与镜像拉取阶段
Pod 从创建到运行经历明确的阶段序列,镜像拉取发生在 Pod 调度完成之后、容器启动之前。完整生命周期如下:
镜像拉取失败时,Pod 状态停留在 Pending,kubelet 会在后台按退避策略重试。重试期间 Pod 不会进入 CrashLoopBackOff——后者是容器启动后崩溃的机制,两者有本质区别。
1.3 kubelet 镜像拉取流程详解
kubelet 是镜像拉取的执行者,其内部流程包含清晰的决策点和重试逻辑。完整流程如下:
kubelet 镜像拉取的核心参数由 kubelet 启动配置控制,而非 Helm Chart。但 Helm 可以通过 Pod 注解和 容器运行时配置间接影响重试行为。关键参数清单:
| 参数 | 默认值 | 作用域 | 说明 |
|---|---|---|---|
--image-pull-progress-deadline |
1m0s | kubelet 全局 | 镜像拉取进度超时,超时后标记为失败并触发重试 |
--image-gc-high-threshold |
85% | kubelet 全局 | 磁盘使用率超过此值触发镜像垃圾回收,可能删除未使用镜像 |
--image-gc-low-threshold |
80% | kubelet 全局 | 垃圾回收停止的磁盘使用率下限 |
--serialize-image-pulls |
true | kubelet 全局 | 是否串行拉取镜像(默认串行,避免并发拉取耗尽带宽) |
--max-pods |
110 | kubelet 全局 | 节点最大 Pod 数,间接影响并发拉取压力 |
注意:Helm Chart 无法直接修改 kubelet 全局参数。优化镜像拉取重试机制的正确路径是:
1. 在 Chart 中合理设置
2. 通过
3. 在集群层面调整 kubelet 配置(如
1. 在 Chart 中合理设置
imagePullPolicy 和 imagePullSecrets。2. 通过
Pod.spec.containers[].startupProbe 和 livenessProbe 配合重试。3. 在集群层面调整 kubelet 配置(如
KubeletConfiguration 或节点池配置)。
1.4 镜像拉取重试的默认行为
kubelet 内置的镜像拉取重试机制遵循以下规则:
- 重试触发条件:镜像拉取返回非零退出码(网络超时、认证失败、仓库不可达、镜像不存在等)。
- 重试间隔:采用指数退避策略,初始间隔约 300ms,最大间隔 5s,总重试次数上限 10 次。
- 重试队列:每个 Pod 的镜像拉取请求独立排队,失败后进入重试队列,不阻塞其他 Pod。
- 重试重置:一旦拉取成功,该 Pod 的重试计数清零;若持续失败,10 次后放弃并上报
ImagePullBackOff事件。