Jenkins 插件之 Configuration as Code - 自動(dòng)化配置你的 Jenkins

在上一篇介紹的 如何利用 Helm 在 Kubernetes 上快速部署 Jenkins 文章中,我們講解了如何利用 Helm 官方提供的 Jenkins Chart,來快速部署一個(gè)滿足我們需求的 Jenkins 實(shí)例。

雖然新部署的 Jenkins 實(shí)例自動(dòng)為我們安裝了所有所需的插件,并配置好了初始化 Job 等工作,但在開始使用它之前,我們?nèi)孕枰瓿梢幌盗惺謩?dòng)工作,如配置 Jenkins 的 “Configure System” 頁面:

Jenkins Configure System Page

如果你是一名 Jenkins 管理員,那么你一定不會(huì)對(duì)這個(gè)頁面感到陌生,每次部署完一個(gè)新的 Jenkins 實(shí)例,在可以使用之前,我們往往都需要在該頁面作出一些相應(yīng)的配置。 該頁面除了包含 Jenkins 自身的一些基本配置信息外,同時(shí)還包括了當(dāng)前系統(tǒng)中所安裝的插件的配置信息。也就是說,當(dāng)你的 Jenkins 安裝的插件越多,該頁面的配置項(xiàng)就有可能會(huì)越多。

而除此之外,你可能還需要對(duì)它進(jìn)行一些其它的諸如配置 Jenkins 安全相關(guān)的配置項(xiàng)、創(chuàng)建 Jenkins Credentials、配置 Jenkins Job 的工作節(jié)點(diǎn)(包括物理節(jié)點(diǎn)和 Cloud 節(jié)點(diǎn))等手動(dòng)工作。

Jenkins Configuration as Code ,正是這樣一款能夠幫助我們從這些大量手動(dòng)配置的工作中解放出來的 Jenkins 插件。本文將簡單介紹什么是 Jenkins Configuration as Code 以及如何在 Helm Chart 中使用它來自動(dòng)配置我們所部署的 Jenkins 實(shí)例。

Jenkins Configuration as Code 簡介

Jenkins Configuration as Code,又名 JCasC,它允許我們將所有關(guān)于 Jenkins 的配置以 YAML 的格式寫入到配置文件中去,并通過對(duì)裝有該插件的 Jenkins 實(shí)例應(yīng)用這些配置文件,來實(shí)現(xiàn)一鍵式自動(dòng)化配置 Jenkins 的目的。

JCasC 為編寫 YAML 文件提供一系列特定的 Key 值,這些 Key 值分別對(duì)應(yīng) Jenkins 中不同的配置項(xiàng)。通過為這些 Key 值賦值的方式來達(dá)到配置 Jenkins 的目的,下面是官方提供的一個(gè)示例配置文件:

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 提供的三個(gè)根配置元素 Key 值:jenkins、toolcredentials,分別對(duì)應(yīng) Jenkins 的基本配置項(xiàng)、全局工具配置項(xiàng),以及 Jenkins Credentials 相關(guān)的配置項(xiàng)。通過為這些根 Key 值所提供的子配置項(xiàng) Key 設(shè)定適當(dāng)?shù)闹?,我們分別對(duì) Jenkins 作出了如下配置:

  • jenkins
    • systemMessage Key 設(shè)定了 Jenkins 的 "System Message" 信息。
    • securityRealm Key 設(shè)定了 LDAP 相關(guān)配置,并使其設(shè)定為 Jenkins 的認(rèn)證方式。
    • nodes Key 創(chuàng)建一個(gè)名為 static-agent 的節(jié)點(diǎn),并對(duì)其進(jìn)行了適當(dāng)對(duì)配置。
    • slaveAgentPort Key 設(shè)定了 Jenkins 主機(jī)與節(jié)點(diǎn)之間的通信端口號(hào)以及通信協(xié)議。
    • agentProtocols Key 設(shè)定 Jenkins 主機(jī)與節(jié)點(diǎn)之間對(duì)通信協(xié)議。
  • tool
    • git 為 Jenkins 的全局工具 Git 指定了默認(rèn)執(zhí)行路徑。
  • credentials
    • 創(chuàng)建一個(gè) ID 為 ssh_with_passphrase_provided 的系統(tǒng)級(jí)的 SSH credential。

JCasC 插件頁

JCasC 在 Jenkins 中提供了單獨(dú)的插件頁面,可在安裝了該插件的 Jenkins 中可通過 "Manage Jenkins" -> "Configuration as Code" 菜單來打開它:

Configuration as Code

該頁面包含了一些常用的功能選項(xiàng),如對(duì)當(dāng)前 Jenkins 實(shí)例應(yīng)用某個(gè)給定的配置文件,查看為當(dāng)前 Jenkins 實(shí)例生成的配置文件等等。

