首页 星云 工具 资源 星选 资讯 热门工具
:

PDF转图片 完全免费 小红书视频下载 无水印 抖音视频下载 无水印 数字星空

Jenkins 配置即代码(Configuration as Code)详解

编程知识
2024年08月01日 19:34

1、概述

  在《Centos7下安装配置最新版本Jenkins(2.452.3)》这篇博文中讲解了如何安装Jenkins,虽然在安装Jenkins时安装了一些必备的推荐插件,但在企业环境中使用Jenkins之前,我们仍需完成一系列手动配置工作,如配置 System Configuration、Security。

  • System Configuration是确保Jenkins正常运行的关键步骤,包括配置全局环境变量、设置邮件服务器、配置存储和归档策略;指定JDK、Git、Maven等工具的路径;配置构建执行的节点和代理等。
  • Security是保护Jenkins系统免受潜在威胁的核心任务,包括配置用户认证和授权策略;配置跨站请求伪造保护;配置API Token;配置凭证等。

示例 1  配置 System Configuration——System(配置系统)页面:

  如果你是一名 Jenkins 管理员,那么你一定不会对上面这个页面感到陌生,每次部署完一个新的Jenkins实例,在可以使用之前,往往都需要在上面页面作出一些相应的配置(主目录、执行器数量、Jenkins URL、系统管理员邮件地址、Resource Root URL等)。 该页面除了包含 Jenkins 自身的一些基本配置信息外,同时还包括了当前系统中所安装的插件的配置信息。也就是说,当你的 Jenkins 安装的插件越多,该页面的配置项就有可能会越多。

示例 2  配置 Security——Security(配置全局安全性)页面:

  Jenkins 管理员在这里可以配置认证、授权、代理、跨域等内容。

  而 Jenkins 配置即代码(Configuration as Code) ,正是这样一款能够帮助我们从这些大量手动配置的工作中解放出来的 Jenkins 插件。Jenkins Configuration as Code Plugin 允许用户将System Configuration、Security等 Jenkins 的配置信息写入到一个 YAML 文件中。这样,可以将 Jenkins 的配置标准化,便于在团队内部复用,易于传播、便于快速搭建开箱即用的 Jenkins 服务。借助这个插件,我们几乎不再需要通过人工在 UI 界面上点击的方式来配置 Jenkins 服务。而且,绝大部分其他插件几乎(甚至)不需要做任何调整,就可以与该插件兼容。本文将详细解决如何在Jenkins使用 Jenkins Configuration as Code。

注意 1:Configuration as Code 插件的主要作用是减少 Jenkins 管理员通过 UI 界面进行手动配置的工作。然而,并不能通过CasC管理的配置文件安装 Jenkins 插件。因此,在使用 Configuration as Code 插件之前,需要确保 Jenkins 实例已经安装了配置文件中涉及到的所有插件。

2、Jenkins Configuration as Code 详解

  Jenkins Configuration as Code,又名 JCasC,它允许我们将所有关于 Jenkins 的配置以 YAML 的格式写入到配置文件中去,并通过对装有该插件的 Jenkins 实例应用这些配置文件,来实现一键式自动化配置 Jenkins 的目的。

  JCasC 为编写 YAML 文件提供一系列特定的 Key 值,这些 Key 值分别对应 Jenkins 中不同的配置项。通过为这些 Key 值赋值的方式来达到配置 Jenkins 的目的,下面是官方提供的一个示例配置文件:

jenkins:
  systemMessage: "Jenkins configured automatically by Jenkins Configuration as Code plugin\n\n"
  securityRealm:
    ldap:
      configurations:
        - groupMembershipStrategy:
            fromUserRecord:
              attributeName: "memberOf"
          inhibitInferRootDN: false
          rootDN: "dc=acme,dc=org"
          server: "ldaps://ldap.acme.org:1636"
  nodes:
    - permanent:
        name: "static-agent"
        remoteFS: "/home/jenkins"
        launcher:
          jnlp:
            workDirSettings:
              disabled: true
              failIfWorkDirIsMissing: false
              internalDir: "remoting"
              workDirPath: "/tmp"
  slaveAgentPort: 50000
  agentProtocols:
    - "jnlp2"
