You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用jq将Deployment中的PV Claim转换为ConfigMap

Kubernetes Deployment配置转换:PVC转ConfigMap并调整VolumeMounts

需求描述

将Deployment配置中所有以扩展名结尾的mountPath对应的PersistentVolumeClaim(PVC)替换为ConfigMap对象,同时调整volumeMounts配置:

  • 修改卷名称为指定格式(基于原卷前缀+文件名转小写、特殊字符替换为短横线)
  • 添加subPath字段,值为mountPath对应的文件名

输入配置

{
  "apiVersion": "apps/v1",
  "kind": "Deployment",
  "spec": {
    "template": {
      "spec": {
        "containers": [
          {
            "volumeMounts": [
              {
                "mountPath": "/var/www/html",
                "name": "shared"
              },
              {
                "mountPath": "/var/www/html/LocalSettings.d/LocalSettings.override.php",
                "name": "movies-wikibase-claim1"
              },
              {
                "mountPath": "/var/www/html/img/wikibase_logo.png",
                "name": "movies-wikibase-claim2"
              }
            ]
          }
        ],
        "volumes": [
          {
            "name": "shared",
            "persistentVolumeClaim": {
              "claimName": "shared"
            }
          },
          {
            "name": "movies-wikibase-claim1",
            "persistentVolumeClaim": {
              "claimName": "movies-wikibase-claim1"
            }
          },
          {
            "name": "movies-wikibase-claim2",
            "persistentVolumeClaim": {
              "claimName": "movies-wikibase-claim2"
            }
          }
        ]
      }
    }
  }
}

预期结果

{
  "apiVersion": "apps/v1",
  "kind": "Deployment",
  "spec": {
    "template": {
      "spec": {
        "containers": [
          {
            "volumeMounts": [
              {
                "mountPath": "/var/www/html",
                "name": "shared"
              },
              {
                "mountPath": "/var/www/html/LocalSettings.d/LocalSettings.override.php",
                "name": "movies-wikibase-localsettings-override-php",
                "subPath": "LocalSettings.override.php"
              },
              {
                "mountPath": "/var/www/html/img/wikibase_logo.png",
                "name": "movies-wikibase-wikibase-logo-png",
                "subPath": "wikibase_logo.png"
              }
            ]
          }
        ],
        "volumes": [
          {
            "name": "shared",
            "persistentVolumeClaim": {
              "claimName": "shared"
            }
          },
          {
            "name": "movies-wikibase-localsettings-override-php",
            "configMap": {
              "defaultMode": 420,
              "name": "movies-wikibase-localsettings-override-php"
            }
          },
          {
            "name": "movies-wikibase-wikibase-logo-png",
            "configMap": {
              "defaultMode": 420,
              "name": "movies-wikibase-wikibase-logo-png"
            }
          }
        ]
      }
    }
  }
}

用户尝试的代码问题

用户提供的jq命令存在以下缺陷:

  1. 未删除旧PVC卷:使用+=追加新卷,导致原PVC卷残留
  2. 变量捕获不完整:仅捕获最后一个匹配的卷名称,无法批量生成ConfigMap卷
  3. 逻辑顺序未完全匹配需求:未先收集旧卷名再过滤删除

正确的jq命令

jq '
# 第一步:收集所有需要替换的旧PVC卷名称
(
  [.spec.template.spec.containers[].volumeMounts[]? | select(.mountPath | test("\\.[^.]+$")) | .name] as $oldVolumeNames
)
# 第二步:修改符合条件的volumeMounts:更新名称+添加subPath
| .spec.template.spec.containers[].volumeMounts[] |= (
  if .mountPath | test("\\.[^.]+$") then
    let baseName = .name | split("-claim")[0]
    fileName = .mountPath | split("/") | last
    newName = baseName + "-" + (fileName | gsub("_"; "-") | gsub("\\."; "-") | ascii_downcase)
    in
    . + {name: newName, subPath: fileName}
  else
    .
  end
)
# 第三步:处理volumes:移除旧PVC卷,添加新ConfigMap卷
| (
  # 保留不需要替换的卷(非目标PVC卷)
  filteredVolumes = .spec.template.spec.volumes | map(select(.name | IN($oldVolumeNames[]) | not))
  # 收集修改后的新卷名称
  newVolumeNames = [.spec.template.spec.containers[].volumeMounts[]? | select(.mountPath | test("\\.[^.]+$")) | .name]
  # 生成ConfigMap卷配置
  newVolumes = newVolumeNames | map({
    name: .,
    configMap: {
      defaultMode: 420,
      name: .
    }
  })
  in
  .spec.template.spec.volumes = filteredVolumes + newVolumes
' movies-wikibase-deployment.json

命令说明

  1. 收集旧卷名:先标记所有需要替换的PVC卷名称,为后续删除做准备
  2. 更新volumeMounts:遍历每个挂载项,对带扩展名的路径生成新卷名,并添加subPath
  3. 替换volumes:过滤移除旧PVC卷,批量生成对应的ConfigMap卷并追加到配置中

内容的提问来源于stack exchange,提问作者Nathanaël Blanchet

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 21:29:59