diff --git a/docs/zh/docs/amamba/customize-step.md b/docs/zh/docs/amamba/customize-step.md index e25e2696df..51d89a9976 100644 --- a/docs/zh/docs/amamba/customize-step.md +++ b/docs/zh/docs/amamba/customize-step.md @@ -27,10 +27,119 @@ ## 使用自定义步骤 -对于启用状态的自定义步骤,可以前往工作空间流水线模块, +### 配置 Jenkins + +自定义插件功能依赖于 Jenkins 的[共享库](https://www.jenkins.io/doc/book/pipeline/shared-libraries/)功能, +因此首先需要在 Jenkins 中配置共享库。 + +修改 Jenkins 的 casc 配置项使之开启: + +1. 点击左上角的 **≡** 打开导航栏,选择 **容器管理** -> **集群列表** ,找到需要安装 Jenkins 的集群,点击该集群的名称。 +2. 找到 **配置与密钥** -> **配置项** ,搜索 **jenkins-casc-config** ,在操作列点击 **编辑 YAML** 。 +3. 在 **data** -> **jenkins.yaml** -> **unclassified** 字段下添加如下内容: + + ```yaml + unclassified: + globalLibraries: # (1)! + libraries: + - name: amamba-shared-lib + defaultVersion: main + implicit: true # (2)! + retriever: + modernSCM: + libraryPath: ./ + scm: + git: + remote: https://github.com/amamba-io/amamba-shared-lib.git # (3)! + ``` + + 1. 共享库配置 + 2. 表示该共享库会被默认引入到所有流水线中,在 Jenkinsfile 中就 **不再需要** 使用 @Library 注解引入。 + 如果开启了此参数将会对所有的流水线生效,会略微延长流水线的执行时间。 + 如果不需要则设置为 false,后续如果某个流水线需要使用到自定义插件功能, + 则需要在 Jenkinsfile 中使用 `@Library('amamba-shared-lib@main') _` 引入。 + 3. 表示工作台维护的共享库地址,是实现自定义插件的代码仓库地址。仓库地址是公开的。 + **在网络受限的环境下,您可以将其 clone 到内网的 git 服务器上,然后将地址改为内网地址。** + + +### 使用自定义插件 1. 选择一条流水线,进入详情,点击 __编辑流水线__ 2. 点击 __添加步骤__ ,即可看到自定义步骤,选择后填写相关参数即可 ![cus-step2](./images/custermize2.jpg) + + +注意,自定义步骤有以下限制: + +- 必须要在一个包含 Docker 或者 Podman 的容器中运行,因此您需要选择 __使用容器__ +- 因为本质上是在容器中执行脚本,某些脚本可能需要一些特殊的权限。当自定义步骤无法实现时,推荐使用 __执行 Shell__ 步骤,自行编写脚本。 + +自定义插件使用时会被渲染成如下的 Jenkinsfile 片段: + +```groovy +container("base") { + amambaCustomStep( + pluginID: 'printEnv', // 插件名称 + version: 'v1.0.0', // 插件版本 + docker: [ + image: 'alpine', // 插件使用的镜像 + shell: '/bin/bash', // 解释器 + script: 'env', // 在镜像中执行的脚本 + ], + args: [ + key1: 'val', // 插件中定义的参数 + key2: [ + 'key3': 'val3' + ], + key4: ["val4", "val5"] + ], + ) +} +``` + +args 中的所有参数都会以环境变量的形式传递到插件中,因此您可以在 script中 通过 `$key1` 的形式获取到参数的值。 +如果参数的类型是 kv,参数的 key 会以 `_` 连接后传递到插件中,如 `key2_key3=val3`。 +如果参数定义的是数组类型,则传递到插件中的值是 `["val4", "val5"]`,您需要按照不同的语言自行解析。 + +因此,即使您不采用 DAG 的形式编排,依旧可以按照上述标准在 Jenkinsfile 中使用自定义插件。 +只是需要注意,参数的值类型为 string 时请使用单引号,避免无法替换环境变量的问题。 + +### 环境变量和凭证 + +在 Jenkinsfile 中定义的环境变量和凭证,都可以在插件中读取到,比如: + +```groovy +withCredential([usernamePassword(credentialsId: 'my-credential', usernameVariable: 'USERNAME', passwordVariable: 'PASSWORD')]) { + amambaCustomStep( + pluginID: 'printEnv', + version: 'v1.0.0', + docker: [ + image: 'alpine', + shell: '/bin/bash', // 可以在插件的 script 中读取到 USERNAME 和 PASSWORD 变量 + script: 'env', + ], + args: [], + ) +} +``` + +### 如何拉取私有镜像 + +如果您在定义插件时使用的是私有镜像,则需要通过以下方式使用自定义步骤: + +1. 在工作台中创建一个用户名密码类型的凭证,用于存储私有镜像的用户名和密码。 +2. 在使用自定义步骤之前,添加一个 __使用凭证__ 的步骤,用户名变量填写 `PLUGIN_REGISTRY_USER`,密码变量填写 `PLUGIN_REGISTRY_PASSWORD`。 + +渲染出的 Jenkinsfile 片段如下: + +```groovy +withCredential([usernamePassword(credentialsId: 'my-credential', usernameVariable: 'PLUGIN_REGISTRY_USER', passwordVariable: 'PLUGIN_REGISTRY_PASSWORD')]) { + amambaCustomStep( + ... + ) +} +``` + +后续即可使用私有的镜像作为插件的基础镜像。 diff --git a/docs/zh/docs/amamba/quickstart/job-cacher.md b/docs/zh/docs/amamba/quickstart/job-cacher.md deleted file mode 100644 index ce36beb1ac..0000000000 --- a/docs/zh/docs/amamba/quickstart/job-cacher.md +++ /dev/null @@ -1,131 +0,0 @@ -# 在流水线中使用缓存 - -CI 中经常使用流水线执行编译、构建等工作,现代语言中,无论是 Java、NodeJS、Python 还是 Go, -都需要下载依赖包来执行构建工作。这一过程往往需要占用大量网络资源,会拖慢流水线构建速度,成为 CI/CD 中的瓶颈,降低我们的生产效率。 - -类似的,还包括语法检查产生的缓存文件,Sonarqube 扫描代码生成的缓存文件,如果每次都重新开始运行,将无法有效利用工具本身的缓存机制。 - -应用工作台本身提供了基于 K8S 的 `hostPathVolume` 的缓存机制,利用节点本地路径可以缓存例如 -`/root/.m2`、`/home/jenkins/go/pkg`、`/root/.cache/pip` 等包默认路径。 - -但是在 DCE 5.0 多租户的场景下,更多用户希望保持缓存的隔离,避免侵入和冲突。这里介绍一种基于 Jenkins 插件 -[Job Cacher](https://plugins.jenkins.io/jobcacher/) 实现的一种缓存机制。 - -通过 Job Cacher,我们可以使用 AWS S3 或者 S3 接口兼容的存储系统(例如 MinIO)来实现流水线级别的缓存隔离。 - -## 准备工作 - -1. 提供一个 S3 或类 S3 的存储后端,可以参考[创建 MinIO 实例 - DaoCloud Enterprise](../../middleware/minio/user-guide/create.md) - 在 DCE 5.0 上创建一个 MinIO,并创建一个 bucket,准备好 `access key` 和 `secret`。 - - ![准备 S3](../images/job-cacher01.png) - -2. 在 Jenkins 的 **系统管理** -> **插件管理** 界面下,安装插件 job-cacher: - - ![安装插件](../images/job-cacher02.png) - -3. 如果要使用 S3 的存储,还需要安装插件如下: - - ```yaml - - groupId: org.jenkins-ci.plugins - artifactId: aws-credentials - source: - version: 218.v1b_e9466ec5da_ - - groupId: org.jenkins-ci.plugins.aws-java-sdk - artifactId: aws-java-sdk-minimal # (1)! - source: - version: 1.12.633-430.vf9a_e567a_244f - - groupId: org.jenkins-ci.plugins - artifactId: jackson2-api # (2)! - source: - version: 2.16.1-373.ve709c6871598 - ``` - - 1. aws-crendetials 依赖 - 2. 被其他插件依赖 - -!!! note - - Amamba 提供的 v0.3.2 及之前的 Helm Chart 对应的 Jenkins 版本为 2.414,经测试这个版本的 - Job Cacher 399.v12d4fa_dd3db_d 不能正确的识别 S3 配置,请注意使用升级后的 Jenkins 及 Job Cacher。 - -## 配置 - -在 **系统管理** 界面,如下配置 S3 的参数: - -![配置插件](../images/job-cacher03.png) - -或者可以通过 CasC 的方式修改 ConfigMap,以持久化配置。 - -修正后的 YAML 示例如下: - -```yaml -unclassified: - ... - globalItemStorage: - storage: - nonAWSS3: - bucketName: jenkins-cache - credentialsId: dOOkOgwIDUEcAYxWd9cF - endpoint: http://10.6.229.90:30404 - region: Auto - signerVersion: - parallelDownloads: true - pathStyleAccess: false -``` - -## 使用 - -完成上述配置后,我们就可以在 Jenkinsfile 中使用 Job Cacher 提供的函数 `cache`,以如下的流水线为例: - -```groovy -pipeline { - agent { - node { - label 'nodejs' - } - } - stages { - stage('clone') { - steps { - git(url: 'https://gitlab.daocloud.cn/ndx/engineering/application/amamba-test-resource.git', branch: 'main', credentialsId: 'git-amamba-test') - } - } - stage('test') { - steps { - sh 'git rev-parse HEAD > .cache' - cache(caches: [ - arbitraryFileCache( - path: "pipeline-template/nodejs/node_modules", - includes: "**/*", - cacheValidityDecidingFile: ".cache", - ) - ]){ - sh 'cd pipeline-template/nodejs/ && npm install && npm run build && npm install jest jest-junit && npx jest --reporters=default --reporters=jest-junit' - junit 'pipeline-template/nodejs/junit.xml' - } - } - } - } -} -``` - -该流水线定义了两个阶段 clone 和 test,在 test 阶段,我们通过对 node_modules 下的所有文件进行缓存, -避免每次都要拉取 npm 包。同时,我们定义了 .cache 文件作为缓存的唯一性标识, -也就是说当前分支一旦有任何更新缓存将会失效,并重新拉取 npm 包。 - -完成之后可以看到,第二次重复运行流水线,时间大大缩短: - -![运行流水线日志](../images/job-cacher04.png) - -![运行流水线结果](../images/job-cacher05.png) - -更多的选项可以参考文档:[Job Cacher | Jenkins plugin](https://plugins.jenkins.io/jobcacher/) - -## 其他 - -- **关于性能** :job-cacher 也是基于 `MasterToSlaveFileCallable` 实现的,是基于远程调用在 - agent 中直接上传和下载的,而不是 agent -> controller -> S3 的方式; -- **关于缓存大小** :job-cacher 支持多种压缩算法,包括 - `ZIP`、`TARGZ`、`TARGZ_BEST_SPEED`、`TAR_ZSTD`、`TAR`,默认是使用 `TARGZ`; -- **关于缓存清理** :job-cacher 支持按流水线设置 `maxCacheSize`。 diff --git a/docs/zh/docs/amamba/user-guide/pipeline/custom-plugin.md b/docs/zh/docs/amamba/user-guide/pipeline/custom-plugin.md deleted file mode 100644 index e7f52f0a13..0000000000 --- a/docs/zh/docs/amamba/user-guide/pipeline/custom-plugin.md +++ /dev/null @@ -1,303 +0,0 @@ -# 自定义流水线插件 - -在使用流水线功能时,各个团队的使用场景各有差异,可以将一些常用的脚本、命令、工具等封装成一个自定义插件, -方便复用,或者当工作台提供的功能无法满足需求时,可以通过自定义插件来扩展功能。 - -## 配置 Jenkins - -自定义插件功能依赖于 Jenkins 的[共享库](https://www.jenkins.io/doc/book/pipeline/shared-libraries/)功能, -因此首先需要在 Jenkins 中配置共享库。 - -修改 Jenkins 的 casc 配置项使之开启: - -1. 点击左上角的 **≡** 打开导航栏,选择 **容器管理** -> **集群列表** ,找到需要安装 Jenkins 的集群,点击该集群的名称。 -2. 找到 **配置与密钥** -> **配置项** ,搜索 **jenkins-casc-config** ,在操作列点击 **编辑 YAML** 。 -3. 在 **data** -> **jenkins.yaml** -> **unclassified** 字段下添加如下内容: - - ```yaml - unclassified: - globalLibraries: # (1)! - libraries: - - name: amamba-shared-lib - defaultVersion: main - implicit: true # (2)! - retriever: - modernSCM: - libraryPath: ./ - scm: - git: - remote: https://github.com/amamba-io/amamba-shared-lib.git # (3)! - ``` - - 1. 共享库配置 - 2. 表示该共享库会被默认引入到所有流水线中,在 Jenkinsfile 中就 **不再需要** 使用 @Library 注解引入。 - 如果开启了此参数将会对所有的流水线生效,会略微延长流水线的执行时间。 - 如果不需要则设置为 false,后续如果某个流水线需要使用到自定义插件功能, - 则需要在 Jenkinsfile 中使用 `@Library('amamba-shared-lib@main') _` 引入。 - 3. 表示工作台维护的共享库地址,是实现自定义插件的代码仓库地址。仓库地址是公开的。 - **在网络受限的环境下,您可以将其 clone 到内网的 git 服务器上,然后将地址改为内网地址。** - -## 创建自定义插件 - -创建自定义插件需要工作台的管理员权限,在 __工作台管理__-> __流水线设置__ -> __自定义步骤__ 页面对插件进行管理。 - -自定义插件目前只支持以 YAML 文件的形式定义,YAML 格式如下: - -```yaml -apiVersion: pipeline.amamba.io/v1alpha1 -kind: PipelinePlugin -metadata: - name: deploy-application # required 插件的ID,只能包含小写字母、数字及分隔符("- _") - labels: - pipeline.amamba.io/category: build # 必须定义为其中一个:others,build,test,security,release,deploy,command,general,repository,quality - pipeline.amamba.io/version: 1.0.0 # required 插件的版本,与 name 必须唯一 - annotations: - pipeline.amamba.io/description: 部署应用到k8s集群 # 插件的描述 - pipeline.amamba.io/versionDescription: 修复了xxx问题 # 插件的版本描述 - pipeline.amamba.io/icon: 插件的图标 # 图标链接 -spec: - image: "docker.m.daocloud.io/amambadev/jenkins-agent-base:v0.3.2-podman" # required 插件的基础镜像 - entrypoint: "" # 可以自定义入口脚本, 本质上是替换 --entrypoint - shell: "/bin/bash" # 脚本解释器,如shell, python等 - script: "kubectl apply -f ." # required 需要在容器中执行的脚本 - params: # required - - name: namespace # required 名称必须唯一 - sort: 2 # 参数展示的顺序 - uiType: NamespaceSelector - type: string - uiConfig: - displayName: "命名空间" - placeholder: "namespace" - tips: "应用部署的命名空间" - helper: "未找到命名空间?请前往全局管理配置" - validate: - required: true - requiredMessage: "命名空间不能为空" - pattern: ^[a-zA-Z0-9_-]+$ - patternMessage: "命名空间只能包含字母,数字,下划线和中划线" - minLength: 1 - maxLength: 64 - immutable: false # 是否可修改 - default: "my-namespace" # 默认值 - options: - - label: 默认 - value: default - env: NAMESPACE # 存在env这个属性则将env的值作为环境变量的key传递到插件,否则按照name的值传递 - dependProperties: # 属性依赖,如 namespace 字段依赖于 cluster 字段,给前端交互使用 - cluster: cls -``` - -参数介绍: - -| 属性名 | 含义 | 示例 | -| ---------------- | -------------------------------------------- | ------------------------------------------- | -| name | 参数名称 | cluster | -| type | 参数类型 | string | -| env | 对应环境变量的值,没有此字段则默认与name相同 | CLUSTER_NAME | -| validateConfig | 参数的校验规则 | {} | -| uiConfig | ui页面上的一些选项 | {} | -| dependProperties | ui上的属性依赖项 | 比如namespace依赖于cluster, 给前端交互使用 | - -dependProperties 依赖参数介绍: - -因为某些参数之间存在着依赖关系,例如namespace依赖于cluster,为了更好的UI交互体验,可以在dependProperties中添加属性依赖项说明,那么前端会自动根据uiType以及dependProperties来动态获取数据进行交互。dependProperties是一个map结构,key是前端在组件中会使用到的参数,value是在params中定义的参数名称,可以声明多个依赖项。 - -依赖项举例: - -NamespaceSelector: - -```yaml -params: - - name: cls - uiType: ClusterSelector - - name: namespace - uiType: NamespaceSelector - dependProperties: - cluster: cls # (1)! -``` - -1. key 是前端在组件中会使用到的参数,value 是在 params 中定义的参数名称 - -WorkloadSelector: - -```yaml -params: - - name: cls - uiType: ClusterSelector - - name: namespace - uiType: NamespaceSelector - dependProperties: - cluster: cls - - name: workloadType - uiType: Select - - name: workloadName - uiType: WorkloadSelector # 级联依赖于 cluster、namespace、workloadType 属性 - dependProperties: - cluster: cls - namespace: namespace - workloadType: workloadType -``` - -ContainerSelector: - -```yaml -params: - - name: cls - uiType: ClusterSelector - - name: namespace - uiType: NamespaceSelector - dependProperties: - cluster: cls - - name: workload_type - uiType: Select - - name: workloadName - uiType: WorkloadSelector - dependProperties: - cluster: cls - namespace: namespace - workloadType: workloadType - - name: containerName - uiType: ContainerSelector - dependProperties: - cluster: cls - namespace: namespace - workloadType: workload_type - workloadName: workloadName -``` - -validate 参数校验规则介绍: - -```yaml -required: true # 是否必填 -requiredMessage: "xxx必须填写" # 必填时的提示信息 -pattern: "*" # 合法的正则表达式 -patternMessage: "xxx不匹配" # 正则表达式不匹配时的提示信息 -min: 0 # 最小值,合法的数字 -max: 1 # 最大值,合法的数字,需要 > min -minLength: 64 # 最小长度 -maxLength: 64 # 最大长度 -integer: true # 是否为整数 -immutable: false # 是否可修改,false 代表可以修改,true 代表不可修改, -default: "cluster1" # 默认值 -options: - - label: "无状态负载" # 针对下拉框 - value: "Deployment" - - label: "有状态负载" - value: "StatefulSet" -``` - -uiConfig 参数介绍: - -uiConfig 必须是预定义的类型,主要是一些 UI 展示上的配置项: - -```yaml -displayName: 显示的名称 -helper: 帮助信息(位于输入框的下面) -tips: 提示信息(鼠标点击?时的提示) -placeholder: 占位符信息 -``` - -UI 参数预定义类型及使用场景如下: - -| 参数类型 | UI类型 | 说明 | 依赖项说明 | -| -------- | ------------------ | ------------------------------------ | -------------------------------------------------------- | -| string | Text | 大文本输入框 | | -| string | Shell | Shell 高亮输入框 | | -| string | Yaml | Yaml 高亮输入框 | | -| string | Input | 输入框,单行文本 | | -| string | Select | 下拉框,与参数定义中的options配合使用 | | -| string | Radio | 单选框 | | -| bool | Switch | 开关 | | -| string | Password | 密码 `****` | | -| int | Number | 数字输入框 | | -| string | ImageInput | 镜像选择器 | | -| string | ClusterSelector | 集群选择器 | | -| string | NamespaceSelector | 命名空间选择器 | 依赖于 cluster 属性 | -| string | CredentialSelector | 凭证选择器 | | -| string | WorkloadSelector | 工作负载选择器 | 依赖于 cluster,namespace,workloadType 属性 | -| string | ContainerSelector | 容器选择器 | 依赖于 cluster,namespace,workloadType,workloadName 属性 | -| array | Strings | 字符串数组 | | -| array | Numbers | 数字数组 | | -| map | KV | kv 键值对结构,如环境变量 | | -| bool | Ignore | 不展示此字段 | | -| string | CPUNumber | CPU 数量输入框 | | -| string | MemoryNumber | 内存数量输入框 | | - -在创建插件之后,为了保证插件的兼容性,当您需要更改插件定义时,最佳实践是递增插件的版本号,并在版本描述中说明更改的内容。 - -## 使用自定义插件 - -在流水线的编辑页面(DAG),点击 __添加步骤__ -> __自定义步骤__ -> __自定义插件及对应版本__ ,填写参数后点击 __确定__ 。 - -注意,自定义步骤有以下限制: - -- 必须要在一个包含 Docker 或者 Podman 的容器中运行,因此您需要选择 __使用容器__ -- 因为本质上是在容器中执行脚本,某些脚本可能需要一些特殊的权限。当自定义步骤无法实现时,推荐使用 __执行 Shell__ 步骤,自行编写脚本。 - -自定义插件使用时会被渲染成如下的 Jenkinsfile 片段: - -```groovy -container("base") { - amambaCustomStep( - pluginID: 'printEnv', // 插件名称 - version: 'v1.0.0', // 插件版本 - docker: [ - image: 'alpine', // 插件使用的镜像 - shell: '/bin/bash', // 解释器 - script: 'env', // 在镜像中执行的脚本 - ], - args: [ - key1: 'val', // 插件中定义的参数 - key2: [ - 'key3': 'val3' - ], - key4: ["val4", "val5"] - ], - ) -} -``` - -args 中的所有参数都会以环境变量的形式传递到插件中,因此您可以在 script中 通过 `$key1` 的形式获取到参数的值。 -如果参数的类型是 kv,参数的 key 会以 `_` 连接后传递到插件中,如 `key2_key3=val3`。 -如果参数定义的是数组类型,则传递到插件中的值是 `["val4", "val5"]`,您需要按照不同的语言自行解析。 - -因此,即使您不采用 DAG 的形式编排,依旧可以按照上述标准在 Jenkinsfile 中使用自定义插件。 -只是需要注意,参数的值类型为 string 时请使用单引号,避免无法替换环境变量的问题。 - -### 环境变量和凭证 - -在 Jenkinsfile 中定义的环境变量和凭证,都可以在插件中读取到,比如: - -```groovy -withCredential([usernamePassword(credentialsId: 'my-credential', usernameVariable: 'USERNAME', passwordVariable: 'PASSWORD')]) { - amambaCustomStep( - pluginID: 'printEnv', - version: 'v1.0.0', - docker: [ - image: 'alpine', - shell: '/bin/bash', // 可以在插件的 script 中读取到 USERNAME 和 PASSWORD 变量 - script: 'env', - ], - args: [], - ) -} -``` - -### 如何拉取私有镜像 - -如果您在定义插件时使用的是私有镜像,则需要通过以下方式使用自定义步骤: - -1. 在工作台中创建一个用户名密码类型的凭证,用于存储私有镜像的用户名和密码。 -2. 在使用自定义步骤之前,添加一个 __使用凭证__ 的步骤,用户名变量填写 `PLUGIN_REGISTRY_USER`,密码变量填写 `PLUGIN_REGISTRY_PASSWORD`。 - -渲染出的 Jenkinsfile 片段如下: - -```groovy -withCredential([usernamePassword(credentialsId: 'my-credential', usernameVariable: 'PLUGIN_REGISTRY_USER', passwordVariable: 'PLUGIN_REGISTRY_PASSWORD')]) { - amambaCustomStep( - xxx - ) -} -``` - -后续即可使用私有的镜像作为插件的基础镜像。 diff --git a/docs/zh/navigation.yml b/docs/zh/navigation.yml index ef7582d7cb..b45a35b32f 100644 --- a/docs/zh/navigation.yml +++ b/docs/zh/navigation.yml @@ -158,8 +158,6 @@ nav: - Jenkins自定义工具链: amamba/quickstart/jenkins-custom.md - 在指定的节点上运行: amamba/quickstart/pipeline-on-node.md - 构建多架构镜像: amamba/user-guide/pipeline/podman.md - - 在流水线中使用缓存: amamba/quickstart/job-cacher.md - - 使用自定义插件: amamba/user-guide/pipeline/custom-plugin.md - 系统环境变量: amamba/user-guide/pipeline/system-env.md - 流水线监控指标: amamba/user-guide/pipeline/jenkins-metric.md - 保留Jenkins配置项: amamba/user-guide/pipeline/retain-jenkins-config.md