tool:
  git:
    installations:
      - name: git
        home: /usr/local/bin/git
credentials:
  system:
    domainCredentials:
      - credentials:
          - basicSSHUserPrivateKey:
              scope: SYSTEM
              id: ssh_with_passphrase_provided
              username: ssh_root
              passphrase: ${SSH_KEY_PASSWORD}
              description: "SSH passphrase with private key file. Private key provided"
              privateKeySource:
                directEntry:
                  privateKey: ${SSH_PRIVATE_KEY}

  该配置文件中使用了 JCasC 提供的三个根配置元素 Key 值:jenkins、tool 和 credentials,分别对应 Jenkins 的基本配置项、全局工具配置项,以及 Jenkins Credentials 相关的配置项。通过为这些根 Key 值所提供的子配置项 Key 设定适当的值,我们分别对 Jenkins 作出了如下配置:

  • jenkins
    • systemMessage Key 设定了 Jenkins 的 "System Message" 信息。
    • securityRealm Key 设定了 LDAP 相关配置,并使其设定为 Jenkins 的认证方式。
    • nodes Key 创建一个名为 static-agent 的节点,并对其进行了适当对配置。
    • slaveAgentPort Key 设定了 Jenkins 主机与节点之间的通信端口号以及通信协议。
    • agentProtocols Key 设定 Jenkins 主机与节点之间对通信协议。
  • tool
    • git 为 Jenkins 的全局工具 Git 指定了默认执行路径。
  • credentials
    • 创建一个 ID 为 ssh_with_passphrase_provided 的系统级的 SSH credential。

  除了上面示例中所使用到的三个根配置元素外, unclassified 是另一个非常常见的根配置元素,大部分针对于插件的配置都被包含在了该根元素下。

  而除了这几个根配置元素自身外,每个根配置元素下又提供了大量子配置 Key 值,并且根据安装的插件的不同,每个 Jenkins 实例所支持的这些子 Key 值也不尽相同。JCasC 提供的Documentation 页面(Dashboard -> Manage Jenkins -> Configuration as Code -> 页面最下面参考 -> 文档)列出了当前 Jenkins 实例中所支持的所有 Key 值信息。

3、Jenkins安装Configuration as Code Plugin 

Jenkins插件中心安装Configuration as Code Plugin插件,安装完成后需要重启Jenkins。

安装成功后,可以看到System Configuration功能模块下多了Configuration as Code功能选项。

鼠标点击Configuration as Code功能选项进入Configuration as Code功能页面。功能比较简单,这里不再多说。这里有2个快速编写jenkins.yaml文件的小技巧:

  • JCasC 插件官方文档中提供了大量的 配置示例,这其中包含了几乎所有关于 Jenkins 的配置以及大部分的插件配置,参考这些配置示例可帮助我们快速编写出自己的配置文件来。
  • 另一中编写 YAML 配置文件的小技巧是,首先通过手动的方式在 Jenkin UI 界面做好所有配置,在通过该插件页的 “View Configuration” 获取 JCasC 为我们自动生成出来的配置文件作为参考,来编写我们自己的配置文件。

示例,当前的Jenkins环境仅安装了一些插件,并进行了基本的系统配置和安全配置。通过图形化界面查看和导出配置可以生成一个 jenkins.yaml 文件。下次安装新的Jenkins时,只需简单调整这个 jenkins.yaml 文件即可,无需再次在图形化界面手动配置这些参数。

除了可以在 UI 界面上操作 CasC 的相关功能,CLI 也有对应的支持。

$ jcli casc
Configuration as Code

Usage:
  jcli casc [command]

Available Commands:
  apply       从应用已有的配置
  export      导出配置及代码的配置
  open        在浏览器中打开配置及代码的页面
  reload      重新加载配置及代码的配置
  schema      获取配置及代码的结构

也可以通过Restful接口操作 CasC 的相关功能。

