自动化部署
在采用持续集成和持续部署的开发流程中,自动化部署是至关重要的一环。它可以使得代码的变更能够快速、自动地被部署到生产环境中,从而实现快速交付和持续集成的目标。没有自动化部署便没有自动化测试。一旦代码被自动部署到相应的环境中,自动化测试可以立即启动,以确保新的更改没有引入新的错误或破坏现有的功能。这种集成测试的自动触发可以在代码交付到生产环境之前提供及时的反馈。
自动化部署简单讲就是将开发的应用程序成功的部署一台或者多台计算机上。软件架构的复杂度决定了自动化部署的复杂度。如上图所示,简单部署可以是通过ssh协议到远程的设备执行一段shell脚本就可以完成自动化部署。负载的部署可能需要专门的环境管理软件,是一个可循环执行的部署过程。个人任务大致包括一下三个过程:
资源的回收
在自动化部署之前的资源回收是指在进行新版本或更新的部署之前,对之前版本所占用的资源进行清理和回收的过程。这个过程的目的是确保新部署的应用程序不会与旧版本的应用程序发生冲突或资源竞争,同时也可以释放之前版本所占用的资源,提高资源利用率和效率。
资源回收的具体内容可以包括以下几个方面:
-
停止旧版本的服务或应用程序实例:在部署新版本之前,需要停止之前版本的服务或应用程序实例。这样可以确保新版本的应用程序能够顺利启动并占用所需的资源。
-
释放之前版本的资源:停止旧版本的服务或应用程序实例后,需要释放其占用的资源,包括CPU、内存、存储等。这可以通过关闭相关的进程、释放占用的内存和删除不再需要的临时文件来实现。
-
清理旧版本的配置和数据:在停止旧版本的服务或应用程序实例之前,可能需要清理其使用的配置文件、日志文件、缓存数据等。这样可以确保新版本的部署不受到之前版本的配置和数据的影响。
-
更新相关的资源配置:如果新版本的应用程序需要占用之前版本所使用的资源(如端口号、存储路径等),则可能需要更新相关的资源配置,以确保新版本能够顺利启动并正常运行。
部署基础设施组件
应用不是独立运行的,正在应用部署前可能还需要以下等基础组件的部署:
自动化部署的基础环境部署通常包括以下关键组件:
-
数据库:用于存储和管理应用程序的数据。
-
缓存服务器:用于缓存经常访问的数据或计算结果,减少对数据库的访问压力,提高应用程序性能。
-
消息队列/消息中间件:用于实现应用程序之间的异步通信和解耦,提高系统的可靠性和可扩展性。
-
安全设施:用于保护应用程序和基础设施免受网络攻击、恶意行为和数据泄露的威胁。
-
日志管理系统:用于收集、存储和分析应用程序的日志数据,帮助识别和解决问题、监视系统性能和行为。
-
监控和警报系统:用于实时监视应用程序和基础设施的运行状态、性能指标和异常情况,发送警报通知并执行自动化的响应操作。
通过部署这些基础设施组件, 可以为应用软件运行提供基础保障。
部署应用
在基础设施完成后,正在的应用可以采取以下方式:
-
蓝绿部署(Blue-Green Deployment):蓝绿部署是一种零宕机部署策略,通过同时部署两个相同的环境(蓝环境和绿环境),其中一个环境用于生产,另一个环境用于备份或测试。在部署新版本时,首先将新版本部署到绿环境中进行测试和验证,然后通过切换负载均衡器的指向将流量逐步转移到绿环境,最终完成全量切换。
-
灰度发布(Canary Deployment):灰度发布是一种逐步放大风险的部署策略,通过逐步将新版本应用程序部署到一小部分用户或服务器上,并观察其性能和稳定性,如果没有问题,则逐步扩大部署范围,直到完全替换旧版本。
-
金丝雀发布(Canary Release):金丝雀发布是灰度发布的一种变体,它允许将新版本应用程序部署到一小部分用户或服务器上,然后根据用户反馈或监控指标决定是否继续推进部署。如果发现问题,则可以快速回滚或修复,避免对所有用户造成影响。
-
AB测试:AB测试是一种通过将用户分成不同的群组并分别向其提供不同版本的应用程序,然后比较不同版本的性能和用户反馈来决定最终采用哪个版本的策略。这种方式可以帮助评估新功能或变化对用户体验和业务指标的影响,从而优化产品设计和功能迭代。
这些高级部署策略可以在基础环境部署完成后实施,并通过适当的工具和技术来支持,例如使用负载均衡器实现流量切换、监控系统实时监测性能指标、自动化部署工具实现快速回滚等。它们可以帮助团队更加安全和可控地发布新版本,最大程度地减少对用户的影响和业务的风险。
总之自动化部署是一个复杂的过程,需要强大的工具链支持。我只有两台电脑无法演示这个复杂的过程,所以提供一个简单的例子说明这个问题。
简单的单体应用部署
deployapp.sh
在scripts目录下创建deployapp.sh文件,该脚本会在要部署的机器上执行:首先删除名字为app的容易,然后重新部署新的应用
bash
#!/bin/bash
container_name="app"
if docker ps -aqf "name=$container_name" &> /dev/null; then
echo "Deleting container $container_name..."
docker rm -f "$container_name"
else
echo "Container $container_name does not exist."
fi
docker run -d -p 9999:8080 --name app docker.mvcode.cn:8083/springdemo:1.0.0-SNAPSHOT
deploy.sh
在scripts目录下创建deploy.sh文件,CI/CD的Deploy Job会执行该脚本。该脚本的逻辑就是使用工具镜像开启容器,通过sshpass到远程机器上执行deployapp.sh脚本。
bash
#!/bin/bash
# 回收环境
# 1. curl http://x.x.x.x/env/destroy?env=${envname}
# 部署基础设施
# 2.curl http://x.x.x.x/env/init?env=${envname}
# 3.curl http://x.x.x.x/env/deploy?app=${app}&version=${version}
APP_ROOT=$(pwd)
docker run --rm -v $APP_ROOT:/app \
-w /app \
docker.mvcode.cn:8083/devtools:1.0.0 \
sshpass -p '你的密码' ssh -o StrictHostKeyChecking=no copier@192.168.3.52 sh ./deployapp.sh
.gitlab-ci.yml
修改.gitlab-ci.yml添加名字为deploy的job
bash
stages:
- build
build:
stage: build
script:
- sh ./scripts/build.sh
deploy:
stage: build
dependencies:
- "build"
script:
- sh ./scripts/deploy.sh
执行测试
提交代码后可以看到先执行Build JOB 然后执行Deploy JOB,成功在节点部署应用。