云上CI/CD发布应用
更新时间 2026-07-06 10:56:29
最近更新时间: 2026-07-06 10:56:29
本场景为云上服务部署前脚本通过调用天翼云CLI,对各类资源的检查,实时拨测和部署完成的验证:
发布前检查基础设施是否满足上线条件
发布后验证 ELB 后端和公网访问是否正常
失败时自动回滚应用版本
全过程保留 CLI 请求日志和资源状态快照
目标架构
用户访问
↓
EIP / 公网 ELB
↓
ELB 监听器
↓
后端 ECS:web-01、web-02
↓
应用服务:8080CI/CD 阶段
1. 发布前检查
2. 构建应用
3. 部署应用到 ECS
4. 发布后验证
5. 失败回滚
6. 日志留痕
具体步骤
1.配置CI变更
CTYUN_AK
CTYUN_SK
CTYUN_REGION_ID
CTYUN_ELB_ID
CTYUN_SECURITY_GROUP_ID
CTYUN_TARGET_GROUP_IDS
CTYUN_ECS_IDS="ecs-xxx,ecs-yyy"
APP_HEALTH_URL="http://example.com/health"
SSH_USER="root"
SSH_PRIVATE_KEY
APP_PACKAGE="web-app.tar.gz"
APP_DEPLOY_DIR="/opt/web-app"
确保日志留痕,开启ctyun-cli调用日志:
export CTYUN_LOG=true
export CTYUN_LOG_FILE="./ctyun-cli-ci.log"
export CTYUN_LOG_FORMAT="json"2.发布前检查
ctyun-cli version
# 检查ecs
ctyun-cli ecs GetEcsInstanceDetails \
--regionID "$CTYUN_REGION_ID" \
--instanceID "$ecs_id" \
-o json
# 检查elb
ctyun-cli elb ShowLoadbalancer \
--regionID "$CTYUN_REGION_ID" \
--elbID "$CTYUN_ELB_ID" \
-o json
# 检查elb 监听器
ctyun-cli elb ListElbListener \
--regionID "$CTYUN_REGION_ID" \
--loadBalancerID "$CTYUN_ELB_ID" \
-o json
# 检查后端主机组
ctyun-cli elb ShowElbTargetGroup \
--regionID "$CTYUN_REGION_ID" \
--targetGroupID "$tg_id" \
-o json
# 检查健康检查
ctyun-cli elb ShowElbHealthCheck \
--regionID "$CTYUN_REGION_ID" \
--healthCheckID "$health_check_id"\
-o json
# 检查安全组
ctyun-cli vpc DescribeVpcSecurityGroupRules \
--regionID "$CTYUN_REGION_ID" \
--securityGroupID "$CTYUN_SECURITY_GROUP_ID" \
--pageNo 1 \
--pageSize 50 \
-o json部署前检查脚本示例,用户需要根据实际业务情况进行信息的检查:
#!/usr/bin/env bash
set -euo pipefail
echo "[precheck] checking ctyun-cli"
ctyun-cli version
echo "[precheck] checking ecs instances"
IFS=',' read -ra ECS_IDS <<< "$CTYUN_ECS_IDS"
for ecs_id in "${ECS_IDS[@]}"; do
echo "[precheck] ecs: $ecs_id"
ctyun-cli ecs GetEcsInstanceDetails \
--regionID "$CTYUN_REGION_ID" \
--instanceID "$ecs_id" \
-o json > "precheck-ecs-${ecs_id}.json"
status=$(ctyun-cli ecs GetEcsInstanceDetails \
--regionID "$CTYUN_REGION_ID" \
--instanceID "$ecs_id" \
--cli-query 'returnObj.instanceStatus' \
-o json)
echo "[precheck] ecs $ecs_id status: $status"
if [ "$status" != '"running"' ]; then
echo "ECS $ecs_id is not running"
exit 1
fi
done
echo "[precheck] checking load balancer"
ctyun-cli elb ShowLoadbalancer \
--regionID "$CTYUN_REGION_ID" \
--elbID "$CTYUN_ELB_ID" \
-o json > precheck-elb.json
elb_status=$(ctyun-cli elb ShowLoadbalancer \
--regionID "$CTYUN_REGION_ID" \
--elbID "$CTYUN_ELB_ID" \
--cli-query 'returnObj[0].status' \
-o json)
echo "[precheck] elb status: $elb_status"
if [ "$elb_status" != '"ACTIVE"' ]; then
echo "ELB $CTYUN_ELB_ID is not ACTIVE"
exit 1
fi
echo "[precheck] checking listeners"
ctyun-cli elb ListElbListener \
--regionID "$CTYUN_REGION_ID" \
--loadBalancerID "$CTYUN_ELB_ID" \
-o json > precheck-elb-listeners.json
echo "[precheck] checking target groups and targets"
IFS=',' read -ra TARGET_GROUP_IDS <<< "$CTYUN_TARGET_GROUP_IDS"
for tg_id in "${TARGET_GROUP_IDS[@]}"; do
echo "[precheck] target group: $tg_id"
ctyun-cli elb ShowElbTargetGroup \
--regionID "$CTYUN_REGION_ID" \
--targetGroupID "$tg_id" \
-o json > "precheck-target-group-${tg_id}.json"
ctyun-cli elb ListElbTarget \
--regionID "$CTYUN_REGION_ID" \
--targetGroupID "$tg_id" \
-o json > "precheck-targets-${tg_id}.json"
done
echo "[precheck] checking security group rules"
ctyun-cli vpc DescribeVpcSecurityGroupRules \
--regionID "$CTYUN_REGION_ID" \
--securityGroupID "$CTYUN_SECURITY_GROUP_ID" \
--pageNo 1 \
--pageSize 50 \
-o json > precheck-security-group-rules.json
echo "[precheck] passed"3. 应用部署,将业务滚动发布到各台ecs
先部署 web-01
检查 web-01 本机健康
再部署 web-02
检查 web-02 本机健康
最后检查 ELB 整体健康4. 发布后验证
验证项:
ECS 进程是否正常
ELB 后端是否健康
公网健康检查 URL 是否正常
# 检查ecs状态
ctyun-cli ecs GetEcsInstanceDetails \
--regionID "$CTYUN_REGION_ID" \
--instanceID "$ecs_id" \
--cli-query 'returnObj.instanceStatus'
# 后端主机校验
ctyun-cli elb ListElbTarget \
--regionID "$CTYUN_REGION_ID" \
--targetGroupID "$tg_id" \
-o json通过调用CLI,实现具体校验脚本如下:
#!/usr/bin/env bash
set -euo pipefail
echo "[postcheck] checking ecs instances"
IFS=',' read -ra ECS_IDS <<< "$CTYUN_ECS_IDS"
for ecs_id in "${ECS_IDS[@]}"; do
status=$(ctyun-cli ecs GetEcsInstanceDetails \
--regionID "$CTYUN_REGION_ID" \
--instanceID "$ecs_id" \
--cli-query 'returnObj.instanceStatus' \
-o json)
echo "[postcheck] ecs $ecs_id status: $status"
if [ "$status" != '"running"' ]; then
echo "ECS $ecs_id is not running"
exit 1
fi
done
echo "[postcheck] checking elb targets"
IFS=',' read -ra TARGET_GROUP_IDS <<< "$CTYUN_TARGET_GROUP_IDS"
for tg_id in "${TARGET_GROUP_IDS[@]}"; do
ctyun-cli elb ListElbTarget \
--regionID "$CTYUN_REGION_ID" \
--targetGroupID "$tg_id" \
-o json > "postcheck-targets-${tg_id}.json"
ctyun-cli elb ListElbTarget \
--regionID "$CTYUN_REGION_ID" \
--targetGroupID "$tg_id" \
--cli-query 'returnObj[].{id:ID,instanceID:instanceID,status:status,health:healthCheckStatus,port:protocolPort}' \
-o table
done
echo "[postcheck] checking public health url"
curl -fsS --retry 5 --retry-delay 3 "$APP_HEALTH_URL"
echo "[postcheck] passed"#!/usr/bin/env bash
set -euo pipefail
echo "[postcheck] checking ecs instances"
IFS=',' read -ra ECS_IDS <<< "$CTYUN_ECS_IDS"
for ecs_id in "${ECS_IDS[@]}"; do
status=$(ctyun-cli ecs GetEcsInstanceDetails \
--regionID "$CTYUN_REGION_ID" \
--instanceID "$ecs_id" \
--cli-query 'returnObj.instanceStatus' \
-o json)
echo "[postcheck] ecs $ecs_id status: $status"
if [ "$status" != '"running"' ]; then
echo "ECS $ecs_id is not running"
exit 1
fi
done
echo "[postcheck] checking elb targets"
IFS=',' read -ra TARGET_GROUP_IDS <<< "$CTYUN_TARGET_GROUP_IDS"
for tg_id in "${TARGET_GROUP_IDS[@]}"; do
ctyun-cli elb ListElbTarget \
--regionID "$CTYUN_REGION_ID" \
--targetGroupID "$tg_id" \
-o json > "postcheck-targets-${tg_id}.json"
ctyun-cli elb ListElbTarget \
--regionID "$CTYUN_REGION_ID" \
--targetGroupID "$tg_id" \
--cli-query 'returnObj[].{id:ID,instanceID:instanceID,status:status,health:healthCheckStatus,port:protocolPort}' \
-o table
done
echo "[postcheck] checking public health url"
curl -fsS --retry 5 --retry-delay 3 "$APP_HEALTH_URL"
echo "[postcheck] passed"