导出配置 curl -X POST -u admin:112e74ac1ded9b9af4854e594405819df9 http://localhost:8080/configuration-as-code/export
查看 Schema curl -X POST -u admin:112e74ac1ded9b9af4854e594405819df9 http://localhost:8080/configuration-as-code/schema
重新加载配置 curl -X POST -u admin:112e74ac1ded9b9af4854e594405819df9 http://localhost:8080/configuration-as-code/reload
从请求中应用配置 curl -X POST -u admin:112e74ac1ded9b9af4854e594405819df9 http://localhost:8080/configuration-as-code/apply 

4、启动Jenkins时CasC配置文件加载流程

 另外,CasC只是配置支持同时加载多个配置文件。如果我们将 Jenkins 的不同部分拆分成多个文件,维护起来会很方便。

支持的策略:

  • ErrorOnConflictMergeStrategy(默认):该策略名称为errorOnConflict;如果多个 YAML 文件存在冲突,则会引发异常。
  • 覆盖合并策略:该策略名称是override;根据加载顺序覆盖配置文件。

策略名称的配置方式有两种:

  • 设置环境CASC_MERGE_STRATEGY
  • 设置系统属性casc.merge.strategy

5、Jenkins Configuration as Code 配置示例

jenkins:
  mode: EXCLUSIVE
  numExecutors: 0
  scmCheckoutRetryCount: 2
  disableRememberMe: true

  clouds:
    - kubernetes:
        name: "kubernetes"
        serverUrl: "https://kubernetes.default"
        skipTlsVerify: true
        namespace: "devops-system"
        credentialsId: "k8s-service-account"
        jenkinsUrl: "http://devops-jenkins.devops-system:80"
        jenkinsTunnel: "devops-jenkins-agent.devops-system:50000"
        containerCapStr: "10"
        connectTimeout: "60"
        readTimeout: "60"
        maxRequestsPerHostStr: "32"
        templates:
          - name: "base"
            namespace: "devops-system"
            label: "base"
            nodeUsageMode: "NORMAL"
            idleMinutes: 0
            containers:
            - name: "base"
              image: "builder-base:v3.2.2"
              command: "cat"
              args: ""
              ttyEnabled: true
              privileged: false
              resourceRequestCpu: "100m"
              resourceLimitCpu: "4000m"
              resourceRequestMemory: "100Mi"
              resourceLimitMemory: "8192Mi"
            - name: "jnlp"
              image: "jenkins/inbound-agent:4.10-2"
              args: "^${computer.jnlpmac} ^${computer.name}"
              resourceRequestCpu: "50m"
              resourceLimitCpu: "500m"
              resourceRequestMemory: "400Mi"
              resourceLimitMemory: "1536Mi"
            workspaceVolume:
              emptyDirWorkspaceVolume:
                memory: false
            volumes:
            - hostPathVolume:
                hostPath: "/var/run/docker.sock"
                mountPath: "/var/run/docker.sock"
            - hostPathVolume:
                hostPath: "/var/data/jenkins_sonar_cache"
                mountPath: "/root/.sonar/cache"
            yaml: |
              spec:
                affinity:
                  nodeAffinity:
                    preferredDuringSchedulingIgnoredDuringExecution:
                    - weight: 1
                      preference:
                        matchExpressions:
                        - key: node-role.kubernetes.io/worker
                          operator: In
                          values:
                          - ci
                tolerations:
                - key: "node.kubernetes.io/ci"
                  operator: "Exists"
                  effect: "NoSchedule"
                - key: "node.kubernetes.io/ci"
                  operator: "Exists"
                  effect: "PreferNoSchedule"
                containers:
                - name: "base"
                  resources:
                    requests:
                      ephemeral-storage: "1Gi"
                    limits:
                      ephemeral-storage: "10Gi"
                securityContext:
                  fsGroup: 1000

          - name: "nodejs"
            namespace: "devops-system"
            label: "nodejs"
            nodeUsageMode: "EXCLUSIVE"
            idleMinutes: 0
            containers:
            - name: "nodejs"
              image: "builder-nodejs:v3.2.0"
              command: "cat"
              args: ""
              ttyEnabled: true
              privileged: false
              resourceRequestCpu: "100m"
              resourceLimitCpu: "4000m"
              resourceRequestMemory: "100Mi"
              resourceLimitMemory: "8192Mi"
            - name: "jnlp"
              image: "jenkins/inbound-agent:4.10-2"
              args: "^${computer.jnlpmac} ^${computer.name}"
              resourceRequestCpu: "50m"
              resourceLimitCpu: "500m"
              resourceRequestMemory: "400Mi"
              resourceLimitMemory: "1536Mi"
            workspaceVolume:
              emptyDirWorkspaceVolume:
                memory: false
            volumes:
            - hostPathVolume:
                hostPath: "/var/run/docker.sock"
                mountPath: "/var/run/docker.sock"
            - hostPathVolume:
                hostPath: "/var/data/jenkins_nodejs_yarn_cache"
                mountPath: "/root/.yarn"
            - hostPathVolume:
                hostPath: "/var/data/jenkins_nodejs_npm_cache"
                mountPath: "/root/.npm"
            - hostPathVolume:
                hostPath: "/var/data/jenkins_sonar_cache"
                mountPath: "/root/.sonar/cache"
            yaml: |
              spec:
                affinity:
                  nodeAffinity:
                    preferredDuringSchedulingIgnoredDuringExecution:
                    - weight: 1
                      preference:
                        matchExpressions:
                        - key: node-role.kubernetes.io/worker
                          operator: In
                          values:
                          - ci
                tolerations:
                - key: "node.kubernetes.io/ci"
                  operator: "Exists"
                  effect: "NoSchedule"
                - key: "node.kubernetes.io/ci"
                  operator: "Exists"
                  effect: "PreferNoSchedule"
                containers:
                - name: "nodejs"
                  resources:
                    requests:
                      ephemeral-storage: "1Gi"
                    limits:
                      ephemeral-storage: "10Gi"
                securityContext:
                  fsGroup: 1000

         
  securityRealm:
    ldap:
      configurations:
      - displayNameAttributeName: "uid"
        mailAddressAttributeName: "mail"
        inhibitInferRootDN: false
        managerDN: "cn=admin,dc=zmc,dc=io"
        managerPasswordSecret: "admin"
        rootDN: "dc=zmc,dc=io"
        userSearchBase: "ou=Users"
        userSearch: "(&(objectClass=inetOrgPerson)(|(uid={0})(mail={0})))"
        groupSearchBase: "ou=Groups"
        groupSearchFilter: "(&(objectClass=posixGroup)(cn={0}))"
        server: "ldap://openldap.kubernetes-system.svc:389"
      disableMailAddressResolver: false
      disableRolePrefixing: true


