流水线关键概念解析

更新时间:
复制 MD 格式

本文主要介绍云效流水线的关键概念和组件,帮助您更全面地理解云效流水线在构建、测试和部署代码等功能。

概述

image

sources:
  my_repo:
    type: gitSample
    name: JAVA代码仓库
    endpoint: https://atomgit.com/flow-example/spring-boot.git
    branch: master
stages:
  java_build_stages:
    name: 构建
    jobs:
      java_build_jobs:
        name: Java 构建
        runsOn: public/cn-beijing  # 云效托管集群,也可填写 private/<集群ID> 指定自托管私有构建集群
        steps:
          - step: JavaBuild
            with:
              jdkVersions: '1.8'
              mavenVersion: '3.5.2'
              run: 'mvn -B clean package -Dmaven.test.skip=true -Dautoconfig.skip=true'
  1. 配置不同的触发器,以不同方式触发流水线。

  2. 流水线顶层结构是阶段,默认按照顺序执行。

  3. 阶段内可以包含多个任务,任务默认并行执行(YAML模式下),可以配置Job间的依赖关系(可跨阶段)。

  4. 任务分为顺序执行任务交互式执行任务服务端任务

    1. 顺序执行任务可以完成各种工作,包括对Kubernetes集群进行部署。

    2. 交互式执行任务用于在某些操作后让用户选择下一步操作。

    3. 服务端任务包括人工卡点和主机部署,主机部署负责对主机组中的主机进行操作。

  5. 所有任务都可以配置生命周期插件,在特定生命周期节点执行通知类操作。

  6. 云效流水线提供托管集群执行顺序执行任务和交互式执行任务。您也可以通过Runner应用程序将自己的主机托管到云效流水线,并关联到私有构建集群(自托管集群),以便将任务调度到这些主机上执行。

流水线 pipeline

流水线是一套定义工作流程的工具,支持多层级的串并联、暂停和条件执行,帮助自动化研发过程。

可以通过流水线提供的预置模板来创建流水线。您可以通过预置模板创建GUIYAML类型的流水线。YAML类型提供更多功能,如OpenAPI条件判断能力。

在新建流水线时,可在模板选择对话框中按编程语言(如 Java、PHP、Node.js、Go、Python、.NET Core 等)挑选预置模板,并通过顶部入口切换为可视化编排YAML 化编排

创建流水线后,可以进行编排和设置,如触发设置、环境变量和缓存等。

触发器 trigger

您可以手动触发流水线。

手动触发的入口为流水线详情页右上角的运行按钮。

同时也可以配置不同的触发器来自动触发流水线运行。包括:

  1. 代码源触发。当代码库有推送等事件发生时候触发流水线。

  2. Webhook 触发流水线。直接通过RESTful方式调用固定的URL来触发流水线。

  3. ACR 触发。当阿里云ACR仓库发生推送等事件时,触发流水线。

  4. 定时触发。通过定时配置,可以周期性地自动触发流水线的执行。

  5. Flow流水线触发。当另一条流水线执行完毕时候触发流水线。

  6. Jenkins 触发。配置一个Jenkins任务执行完毕之后触发流水线。

阶段 stages

阶段表示研发过程中的不同环节,例如测试、构建、部署等阶段。

YAML流水线中,使用stages关键字定义不同的阶段。

stages:
  java_p2_c_scan_stages:
    name: 代码扫描
    jobs:
      java_p2_c_scan_jobs:
        name: Java 代码扫描
        steps:
          - step: JavaP2CScan
  maven_unit_test_stages:
    name: 单元测试
    jobs:
      maven_unit_test_jobs:
        name: Maven 单元测试
        steps:
          - step: MavenUnitTest
  java_build_stages:
    name: 构建
    jobs:
      java_build_jobs:
        name: Java 构建
        steps:
          - step: JavaBuild
  kubectl_apply_stages:
    name: 部署
    jobs:
      kubectl_apply_jobs:
        name: Kubernetes 发布
        steps:
          - step: KubectlApply

任务 jobs

一个阶段中可以包含多个并行执行的任务,如不同类型的测试。

在 YAML 流水线中,使用stages.<stage_id>.jobs关键字定义任务。

stages:
  test_stages:
    name: 测试
    jobs:
      java_p2c_scan_jobs:
        name: Java 代码扫描
        steps:
          - step: JavaP2CScan
            with:
              incrementalScan: false
              jdkVersion: '1.8'
      maven_unit_test_jobs:
        name: Maven 单元测试
        steps:
          - step: MavenUnitTest
            with:
              jdkVersion: '1.8'
              mavenVersion: '3.5.2'

