脚本考虑了有init容器存在的情况
#!/bin/bash
set -e
namespace1="source_namespace"
namespace2="target_namespace"
# 获取 namespace1 中所有 Deployment 名称
deployments=$(kubectl get deployments -n "$namespace1" -o jsonpath="{.items[*].metadata.name}")
echo "Comparing Deployments in $namespace1 and $namespace2"
for deployment in $deployments; do
echo "------------------------------------------------"
echo "Deployment: $deployment"
# 获取 source 和 target 的 YAML
yaml1=$(kubectl get deployment "$deployment" -n "$namespace1" -o yaml 2>/dev/null)
yaml2=$(kubectl --kubeconfig=/root/config-back get deployment "$deployment" -n "$namespace2" -o yaml 2>/dev/null)
if [ -z "$yaml1" ]; then
echo "Deployment $deployment not found in namespace $namespace1"
continue
fi
if [ -z "$yaml2" ]; then
echo "Deployment $deployment not found in namespace $namespace2"
continue
fi
# 输出调试信息,确认 YAML 是否正确获取
echo "DEBUG: Successfully fetched YAML for deployment $deployment"
changed=false
# ---------------------------
# 对比 containers 部分,只更新 image 字段
# ---------------------------
src_containers_count=$(echo "$yaml1" | yq e '.spec.template.spec.containers | length' -)
echo "DEBUG: Found $src_containers_count containers in source deployment."
for (( i=0; i<src_containers_count; i++ )); do
cname=$(echo "$yaml1" | yq e ".spec.template.spec.containers[$i].name" - | xargs)
cimage_src=$(echo "$yaml1" | yq e ".spec.template.spec.containers[$i].image" - | xargs)
cimage_target=$(echo "$yaml2" | yq e ".spec.template.spec.containers[] | select(.name==\"$cname\") | .image" - | xargs)
echo "Container '$cname': source image: [$cimage_src] target image: [$cimage_target]"
if [ "$cimage_src" != "$cimage_target" ]; then
echo "-> Updating container '$cname' image in $deployment..."
kubectl --kubeconfig=/root/config-back set image deployment/"$deployment" -n "$namespace2" "$cname=$cimage_src"
changed=true
fi
done
# ---------------------------
# 对比 initContainers 部分,仅更新 image 字段,保留其它字段不变
# ---------------------------
target_init_exists=$(echo "$yaml2" | yq e 'has("spec.template.spec.initContainers")' -)
if [ "$target_init_exists" != "true" ]; then
echo "Target deployment does not have initContainers. Skipping init container updates."
else
src_init_count=$(echo "$yaml1" | yq e '.spec.template.spec.initContainers | length' - 2>/dev/null || echo 0)
echo "DEBUG: Found $src_init_count initContainers in source deployment."
for (( i=0; i<src_init_count; i++ )); do
iname=$(echo "$yaml1" | yq e ".spec.template.spec.initContainers[$i].name" - | xargs)
iimage_src=$(echo "$yaml1" | yq e ".spec.template.spec.initContainers[$i].image" - | xargs)
iimage_target=$(echo "$yaml2" | yq e ".spec.template.spec.initContainers[] | select(.name==\"$iname\") | .image" - | xargs)
echo "Init container '$iname': source image: [$iimage_src] target image: [$iimage_target]"
if [ -z "$iimage_target" ]; then
echo "Init container '$iname' not found in target. Skipping."
continue
fi
if [ "$iimage_src" != "$iimage_target" ]; then
echo "-> Updating init container '$iname' image in $deployment..."
# 获取 target 中该 init container 的索引
index=$(echo "$yaml2" | yq e '.spec.template.spec.initContainers | to_entries | map(select(.value.name=="'"$iname"'")) | .[0].key' -)
if [ -z "$index" ]; then
echo "Cannot determine index for init container '$iname' in target. Skipping."
continue
fi
patch=$(cat <<EOF
[
{
"op": "replace",
"path": "/spec/template/spec/initContainers/$index/image",
"value": "$iimage_src"
}
]
EOF
)
kubectl --kubeconfig=/root/config-back patch deployment "$deployment" -n "$namespace2" --type='json' -p "$patch"
changed=true
fi
done
fi
if [ "$changed" = false ]; then
echo "Result: All images are identical for $deployment"
fi
done
echo "------------------------------------------------"
echo "Comparison and sync complete."
评论区