基于Azure Pipelines的Docker微服务MonoRepo CI/CD架构方案咨询
MonoRepo 场景下 Azure Pipelines CI/CD 架构设计方案
1. 整体架构分层
采用两级流水线架构,拆分公共触发逻辑和单服务构建部署逻辑,兼顾灵活性和维护性:
- 根触发流水线:全局唯一,负责监听main分支合入事件、检测代码变更路径、按需触发对应微服务的子流水线
- 微服务子流水线:每个微服务独立配置一套,负责本服务的镜像构建、仓库推送、K8s 部署逻辑
2. 根触发流水线配置
核心逻辑是变更路径检测,公共类库变更时触发所有微服务流水线,单服务路径变更时仅触发对应流水线,参考配置如下:
# 仓库根目录下的 azure-pipelines.yml trigger: branches: include: - main # 仅监听main分支合入事件 pool: vmImage: 'ubuntu-latest' steps: - task: Bash@3 name: DetectChanges inputs: targetType: 'inline' script: | # 对比上一次成功构建的commit,获取所有变更文件 git diff --name-only HEAD~1 HEAD > changed_files.txt # 标记公共类库是否变更 if grep -q "^Common/src" changed_files.txt; then echo "##vso[task.setvariable variable=CommonChanged;isOutput=true]true" fi # 标记SvcA是否需要构建:自身路径变更 或 公共类库变更 if grep -q "^SvcA/" changed_files.txt || [ "$CommonChanged" = "true" ]; then echo "##vso[task.setvariable variable=SvcAChanged;isOutput=true]true" fi # 标记SvcB是否需要构建:自身路径变更 或 公共类库变更 if grep -q "^SvcB/" changed_files.txt || [ "$CommonChanged" = "true" ]; then echo "##vso[task.setvariable variable=SvcBChanged;isOutput=true]true" fi # 触发SvcA子流水线 - task: TriggerBuild@4 inputs: definition: 'SvcA-CI-CD' # 子流水线的定义名称 branchToUse: 'main' waitForQueuedBuildsToFinish: true condition: eq(variables['DetectChanges.SvcAChanged'], 'true') # 触发SvcB子流水线 - task: TriggerBuild@4 inputs: definition: 'SvcB-CI-CD' branchToUse: 'main' waitForQueuedBuildsToFinish: true condition: eq(variables['DetectChanges.SvcBChanged'], 'true')
注:TriggerBuild为Azure DevOps市场扩展,也可以替换为调用Azure DevOps REST API触发子流水线的逻辑。
3. 微服务子流水线配置
每个微服务单独维护一套子流水线,以SvcA为例,配置文件放在SvcA/azure-pipelines.yml,参考配置如下:
# SvcA 子流水线配置 trigger: none # 禁用主动触发,仅由根流水线调用 pool: vmImage: 'ubuntu-latest' variables: dockerRegistryConn: '你的镜像仓库服务连接名' imageRepo: 'svca' registryAddr: '你的仓库地址如xxx.azurecr.io' dockerfilePath: '$(Build.SourcesDirectory)/SvcA/Dockerfile' imageTag: '$(Build.BuildId)' k8sConn: '你的K8s集群服务连接名' steps: # 构建并推送镜像到镜像仓库 - task: Docker@2 displayName: 构建推送镜像 inputs: command: buildAndPush repository: $(imageRepo) dockerfile: $(dockerfilePath) buildContext: '.' # 上下文设为仓库根目录,可正常引用Common类库 containerRegistry: $(dockerRegistryConn) tags: | $(imageTag) latest # 部署到K8s集群 - task: Kubectl@1 displayName: 部署到K8s inputs: kubernetesServiceEndpoint: $(k8sConn) command: 'set' arguments: 'image deployment/svca svca=$(registryAddr)/$(imageRepo):$(imageTag)' namespace: 'prod'
4. 核心注意事项
- 所有微服务的Docker构建上下文必须设置为仓库根目录,否则无法读取Common公共类库的代码,Dockerfile内COPY Common的路径要对应根目录的相对路径
- 镜像标签使用构建ID或Commit哈希,方便出问题时快速追溯代码版本、执行回滚操作
- 可新增PR校验流水线,仅在PR提交时执行单元测试、静态代码检查,不用执行镜像构建和部署逻辑,提升PR迭代效率
- 可添加Nuget缓存步骤,减少.NET依赖包的还原时间,提升构建速度
内容的提问来源于stack exchange,提问作者user210757
相关产品推荐
相关产品推荐

