在 Kubernetes 环境中自动化部署和更新应用程序是一项重要的任务。本文将介绍一个优化后的 Bash 脚本,用于构建镜像、创建快照并更新 Kubernetes 资源。
优化后的脚本
#!/bin/bash
# 配置参数
HOST=10.0.71.20
SERVER_NAME=tree
ECR_REPO=820600610568.dkr.ecr.us-east-1.amazonaws.com/ai/tree
TOKEN=4ecc827755c91854fca04d34b58e255e3ac39475ee92bfebbc1159b6369d42b9
SNAPSHOT_UTILS_DIR=/root/stable-diffusion-on-eks/utils/bottlerocket-images-cache
# 构建并推送新镜像
build_and_push_image() {
local VERSION=$(date +%Y%m%d%H%M%S)
local IMAGE=${ECR_REPO}:${VERSION}
# 替换环境变量
sed -i "s|{env}-light|test-${SERVER_NAME}|g" run.py
# 登录 ECR 并构建推送镜像
aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin ${ECR_REPO%/*}
docker build -t ${IMAGE} .
docker push ${IMAGE}
docker rmi -f ${IMAGE}
echo "${IMAGE}"
}
# 创建新快照并更新 EC2NodeClass 和 Deployment
create_snapshot_and_update() {
local IMAGE=\$1
cd "${SNAPSHOT_UTILS_DIR}"
./snapshot.sh "${IMAGE}" | tee log.txt
local NEW_SNAPSHOT_ID=$(grep -oEi 'snap-[a-z0-9]+' log.txt | tail -1)
# 更新 EC2NodeClass
ssh root@${HOST} "kubectl patch EC2NodeClass test-tree-ai-gpu --type='json' -p '[{\"op\":\"replace\", \"path\":\"/spec/blockDeviceMappings/1/ebs/snapshotID\", \"value\":\"${NEW_SNAPSHOT_ID}\"}]'"
# 更新 Deployment 镜像
ssh root@${HOST} "kubectl set image deployment/test-tree-ai test-tree-ai=${IMAGE}"
}
# 发送钉钉通知
send_notification() {
curl "https://oapi.dingtalk.com/robot/send?access_token=${TOKEN}" \
-H 'Content-Type: application/json' \
-d '{"msgtype": "markdown","markdown": {"title":"Update test-'"${SERVER_NAME}"'-ai Success","text": "<font face='\u9ed1\u4f53' color='#00EC00'>Update test-'"${SERVER_NAME}"'-ai Success</font>\n"}}'
}
# 主逻辑
NEW_IMAGE=$(build_and_push_image)
create_snapshot_and_update "${NEW_IMAGE}"
send_notification
脚本优化点
- 集中配置参数
将配置参数集中在脚本顶部,方便管理和修改。
HOST=10.0.71.20
SERVER_NAME=tree
ECR_REPO=820600610568.dkr.ecr.us-east-1.amazonaws.com/ai/tree
TOKEN=4ecc827755c91854fca04d34b58e255e3ac39475ee92bfebbc1159b6369d42b9
SNAPSHOT_UTILS_DIR=/root/stable-diffusion-on-eks/utils/bottlerocket-images-cache
- 拆分逻辑为函数
将构建镜像、创建快照和更新资源的逻辑拆分为独立函数,提高可读性和可维护性。
build_and_push_image() { ... }
create_snapshot_and_update() { ... }
send_notification() { ... }
- 使用局部变量
使用局部变量来存储中间结果,避免全局变量污染。
local VERSION=$(date +%Y%m%d%H%M%S)
local IMAGE=${ECR_REPO}:${VERSION}
local NEW_SNAPSHOT_ID=$(grep -oEi 'snap-[a-z0-9]+' log.txt | tail -1)
- 优化通知命令
优化了发送钉钉通知的命令,使用单引号包裹字符串以避免特殊字符被解析。
curl "https://oapi.dingtalk.com/robot/send?access_token=${TOKEN}" \
-H 'Content-Type: application/json' \
-d '{"msgtype": "markdown","markdown": {"title":"Update test-'"${SERVER_NAME}"'-ai Success","text": "<font face='\u9ed1\u4f53' color='#00EC00'>Update test-'"${SERVER_NAME}"'-ai Success</font>\n"}}'
- 使用变量代替硬编码
在构建镜像和发送通知时,直接使用变量而不是硬编码的值。
local IMAGE=${ECR_REPO}:${VERSION}
"Update test-'"${SERVER_NAME}"'-ai Success"
- 简化参数传递
在创建快照时,直接将镜像名称作为参数传递给snapshot.sh
脚本,无需使用逗号分隔的字符串。
./snapshot.sh "${IMAGE}" | tee log.txt
- 使用 Unicode 编码
在发送钉钉通知时,使用 Unicode 编码的黑体字符代替 HTML 实体编码。
"<font face='\u9ed1\u4f53' color='#00EC00'>Update test-'"${SERVER_NAME}"'-ai Success</font>\n"
通过上述优化,脚本变得更加易读、易维护和可扩展。每个功能都被封装在独立的函数中,配置参数集中管理,并且避免了全局变量污染。此外,还优化了一些命令的执行方式和参数传递方式,提高了脚本的可靠性和效率。