unclassified:
  gitLabServers:
    servers:
    - name: "https://gitlab.com"
      serverUrl: "https://gitlab.com"

以上jenkins.yaml配置文件是基于CASC插件的,用于在Jenkins实例启动时自动加载配置。它配置了Jenkins的各个方面,包括执行模式、Kubernetes集群的连接和Pod模板、安全设置等。以下是对每个部分的解释:

5.1 Jenkins主配置

jenkins:
  mode: EXCLUSIVE
  numExecutors: 0
  scmCheckoutRetryCount: 2
  disableRememberMe: true
  • mode: EXCLUSIVE: Jenkins的操作模式,设置为“EXCLUSIVE”表示Jenkins将只在设置的节点上运行作业,而不是在主节点上。
  • numExecutors: 0: 主节点上的执行器数量设置为0,表示不在主节点上运行任何作业。
  • scmCheckoutRetryCount: 2: SCM(源码管理)检出重试次数,默认为2次。
  • disableRememberMe: true: 禁用“记住我”功能,提高安全性。

5.2 Kubernetes Cloud配置

clouds:
    - kubernetes:
        name: "kubernetes"
        serverUrl: "https://kubernetes.default"
        skipTlsVerify: true
        namespace: "devops-system"
        credentialsId: "k8s-service-account"
        jenkinsUrl: "http://devops-jenkins.devops-system:80"
        jenkinsTunnel: "devops-jenkins-agent.devops-system:50000"
        containerCapStr: "10"
        connectTimeout: "60"
        readTimeout: "60"
        maxRequestsPerHostStr: "32"
  • name: Kubernetes云的名称。
  • serverUrl: Kubernetes API服务器的URL。
  • skipTlsVerify: 是否跳过TLS验证,设置为true表示跳过。
  • namespace: 用于运行Jenkins agent的命名空间。
  • credentialsId: Kubernetes凭据的ID。
  • jenkinsUrl: Jenkins实例的URL。
  • jenkinsTunnel: Jenkins和Kubernetes agent之间的隧道地址。
  • containerCapStr: 最大容器数量。
  • connectTimeout 和 readTimeout: 连接和读取超时时间。
  • maxRequestsPerHostStr: 每个主机的最大请求数。