JCasC 插件提供了大量的 配置示例,這其中包含了幾乎所有關(guān)于 Jenkins 的配置以及大部分的插件配置,參考這些配置示例可幫助我們快速編寫出自己的配置文件來。

另一中編寫 YAML 配置文件的小技巧是,首先通過手動(dòng)的方式對(duì) Jenkin 做好所有配置,在通過該插件頁的 “View Configuration” 獲取 JCasC 為我們自動(dòng)生成出來的配置文件作為參考,來編寫我們自己的配置文件。

Documentation 頁面

除了上面示例中所使用到的三個(gè)根配置元素外, unclassified 是另一個(gè)非常常見的根配置元素,大部分針對(duì)于插件的配置都被包含在了該根元素下。

而除了這幾個(gè)根配置元素自身外,每個(gè)根配置元素下又提供了大量子配置 Key 值,并且根據(jù)安裝的插件的不同,每個(gè) Jenkins 實(shí)例所支持的這些子 Key 值也不盡相同。JCasC 提供的 Documentation 頁面列出了該插件在當(dāng)前 Jenkins 實(shí)例中所支持的所有 Key 值信息,該頁面可通過插件頁下方的 “Documentation” 鏈接打開:

JCasC Documentation Page

需要注意的是,該頁面的內(nèi)容是動(dòng)態(tài)創(chuàng)建出來的,根據(jù)當(dāng)前 Jenkins 中所安裝的插件的不同,所展示出來的 Key 值也可能會(huì)有稍微的不同。

在 Jenkins Helm Chart 中使用 JCasC 插件

Jenkins Helm Chart 實(shí)現(xiàn)了對(duì) JCasC 插件對(duì)集成。它允許我們將 JCasC 的配置信息存儲(chǔ)在自定義的 values 文件中,并在部署好 Jenkins 后自動(dòng)應(yīng)用這些配置信息。下面是一個(gè)包含了簡單配置的 values.yaml 文件:

master:
  JCasC:
    enabled: true
    configScripts:
      welcome-message: |
        jenkins:
          systemMessage: Welcome to our CI\CD server.  This Jenkins is configured and managed 'as code'.

在該 values 文件中首先將 JCasC.enabled 設(shè)置為 true,表示在部署的過程中自動(dòng)安裝 JCasC 插件,并使用它來配置部署的 Jenkins 實(shí)例。

注:自 Jenkins HELM Chart 1.18.0 版本之后,設(shè)定 master.JCasC.enabled=true 并不會(huì)自動(dòng)安裝該插件,仍需要我們手動(dòng)在 master.installPlugins 中明確指定要安裝該插件,如:

master:
  installPlugins:
  - configuration-as-code

JCasC.configScripts 用于保存所有 JCasC 的配置信息,我們可通過定義全局唯一的 Key 的方式,將這些配置文件分成不同的配置塊,每個(gè)配置塊下包含的就是 JCasC 原生的 YAML 格式的配置信息,如 welcome-message 配置下使用了根配置元素 jenkins 下的 systemMessage Key 來為我們部署的 Jenkins 實(shí)例設(shè)置 “Configure System” 信息。

在了解了如何在 Helm Chart 的自定義 values 文件中編寫 JCasC 配置信息后,接下來就讓我們看一下常見的 Jenkins 配置都是如何在 JCasC 中的實(shí)現(xiàn)。

Jenkins 基本配置

Jenkins 包含了許多基本配置項(xiàng),首先讓我們看一下 Jenkins 的基本配置項(xiàng):

master:
  JCasC:
    enabled: true
    configScripts:
      basic-configuration: |
        jenkins:
          systemMessage: Welcome to our CI\CD server.  This Jenkins is configured and managed 'as code'.
          markupFormatter:
             rawHtml:
               disableSyntaxHighlighting: false
        unclassified:
          location:
            adminAddress: "you@example.com"
            url: "https://ci.example.com/"
          mailer:
            replyToAddress: do-not-reply@acme.org
            smtpHost: smtp.acme.org
            smtpPort: 4441
      approval-scripts: |
         security:
           scriptApproval:
             approvedSignatures:
             - "method groovy.json.JsonSlurperClassic parseText java.lang.String"
             - "new groovy.json.JsonSlurperClassic"
      global-libraries: |
        unclassified:
          globalLibraries:
            libraries:
              - name: "awesome-lib"
                defaultVersion: "master"
                implicit: false
                allowVersionOverride: true
                includeInChangesets: true
                retriever:
                  modernSCM:
                    scm:
                      git:
                        remote: "git@github.com:gbyukg/jenkins-libirary.git"
                        credentialsId: "SSHKEY4Github"

