GitLab CI/CD

一、什么是CI/CD

  CI/CD 是一种通过在应用开发阶段引入自动化来频繁向客户交付应用的方法

  CI/CD 的核心概念是持续集成、持续交付和持续部署

  具体而言,CI/CD 可让持续自动化和持续监控贯穿于应用的整个生命周期(从集成和测试阶段,到交付和部署)。这些关联的事务通常被统称为"CI/CD 管道",由开发和运维团队以敏捷方式协同支持

 

  CI 是什么?CI 和 CD 有什么区别?

    缩略词 CI/CD 具有几个不同的含义。CI/CD 中的"CI"始终指持续集成,它属于开发人员的自动化流程。成功的 CI 意味着应用代码的新更改会定期构建、测试并合并到共享存储库中。该解决方案可以解决在一次开发中有太多应用分支,从而导致相互冲突的问题

    CI/CD 中的"CD"指的是持续交付和/或持续部署,这些相关概念有时会交叉使用。两者都事关管道后续阶段的自动化,但它们有时也会单独使用,用于说明自动化程度

    持续交付通常是指开发人员对应用的更改会自动进行错误测试并上传到存储库(如 GitHub 或容器注册表),然后由运维团队将其部署到实时生产环境中。这旨在解决开发和运维团队之间可见性及沟通较差的问题。因此,持续交付的目的就是确保尽可能减少部署新代码时所需的工作量

    持续部署(另一种"CD")指的是自动将开发人员的更改从存储库发布到生产环境,以供客户使用。它主要为了解决因手动流程降低应用交付速度,从而使运维团队超负荷的问题。持续部署以持续交付的优势为根基,实现了管道后续阶段的自动化

  

    CI/CD 既可能仅指持续集成和持续交付构成的关联环节,也可以指持续集成、持续交付和持续部署这三项构成的关联环节。更为复杂的是,有时"持续交付"也包含了持续部署流程   

    归根结底,我们没必要纠结于这些语义,您只需记得 CI/CD 其实就是一个流程(通常形象地表述为管道),用于实现应用开发中的高度持续自动化和持续监控。因案例而异,该术语的具体含义取决于 CI/CD 管道的自动化程度。

  

  CI 持续集成(Continuous Integration)

    现代应用开发的目标是让多位开发人员同时处理同一应用的不同功能。但是,如果企业安排在一天内将所有分支源代码合并在一起(称为"合并日"),最终可能造成工作繁琐、耗时,而且需要手动完成。这是因为当一位独立工作的开发人员对应用进行更改时,有可能会与其他开发人员同时进行的更改发生冲突。如果每个开发人员都自定义自己的本地集成开发环境(IDE),而不是让团队就一个基于云的 IDE 达成一致,那么就会让问题更加雪上加霜

    持续集成(CI)可以帮助开发人员更加频繁地(有时甚至每天)将代码更改合并到共享分支或"主干"中。一旦开发人员对应用所做的更改被合并,系统就会通过自动构建应用并运行不同级别的自动化测试(通常是单元测试和集成测试)来验证这些更改,确保这些更改没有对应用造成破坏。这意味着测试内容涵盖了从类和函数到构成整个应用的不同模块。如果自动化测试发现新代码和现有代码之间存在冲突,CI 可以更加轻松地快速修复这些错误

 

  CD 持续交付(Continuous Delivery)

    完成 CI 中构建及单元测试和集成测试的自动化流程后,持续交付可自动将已验证的代码发布到存储库。为了实现高效的持续交付流程,务必要确保 CI 已内置于开发管道。持续交付的目标是拥有一个可随时部署到生产环境的代码库。

    在持续交付中,每个阶段(从代码更改的合并,到生产就绪型构建版本的交付)都涉及测试自动化和代码发布自动化。在流程结束时,运维团队可以快速、轻松地将应用部署到生产环境中

 

  CD 持续部署(Continuous Deployment)

    对于一个成熟的 CI/CD 管道来说,最后的阶段是持续部署。作为持续交付——自动将生产就绪型构建版本发布到代码存储库——的延伸,持续部署可以自动将应用发布到生产环境。由于在生产之前的管道阶段没有手动门控,因此持续部署在很大程度上都得依赖精心设计的测试自动化

    实际上,持续部署意味着开发人员对应用的更改在编写后的几分钟内就能生效(假设它通过了自动化测试)。这更加便于持续接收和整合用户反馈。总而言之,所有这些 CI/CD 的关联步骤都有助于降低应用的部署风险,因此更便于以小件的方式(而非一次性)发布对应用的更改。不过,由于还需要编写自动化测试以适应 CI/CD 管道中的各种测试和发布阶段,因此前期投资还是会很大

 

 

 

 

