介绍
yq是一个用于处理YAML文件的命令行工具,它可以帮助你解析、查询、修改和生成YAML文件。
GitHub地址:https://github.com/mikefarah/yq/releases/
安装
wget -O yq https://github.com/mikefarah/yq/releases/download/v4.45.4/yq_linux_amd64
chmod +x yq
cp yq /usr/bin
yq -V
使用
我这里是的环境是k8s 1.20,低版本的k8s在rancher上导出yaml时会包括managedFields字段,批量导出时如果挨个修改yaml会非常麻烦且耗时;在yaml中批量添加亲和性使用sed和awk容易出错调试起来也麻烦。这时就可以使用yq来实现。
去除字段
假设目录下有很多yaml文件,实现删除managedFields等字段的脚本如下:
for file in *.yaml ; do
echo "Processing $file ..."
yq eval 'del(.metadata.annotations, .metadata.creationTimestamp, .metadata.generation, .metadata.managedFields, .metadata.resourceVersion, .metadata.uid, .spec.template.metadata.annotations, .spec.template.metadata.creationTimestamp)' -i $file
done
还有第二种写法:
#!/bin/bash
# 遍历当前目录下的所有 .yaml 文件
for file in *.yaml; do
# 检查文件是否存在
if [[ -f "$file" ]]; then
echo "Processing $file ..."
# 创建一个临时文件
temp_file=$(mktemp)
# 使用 yq 处理文件并将结果输出到临时文件
yq eval 'del(.metadata.annotations, .metadata.creationTimestamp, .metadata.generation, .metadata.managedFields, .metadata.resourceVersion, .metadata.uid, .spec.template.metadata.annotations, .spec.template.metadata.creationTimestamp)' "$file" > "$temp_file"
# 检查 yq 命令是否成功执行
if [ $? -eq 0 ]; then
# 将临时文件内容写回原文件
mv "$temp_file" "$file"
echo "Processed $file successfully."
else
echo "Failed to process $file."
# 清理临时文件
rm -f "$temp_file"
fi
fi
done
批量执行yq时会保存所有的处理结果到第一个文件,还得单独处理第一个文件,或者只使用第一个文件。使用临时文件后每个文件都会被直接修改的同时也不会把修改结果保存到第一个文件中。
添加亲和性
下面是一个批量添加deployment亲和性的脚本,k8s-node1权重是100,k8s-node2,k8s-node3权重是50,k8s-node3-6权重是20,节点的标签是env=develop。
#!/bin/bash
for file in *.yaml; do
echo "处理文件: $file"
# 分步构建 affinity 结构
yq eval '.spec.template.spec.affinity = {}' -i "$file"
yq eval '.spec.template.spec.affinity.nodeAffinity = {}' -i "$file"
# 添加 preferredDuringSchedulingIgnoredDuringExecution 数组
yq eval '.spec.template.spec.affinity.nodeAffinity.preferredDuringSchedulingIgnoredDuringExecution = []' -i "$file"
# 添加第一个权重配置
yq eval '.spec.template.spec.affinity.nodeAffinity.preferredDuringSchedulingIgnoredDuringExecution += [{"weight": 100, "preference": {"matchExpressions": [{"key": "kubernetes.io/hostname", "operator": "In", "values": ["k8s-node1"]}]}}]' -i "$file"
# 添加第二个权重配置
yq eval '.spec.template.spec.affinity.nodeAffinity.preferredDuringSchedulingIgnoredDuringExecution += [{"weight": 50, "preference": {"matchExpressions": [{"key": "kubernetes.io/hostname", "operator": "In", "values": ["k8s-node2", "k8s-node3"]}]}}]' -i "$file"
# 添加第三个权重配置
yq eval '.spec.template.spec.affinity.nodeAffinity.preferredDuringSchedulingIgnoredDuringExecution += [{"weight": 20, "preference": {"matchExpressions": [{"key": "kubernetes.io/hostname", "operator": "In", "values": ["k8s-node4", "k8s-node5", "k8s-node6"]}]}}]' -i "$file"
# 添加 required 配置
yq eval '.spec.template.spec.affinity.nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution = {"nodeSelectorTerms": [{"matchExpressions": [{"key": "env", "operator": "In", "values": ["develop"]}]}]}' -i "$file"
echo "成功处理 $file"
done
必须得分开执行,否则可能会报错:Error: 24: lexer: invalid input text "affinity:\n node..