5.3 Pod模板

配置了多个Pod模板,用于不同的构建环境。每个模板都包含具体的容器配置、资源请求和限制、存储卷以及亲和性等。示例中配置了base、nodejs,如需其他容器模板的话,按需添加即可。

    templates:
          - name: "base"
            namespace: "devops-system"
            label: "base"
            nodeUsageMode: "NORMAL"
            idleMinutes: 0
                ......
                securityContext:
                  fsGroup: 1000
  • name: Pod模板的名称。
  • namespace: 运行Pod的命名空间。
  • label: Pod的标签,用于在Jenkins作业中指定节点。
  • nodeUsageMode: 节点使用模式。
  • containers: 包含在Pod中的容器配置。
  • workspaceVolume: Jenkins工作空间的卷配置。
  • volumes: 挂载在Pod中的卷。

5.4 安全配置

securityRealm:
    ldap:
      configurations:
      - displayNameAttributeName: "uid"
        mailAddressAttributeName: "mail"
        inhibitInferRootDN: false
        managerDN: "cn=admin,dc=zmc,dc=io"
        managerPasswordSecret: "admin"
        rootDN: "dc=zmc,dc=io"
        userSearchBase: "ou=Users"
        userSearch: "(&(objectClass=inetOrgPerson)(|(uid={0})(mail={0})))"
        groupSearchBase: "ou=Groups"
        groupSearchFilter: "(&(objectClass=posixGroup)(cn={0}))"
        server: "ldap://openldap.kubernetes-system.svc:389"
      disableMailAddressResolver: false
      disableRolePrefixing: true
  • ldap: 配置LDAP作为安全域。
  • configurations: LDAP服务器配置,包括DN、密码、搜索基准等。
  • server: LDAP服务器地址。

5.4 未分类配置

unclassified:
  gitLabServers:
    servers:
    - name: "https://gitlab.com"
      serverUrl: "https://gitlab.com"
  • gitLabServers: GitLab服务器配置。

6、总结

  Jenkins 配置即代码(Configuration as Code) 能够帮助我们从大量手动配置Jenkins的工作中解放出来。Jenkins Configuration as Code Plugin 允许用户将System Configuration、Security等 Jenkins 的配置信息写入到一个 YAML 文件中。这样,可以将 Jenkins 的配置标准化,便于在团队内部复用,易于传播、便于快速搭建开箱即用的 Jenkins 服务。借助这个插件,我们几乎不再需要通过人工在 UI 界面上点击的方式来配置 Jenkins 服务(实现Jenkins零配置)。而且,绝大部分其他插件几乎(甚至)不需要做任何调整,就可以与该插件兼容。

  对于CASC管理的配置文件,除了这几个根配置元素自身外,每个根配置元素下又提供了大量子配置 Key 值,并且根据安装的插件的不同,每个 Jenkins 实例所支持的这些子 Key 值也不尽相同。JCasC 提供的Documentation 页面(Dashboard -> Manage Jenkins -> Configuration as Code -> 页面最下面参考 -> 文档)列出了当前 Jenkins 实例中所支持的所有 Key 值信息(如果不清楚配置放到哪个配置元素下,一定要看当前Jenkins实例的Documentation 页面)。

  Jenkins 的插件成千上万,Jenkins 的配置也同样千变万化,关于更多如何编写 JCasC 配置文件,请参考官方示例

