10.2. 配置 Jenkins 镜像
OpenShift Container Platform 为运行 Jenkins 提供容器镜像。此镜像提供 Jenkins 服务器实例,可用于为连续测试、集成和交付设置基本流程。
该镜像基于 Red Hat Universal Base Images (UBI)。
OpenShift Container Platform 遵从 Jenkins 的 LTS 的发行版本。OpenShift Container Platform 提供一个包含 Jenkins 2.x 的镜像。
OpenShift Container Platform Jenkins 镜像在 quay.io
或 registry.redhat.io
上提供。
例如:
$ docker pull registry.redhat.io/openshift4/ose-jenkins:<v4.2.0>
要使用这些镜像,您可直接从这些 registry 访问镜像或将其推送(push)到 OpenShift Container Platform 容器镜像 registry 中。另外,您还可在容器镜像 registry 或外部位置创建一个指向镜像的 ImageStream。然后,OpenShift Container Platform 资源便可引用 ImageStream。
但为方便起见,OpenShift Container Platform 会在 openshift
命名空间中为核心 Jenkins 镜像以及针对 OpenShift Container Platform 与 Jenkins 集成提供的示例代理镜像提供 ImageStream。
10.2.1. 配置和自定义
您可采用两种方式管理 Jenkins 身份验证:
- 由 OpenShift Login 插件提供的 OpenShift Container Platform Oauth 身份验证。
- 由 Jenkins 提供的标准身份验证。
10.2.1.1. OpenShift Container Platform OAuth 身份验证
OAUTH 身份验证激活方法:配置 Jenkins UI 中 Configure Global Security 面板上的选项,或者将 Jenkins Deployment configuration 上的 OPENSHIFT_ENABLE_OAUTH
环境变量设置为非 false
。这会激活 OpenShift Container Platform Login 插件,该插件从 Pod 数据或通过与 OpenShift Container Platform API 服务器交互来检索配置信息。
有效凭证由 OpenShift Container Platform 身份提供程序控制。
Jenkins 支持浏览器和非浏览器访问。
登录时,有效用户会自动添加到 Jenkins 授权列表中,其中的 OpenShift Container Platform Role
规定了用户拥有的特定 Jenkins 权限。默认使用的 Role
是预定义的 admin
、edit
和 view
。登录插件对 Jenkins 正在其中运行的 Project
或命名空间中的那些 Role
执行自身 SAR 请求。
具有 Admin
角色的用户拥有传统 Jenkins 管理用户权限,而具有 edit
或 view
角色的用户的权限逐渐减少。
默认的 OpenShift Container Platform admin
、edit
和 view
Role
以及这些 Role
在 Jenkins 实例中分配的 Jenkins 权限均可配置。
在 OpenShift Container Platform Pod
中运行 Jenkins 时,登录插件会在 Jenkins 正在其中运行的命名空间中查找名为 openshift-jenkins-login-plugin-config
的 ConfigMap
。
如果该插件找到 ConfigMap
且可读取,您就可以定义 Role
到 Jenkins 权限的映射。具体来说:
-
登录插件会将
ConfigMap
中的键值对视为 Jenkins 权限到 OpenShift 角色的映射。 - 其中,键是 Jenkins 权限组短 ID 和 Jenkins 权限短 ID,两者之间用连字符隔开。
-
如果要向 OpenShift Container Platform
Role
中添加Overall Jenkins Administer
权限,该键应为Overall-Administer
。 - 要了解有哪些权限组和权限 ID 可用,请转至 Jenkins 控制台中的列表授权页,并在它们提供的表中查找组 ID 和个别权限。
-
键值对的值是权限应当应用于的 OpenShift Container Platform
Roles
的列表,各个角色之间用逗号隔开。 -
如果要将
Overall Jenkins Administer
权限添加到默认的admin
和edit
Role
以及您创建的新 Jenkins 角色,则Overall-Administer
键的值将为admin,edit,jenkins
。
使用 OpenShift Container Platform OAuth 时,OpenShift Container Platform Jenkins 镜像中预填充了管理特权的 admin
用户不会被授予这些特权。要授予这些权限,OpenShift Container Platform 集群管理员必须在 OpenShift Container Platform 身份提供程序中显式定义该用户,并为该用户分配 admin
角色。
最初建立用户后,可对存储的 Jenkins 用户权限进行更改。OpenShift Login 插件轮询 OpenShift Container Platform API 服务器以获取权限,并利用从 OpenShift Container Platform 检索的权限更新存储在 Jenkins 中的每个用户的权限。如果 Jenkins UI 用于为 Jenkins 用户更新权限,则权限更改将在插件下次轮询 OpenShift Container Platform 时被覆盖。
您可通过 OPENSHIFT_permissions_poll_interval
环境变量来控制轮询频率。默认轮询间隔为五分钟。
使用 Oauth 身份验证创建新的 Jenkins 服务的最简单方式是借助模板。
10.2.1.2. Jenkins 身份验证
如果镜像未使用模板直接运行,则默认使用 Jenkins 身份验证。
Jenkins 首次启动时,配置与管理员用户和密码一同创建。默认用户凭证为 admin
和 password
。在使用标准 Jenkins 身份验证时,且仅这种情况下,通过设置 JENKINS_PASSWORD
环境变量来配置默认密码。
流程
创建使用标准 Jenkins 身份验证的 Jenkins 应用程序:
$ oc new-app -e \ JENKINS_PASSWORD=<password> \ openshift4/ose-jenkins
10.2.2. Jenkins 环境变量
Jenkins 服务器可通过以下环境变量进行配置:
变量 | 定义 | 值和设置示例 |
---|---|---|
|
决定在登录 Jenkins 时,OpenShift Login 插件可否管理身份验证。要启用,请设为 |
默认: |
|
使用标准 Jenkins 身份验证时 |
默认: |
|
这些值控制 Jenkins JVM 的最大堆大小。如果设置了 默认情况下,Jenkins JVM 的最大堆大小设置为容器内存限值的 50%,且无上限。 |
|
|
这些值控制 Jenkins JVM 的初始堆大小。如果设置了 默认情况下,JVM 设置初始堆大小。 |
|
| 如果设置,请将用于调整内部 JVM 线程数的内核数指定为整数。 |
示例设置: |
| 指定应用于该容器中运行的所有 JVM 的选项。不建议覆盖该值。 |
默认: |
| 指定 Jenkins JVM 垃圾回收参数。不建议覆盖该值。 |
默认: |
| 指定适用于 Jenkins JVM 的附加选项。这些选项附加到所有其他选项中,包括上面的 Java 选项,必要时可用于覆盖其中任何一个选项。用空格分开各个附加选项;如有任意选项包含空格字符,请使用反斜杠转义。 |
示例设置: |
| 为 Jenkins 指定参数。 | |
|
指定在容器首次运行或 |
示例设置: |
| 指定 OpenShift Login 插件轮询 OpenShift Container Platform 的时间间隔(以毫秒为单位),以获取与 Jenkins 中定义的每个用户关联的权限。 |
默认: |
|
当使用 Jenkins 配置目录的 OpenShift Container Platform 持久性卷运行此镜像时,从镜像到持久性卷的配置传输仅在镜像首次启动时执行,因为在创建持久性卷声明时会分配持久性卷。如果您在初始启动后创建自定义镜像来扩展此镜像并更新自定义镜像中的配置,则不会复制该配置,除非将该环境变量设置为 |
默认: |
|
当使用 Jenkins 配置目录的 OpenShift Container Platform 持久性卷运行此镜像时,从镜像到持久性卷的插件传输仅在镜像首次启动时执行,因为在创建持久性卷声明时会分配持久性卷。如果您在初始启动后创建自定义镜像来扩展此镜像并更新自定义镜像中的插件,则不会复制该插件,除非将该环境变量设置为 |
默认: |
|
当使用 Jenkins 配置目录的 OpenShift Container Platform 持久性卷声明运行此镜像时,该环境变量允许在发生严重错误时,保留严重错误日志文件。严重错误文件保存在: |
默认: |
|
设置此值将覆盖用于 NodeJS 代理 Pod 默认配置的镜像。项目中有一个名为 |
Jenkins 服务器中的默认 NodeJS 代理镜像: |
|
设置此值将覆盖用于默认 Maven 代理 Pod 配置的镜像。项目中有一个名为 |
Jenkins 服务器中的默认 Maven 代理镜像: |
10.2.3. 向 Jenkins 提供跨项目访问权限
如果要在与您的项目不同的其他位置运行 Jenkins,则必须向 Jenkins 提供访问令牌来访问您的项目。
流程
识别对 Jenkins 必须访问的项目具有适当访问权限的服务帐户的 secret:
$ oc describe serviceaccount jenkins Name: default Labels: <none> Secrets: { jenkins-token-uyswp } { jenkins-dockercfg-xcr3d } Tokens: jenkins-token-izv1u jenkins-token-uyswp
这种情况下,secret 被命名为
jenkins-token-extensionswp
。从 secret 中检索令牌:
$ oc describe secret <secret name from above> Name: jenkins-token-uyswp Labels: <none> Annotations: kubernetes.io/service-account.name=jenkins,kubernetes.io/service-account.uid=32f5b661-2a8f-11e5-9528-3c970e3bf0b7 Type: kubernetes.io/service-account-token Data ==== ca.crt: 1066 bytes token: eyJhbGc..<content cut>....wRA
令牌参数包含 Jenkins 访问项目所需的令牌值。
10.2.4. Jenkins 跨卷挂载点
可使用挂载卷运行 Jenkins 镜像,以便为配置启用持久性存储:
-
/Var/lib/jenkins
- 这是 Jenkins 存储配置文件的数据目录,包含任务定义。
10.2.5. 通过 Source-To-Image 自定义 Jenkins 镜像
要自定义官方 OpenShift Container Platform Jenkins 镜像,可使用该镜像作为 Source-To-Image (S2I) 构建程序。
您可使用 S2I 来复制自定义 Jenkins 任务定义,添加其它插件,或使用您自己的自定义配置来替换所提供的 config.xml
文件。
要在 Jenkins 镜像中包括您的修改,必须要有采用以下目录结构的 Git 存储库:
plugins
- 该目录包含要复制到 Jenkins 中的二进制 Jenkins 插件。
plugins.txt
- 该文件使用以下语法列出要安装的插件:
pluginId:pluginVersion
configuration/jobs
- 该目录包含 Jenkins 任务定义。
configuration/config.xml
- 该文件包含您的自定义 Jenkins 配置。
configuration/
目录的内容会被复制到 /var/lib/jenkins/
目录中,以便也可以包括其他文件,如 credentials.xml
。
以下构建配置示例对 OpenShift Container Platform 中的 Jenkins 镜像进行了自定义:
apiVersion: v1 kind: BuildConfig metadata: name: custom-jenkins-build spec: source: 1 git: uri: https://github.com/custom/repository type: Git strategy: 2 sourceStrategy: from: kind: ImageStreamTag name: jenkins:2 namespace: openshift type: Source output: 3 to: kind: ImageStreamTag name: custom-jenkins:latest
10.2.6. 配置 Jenkins Kubernetes 插件
OpenShift Container Platform Jenkins 镜像包含预装的 Kubernetes 插件,支持使用 Kubernes 和 OpenShift Container Platform 在多个容器主机上动态置备 Jenkins 代理。
为了使用 Kubernetes 插件,OpenShift Container Platform 提供了适合用作 Jenkins 代理的镜像:Base
、Maven
和 Node.js
镜像。
Maven 和 Node.js 代理镜像均会在 OpenShift Container Platform Jenkins 镜像的 Kubernetes 插件配置中自动配置为 Kubernetes Pod 模板镜像。该配置包含各个镜像的标签,可应用于 Restrict where this project can be run
设置下的任何 Jenkins 任务。如果应用了标签,任务将在运行相应代理镜像的 OpenShift Container Platform Pod 下运行。
Jenkins 镜像还为 Kubernetes 插件提供附加代理镜像的自动发现和自动配置。
使用 OpenShift Container Platform Sync 插件,Jenkins 启动上的 Jenkins 镜像会在其运行的项目中或插件配置中特别列出的项目中搜索以下内容:
-
将标签
role
设置为jenkins-slave
的镜像流。 -
将注解
role
设置为jenkins-slave
的镜像流标签。 -
将标签
role
设置为jenkins-slave
的 ConfigMaps。
当该镜像找到具有适当标签的镜像流或具有适当注解的 imagestreamtag 时,它会生成对应的 Kubernetes 插件配置,以便您可以将 Jenkins 任务分配到运行镜像流提供的容器镜像的 Pod 中运行。
镜像流或 imagestreamtag 的名称和镜像引用被映射到 Kubernetes 插件 Pod 模板中的名称和镜像字段。您可利用 slave-label
键在镜像流或 imagestreamtag 对象上设置注解,从而控制 Kubernetes 插件 Pod 模板的标签字段。否则,名称将用作标签。
不要登录到 Jenkins 控制台,也不要修改 Pod 模板配置。如果您在创建 Pod 模板后这样做,且 OpenShift Sync 插件检测到与 ImageStream 或 ImageStreamTag 关联的镜像已更改,则该插件会替换 Pod 模板并覆盖这些配置更改。您无法将新配置与现有配置合并。
如有更为复杂的配置需求,请考虑 ConfigMap 方法。
找到具有适当标签的 ConfigMap 时,它会假定 ConfigMap 的键值数据有效负载中的任何值均包含与 Jenkins 和 Kubernetes 插件 Pod 模板的配置格式一致的 XML。使用 ConfigMaps 而非镜像流或 imagestreamtag 时,需要注意的一个关键区别是您可以控制 Kubernetes 插件 Pod 模板的所有参数。
jenkins-agent
的 ConfigMap 示例:
kind: ConfigMap apiVersion: v1 metadata: name: jenkins-agent labels: role: jenkins-slave data: template1: |- <org.csanchez.jenkins.plugins.kubernetes.PodTemplate> <inheritFrom></inheritFrom> <name>template1</name> <instanceCap>2147483647</instanceCap> <idleMinutes>0</idleMinutes> <label>template1</label> <serviceAccount>jenkins</serviceAccount> <nodeSelector></nodeSelector> <volumes/> <containers> <org.csanchez.jenkins.plugins.kubernetes.ContainerTemplate> <name>jnlp</name> <image>openshift/jenkins-agent-maven-35-centos7:v3.10</image> <privileged>false</privileged> <alwaysPullImage>true</alwaysPullImage> <workingDir>/tmp</workingDir> <command></command> <args>${computer.jnlpmac} ${computer.name}</args> <ttyEnabled>false</ttyEnabled> <resourceRequestCpu></resourceRequestCpu> <resourceRequestMemory></resourceRequestMemory> <resourceLimitCpu></resourceLimitCpu> <resourceLimitMemory></resourceLimitMemory> <envVars/> </org.csanchez.jenkins.plugins.kubernetes.ContainerTemplate> </containers> <envVars/> <annotations/> <imagePullSecrets/> <nodeProperties/> </org.csanchez.jenkins.plugins.kubernetes.PodTemplate>
如果您登录到 Jenkins 控制台并在 Pod 模板创建后对 Pod 模板配置进行进一步更改,且 OpenShift Sync 插件检测到 ConfigMap 已更改,则该插件会替换 Pod 模板并覆盖这些配置更改。您无法将新配置与现有配置合并。
不要登录到 Jenkins 控制台,也不要修改 Pod 模板配置。如果您在创建 Pod 模板后这样做,且 OpenShift Sync 插件检测到与 ImageStream 或 ImageStreamTag 关联的镜像已更改,则该插件会替换 Pod 模板并覆盖这些配置更改。您无法将新配置与现有配置合并。
如有更为复杂的配置需求,请考虑 ConfigMap 方法。
安装后,OpenShift Sync 插件会监控 OpenShift Container Platform 的 API 服务器,以获取对 ImageStreams
、ImageStreamTags
和 ConfigMaps
的更新,并调整 Kubernetes 插件的配置。
适用以下规则:
-
从
ConfigMap
、ImageStream
或ImageStreamTag
中删除标签或注解会导致从 Kubernetes 插件配置中删除任何现有PodTemplate
。 - 如果删除了这些对象,相应配置也会从 Kubernetes 插件中删除。
-
无论是创建适当标记或注解的
ConfigMap
、ImageStream
或ImageStreamTag
对象,还是在最初创建后添加标签,都会导致在 Kubernetes-plugin 配置中创建PodTemplate
。 -
对于按照
ConfigMap
表单排布的PodTemplate
,对PodTemplate
的ConfigMap
数据的更改将应用于 Kubernetes 插件配置中的PodTemplate
设置,并在ConfigMap
更改之间覆盖通过 Jenkins UI 对PodTemplate
所做的任何更改。
要将容器镜像用作 Jenkins 代理,该镜像必须运行 slave 代理,作为入口点。有关此方面的更多详情,请参阅官方 Jenkins 文档。
10.2.7. Jenkins 权限
在 ConfigMap 中,如果 Pod 模板 XML 的 <serviceAccount>
元素是用于生成的 Pod 的 OpenShift Container Platform 服务帐户,则服务帐户凭证将挂载到 Pod 中。权限与服务帐户关联,并控制允许从 Pod 对 OpenShift Container Platform master 执行的操作。
考虑以下场景,服务帐户用于 OpenShift Container Platform Jenkins 镜像中运行的 Kubernetes 插件启动的 Pod:
如果您使用 OpenShift Container Platform 提供的 Jenkins 示例模板,则 jenkins
服务帐户将由运行 Jenkins 的项目的 edit
角色定义,且 master Jenkins Pod 已挂载了该服务帐户。
注入 Jenkins 配置的两个默认 Maven 和 NodeJS Pod 模板也将设置为使用与 Jenkins master 相同的服务帐户。
- 由于镜像流或 imagestreamtag 具有所需的标签或注解而被 OpenShift Sync 插件自动发现的任何 Pod 模板均会被配置为使用 Jenkins master 的服务帐户作为其服务帐户。
-
对于其他方法,您可在 Jenkins 和 Kubernetes 插件中提供 Pod 模板定义,但必须明确指定要使用的服务帐户。其它方法包括 Jenkins 控制台、由 Kubernetes 插件提供的
podTemplate
管道 DSL,或标记其数据为 Pod 模板的 XML 配置的 ConfigMap。 -
如果没有为服务帐户指定值,则将使用
default
服务帐户。 - 确保所使用的任何服务帐户均具有 OpenShift Container Platform 中定义的必要权限、角色等,以操作您选择从 Pod 中操作的任何项目。
10.2.8. 从模板创建 Jenkins 服务
模板提供参数字段来定义具有预定义默认值的所有环境变量。OpenShift Container Platform 提供模板,以简化 Jenkins 服务的新建操作。在初始集群设置期间,您的集群管理员应在默认 openshift
项目中注册 Jenkins 模板。
提供的两个模板均定义了部署配置和服务。两个模板的不同之处在于存储策略,这会影响在 Pod 重启后是否保留 Jenkins 内容。
当 Pod 移到另一节点,或当对部署配置的更新触发了重新部署时,Pod 可能会重启。
-
jenkins-ephemeral
使用临时存储。Pod 重启时,所有数据均会丢失。该模板仅适用于开发或测试。 -
jenkins-persistent
使用持久性卷存储。数据不会因 Pod 重启而丢失。
要使用持久卷存储,集群管理员必须在 OpenShift Container Platform 部署中定义一个持久性卷池。
选好所需模板后,您还必须对模板进行实例化,才能使用 Jenkins。
流程
使用以下任一方法新建 Jenkins 应用程序:
持久性卷:
$ oc new-app jenkins-persistent
或
emptyDir
类型卷,其配置在 Pod 重启后不保留:$ oc new-app jenkins-ephemeral
10.2.9. 使用 Jenkins Kubernetes 插件
在以下示例中,openshift-jee-sample
BuildConfig 会致使 Jenkins Maven 代理 Pod 进行动态置备。该 Pod 会克隆一些 Java 源代码,构建一个 WAR 文件,并致使第二 BuildConfig“openshift-jee-sample-docker
”运行。第二 BuildConfig 会将新的 WAR 文件分层到一个容器镜像中。
以下示例是使用 Jenkins Kubernetes 插件的 BuildConfig。
kind: List apiVersion: v1 items: - kind: ImageStream apiVersion: v1 metadata: name: openshift-jee-sample - kind: BuildConfig apiVersion: v1 metadata: name: openshift-jee-sample-docker spec: strategy: type: Docker source: type: Docker dockerfile: |- FROM openshift/wildfly-101-centos7:latest COPY ROOT.war /wildfly/standalone/deployments/ROOT.war CMD $STI_SCRIPTS_PATH/run binary: asFile: ROOT.war output: to: kind: ImageStreamTag name: openshift-jee-sample:latest - kind: BuildConfig apiVersion: v1 metadata: name: openshift-jee-sample spec: strategy: type: JenkinsPipeline jenkinsPipelineStrategy: jenkinsfile: |- node("maven") { sh "git clone https://github.com/openshift/openshift-jee-sample.git ." sh "mvn -B -Popenshift package" sh "oc start-build -F openshift-jee-sample-docker --from-file=target/ROOT.war" } triggers: - type: ConfigChange
它还可覆盖动态创建的 Jenkins 代理 Pod 的规范。下面是对前一示例的修改,可覆盖容器内存并指定环境变量:
以下示例是使用 Jenkins Kubernetes 插件的 BuildConfig,指定内存限值和环境变量。
kind: BuildConfig apiVersion: v1 metadata: name: openshift-jee-sample spec: strategy: type: JenkinsPipeline jenkinsPipelineStrategy: jenkinsfile: |- podTemplate(label: "mypod", 1 cloud: "openshift", 2 inheritFrom: "maven", 3 containers: [ containerTemplate(name: "jnlp", 4 image: "openshift/jenkins-agent-maven-35-centos7:v3.10", 5 resourceRequestMemory: "512Mi", 6 resourceLimitMemory: "512Mi", 7 envVars: [ envVar(key: "CONTAINER_HEAP_PERCENT", value: "0.25") 8 ]) ]) { node("mypod") { 9 sh "git clone https://github.com/openshift/openshift-jee-sample.git ." sh "mvn -B -Popenshift package" sh "oc start-build -F openshift-jee-sample-docker --from-file=target/ROOT.war" } } triggers: - type: ConfigChange
- 1
- 动态定义的名为
mypod
的新 Pod 模板。新 Pod 模板名称在节点片段中引用。 - 2
cloud
值必须设置为openshift
。- 3
- 新 Pod 模板可继承现有 Pod 模板的配置。在本例中,继承自 OpenShift Container Platform 预定义的 Maven Pod 模板。
- 4
- 本例覆盖了预先存在容器中的值,且必须按名称指定。OpenShift Container Platform 附带的所有 Jenkins 代理镜像均使用容器名称
jnlp
。 - 5
- 再次指定容器镜像名称。这是个已知问题。
- 6
- 指定了
512 Mi
的内存请求。 - 7
- 指定了
512 Mi
的内存限值。 - 8
CONTAINER_HEAP_PERCENT
环境变量,其值指定为0.25
。- 9
- 节点片段引用所定义的 Pod 模板的名称。
构建完成后会默认删除 pod。该行为可通过插件或在 Jenkinsfile 管道中修改。
10.2.10. Jenkins 内存要求
使用所提供的 Jenkins Ephemeral 或 Jenkins Persistent 模板部署时,默认内存限值为 1 Gi
。
默认情况下,Jenkins 容器中运行的所有其他进程使用的内存总量不超过 512 MiB
。如果这些进程需要更多内存,容器将停止。因此,我们强烈建议管道尽可能在代理容器中运行外部命令。
如果 Project
配额允许,请参阅 Jenkins 文档,了解 Jenkins master 应具有多少内存的建议。这些建议禁止为 Jenkins master 分配更多内存。
建议在由 Jenkins Kubernetes 插件创建的代理容器上指定内存请求和限值。管理员用户可通过 Jenkins 配置基于每个代理镜像设置默认值。内存请求和限值参数也可基于每个容器覆盖。
在实例化 Jenkins Ephemeral 或 Jenkins Persistent 模板时,您可通过覆盖 MEMORY_LIMIT
参数来增加 Jenkins 的可用内存量。
10.2.11. 其它资源
- 有关 Red Hat Universal Base Images (UBI) 的更多信息,请参阅 基础镜像选项。