如果流水线仅含一个 stage,则可直接定义 jobs,无需显示指定stages

jobs:
  java_p2c_scan_jobs:
    name: Java 代码扫描
    steps:
      - step: JavaP2CScan
        with:
          incrementalScan: false
  maven_unit_test_jobs:
    name: Maven 单元测试
    steps:
      - step: MavenUnitTest
        with:
          jdkVersion: '1.8'
          mavenVersion: '3.5.2'

步骤 steps

步骤是执行在某个构建集群上的命令描述,如Java构建、镜像构建等。

在 YAML 流水线中,使用jobs.<job_id>.steps关键字定义步骤。

stages:
  java_build_stages:
    name: 构建
    jobs:
      java_build_jobs:
        name: Java 构建
        steps:
          - step: JavaBuild
            with:
              jdkVersions: '1.8'
              mavenVersion: '3.5.2'
              run: 'mvn -B clean package -Dmaven.test.skip=true -Dautoconfig.skip=true'
          - step: ACRDockerBuild
            with:
              artifact: my_image
              dockerfilePath: Dockerfile
              dockerRegistry: <your-docker-registry-url>

如果流水线仅包含一个 job,可直接定义 steps

steps:
  - step: JavaBuild
    name: Java 构建
    with:
      jdkVersions: '1.8'
      mavenVersion: '3.5.2'
      run: 'mvn -B clean package -Dmaven.test.skip=true -Dautoconfig.skip=true'
  - step: ACRDockerBuild
    name: ACRDockerBuild
    with:
      artifact: my_image
      dockerfilePath: Dockerfile
      dockerRegistry: <your-docker-registry-url>
      dockerTags: 1.0
      region: cn-hangzhou
      serviceConnections: <your-service-connection-id>

云效内置了丰富的步骤,您也可以景自定义一个步骤来满足特殊场景。

顺序执行任务

顺序执行任务是指如Java构建、镜像构建等任务,通过执行一段脚本完成。

交互式任务

SAE部署中,发布后需要等待第一批发布结束,用户验证后选择继续发布或回滚。这种任务称为交互式任务。

交互式任务通过步骤实现。第一次运行结束后,步骤返回特定数据结构,告知接下来的Action。步骤处理逻辑包含处理各种Action的能力,服务端通过重复调用任务并传入用户选择的Action实现交互效果。

服务连接管理

在步骤运行过程中,会涉及到一些密钥信息,比如代码克隆的账密、Jenkins的账密、Kuberneteskubeconfig、用于访问阿里云API的临时token等。云效流水线使用服务连接的概念来统一管理这些信息。

可在云效全局设置 > 服务连接管理新建服务连接,选择代码服务类型即可创建云效Codeup、Github、Gitlab、Bitbucket 等代码源的连接凭证。

服务连接类型还涵盖阿里云服务,可选择云服务器(ECS)容器镜像服务(ACR)容器服务Kubernetes版(ACK)对象存储(OSS)SAEEDAS 等多种云产品。

在流水线编辑器中添加流水线源时,也可直接选择该账号下已有的服务连接(如已配置的云效Codeup连接),或通过添加服务连接入口现场新建。

在镜像构建并推送步骤的编辑面板中,通过选择服务连接下拉框挑选已配置的容器镜像服务(ACR)服务连接,即可在步骤运行时使用对应账号凭证完成镜像推送。

在 YAML 流水线中,通过 serviceConnection 关键字指定。

jobs:
  java_build_jobs:
    name: Java 镜像构建
    steps:
      - step: ACRDockerBuild
        name: 镜像构建并推送至阿里云镜像仓库企业版
        with:
          artifact: my_image
          dockerfilePath: Dockerfile
          dockerRegistry: <your-docker-registry-url>
          dockerImage: <your-image-name>
          dockerTags: '1.0'
          region: cn-hangzhou
          serviceConnections: <your-service-connection-id>

在上述「Java 镜像构建」步骤在运行时可以获取到对应的docker login的账密,并写入到~/.docker/config.json,以便后续的docker pulldocker push使用。

Kubernetes 部署

云效流水线提供 Kubernetes 集群管理功能,允许在步骤中引用 Kubernetes 集群的 kubeconfig。

Kubernetes 集群的管理入口位于全局设置 > Kubernetes集群管理,可在此查看已添加的集群列表(含集群名称、集群ID、集群类型等)并通过新建Kubernetes集群按钮添加集群。