在上面的 values.yaml 文件中,我們?yōu)?configScripts 定義了三個(gè)配置腳本:

  • basic-configuration

    • 為 Jenkins 設(shè)定 “System Message”。
    • 將 Jenkins “Global Security” 頁面的 “Markup Formatter” 值設(shè)置為 “Saft HTML”
    • 為 Jenkins 配置頁面的 “Jenkins URL” 和 “System Admin e-mail address” 設(shè)定值。
    • 設(shè)定 Jenkins 的 “E-mail Notification”。
  • approval-scripts

    • 為 Jenkins 設(shè)定可信任的 Groovy 方法。
  • global-libraries

    • 為 Jenkins 添加一個(gè)名為 awesome-lib 的 “Global Pipeline Libraries”,并用給定的 Credential 從遠(yuǎn)程 Git 倉庫的 master 分之下載該共享庫。

其中所使用的 SSHKEY4Github Credentials 為我們接下來要?jiǎng)?chuàng)建的。

再次提示:你可以在官方提供的 配置示例 中找到絕大多數(shù)你需要的配置。

創(chuàng)建 Credentials

JCasC 插件提供了專門的根配置元素 credentials,用于自動(dòng)創(chuàng)建 Jenkins Credentials:

    configScripts:
      credentials-config: |
        credentials:
          system:
            domainCredentials:
            - credentials:
              - usernamePassword:
                  description: "Password:  GitHub Token"
                  id: DevOpsToken4EEGithubAsPWD
                  username: "devops@email.com"
                  password: "DEVOPS-TOKEN-FOR-GITHUB"
                  scope: GLOBAL
              - string:
                  description: "Secret: GitHub Token"
                  id: "DevOpsToken4EEGithubAsSecret"
                  secret: "DEVOPS-TOKEN-FOR-GITHUB"
                  scope: GLOBAL
              - basicSSHUserPrivateKey:
                  description: "SSH-KEY: SSH Key for GitHub"
                  scope: GLOBAL
                  id: "SSHKEY4Github"
                  username: "devops@email.com"
                  privateKeySource:
                    directEntry:
                      privateKey: |
                        -----BEGIN OPENSSH PRIVATE KEY-----
                        ...
                        ...
                        ...
                        -----END OPENSSH PRIVATE KEY-----

在上面定義的 credentials-config 配置腳本中,分別創(chuàng)建了三個(gè)系統(tǒng)級(jí)別的 credentials:

  • Username and password 類型的 DevOpsToken4EEGithubAsPWD
  • Secret text 類型的 DevOpsToken4EEGithubAsSecret
  • SSH Username with private key 類型的 SSHKEY4Github

除了這三種類型的 Credentials 外,該插件還支持許多其它類型的 Credentials,更多細(xì)節(jié)請(qǐng)查看文檔中關(guān)于 domainCredentials key 的說明。

配置 LDAP 認(rèn)證及設(shè)置權(quán)限管理

我們通常會(huì)使用企業(yè)所提供的 LDAP 服務(wù),來代替 Jenkins 系統(tǒng)默認(rèn)的認(rèn)證方式,下面展示了如何為 Jenkins 配置 LDAP 并使用它作為 Jenkins 的認(rèn)證方式:

        ldap-configuration: |
          jenkins:
            securityRealm:
              ldap:
                configurations:
                - groupSearchBase: "ou=memberlist,ou=ibmgroups"
                  inhibitInferRootDN: false
                  managerPasswordSecret: "XXXXXXXXXXXXXXXXXX"
                  rootDN: "o=ibm.com"
                  server: "ldaps://ldapserver.com:636"
                  userSearch: "mail={0}"
                  userSearchBase: "ou=bluepages"
                disableMailAddressResolver: false
                disableRolePrefixing: true
                groupIdStrategy: "caseInsensitive"
                userIdStrategy: "caseInsensitive"
      matrix-config: |
        jenkins:
          authorizationStrategy:
            projectMatrix:
              grantedPermissions:
                - "Agent/Build:sdp-devops-admins"
                - "Agent/Configure:sdp-devops-admins"
                ... more content

將 Jenkins 的認(rèn)證方式設(shè)定為 LDAP,并設(shè)定為 “Project-based Matrix Authorization Strategy”:

Jenkins Project-based Matrix Authorization Strategy