二、GitLab CI/CD

  GitLab CI/CD是 GitLab 的一部分,可用于所有持续方法(持续集成、交付和部署)。使用 GitLab CI/CD,您可以测试、构建和发布您的软件,而无需第三方应用程序或集成

  GitLab工作流程

     

 

   

    如果您深入了解工作流程,您可以在 DevOps 生命周期的每个阶段看到 GitLab 中可用的功能。

 

 

 

三、CI配置

  CI/CD管道的配置文件为 .gitlab-ci.yml , 位于项目根目录下

  .gitlab-ci.yml 配置关键词

    1、配置管道行为的全局关键词

关键词 描述
default 工作关​​键字的自定义默认值。
include 从其他 YAML 文件导入配置。
stages 流水线阶段的名称和顺序。
variables 为管道中的所有作业定义 CI/CD 变量。
workflow 控制运行什么类型的管道。

      stages:

        用于定义包括作业组的阶段。在作业中使用stage以将作业配置为在特定阶段运行    

        如果stages未在.gitlab-ci.yml文件中定义,则默认管道阶段为:

        .pre - build - test - deploy - .post
        

        stages定义了作业的执行顺序:

          同一阶段的作业并行运行。
          下一阶段的作业在上一阶段的作业成功完成后运行

        示例:

stages:
  - build
  - test
  - deploy

 





 

    2、配置作业(job)的关键词

关键词 描述
after_script 覆盖作业后执行的一组命令。
allow_failure 允许作业失败。失败的作业不会导致管道失败。
artifacts 成功后附加到作业的文件和目录列表。
before_script 覆盖在作业之前执行的一组命令。
cache 应在后续运行之间缓存的文件列表。
coverage 给定作业的代码覆盖率设置。
dast_configuration 在作业级别使用 DAST 配置文件中的配置。
dependencies 通过提供要从中获取工件的作业列表来限制将哪些工件传递给特定作业。
environment 作业部署到的环境的名称。
except 控制何时不创建作业。
extends 此作业继承的配置条目。
image 使用 Docker 镜像。
inherit 选择所有作业继承的全局默认值。
interruptible 定义一个作业是否可以在被较新的运行冗余时取消。
needs 在阶段排序之前执行作业。
only 控制何时创建工作。
pages 上传作业结果以与 GitLab 页面一起使用。
parallel 应并行运行多少个作业实例。
release 指示运行器生成释放对象。
resource_group 限制作业并发。
retry 发生故障时可以自动重试作业的时间和次数。
rules 用于评估和确定作业的选定属性以及是否已创建的条件列表。
script 由运行程序执行的 Shell 脚本。
secrets CI/CD 是工作需要的秘密。
services 使用 Docker 服务镜像。
stage 定义作业阶段。
tags 用于选择跑步者的标签列表。
timeout 定义优先于项目范围设置的自定义作业级超时。
trigger 定义下游管道触发器。
variables 在工作级别定义工作变量。
when 何时运行作业。

 

      only/except:控制何时将作业添加到管道

        only用于定义作业何时运行

        except用于定义作业何时不运行

        以下四个关键字可以在only和except下结合使用:refs、variables、changes、kubernetes

        only:refs/except:refs

          使用only:refsandexcept:refs关键字来控制何时根据分支名称或管道类型将作业添加到管道,如:

job1:
  script: echo
  only:
    - main
    - /^issue-.*$/
    - merge_requests

job2:
  script: echo
  except:
    - main
    - /^stable-branch.*$/
    - schedules

        only:changes/except:changes

          使用changes关键字,当 Git 推送事件修改文件时,only:changes下的文件运行作业,except:changes下的文件不运行作业

docker build:
  script: docker build -t my-image:$CI_COMMIT_REF_SLUG .
  only:
    refs:
      - branches
    changes:
      - Dockerfile
      - docker/scripts/*
      - dockerfiles/**/*
      - more_scripts/*.{rb,py,sh}
      - "**/*.json"

      script:

        使用script用于执行runner要执行的命令

        除 trigger job之外,其他的作业都需要script

        可能的输入:

          单行命令

          长命令分成多行

 

     artifacts:

        使用 artifacts 在 stage 之间传递中间构建结果

        artifacts 由 Job 生成,存储在GitLab中,可以下载;

        artifacts 和 cache 都定义了它们相对于项目目录的路径,并且不能链接到项目目录之外的文件

        

 

    自定义CI/CD变量

      ①:在项目的 .gitlab-ci.yml 文件中

      ②:在 project's setting中

      

      variables

        使用variables关键字在Job或者gitlab-ci.yml 文件的顶层定义自定义变量。

        如果变量位于顶层,那么它是全局可用的,并且所有的Job都可以使用它。如果只在Job中定义,则只有Job可以使用它

