脚本整体架构
- 参数解析:获取需要升级的Pod所在的Deployment名称、新镜像版本等参数。
- 滚动升级:使用
kubectl set image
命令对Deployment进行镜像升级,触发滚动升级。
- 健康检查:在升级过程中,通过
kubectl rollout status
命令实时检查滚动升级状态,结合自定义的健康检查逻辑(例如检查Pod内服务端口是否可访问等)。
- 回滚处理:如果健康检查失败,使用
kubectl rollout undo
命令回滚到上一个版本。
关键实现步骤
- 初始化变量:定义Deployment名称、新镜像版本等变量。
- 执行滚动升级:使用
kubectl set image deployment/${deployment_name} ${container_name}=${new_image}
命令设置新镜像。
- 健康检查:通过循环结合
kubectl rollout status
检查升级状态,并添加自定义健康检查逻辑。
- 回滚操作:如果健康检查失败,执行
kubectl rollout undo deployment/${deployment_name}
。
主要代码片段
#!/bin/bash
# 参数解析
if [ $# -ne 3 ]; then
echo "Usage: $0 <deployment_name> <container_name> <new_image>"
exit 1
fi
deployment_name=$1
container_name=$2
new_image=$3
# 执行滚动升级
kubectl set image deployment/${deployment_name} ${container_name}=${new_image}
# 健康检查并处理回滚
rollout_timeout=120
start_time=$(date +%s)
while true; do
rollout_status=$(kubectl rollout status deployment/${deployment_name})
if [[ $rollout_status == *"successfully rolled out"* ]]; then
echo "Rollout successful"
break
elif (( $(date +%s) - start_time > rollout_timeout )); then
echo "Rollout timeout, starting rollback"
kubectl rollout undo deployment/${deployment_name}
break
else
# 自定义健康检查,例如检查Pod内服务端口是否可访问
pod_name=$(kubectl get pods -l app=${deployment_name} -o jsonpath='{.items[0].metadata.name}')
if kubectl exec -it $pod_name -- curl -s http://localhost:8080 > /dev/null; then
sleep 5
else
echo "Health check failed, starting rollback"
kubectl rollout undo deployment/${deployment_name}
break
fi
fi
done