子路径挂载为什么收不到更新
默认把整个卷挂载到某个目录时,卷内容的更新会同步到容器里;但使用子路径把卷里的单个键挂成单个文件时,这个映射只在容器启动时建立一次,之后源内容无论怎么改都不会传播进容器。这是「修改了配置对象但应用一直是旧值」最常见的原因。
为什么大家还是爱用它
子路径能让一个键挂成指定文件名,覆盖镜像里原有的配置文件,看起来干净利落。代价是同时关闭了更新传播能力。取舍很清楚:需要跟随更新就用目录挂载,需要精确覆盖单个文件就接受手动重建的现实。
基本信息
| 适用环境 | 任何 Kubernetes 发行版,属于卷挂载的写法 |
|---|---|
| 挂载对象 | 卷中的单个键或目录 |
| 更新传播 | 不传播,映射在容器启动时固定 |
| 对照写法 | 整卷挂载到目录,通常会跟随更新 |
| 删除源键的影响 | 容器内旧文件仍然存在 |
| 生效方式 | 重建实例才会读到新内容 |
典型使用场景
- 覆盖镜像内配置文件:用配置对象里的单个键替换原有文件
- 挂载单个证书文件:只把证书挂到指定路径
- 避免目录遮蔽:整卷挂载会覆盖镜像里同目录的其他文件,子路径可避免
- 按文件名定制:把键挂成应用期望的固定文件名
- 排查配置不生效:确认挂载方式是否属于这一类别
- 迁移改造:从子路径挂载改为目录挂载以获得更新能力
子路径写法
子路径写法
volumes:
- name: config
configMap:
name: app-config
containers:
- name: app
volumeMounts:
- name: config
mountPath: /etc/app/app.properties # 挂成单个文件
subPath: app.properties # 卷里的键名
# 注意:此后该键的更新不会进入容器验证与重建
验证与重建
kubectl exec -it web-x -- cat /etc/app/app.properties # 看容器内的实际内容
kubectl get cm app-config -o jsonpath='{.data.app\.properties}' # 看对象里的最新内容
kubectl rollout restart deploy/web # 需要新内容时重建实例
kubectl get pods -l app=web -o wide | head # 确认实例已替换两种挂载方式对照
| 方式 | 更新传播 | 适用场景 |
|---|---|---|
| 整卷挂载到目录 | 通常会跟随更新 | 需要配置自动生效的场景 |
| 子路径挂载单个键 | 不传播,需重建实例 | 精确覆盖镜像内单个文件 |
| 子路径挂载目录 | 同样不跟随更新 | 需要保留目录其他文件的场景 |
| 组合使用 | 按需要分别选择 | 部分文件需更新、部分需覆盖 |
子路径挂载的映射只在容器启动时建立,之后源内容的增删改都不会进入容器,需要重建实例才生效。
源对象的键被删除后,容器里挂载的旧文件依然存在,容易误判为「配置没有改动」。