其它常用插件設(shè)置

    configScripts:
      git-config: |
        unclassified:
          gitscm:
            globalConfigName: jenkins
            globalConfigEmail: jenkins@email.com
            createAccountBasedOnEmail: false
      github-config: |
        gitHubConfiguration:
          apiRateLimitChecker: ThrottleForNormalize
          endpoints:
          - apiUri: "https://github.example.com/api/v3"
            name: "GitHub EE"
      github-ee: |
        unclassified:
          githubpluginconfig:
            configs:
            - credentialsId: "DevOpsToken4GithubAsSecret"
              manageHooks: false
              name: "GitHub"
            - name: "GitHub EE"
              apiUrl: "https://github.example.com/api/v3/"
              credentialsId: "DevOpsToken4EEthubAsSecret"
              manageHooks: false
      slack-config: |
        unclassified:
          slackNotifier:
            botUser: false
            room: "#slack-channel"
            sendAsText: false
            teamDomain: "luke"
            tokenCredentialId: "Token4SlackSecret"
  • git-config 為 Git 插件設(shè)定了 “Global Config user.name Value” 和 “Global Config user.name Value”;
  • github-config 為 Jenkins 添加 GitHub Enterprise Servers 項(xiàng);
  • github-ee 為 Jenkins 設(shè)定了兩個(gè) GitHub Servers,一個(gè)是官方 Github,一個(gè)是 企業(yè)版Github,并分別為他們?cè)O(shè)定了對(duì)應(yīng)的 Credentials;
  • slack-config 配置 Slack 插件,可用于向 Slack 發(fā)送消息;

啟用 Sidecars 自動(dòng)加載 JCasC

默認(rèn)情況下,當(dāng)我們對(duì) values 文件中關(guān)于 JCasC 部分改動(dòng)后,并使用 helm upgrade 對(duì)部署的 Jenkins 升級(jí)時(shí),Helm Chart 會(huì)通過重新創(chuàng)建 Pod 對(duì)方式使這些更改生效,這會(huì)導(dǎo)致我們的 Jenkins 服務(wù)短暫離線。

Helm Chart 提供了另一種通過 sidecars 的方式將改動(dòng)的 JCasC 配置信息實(shí)時(shí)應(yīng)用到我們的 Jenkins 實(shí)例上,而無需重啟 Pod。

采用該種方式部署 Jenkins 時(shí),會(huì)將 JCasC.configScripts 下的每個(gè)配置塊中的配置信息分別存儲(chǔ)到與該配置塊 Key 同名的 ConfigMap 中。同時(shí)會(huì)在 Jenkin Pod 中創(chuàng)建另一個(gè)名為 jenkins-sc-config 的容器,用于監(jiān)控這些 ConfigMap 的改動(dòng)。當(dāng)我們使用 helm upgrade 升級(jí)部署時(shí),這些 ConfigMap 的變更會(huì)被 jenkins-sc-config 容器捕獲到,并將這些改動(dòng)實(shí)施應(yīng)用到 Jenkins 上。

開啟 sidecars 非常簡單,只需將 master.sidecars.configAutoReload.enabled 值設(shè)為 true 即可:

master:
  sidecars:
    configAutoReload:
      enabled: true

當(dāng)部署完成后,會(huì)看到每個(gè)配置塊都對(duì)應(yīng)地生成了一個(gè) ConfigMap:

$ kubectl -n jenkins get configmap
NAME                                         DATA   AGE
jenkins-jenkins-config-approval-scripts      1      2m45s
jenkins-jenkins-config-basic-configuration   1      2m45s
jenkins-jenkins-config-credentials-config    1      2m45s
jenkins-jenkins-config-global-libraries      1      2m45s
jenkins-jenkins-config-node-config           1      2m45s
... more output

并且此時(shí) Jenkins Pod 中包含了 2 個(gè)運(yùn)行中的容器:

$ kubectl -n jenkins get pods
NAME                       READY   STATUS    RESTARTS   AGE
jenkins-64c7cf4fc6-pjbps   2/2     Running   0          3m6s

通過這種方式部署的 Jenkins 實(shí)例,當(dāng)我們對(duì) JCasC.configScripts 下的配置信息進(jìn)行更新,并通過 helm upgrade 方式升級(jí) Jenkins 實(shí)例后,這些改動(dòng)就將會(huì)被立刻應(yīng)用到 Jenkins 實(shí)例中去了。

結(jié)束語

通過本小節(jié)的學(xué)習(xí),我們已經(jīng)了解了如何在 Jenkins Helm Chart 自定的 values 文件中,通過為 JCasC.configScripts Key 值設(shè)定 JCasC 配置項(xiàng)的方式,來幫助我們自動(dòng)配置通過該 Chart 部署的新的 Jenkins 實(shí)例,實(shí)現(xiàn)真正的零配置。

Jenkins 的插件成千上萬,Jenkins 的配置也同樣千變?nèi)f化,關(guān)于更多如何編寫 JCasC 配置文件,請(qǐng)參考官方示例。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容