Azure DevOps Pipeline执行Bash脚本意外退出:AKS无PDB命名空间致失败
解决AKS命名空间无PDB时Azure Pipeline脚本终止问题
问题背景
需求是获取AKS所有命名空间中的PDB(PodDisruptionBudget),无PDB的命名空间直接跳过。本地执行Bash脚本可正常运行,但在Azure DevOps Pipeline中,遇到无PDB的命名空间时脚本直接终止,抛出错误:
No resources found in default namespace.
##[error]Bash exited with code '1'
原Bash脚本:
namespace=$(kubectl get namespace|egrep -iv 'name|kube-system'|awk '{ print $1 }') echo "${namespace}" for ns in ${namespace}; do poddisruptionbudget=$(kubectl get pdb -n ${ns}|awk '{ print $1 }'|grep -iv 'name'); for pdb in ${poddisruptionbudget}; do echo "PDB $pdb in namespace $ns" kubectl get -o=yaml pdb $pdb -n $ns >/azp/pdb/$ns-${pdb}.yaml; kubectl delete pdb $pdb -n $ns done; done
Azure Pipeline配置:
- task: Bash@3 displayName: Upgrade AKS cluster inputs: filePath: '$(System.DefaultWorkingDirectory)/aks-operation/aks_upgrade.sh'
问题原因
kubectl命令在未找到指定资源时会返回非0退出码,而Azure DevOps的Bash任务默认会将脚本中的非0退出码视为执行失败,直接终止整个任务。原脚本中遍历到无PDB的命名空间时,kubectl get pdb -n ${ns}会返回错误码1,触发Pipeline的失败逻辑。
解决方案
修改脚本,让kubectl在无PDB时不返回错误,同时优化资源获取逻辑提升稳定性:
修改后的脚本
# 用kubectl内置jsonpath获取命名空间,排除kube-system,避免grep/awk解析表头的问题 namespaces=$(kubectl get namespaces -o jsonpath='{.items[*].metadata.name}' | tr ' ' '\n' | grep -v kube-system) # 遍历每个命名空间 for ns in $namespaces; do # 使用--ignore-not-found参数,无PDB时kubectl返回0退出码;-o name直接获取PDB的资源标识(格式:poddisruptionbudget/<名称>) pdbs=$(kubectl get pdb -n "$ns" -o name --ignore-not-found | cut -d '/' -f 2) # 仅当存在PDB时才执行后续操作 if [ -n "$pdbs" ]; then for pdb in $pdbs; do echo "PDB $pdb in namespace $ns" # 导出PDB YAML文件 kubectl get -o=yaml pdb "$pdb" -n "$ns" > "/azp/pdb/${ns}-${pdb}.yaml" # 删除PDB时同样添加--ignore-not-found,避免因意外情况(如文件写入失败导致PDB已被删除)报错 kubectl delete pdb "$pdb" -n "$ns" --ignore-not-found done fi done
关键修改点
- 命名空间获取优化:使用
kubectl get namespaces -o jsonpath直接提取命名空间名称,比grep+awk解析表格输出更稳定,避免表头或格式变化导致的错误。 - 忽略无资源错误:给
kubectl get pdb添加--ignore-not-found参数,无PDB时返回0退出码,不会触发Pipeline的失败逻辑。 - PDB名称提取优化:用
-o name获取PDB的标准资源标识,再通过cut提取名称,无需过滤表头,逻辑更简洁可靠。 - 空值判断:添加
if [ -n "$pdbs" ]判断,避免空循环执行无效操作。 - 删除操作容错:删除PDB时也添加
--ignore-not-found,防止因意外情况导致PDB已不存在时触发错误。
内容的提问来源于stack exchange,提问作者hola
相关产品推荐
相关产品推荐

