共计 2933 个字符,预计需要花费 8 分钟才能阅读完成。
导读 | Jenkins 是由 Java 编写的编排引擎,在 Full GC 时会 Stop The World(STW)。在大规模构建时,STW 可能会导致 Jenkins 无法处理新的请求。 |
Jenkins 是由 Java 编写的编排引擎,在 Full GC 时会 Stop The World(STW)。在大规模构建时,STW 可能会导致 Jenkins 无法处理新的请求。
为了避免频繁的 STW,同时增大并发量,建议设置较大的堆,-Xms3g -Xmx6g -XX:MaxRAM=6g。具体数值可以根据监控值来设置,Java Full GC 之后,内存占用会陡降。
request 设置太小,可能会导致 Jenkins 运行起来之后,节点资源不足,引发驱逐,甚至压垮节点。
request 应该接近真实值,如果有足够的机器资源,应该配置亲和性,让 Jenkins 尽可能运行在单独的机器上。request >= 1.25 * JVM 最大堆内存,limit >= 2 * JVM 最大堆内存。
Jenkins 使用磁盘文件存储数据,每条流水线、每次构建都会占用一个文件目录,产生大量文件。通常流水线数量有限,但在构建历史达到 10000+ 级别时,会感受到 IO 对 Jenkins 的影响。
如果使用本地存储,推荐使用高性能的 SSD。如果是使用网络存储,需要高性能的网络支持,同时加大客户端的缓存池。
磁盘满时,Jenkins 将不能工作,在 Jenkins 后台会有错误提示。
建议对 Jenkins 的工作目录进行磁盘使用率监控,并配置告警规则。如果没有监控告警系统,那么建议直接设置一个较大的磁盘空间给 /var/jenkins_home 目录。因为有一些 Storage Class 不支持动态扩容,当磁盘满时,就只能手动拷贝了。
基于物理机、虚拟机的构建,增加了运维成本、限制了并发的数量。
使用 Kubernetes plugin 插件在 Kubernetes 上进行构建能充分利用云原生易扩展、易维护的优势,进行大规模的构建。参考: 在 Kubernetes 上动态创建 Jenkins Slave,https://www.chenshaowen.com/blog/creating-jenkins-slave-dynamically-on-kubernetes.html)。由于构建比较占用资源,为了避免对集群的影响,可以配置亲和性,将构建 Pod 集中到指定的节点执行。
通过 Jenkins 页面进行各种构建、安全等配置,不仅繁琐、不易维护,而且不能够复用。
使用 CasC 插件,允许用户将 Jenkins 的配置,通过文本的形式进行描述,还可以放置到 Git 仓库中进行版本管理。
jenkins: | |
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" |
在部署一套新的 Jenkins 环境时,会需要安装大量插件,非常影响部署速度,同时插件是否能正常下载也存在不确定性。
Custom WAR Packager 允许用户将 Jenkins、配置、插件打包成一个完整的 war 包或者镜像。这样无论是开发测试,还是线上部署,都可以很方便的部署,并且环境一致,而用户只需要写一个 yaml 文件。
bundle: | |
groupId: com.dev | |
artifactId: "jenkins" | |
description: "Jenkins Custom With Package" | |
vendor: "Jenkins Project" | |
buildSettings: | |
docker: | |
base: jenkins/jenkins:2.277.4 | |
tag: shaowenchen/jenkins:2.277.4 | |
build: true | |
war: | |
groupId: org.jenkins-ci.main | |
artifactId: jenkins-war | |
source: | |
version: 2.277.4 | |
plugins: | |
- groupId: io.jenkins | |
artifactId: configuration-as-code | |
source: | |
version: "1.47" | |
libPatches: | |
- groupId: "org.jenkins-ci.main" | |
artifactId: "remoting" | |
source: | |
git: https://github.com/jenkinsci/remoting.git | |
systemProperties: { | |
jenkins.model.Jenkins.slaveAgentPort: "50000", | |
jenkins.model.Jenkins.slaveAgentPortEnforce: "true"} | |
groovyHooks: | |
- type: "init" | |
id: "initScripts" | |
source: | |
dir: scripts | |
casc: | |
- id: "jcasc-config" | |
source: | |
dir: jenkins.yml |
在使用 Groovy 编写 Pipeline 的过程中,经常会有大量重复代码。
Jenkins 共享库提供函数级别的共享,可以在不同流水线之间复用同一套函数逻辑,对于平台建设、大规模使用场景适用。不仅能加快 Pipeline 编写,还方便维护、平滑升级。
import org.foo.Utilities | |
def utils = new Utilities(this) | |
node {utils.mvn 'clean package'} |
- https://www.jenkins.io/zh/doc/book/pipeline/shared-libraries/
- https://github.com/jenkinsci/configuration-as-code-plugin
- https://github.com/jenkinsci/custom-war-packager
- https://zhuanlan.zhihu.com/p/370241822