variables:
  TEST_VAR: "All jobs can use this variable's value"

job1:
  variables:
    TEST_VAR_JOB: "Only job1 can use this variable's value"
  script:
    - echo "$TEST_VAR" and "$TEST_VAR_JOB"

 

       when

        when用于配置作业运行的条件。如果未在作业中定义,则默认值为 when:on_success

        可能的值:

        on_success(默认):仅在早期阶段的所有作业都成功或具有allow_failure: true.
        manual:仅在手动触发时运行作业。
        always:无论早期阶段的作业状态如何,都运行作业。
        on_failure:仅当至少一个早期阶段的作业失败时才运行作业。
        delayed:将作业的执行延迟 指定的持续时间。
        never: 不要运行作业

  

      image:

        用于指定作业在其中运行的Docker镜像

        可能的输入:

          镜像的名称,如果需要,包括注册表路径,采用以下格式之一:

          <image-name>(与使用<image-name>标签latest相同)
          <image-name>:<tag>
          <image-name>@<digest>

        image:name

          作业运行时所在的Docker镜像的名称,如:

image:
  name: "registry.example.com/my/image:latest"

        image:image:entrypoint

          作为容器入口点执行的命令或脚本,如:

image:
  name: super/sql:experimental
  entrypoint: [""]

        

   

 

    更多配置:https://docs.gitlab.com/ee/ci/yaml/index.html

 

 

 

四、示例

  1、.gitlab.yml

stages:
  - build_mimall_pre
  - build_mimall_prd
  - build_youpin_pre
  - build_youpin_prd
  - build_mimall_pre_image
  - build_youpin_pre_image
  - deploy_mimall_pre
  - deploy_youpin_pre
  - build_mimall_prd_image
  - build_youpin_prd_image

build_mimall_pre:
  stage: build_mimall_pre
  image:
    name: cr.d.xiaomi.net/containercloud/ubuntu-openjdk1.8-maven3.5:latest
  script:
    - mvn clean package -P pre -Dmaven.test.skip=true
  artifacts:
    paths:
      - sync-mimall/target/sync-mimall-*.jar
  after_script:
    - echo "build_mimall_pre completed"
  only:
    refs:
      - preview
    changes:
      - sync-mimall/**/*
      - sync-common/**/*
      - sync-deploy/**/*
      - pom.xml

build_mimall_prd:
  stage: build_mimall_prd
  image:
    name: cr.d.xiaomi.net/containercloud/ubuntu-openjdk1.8-maven3.5:latest
  script:
    - mvn clean package -P prd -Dmaven.test.skip=true
  artifacts:
    paths:
      - sync-mimall/target/sync-mimall-*.jar
  after_script:
    - echo "build_mimall_prd completed"
  only:
    refs:
      - master
    changes:
      - sync-mimall/**/*
      - sync-common/**/*
      - sync-deploy/**/*
      - pom.xml

build_youpin_pre:
  stage: build_youpin_pre
  image:
    name: cr.d.xiaomi.net/containercloud/ubuntu-openjdk1.8-maven3.5:latest
  script:
    - mvn clean package -P pre -Dmaven.test.skip=true
  artifacts:
    paths:
      - sync-youpin/target/sync-youpin-*.jar
  after_script:
    - echo "build_youpin_pre completed"
  only:
    refs:
      - preview
    changes:
      - sync-youpin/**/*
      - sync-common/**/*
      - sync-deploy/**/*
      - pom.xml

build_youpin_prd:
  stage: build_youpin_prd
  image:
    name: cr.d.xiaomi.net/containercloud/ubuntu-openjdk1.8-maven3.5:latest
  script:
    - mvn clean package -P prd -Dmaven.test.skip=true
  artifacts:
    paths:
      - sync-youpin/target/sync-youpin-*.jar
  after_script:
    - echo "build_youpin_prd completed"
  only:
    refs:
      - master
    changes:
      - sync-youpin/**/*
      - sync-common/**/*
      - sync-deploy/**/*
      - pom.xml

