Azure Devops下构建.NET Core项目CI/CD Pipelines
想必大家在工作开发中都有在使用类似Jenkins这种CI/CD工具进行自动化的构造、测试、部署服务,省去在每次发版时进行重复机械的构造、生成镜像、启动容器等操作,使得开发者从繁杂的集成中解脱出来,更专注于业务的开发实现;
当然,个人项目我也想这样去做,毕竟每次因为一个小bug的修复我就需要去重复发版的流程,让我无比的抗拒🤣;服务器资源充足的当然无需考虑,直接部署Jenkins服务,毕竟时开源项目,想怎么来就怎么来;但是,对于我这种家境贫寒的来说,一个Jenkins无疑是让我的服务器雪上加霜了,更何况使用频率也不是很高,所以我选择使用第三方的服务Azure Devops,而且对于个人开发者来说基本等于免费(每个月有1,800 分钟免费作业时间);
准备
我的整条链路是这样的:GitHub -> Azure Devops -> Docker Hub -> HuaWeiCloud ECS,大家根据实际情况进行调整流程大致相同;
以我的链路为例,需要准备如下:
- 注册GitHub账号,并创建自己的Repo
- 注册Azure Devops账号
- 注册DockerHub账号
- 拥有自己的云服务
PS:本文重点讲Azure Devops配置过程,其他的大家可以自行搜索教程;
Azure Devops配置
配置前准备
1、创建Project
如果你是新账户,则需要先创建一个Project,存在则跳过;
2、添加Service Connection
此处配置所需的账号授权信息,以便于在Pipelines中使;
PS:此Project下的Service Connection仅能在此Project范围内使用
- 添加GitHub账户配置
- 搜索github,然后创建
- 填写连接信息,并授权Pipelines
- 授权GitHub账号
- 保存
- 添加Docker Hub账户配置
- 搜索Docker,然后创建
- 填写Docker信息
- 添加ECS SSH配置
- 搜索SSH,然后创建
- 填写SSH信息
- 完成配置
创建Pipelines并配置
1、创建Pipeline
2、选择代码仓库
3、选择你的Pipeline配置类型,这里我们需要构建Docker Image
4、进行azure-pipelines.yml配置
如上配置为默认生成的配置yml文件,实际这些配置并不符合我们的要求的,我们需要它做到:
- 拉取GitHub仓库最新代码;
- 替换appsettingds.Production.json文件(.NET Core配置文件)的敏感信息;
- 构建项目Docker镜像,并推送到Docker Hub;
- 在服务环境下删除该项目的容器、镜像,并进行最新镜像的拉取并部署容器;
详细的配置及相关文档信息请移步Azure官方文档:Azure DevOps
最终,修改完后的yml如下:
# Docker
# Build a Docker image
# https://docs.microsoft.com/azure/devops/pipelines/languages/docker
# 管道触发器,具体:https://docs.microsoft.com/zh-cn/azure/devops/pipelines/build/triggers?view=azure-devops
# 此处触发条件为当推送标签为release-*时触发
trigger:
tags:
include:
- release-* # *代表通配符,例如:release-20210321 可以触发
# 表示资源为YML所在的仓储,你也可以指定某个管道的资源
resources:
- repo: self
# 定义变量,使用:$(变量名),例如:$(containerName)
variables:
tag: '$(Build.BuildId)'
containerName: azuredevopstest
imageName: memoyu/azuredevopstest
appsettings: Azure.Devops.Test/appsettings.Production.json
# 阶段集合定义,我们这比较简单,只需一个阶段即可
stages:
- stage: Build
displayName: build api
# 做业集合定义,每个作业其内部是顺序运行的步骤集合
jobs:
- job: Build
pool:
vmImage: ubuntu-latest
steps:
# 步骤1:执行shell进行配置文件appsettings.Production.json值的替换
- script: |
echo ready to execute command
ls
# 此处进行替换,使用sed进行配置文件指定值替换
sed -i 's/{MySqlConStr}/$(MySqlConStr)/g' $(appsettings)
sed -i 's/{ConfigVal}/$(ConfigVal)/g' $(appsettings)
# 打印替换后的配置文件内容
echo "================= print file $(appsettings) start ===================="
cat $(appsettings) | while read line; do echo $line ; done
echo "================= print file $(appsettings) end ===================="
echo command executed
displayName: 'replace config value'
# 步骤2:构建Docker Image,完成后推送到Docker Hub
- task: Docker@2
displayName: 'build docker image and push'
inputs:
containerRegistry: 'MemoyuDockerHub'
repository: $(imageName)
command: 'buildAndPush'
Dockerfile: '$(Build.SourcesDirectory)/docker/Dockerfile' # 注意填写正确的Dockerfile地址
buildContext: $(Build.Repository.LocalPath) # 构建镜像的上下文路径,当前为源代码文件的本地路径(使用了预定义变量)
tags: 'latest'
# 步骤3:连接服务SSH,进行旧容器、镜像删除,然后拉取新镜像并运行镜像
- task: SSH@0
displayName: 'run api container'
inputs:
sshEndpoint: 'HuaWeiCloud'
runOptions: 'inline'
inline: |
echo "================= to del container ===================="
# 判断是否存在容器
docker ps | grep $(containerName) &> /dev/null
# 如果不存在,则Remove
if [ $? -ne 0 ]
then
echo "$(containerName) container not exist continue.. "
else
echo "remove $(containerName) container"
docker kill $(containerName)
docker rm $(containerName)
fi
echo "================= to rm image ===================="
# 判断是否存在镜像
docker images | grep $(imageName) &> /dev/null
# 如果不存在,不做操作
if [ $? -ne 0 ]
then
echo "image does not exist , continue..."
else
echo "image exists !!! remove it"
docker rmi $(imageName)
fi
echo "================= to pull image ===================="
docker pull $(imageName)
echo "================= to run container ===================="
docker run --name $(containerName) -d -p 5100:80 $(imageName)
echo "================= publish success ===================="
readyTimeout: '20000'
1-使用定义的Service Connection
两种方式去使用:
- 手敲yaml,引入connection(确保参数无)
- 使用预定义Tasks模板生成
此处例子采用模板生成,且以构建 Docker Build Task 为例:
- 定位要插入的行
- 搜索模板
- 键入关键参数
- 点击Add,光标对应位置会生成插入yaml
2-定义自定义变量
- 弹出定义变量侧边栏
- 新增变量,实际使用如下有表述,且变量的作用范围仅在此Pipeline内
相关链接
测试项目:Azure.Devops.Test