Kubectl 发布步骤的编辑面板中,通过集群连接下拉框选择已添加的 Kubernetes 集群,并配置 Kubectl 版本、命名空间、YAML 路径等参数。

在 YAML 流水线中,通过kubernetesCluster指定集群ID连接 Kubernetes 集群

jobs:
  kubectl_apply_jobs:
    name: 部署
    steps:
      - step: KubectlApply
        name: Kubectl 发布
        with:
          kubernetesCluster: <your-kubernetes-id>
          kubectlVersion: '1.16.4'
          namespace: default
          yamlPath: 'app-config/manifest-app'
          skipReplace: false

云效流水线支持两种类型的 Kubernetes 集群:

  • 阿里云ACK:先添加服务连接,再选择ACK集群。流水线运行时会计算临时kubeconfig,ApiServer无需开放公网。

  • 普通Kubernetes集群:用户需填写kubeconfig,ApiServer需公网可访问。

主机部署

云效流水线支持主机部署功能。为了使用该功能,需要先创建主机组,然后在主机部署的任务中选择主机组。

主机部署可以引用上游的制品产物,并按照您的配置将这个制品下载到每一台主机对应的目录。主机部署提供了分批发布的能力,并且支持第一批暂停和每批暂停的策略。

在 YAML 流水线中,通过machineGroup指定主机组ID部署。

jobs:
  vm_deploy_jobs:
    name: 主机部署
    steps:
      - step: VMDeploy
        name: 主机部署任务
        with:
          artifact: $[stages.java_build_stage.java_build_job.upload_step.artifacts.flow-public]
          downloadArtifact: true
          useEncodeBase64: false
          machineGroup: <your-machine-group-id>
          run: |
            mkdir -p /home/admin/application/
            tar zxvf /home/admin/app/package.tgz -C /home/admin/application/
            sh /home/admin/application/deploy.sh restart
          executeUser: root
          pauseType: firstBatchPause
          batchNumber: 2

云效流水线支持以下几种方式接入主机:

  • 阿里云ECS阿里云托管实例:首先创建相应类型的服务连接,然后通过这个服务连接选择该账号下的机器,绑定到主机组。云效流水线会通过云助手的通道在机器上安装Runner程序,作为和流水线服务端的通信的客户端。阿里云ECS不需要有访问公网资源的能力,而托管实例则需要访问公网。

    可在全局设置 > 主机组管理页通过新建主机组按钮创建阿里云ECS等类型的主机组。

  • 通过标签的方式定义主机组:在运行时通过标签决定选择哪些主机进行部署。由于实际部署的主机是不确定的,因此在主机组定义时,不会在任何主机上安装Runner程序,而是在运行时通过云助手的命令通道直接进行命令下发,从而完成部署。

    新建主机组对话框中选择对应的阿里云ECS服务连接与地域,并在ECS标签健ECS标签值字段中填写匹配规则,即可在运行时根据标签动态选择目标主机。

    接入新主机对话框中可选择操作系统类型(Linux、Windows、macOS)与添加方式,支持手动安装Runner阿里云ECS混合云托管免费体验主机等多种接入方式。

  • 任意可以访问公网的主机:需要粘贴安装Runner的命令到主机上执行,即可添加该主机到流水线。

私有构建集群

如果您的构建过程需要与内网资源进行交互,比如从内网clone代码,或者从内网的 Maven 服务器上拉取依赖,可以使用私有构建集群将您的内网主机托管到流水线。

全局设置 > 构建集群管理页可以查看云效默认构建集群与已创建的私有构建集群,并通过新建构建集群按钮创建新的私有构建集群。

构建集群中的主机同样是通过安装Runner程序的方式托管到流水线的,支持Linux、Windows、macOS主机的接入,并支持 amd64 和 arm64 两种芯片架构的接入。

流水线任务可以指定任务调度到对应的私有构建集群上。

在 YAML 流水线中,通过runsOn关键字指定任务构建集群。

stages:
  java_build_stages:
    name: 构建
    jobs:
      java_build_jobs:
        name: Java 构建
        runsOn: private/<your-private-cluster-id>  # 自托管私有构建集群
        # 或填写 public/cn-beijing 使用云效托管的北京构建集群
        steps:
          - step: JavaBuild
            with:
              jdkVersions: '1.8'
              mavenVersion: '3.5.2'
              run: 'mvn -B clean package -Dmaven.test.skip=true -Dautoconfig.skip=true'