build_mimall_pre_image:
  stage: build_mimall_pre_image
  image:
    name: cr.d.xiaomi.net/containercloud/kaniko-executor-xiaomi:release
    entrypoint: [""]
  script:
    - MIMALL_IMAGE=$REPO_SERVER/$REPO_NAMESPACE/sync-mimall:pre-$CI_COMMIT_SHORT_SHA
    - echo "{\"auths\":{\"$REPO_SERVER\":{\"username\":\"$REPO_USER\",\"password\":\"$REPO_PASS\"}}}" > /kaniko/.docker/config.json
    - /kaniko/executor --context $CI_PROJECT_DIR --dockerfile $CI_PROJECT_DIR/sync-mimall/Dockerfile --destination $MIMALL_IMAGE --validate-image
  after_script:
    - echo "build_mimall_pre_image completed"
  only:
    refs:
      - preview
    changes:
      - sync-mimall/**/*
      - sync-common/**/*
      - sync-deploy/**/*
      - pom.xml
  retry: 2

build_mimall_prd_image:
  stage: build_mimall_prd_image
  image:
    name: cr.d.xiaomi.net/containercloud/kaniko-executor-xiaomi:release
    entrypoint: [""]
  script:
    - MIMALL_IMAGE=$REPO_SERVER/$REPO_NAMESPACE/sync-mimall:prd-$CI_COMMIT_SHORT_SHA
    - echo "{\"auths\":{\"$REPO_SERVER\":{\"username\":\"$REPO_USER\",\"password\":\"$REPO_PASS\"}}}" > /kaniko/.docker/config.json
    - /kaniko/executor --context $CI_PROJECT_DIR --dockerfile $CI_PROJECT_DIR/sync-mimall/Dockerfile --destination $MIMALL_IMAGE --validate-image
  after_script:
    - echo "build_mimall_prd_image completed"
  only:
    refs:
      - master
    changes:
      - sync-mimall/**/*
      - sync-common/**/*
      - sync-deploy/**/*
      - pom.xml
  retry: 2

build_youpin_pre_image:
  stage: build_youpin_pre_image
  image:
    name: cr.d.xiaomi.net/containercloud/kaniko-executor-xiaomi:release
    entrypoint: [""]
  script:
    - YOUPIN_IMAGE=$REPO_SERVER/$REPO_NAMESPACE/sync-youpin:pre-$CI_COMMIT_SHORT_SHA
    - echo "{\"auths\":{\"$REPO_SERVER\":{\"username\":\"$REPO_USER\",\"password\":\"$REPO_PASS\"}}}" > /kaniko/.docker/config.json
    - /kaniko/executor --context $CI_PROJECT_DIR --dockerfile $CI_PROJECT_DIR/sync-youpin/Dockerfile --destination $YOUPIN_IMAGE --validate-image
  after_script:
    - echo "build_youpin_pre_image completed"
  only:
    refs:
      - preview
    changes:
      - sync-youpin/**/*
      - sync-common/**/*
      - sync-deploy/**/*
      - pom.xml
  retry: 2

build_youpin_prd_image:
  stage: build_youpin_prd_image
  image:
    name: cr.d.xiaomi.net/containercloud/kaniko-executor-xiaomi:release
    entrypoint: [""]
  script:
    - YOUPIN_IMAGE=$REPO_SERVER/$REPO_NAMESPACE/sync-youpin:prd-$CI_COMMIT_SHORT_SHA
    - echo "{\"auths\":{\"$REPO_SERVER\":{\"username\":\"$REPO_USER\",\"password\":\"$REPO_PASS\"}}}" > /kaniko/.docker/config.json
    - /kaniko/executor --context $CI_PROJECT_DIR --dockerfile $CI_PROJECT_DIR/sync-youpin/Dockerfile --destination $YOUPIN_IMAGE --validate-image
  after_script:
    - echo "build_youpin_prd_image completed"
  only:
    refs:
      - master
    changes:
      - sync-youpin/**/*
      - sync-common/**/*
      - sync-deploy/**/*
      - pom.xml
  retry: 2

deploy_mimall_pre:
  stage: deploy_mimall_pre
  image:
    name: cr.d.xiaomi.net/container/xiaomi_alpine_fusion_cli_mice:latest
  script:
    - fusion-cli --json config --access-key $CLOUD_MANAGER_AK --secret-key $CLOUD_MANAGER_SK
    - fusion-cli --json mice update sync-mimall-preview pre-$CI_COMMIT_SHORT_SHA --cluster c3
  only:
    refs:
      - preview
    changes:
      - sync-mimall/**/*
      - sync-common/**/*
      - sync-deploy/**/*
      - pom.xml
  when: on_success

