自定义任务模板

Serverless开发平台内置了自定义任务模板,用于执行用户自定义的流水线逻辑。本文介绍自定义任务模板的实现原理、描述示例和使用方法。

实现原理

Serverless开发平台在任务执行阶段,按照RunnerConfig的描述,为用户部署任务节点(TaskWorker),并将执行上下文信息作为payload的一部分,传入任务节点。任务节点在收到payload后,会按照Steps定义的步骤进行执行。

用户通过在执行上下文中定义RunnerConfig以及Steps,完成对任务节点逻辑的自定义。

image

自定义任务模板描述示例

以下是自定义任务模板的描述示例。通过在spec.worker.presetWorker中指定预置的serverless-runner,可以让执行引擎调度相应的任务节点,并在此节点上运行用户自定义的步骤。

kind: TaskTemplate
name: serverless-runner-task
description: ''
createdTime: '2023-04-11T08:43:58Z'
deletionTime:
generation: 0
labels:
  source: system
resourceVersion: 0
spec:
  description: |-
    Run customized scripts on a serverless runner.
    在Serverless实例上运行自定义地脚本。
  worker:
    # 指定runner类型为Serverless开发平台预置的serverless-runner。
    # serverless-runner的执行引擎会识别runnerConfig以及steps参数。
    presetWorker: serverless-runner
  executeCondition:
    # 在执行上下文中,表达式enable == true的时候才会执行。
    expression: enable == true
  contextSchema: {}

在流水线模板中使用自定义任务模板的示例

自定义任务模板可以在流水线模板中使用。使用示例如下。

kind: PipelineTemplate
name: demo-template
spec:
  context:
    data:
      deployFile: s.yaml
      #  自定义任务节点部署配置。如果不指定,将在Serverless开发平台的某个沙箱环境中执行。
      #  此处设置的runnerConfig将会影响模板中定义的所有任务。
      #  runnerConfig:
      #  指定在新加坡地域部署。
      #  regionId: ap-southeast-1
      #  日志搜集配置。运行时产生的日志将会投递到指定SLS日志库中。
      #  logConfig:
      #    logstore: function-log
      #    project: my-project
      #  网络配置。运行的网络VPC信息。
      #  vpcConfig:
      #    securityGroupId: xxx
      #    vSwitchIds: ["xxx"]
      #    vpcId: xxx
      #  运行规格。采用1核2 GB的计算实例。
      #  cpu: 1
      #  memory: 2048
      #  服务端超时时间。此处设置为15分钟。
      #  timeout: 900
      #  运行在Debug模式。runner对应的FC函数在短时间内不会被回收。一般不建议打开Debug模式。
      #  debugMode: true
      #  任务节点的环境变量配置。
      #  environmentVariables:
      #  DEBUG: '*'
  tasks:
  # 构建并部署。
  - name: build-and-deploy
    context:
      data:
        # 打开任务执行,默认关闭。
        enable: true
        # 同样可以在此处声明或修改runnerConfig。
        # runnerConfig:
        # 执行步骤。下述步骤将会采用开源项目serverless-cd提供的engine进行执行。
        steps:
          # 第一步,checkout代码。
          # 这里采用了plugin机制,运行serverless-cd社区的插件。
          # @serverless-cd/checkout是一个社区提供的插件,它会将代码checkout到默认路径。
          # 函数计算会陆续为社区提供更多的插件。
          - plugin: '@serverless-cd/checkout'
          - run: |
              echo "Setup Serverless Devs ing..."
              # 打开调试模式,将命令输出。
              set -x
              ls -al
              # aliyun cloud authentication infos.
              access_key_id=${{ sts.accessKeyId || "dummy-ak" }}
              access_key_secret=${{ sts.accessKeySecret || "dummy-sk" }}
              security_token=${{ sts.securityToken || "dummy-token" }}
              uid=${{ uid || "dummy-uid" }}
              # account info alias
              alias=my-account
              s --version
              if [[ $? -ne 0 ]]; then
              echo "Serverless Devs is not installed."
              exit 1
              fi
              s config add --AccessKeyID "${access_key_id}" --AccessKeySecret "${access_key_secret}" \
              --AccountID "${uid}" --SecurityToken "${security_token}" --access "${alias}" -f
              if [[ $? -ne 0 ]]; then
              echo "Failed to setup Serverless Devs."
              exit 1
              fi
              echo "Setup Serverless Devs success."
          # 执行s-deploy。
          - run: |
              echo "Deploy by Serverless Devs ing..."
              set -x
              alias=my-account
              deploy_file=${{ ctx.data.deployFile || "" }}
              if [[ -z "${deploy_file}" ]]; then
                if [[ -f "s.yaml" ]]; then
                  deploy_file="s.yaml"
                elif [[ -f "s.yml" ]]; then
                  deploy_file="s.yml"
                fi
              fi
              if [[ ! -f "${deploy_file}" ]]; then
                echo "Failed to find s.yaml file."
                exit 1
              fi
              echo "s.yaml file location: ${deploy_file}"
              s deploy --access "${alias}" -t "${deploy_file}" --use-local --assume-yes --skip-push
              echo "Deploy by Serverless Devs success."
    # 任务模板指定为内置的模板serverless-runner-task。
    taskTemplate: serverless-runner-task
    # 执行顺序。不依赖任何任务,立刻执行。
    runAfters: []