主要参考:https://github.com/jenkinsci/configuration-as-code-plugin

主要参考:https://www.jenkins-zh.cn/tutorial/management/plugin/configuration-as-code/

主要参考:https://www.jianshu.com/p/cc459cb06dd7

From:https://www.cnblogs.com/zhangmingcheng/p/18334922
本文地址: http://shuzixingkong.net/article/676
0评论
提交 加载更多评论
其他文章 Vue Hook 封装通用型表格
一、创建通用型表格的需求 实现一个通用型表格组件,具备以下功能: 动态列配置。 分页功能。 排序功能。 可扩展的行操作功能。 二、设计通用型表格组件 首先,需要设计一个基础的表格组件,它接受列配置、数据和分页信息等参数。 1. 创建 useTable Hook 在 src/hooks 目录下创建 u
在Python中使用sqlalchemy来操作数据库的几个小总结
在探索使用 FastAPI, SQLAlchemy, Pydantic,Redis, JWT 构建的项目的时候,其中数据库访问采用SQLAlchemy,并采用异步方式。数据库操作和控制器操作,采用基类继承的方式减少重复代码,提高代码复用性。在这个过程中设计接口和测试的时候,对一些问题进行跟踪解决,并
ThinkPHP6支持金仓数据库(Kingbase)解决无法使用模型查询问题
参考了很多前人的文章,最后只支持Db::query原生查询,不支持thinkphp数据模型方法,这在实际项目中是很难接受的,特分享出解决方案。 先按照流程配置如下: 1.准备工作 首先确认PHP支持金仓数据库的扩展,可以去金仓官网下载,安装配置(详细配置略过……)。 使用 php -m 命令检查,显
ThinkPHP6支持金仓数据库(Kingbase)解决无法使用模型查询问题 ThinkPHP6支持金仓数据库(Kingbase)解决无法使用模型查询问题 ThinkPHP6支持金仓数据库(Kingbase)解决无法使用模型查询问题
为团队配置Linux环境,简单高效的项目共享方案
前言 最近好久没写博客了,事情太多了,我还搞了个新的好玩的项目,等后续做得差不多了来写篇文章介绍一下。 在我们目前的AI项目中,团队需要共同使用一台GPU服务器来做模型训练和数据处理。为了让每个团队成员都能高效地使用这台服务器,我们决定设置一个多用户共享环境。这样,无论是代码开发、模型测试还是结果验
LangChain的LCEL和Runnable你搞懂了吗
LangChain的LCEL估计行业内的朋友都听过,但是LCEL里的RunnablePassthrough、RunnableParallel、RunnableBranch、RunnableLambda又是什么意思?什么场景下用?
LangChain的LCEL和Runnable你搞懂了吗 LangChain的LCEL和Runnable你搞懂了吗 LangChain的LCEL和Runnable你搞懂了吗
运行期加载时共享库路径搜索优先级实验
目录前言实验环境目录说明单独测试不配置路径默认路径ld.so.cacheRUNPATHLD_LIBRARY_PATHRPATH优先级测试附录库文件源码主程序源码makefile脚本run_nonerun_defaultrun_ld_so_cacherun_runpathrun_ld_library_
架构演化学习思考(3)
架构演化学习思考(3) 接上一篇我们继续对命令模式进行学习。 在这节内容中,我们聊一下经典的命令模式,还记得上一篇文章开头我们实现的简单的命令模式吗?来看代码,非常简单易解。 public interface ICommand { void Execute(); } public class Pla
架构演化学习思考(3)
P5665 [CSP-S2019] 划分
讲解 P5665 [CSP-S2019] 划分。 由朴素 dp 入手,先用二分优化,然后用走指针优化,之后注意到单调性,将状态数压缩,然后使用单调队列优化转移。