• Azure Devops下构建.NET Core项目CI/CD Pipelines


    想必大家在工作开发中都有在使用类似Jenkins这种CI/CD工具进行自动化的构造、测试、部署服务,省去在每次发版时进行重复机械的构造、生成镜像、启动容器等操作,使得开发者从繁杂的集成中解脱出来,更专注于业务的开发实现;
    当然,个人项目我也想这样去做,毕竟每次因为一个小bug的修复我就需要去重复发版的流程,让我无比的抗拒;服务器资源充足的当然无需考虑,直接部署Jenkins服务,毕竟时开源项目,想怎么来就怎么来;但是,对于我这种家境贫寒的来说,一个Jenkins无疑是让我的服务器雪上加霜了,更何况使用频率也不是很高,所以我选择使用第三方的服务Azure Devops,而且对于个人开发者来说基本等于免费(每个月有1,800 分钟免费作业时间);

    准备

    我的整条链路是这样的:GitHub -> Azure Devops -> Docker Hub -> HuaWeiCloud ECS,大家根据实际情况进行调整流程大致相同;
    以我的链路为例,需要准备如下:

    PS:本文重点讲Azure Devops配置过程,其他的大家可以自行搜索教程;

    Azure Devops配置

    配置前准备

    1、创建Project

    如果你是新账户,则需要先创建一个Project,存在则跳过;

    2、添加Service Connection

    此处配置所需的账号授权信息,以便于在Pipelines中使;
    PS:此Project下的Service Connection仅能在此Project范围内使用

    - 添加GitHub账户配置

    1. 搜索github,然后创建

    1. 填写连接信息,并授权Pipelines

    1. 授权GitHub账号

    1. 保存

    - 添加Docker Hub账户配置

    1. 搜索Docker,然后创建

    1. 填写Docker信息

    - 添加ECS SSH配置

    1. 搜索SSH,然后创建

    1. 填写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

  • 相关阅读:
    如何在WinPE下安装xp安装版
    好用、功能强大的JQuery弹出层插件
    设计模式-旧话重提之类工厂的使用
    How can I manage Internet Explorer Security Zones via the registry?
    设计模式行为模式Behavioral Patterns()之FlexibleService模式
    how to design a new tree view control
    在C#中通过webdav操作exchange
    Yahoo! User Interface Library (哈偶然发现了这个东西)
    设计模式[2]旧话重提之工厂模式
    const和static readonly 的区别
  • 原文地址:https://www.cnblogs.com/memoyu/p/16034422.html
Copyright © 2020-2023  润新知