必须使用 yq v4+(mikefarah/yq)原地修改 YAML 文件,通过 -i 参数实现,多操作需合并书写,数组操作须防越界,保留注释需加 -P,缺失路径需用 |=, += 或 // [] 显式处理。

能直接原地修改,但必须用 yq v4+(mikefarah/yq),老版本的 yq r/yq w 语法已废弃,强行用会静默失败或报错。
确认你用的是 yq v4+ 版本
运行 yq --version,输出应类似 yq version 4.44.1。如果看到 3.x 或提示 command not found: yq,说明没装对:
- Debian/Ubuntu:
sudo snap install yq或curl -L https://github.com/mikefarah/yq/releases/latest/download/yq_linux_amd64 -o /usr/local/bin/yq && chmod +x /usr/local/bin/yq - macOS:
brew install yq(Homebrew 默认装的就是 v4+) - 别用系统包管理器装的旧版:
apt install yq在 Ubuntu 22.04 及更早默认装的是 v3,不支持-i原地写入
用 -i 参数直接改文件,不是“输出再重定向”
常见错误是写成 yq '.spec.replicas = 5' config.yaml > config.yaml —— 这会清空原文件。正确做法是用 -i(in-place):
- 把 Deployment 副本数改成 3:
yq -i '.spec.replicas = 3' deployment.yaml - 给容器加一个环境变量:
yq -i '.spec.template.spec.containers[0].env += [{"name": "DEBUG", "value": "true"}]' deployment.yaml - 删掉整个
status字段:yq -i 'del(.status)' pod.yaml - 注意:多个操作要合并写,不能连续调用多个
yq -i,否则后一次会覆盖前一次的修改逻辑
处理数组时小心下标越界和类型错误
YAML 数组字段(如 containers、volumeMounts)在空或不存在时,直接写 .containers[0].image = "nginx" 会报错 Cannot index array with string:
- 先确保数组存在且非空:
yq -i '(.spec.template.spec.containers |= . // []) |= .[0].image = "nginx:1.25"' deployment.yaml - 追加新元素(推荐):
yq -i '.spec.template.spec.containers += [{"name": "sidecar", "image": "busybox"}]' deployment.yaml - 用
+=比=更安全,它会自动创建缺失的父路径(如.spec不存在也会补上)
修改带注释或锚点的 YAML 要加 -P
普通 yq -i 会丢掉注释、折叠写法(&anchor)、多行字符串缩进。如果你的配置里有运维备注或 K8s 生成的注释(比如 kubectl.kubernetes.io/last-applied-configuration),必须加 -P(preserve):
- 保留注释改镜像:
yq -i -P '.spec.template.spec.containers[0].image = "nginx:1.26"' deployment.yaml -
-P会让性能略降,但对 CI/CD 中需人工审核的配置文件是刚需 - 不加
-P的修改在git diff里可能显示整块重写,而非仅一行变更
最易被忽略的是:v4+ 的表达式默认不创建缺失路径,.a.b.c = 1 在 .a 不存在时直接失败;要用 |= 或 += 触发自动补全,或者显式用 // [] 提供默认值。这点和 jq 不同,得习惯。


