deploy_youpin_pre:
  stage: deploy_youpin_pre
  image:
    name: cr.d.xiaomi.net/container/xiaomi_alpine_fusion_cli_mice:latest
  script:
    - fusion-cli --json config --access-key $CLOUD_MANAGER_AK --secret-key $CLOUD_MANAGER_SK
    - fusion-cli --json mice update sync-youpin-preview pre-$CI_COMMIT_SHORT_SHA --cluster c3
  only:
    refs:
      - preview
    changes:
      - sync-youpin/**/*
      - sync-common/**/*
      - sync-deploy/**/*
      - pom.xml
  when: on_success
View Code

  2、Dockerfile

#指定了运行容器的镜像并把生成程序文件拷贝到镜像根目录用以运行
FROM cr.d.xiaomi.net/containercloud/openjdk:8-jre-alpine
ENV TZ "Asia/Shanghai"
COPY sync-youpin/target/sync-youpin-*.jar /opt/sync-youpin.jar
WORKDIR /opt
CMD ["java", "-jar", "sync-youpin.jar"]

 

cicd配置及解释:
打包:

build mico-core-api preview4test:
  stage: build
  image:
    name: cr.d.xiaomi.net/containercloud/ubuntu-openjdk1.8-maven3.5:latest
  script:
    - mvn clean package -P preview4test -Dmaven.test.skip=true
  artifacts:
    paths:
      - mico-core-api/target/*.jar
  after_script:
    - echo "build mico-core-api preview4test completed"
  only:
    refs:
      - preview4test
    changes:
      - mico-common/**/*
      - mico-core-api/**/*
      - mico-core-api/.cicd.yml
      - pom.xml

解释:

这是一个GitLab CI/CD的配置文件,用于构建mico-core-api项目的preview4test分支。
该配置文件定义了一个名为"build mico-core-api preview4test"的任务,它包含以下内容:
- stage: 构建阶段,指定为"build"
- image: 使用的Docker镜像,这里使用了一个包含OpenJDK 1.8和Maven 3.5的Ubuntu镜像
- script: 执行的脚本命令,这里使用Maven命令进行构建,并指定了"preview4test"的profile,并跳过测试
- artifacts: 构建产物,将构建好的jar包保存到artifacts中
- after_script: 构建完成后执行的脚本命令,这里只是简单地输出一条日志
- only: 触发构建的条件,只有当代码库中mico-common、mico-core-api、mico-core-api/.cicd.yml、pom.xml文件有变化,并且分支为preview4test时才会触发构建。
总的来说,这个配置文件定义了一个自动化的构建流程,当代码库中的特定文件有变化时,会自动触发构建任务,构建出jar包并保存到artifacts中。

 

构建镜像:



15:51
build mico-core-api image preview4test:
  stage: buildImage
  image:
    name: cr.d.xiaomi.net/containercloud/kaniko-executor-xiaomi:release
    entrypoint: [ "" ]
  script:
    - export APP_IMAGE=$REPO_SERVER/$REPO_NAMESPACE/mico-core-api:preview4test-$CI_COMMIT_SHORT_SHA-$(date +%Y%m%d%H%M)
    - echo "{\"auths\":{\"$REPO_SERVER\":{\"username\":\"$REPO_USER\",\"password\":\"$REPO_PASS\"}}}" > /kaniko/.docker/config.json
    - /kaniko/executor --context $CI_PROJECT_DIR --dockerfile mico-core-api/Dockerfile --destination $APP_IMAGE --validate-image
  after_script:
    - echo "build mico-core-api image preview4test completed"
  only:
    refs:
      - preview4test
    changes:
      - mico-common/**/*
      - mico-core-api/**/*
      - mico-core-api/.cicd.yml
      - pom.xml
  retry: 2

解释:

这是一个GitLab CI/CD的配置文件,用于构建一个名为mico-core-api的Docker镜像,并将其推送到指定的Docker仓库中。
具体来说,它会使用kaniko-executor-xiaomi镜像作为构建环境,执行mico-core-api/Dockerfile中的指令,生成一个新的Docker镜像,并将其命名为preview4test-$CI_COMMIT_SHORT_SHA-$(date +%Y%m%d%H%M),其中$CI_COMMIT_SHORT_SHA是Git提交的短SHA值,$(date +%Y%m%d%H%M)是当前时间的格式化字符串。
最后,它会将生成的镜像推送到指定的Docker仓库中。这个配置文件只会在Git仓库的preview4test分支上有相关文件修改时触发构建。

 

END.

posted @ 2022-02-11 10:41  杨岂  阅读(850)  评论(0编辑  收藏  举报