---

使用RunnerConfig描述任务节点

以下场景中,用户需要自定义RunnerConfig,来定义CI/CD运行环境。

  • 代码仓库在GitHub,将节点部署到中国内地以外的地域,以解决拉取不到代码导致构建失败的问题。

  • 提升任务节点的规格,以解决内存不足或构建速度慢的问题。

  • 通过镜像自定义构建环境,以解决构建环境时无法找到依赖的问题。

  • 在自己的VPC内构建,以解决私有资源获取不到的问题。

如果指定了RunnerConfig,任务节点将按照描述部署在当前账号下。如果不指定RunnerConfig,任务节点将部署在阿里云沙箱环境。

RunnerConfig的定义如下。

参数

类型

说明

是否必填

参考值

regionID

String

部署任务节点到指定的地域,默认为cn-shanghai。

cn-shanghai

logConfig

LogConfig

收集任务节点日志到日志服务SLS。

请参见LogConfig

vpcConfig

VPCConfig

部署任务节点到指定的VPC。

请参见VPCConfig

nasConfig

NASConfig

将NAS挂载到任务节点文件目录。

请参见NASConfig

serviceRole

String

指定部署任务节点和执行步骤的RAM角色。默认为acs:ram::{uid}:role/aliyunfcserverlessdevsrole

acs:ram::198613743****:role/fc-public-test

internetAccess

Boolean

配置任务节点的访问公网的能力。默认打开此功能。

true

timeout

Integer

配置任务节点的超时时间。默认为900秒,最大为3000秒。

900

cpu

Float

配置任务节点的CPU规格。默认为1核。

1

memory

Integer

配置任务节点的内存规格。默认为2048 MB。

2048

environmentVariables

Map<String, String>

为任务节点指定环境变量配置。

{
    "DEBUG":"*"
}

debugMode

Boolean

Debug模式。打开此模式时,将禁用Runner的即时GC,用于排查问题。

true

使用Steps描述任务节点执行

用户需要通过定义Steps,描述任务节点执行。Steps是一个数组,执行引擎会按顺序执行每一个Step,每一个Step都是执行引擎的独立子进程。

命令类型Step

命令类型Step可以让用户使用Shell命令描述构建行为。Shell命令支持模板语法(执行引擎为开源的art-template),可以通过分割符['${{', '}}']来获取上下文中的变量。例如,打印当前执行上下文中的应用名称,可以通过echo ${{ ctx.data.appName }}实现。

需要特别说明的是,分割符['${{', '}}']与Shell命令中的$语法没有关系。在run命令中,使用${{ key }}${key}具有完全不同的含义,前者是通过模板语法从当前执行上下文中获取变量,后者是通过Shell语法获取当前进程中的变量,包括环境变量。

上下文数据结构如下。

参数

类型

说明

参考值

ctx

Object

执行引擎传递给任务的执行上下文。

{
"appName": "my-application"
}

uid

String

阿里云账号ID。

198613743****

requestId

String

当前处理的请求ID。

94AB79CA-624B-4FBE-89BC-0F94BC1E1E15

sts

Object

阿里云STS临时授权信息,用于调用云服务。其权限由RunnerConfig.serviceRole指定。

{
"accessKeyId": "Lk89k****",
"accessKeySecret": "SEC******",
"securityToken":"KJHLS****"
}

pipeline

Object

当前流水线的详情。

请参见Pipeline

task

Object

当前任务的详情。

请参见Task

Steps的数据结构如下。

参数

类型

说明

是否必填

参考值

run

String

当前步骤运行的Shell命令。

make setup

id

String

步骤ID,用于唯一标识当前步骤。

s-setup

env

Map<String, String>

当前步骤的环境变量。

{
    "debug":"*"
}

working-directory

String

执行当前步骤命令的路径,支持相对路径。默认为engine进程当前路径。

./

continue-on-error

Boolean

是否忽略执行异常,默认不允许忽略执行异常。取值说明如下:

  • true:表示允许步骤执行失败时通过。

  • false:表示不允许步骤执行失败时通过。

false

if

String

条件执行表达式。如果执行结果为true,则继续执行此步骤,否则忽略此步骤。

${{ steps['my-cache'].outputs['cache-hit'] != 'true' }}

插件类型Step

插件由Serverless开发平台官方维护。将重复和繁琐的构建行为抽象为插件后,只需声明插件名称,即可完成大段代码才能完成的工作。例如,需要完成checkout代码工作,只需声明插件为@serverless-cd/checkout即可实现。

参数

类型

说明

是否必填

参考值

plugin

String

当前步骤运行的插件。

@serverless-cd/checkout

id

String

步骤ID,用于唯一标识当前步骤。

s-setup

env

Map<String, String>

当前步骤的环境变量。

{
    "debug":"*"
}

continue-on-error

Boolean

是否忽略执行异常,默认不允许忽略执行异常。取值说明如下:

  • true:表示允许步骤执行失败时通过。

  • false:表示不允许步骤执行失败时通过。

false

inputs

Object

执行插件后接收的参数。

{
  "key1": "value1",
  "key2": "value2"
}

if

String

条件执行表达式。如果执行结果为true,则继续执行此步骤,否则忽略此步骤。

${{ steps['my-cache'].outputs['cache-hit'] != 'true' }}

支持的插件列表