在上一篇介绍的 [如何利用 Helm 在 Kubernetes 上疾速部署 Jenkins](https://segmentfault.com/a/11…
) 文章中,咱们解说了如何利用 Helm 官网提供的 Jenkins Chart,来疾速部署一个满足咱们需要的 Jenkins 实例。
尽管新部署的 Jenkins 实例主动为咱们装置了所有所需的插件,并配置好了初始化 Job 等工作,但在开始应用它之前,咱们仍须要实现一系列手动工作,如配置 Jenkins 的“Configure System”页面:
如果你是一名 Jenkins 管理员,那么你肯定不会对这个页面感到生疏,每次部署完一个新的 Jenkins 实例,在能够应用之前,咱们往往都须要在该页面作出一些相应的配置。该页面除了蕴含 Jenkins 本身的一些根本配置信息外,同时还包含了以后零碎中所装置的插件的配置信息。也就是说,当你的 Jenkins 装置的插件越多,该页面的配置项就有可能会越多。
而除此之外,你可能还须要对它进行一些其它的诸如配置 Jenkins 平安相干的配置项、创立 Jenkins Credentials、配置 Jenkins Job 的工作节点(包含物理节点和 Cloud 节点)等手动工作。
而 Jenkins Configuration as Code,正是这样一款可能帮忙咱们从这些大量手动配置的工作中解放出来的 Jenkins 插件。本文将简略介绍什么是 Jenkins Configuration as Code 以及如何在 Helm Chart 中应用它来主动配置咱们所部署的 Jenkins 实例。
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。
JCasC 插件页
JCasC 在 Jenkins 中提供了独自的插件页面,可在装置了该插件的 Jenkins 中可通过 “Manage Jenkins” -> “Configuration as Code” 菜单来关上它:
该页面蕴含了一些罕用的性能选项,如对以后 Jenkins 实例利用某个给定的配置文件,查看为以后 Jenkins 实例生成的配置文件等等。
JCasC 插件提供了大量的配置示例(https://github.com/jenkinsci/…),这其中蕴含了简直所有对于 Jenkins 的配置以及大部分的插件配置,参考这些配置示例可帮忙咱们疾速编写出本人的配置文件来。
另一种编写 YAML 配置文件的小技巧是,首先通过手动的形式对 Jenkin 做好所有配置,在通过该插件页的“View Configuration”获取 JCasC 为咱们主动生成进去的配置文件作为参考,来编写咱们本人的配置文件。
Documentation 页面
除了下面示例中所应用到的三个根配置元素外,unclassified
是另一个十分常见的根配置元素,大部分针对于插件的配置都被蕴含在了该根元素下。
而除了这几个根配置元素本身外,每个根配置元素下又提供了大量子配置 Key 值,并且依据装置的插件的不同,每个 Jenkins 实例所反对的这些子 Key 值也不尽相同。JCasC 提供的 Documentation 页面列出了该插件在以后 Jenkins 实例中所反对的所有 Key 值信息,该页面可通过插件页下方的“Documentation”链接关上:
须要留神的是,该页面的内容是动态创建进去的,依据以后 Jenkins 中所装置的插件的不同,所展现进去的 Key 值也可能会有略微的不同。
在 Jenkins Helm Chart 中应用 JCasC 插件
Jenkins Helm Chart 实现了对 JCasC 插件对集成。它容许咱们将 JCasC 的配置信息存储在自定义的 values 文件中,并在部署好 Jenkins 后主动利用这些配置信息。上面是一个蕴含了简略配置的 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
设置为 true,示意在部署的过程中主动装置 JCasC 插件,并应用它来配置部署的 Jenkins 实例。
JCasC.configScripts
用于保留所有 JCasC 的配置信息,咱们可通过定义全局惟一的 Key 的形式,将这些配置文件分成不同的配置块,每个配置块下蕴含的就是 JCasC 原生的 YAML 格局的配置信息,如 welcome-message 配置下应用了根配置元素 jenkins
下的 systemMessage
Key 来为咱们部署的 Jenkins 实例设置“Configure System”信息。
在理解了如何在 Helm Chart 的自定义 values 文件中编写 JCasC 配置信息后,接下来就让咱们看一下常见的 Jenkins 配置都是如何在 JCasC 中的实现。
Jenkins 根本配置
Jenkins 蕴含了许多根本配置项,首先让咱们看一下 Jenkins 的根本配置项:
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 文件中,咱们为 configScripts 定义了三个配置脚本:
basic-configuration:
- 为 Jenkins 设定“System Message”。
- 将 Jenkins“Global Security”页面的“Markup Formatter”值设置为“Saft HTML”
- 为 Jenkins 配置页面的“Jenkins URL”和“System Admin e-mail address”设定值。
- 设定 Jenkins 的“E-mail Notification”。
approval-scripts
- 为 Jenkins 设定可信赖的 Groovy 办法。
global-libraries
- 为 Jenkins 增加一个名为
awesome-lib
的“Global Pipeline Libraries”,并用给定的 Credential 从近程 Git 仓库的 master 分之下载该共享库。
其中所应用的 SSHKEY4Github
Credentials 为咱们接下来要创立的。
再次提醒:你能够在官网提供的 配置示例 中找到绝大多数你须要的配置。
创立 Credentials
JCasC 插件提供了专门的根配置元素 credentials
,用于主动创立 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
配置脚本中,别离创立了三个零碎级别的 credentials:
Username and password
类型的 DevOpsToken4EEGithubAsPWDSecret text
类型的 DevOpsToken4EEGithubAsSecretSSH Username with private key
类型的 SSHKEY4Github
除了这三种类型的 Credentials 外,该插件还反对许多其它类型的 Credentials,更多细节请查看文档中对于 domainCredentials
key 的阐明。
配置 LDAP 认证及设置权限治理
咱们通常会应用企业所提供的 LDAP 服务,来代替 Jenkins 零碎默认的认证形式,上面展现了如何为 Jenkins 配置 LDAP 并应用它作为 Jenkins 的认证形式:
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 的认证形式设定为 LDAP,并设定为“Project-based Matrix Authorization Strategy”:
其它罕用插件设置
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 插件设定了“Global Config user.name Value”和“Global Config user.name Value”;github-config
为 Jenkins 增加 GitHub Enterprise Servers 项;github-ee
为 Jenkins 设定了两个 GitHub Servers,一个是官网 Github,一个是 企业版 Github,并别离为他们设定了对应的 Credentials;slack-config
配置 Slack 插件,可用于向 Slack 发送音讯;
启用 Sidecars 主动加载 JCasC
默认状况下,当咱们对 values 文件中对于 JCasC 局部改变后,并应用 helm upgrade
对部署的 Jenkins 降级时,Helm Chart 会通过从新创立 Pod 对形式使这些更改失效,这会导致咱们的 Jenkins 服务短暂离线。
Helm Chart 提供了另一种通过 sidecars 的形式将改变的 JCasC 配置信息实时利用到咱们的 Jenkins 实例上,而无需重启 Pod。
采纳该种形式部署 Jenkins 时,会将 JCasC.configScripts
下的每个配置块中的配置信息别离存储到与该配置块 Key 同名的 ConfigMap 中。同时会在 Jenkin Pod 中创立另一个名为 jenkins-sc-config
的容器,用于监控这些 ConfigMap 的改变。当咱们应用 helm upgrade
降级部署时,这些 ConfigMap 的变更会被 jenkins-sc-config
容器捕捉到,并将这些改变施行利用到 Jenkins 上。
开启 sidecars 非常简单,只需将 master.sidecars.configAutoReload.enabled
值设为 true 即可:
master:
sidecars:
configAutoReload:
enabled: true
当部署实现后,会看到每个配置块都对应地生成了一个 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
并且此时 Jenkins Pod 中蕴含了 2 个运行中的容器:
$ kubectl -n jenkins get pods
NAME READY STATUS RESTARTS AGE
jenkins-64c7cf4fc6-pjbps 2/2 Running 0 3m6s
通过这种形式部署的 Jenkins 实例,当咱们对 JCasC.configScripts
下的配置信息进行更新,并通过 helm upgrade
形式降级 Jenkins 实例后,这些改变就将会被立即利用到 Jenkins 实例中去了。
结束语
通过本大节的学习,咱们曾经理解了如何在 Jenkins Helm Chart 自定的 values 文件中,通过为 JCasC.configScripts
Key 值设定 JCasC 配置项的形式,来帮忙咱们主动配置通过该 Chart 部署的新的 Jenkins 实例,实现真正的零配置。
Jenkins 的插件成千上万,Jenkins 的配置也同样变幻无穷,对于更多如何编写 JCasC 配置文件,请参考官网示例 https://github.com/jenkinsci/…。
起源:DevSecOps SIG
作者:张泽亮
申明:文章取得作者受权在 IDCF 社区公众号(devopshub)转发。优质内容共享给思否平台的技术伙伴,如原作者有其余思考请分割小编删除,致谢。
7 月每周四晚 8 点,【冬哥有话说】研发效力工具专场,公众号留言“效力”可获取地址
- 7 月 8 日,LEANSOFT- 周文洋《微软 DevOps 工具链的 “ 爱恨情仇 ”(Azure DevOps)》
- 7 月 15 日,阿里云智能高级产品专家 - 陈逊《复杂型研发合作模式下的效力晋升实际》
- 7 月 22 日,极狐 (GitLab) 解决⽅案架构师 - 张扬分享《基础设施即代码的⾃动化测试摸索》
- 7 月 29 日,字节跳动产品经理 - 胡贤彬分享《自动化测试,如何做到「攻防兼备」?》
- 8 月 5 日,声网 AgoraCICD System 负责人 - 王志分享《从 0 到 1 打造软件交付质量保证的闭环》