1. 在Jenkins中避免调度过载
过载Jenkins以同时运行多个作业可能导致资源竞争、构建速度变慢和系统性能问题。分配作业启动时间可以防止瓶颈,并确保更顺畅的执行。如何实现?
- 在Cron表达式中使用H:引入抖动(jitter),使用H来错开作业启动时间,避免同时执行多个作业。
H/3 * * * * // 每隔3分钟运行
2. 在cron表达式中正确使用时区。
验证:
Jenkins 还有一组别名,可以使使用常见的时间间隔更容易。
2. 使用环境变量来配置管道
硬编码像API密钥或部署URL这样的值会使管道的灵活性降低,并且更难维护。环境变量允许你将这些值外部化,使你的管道能够适应不同的环境(开发、测试、生产)。
如何实现?
在Jenkinsfile中定义环境变量:
environment {ENV_NAME = 'production'API_KEY = credentials('api-key-id')}
这使得你的管道在不同环境中更加动态和易于管理。
3. 设置构建保留策略以管理磁盘空间
随着Jenkins构建的积累,它们会占用大量的磁盘空间。设置保留策略可以帮助您丢弃旧的、不必要的构建,防止Jenkins变慢。
如何实施?
在每个作业的配置中,启用丢弃旧构建,并指定要保留的构建数量或构建的天数。这样可以确保Jenkins仅保留相关构建,减少存储开销。
4. 参数化构建
有时,拥有多个“参数”的构建是有用的/必要的。考虑以下使用情况:
- 您在Jenkins上设置了一个测试作业,它接受一个分发包作为参数并对其进行测试。您希望开发人员进行本地构建,并让他们提交构建以在Jenkins上执行测试。在这种情况下,您的参数是一个包含分发的zip文件。
- 您的测试套件运行时间很长,以至于在正常执行中您无法承受运行整个测试周期的费用。因此,您希望控制要执行的测试部分。
在这种情况下,您的参数可能是一个字符串令牌,指示要运行的测试套件。这些参数可作为环境变量使用。因此,例如,shell($FOO,%FOO%)或Ant(${env.FOO})可以访问这些值。
定义参数:env和jdk_version:
在pipeline中使用该参数
验证:
5. 使用共享库来简化流水线
创建共享库:要在Jenkins中创建共享库,请按照以下步骤操作:
1. 创建一个Git仓库:首先创建一个Git仓库来托管您的共享库代码。该仓库应具有Jenkins能理解的特定结构。
2. 创建‘vars’目录:在您的仓库中创建一个‘vars’目录。该目录将包含您的可重用函数。
3. 定义函数:在‘vars’目录中,将您的函数定义为Groovy文件。每个文件应包含一个函数,文件名将作为函数名。例如,如果您有一个名为‘sayHello’的函数,请创建一个名为`sayHello.groovy`的文件,其中包含该函数。
#!/usr/bin/env groovydef call(String name = 'human') {echo "Hello, ${name}."
}
4. 提交并推送:将您的更改提交到Git仓库并推送到远程仓库。在Jenkins Pipeline中使用共享库:现在您已创建了一个共享库,可以在您的Jenkins Pipeline脚本中使用它。以下是一个示例:
@Library('pipeline-library-demo')_stage('Demo') {echo 'Hello world'sayHello 'Alex'}
构建管道并检查控制台输出表明共享库正确加载并与用户输入交互。
在上面的例子中,我们使用 `@Library` 加载共享库,并导入我们想用的函数。然后,我们可以在我们的流水线脚本中调用这些函数。
现实世界示例:使用共享库进行 Kubernetes 部署假设你有一个简化 Kubernetes 部署的共享库。以下是你如何在 Jenkins 流水线中使用它的示例:
@Library('k8s-deploy-library') // Load the Kubernetes deployment library
import com.example.kubernetes.*pipeline {agent anyenvironment {DOCKER_IMAGE = 'myapp:latest'}stages {stage('Build and Push Docker Image') {steps {script {buildAndPushDockerImage(image: DOCKER_IMAGE)}}}stage('Deploy to Kubernetes') {steps {script {// Deploy to Kubernetes using the shared library functiondeployToKubernetes(deploymentName: 'myapp', image: DOCKER_IMAGE)}}}}
}
在这个例子中,我们使用共享库来构建并推送 Docker 镜像,然后将其部署到 Kubernetes 集群中。共享库抽象了这些任务的复杂性,使管道脚本更具可读性和可维护性。
6. 在流水线中执行安全扫描
将安全检查融入您的流水线可以尽早发现漏洞,确保在代码进入生产环境之前是更安全的。自动化的安全扫描将减少漏洞被引入代码库的风险。如何实施?
将安全工具,如SonarQube或OWASP依赖检查,集成到您的流水线中:
stage('SonarCloud') {environment {SCANNER_HOME = tool 'SonarQubeScanner'ORGANIZATION = "rock-github"PROJECT_NAME = "java_jenkins-pipeline-as-code"}steps {withSonarQubeEnv('SonarCloudOne') {sh '''$SCANNER_HOME/bin/sonar-scanner -Dsonar.organization=$ORGANIZATION \-Dsonar.java.binaries=build/classes/java/ \-Dsonar.projectKey=$PROJECT_NAME \-Dsonar.sources=.'''}}
}
7. 使用角色来管理用户的权限
企业有这样的需求,开发部门的员工不能访问生产环境的release pipeline。只能看到测试环境的CI pipeline,要实现这样的需求,需要用到基于角色的权限管理。
首先需要安装下面的plug-in。
创建用户,在系统管理-安全-管理用户
点击创建用户
然后创建角色,并指定权限,使用表达式来匹配jenkins-ci开头的job。
然后分配角色给用户
使用该用户登录后,发现只能看到jenkins-ci开头的pipeline。
7. 将您的流水线作为代码
建议使用该功能将Jenkinsfile存储在源代码管理(SCM)中,然后进行版本控制和测试。将您的流水线视为代码可以打开一系列新的功能和能力,如多分支、拉取请求检测以及对GitHub和BitBucket的组织扫描。使用Jenkinsfile调用流水线作为代码使用其默认名称Jenkinsfile调用流水线脚本,并开始遵循脚本头部。这有助于您的IDE、GitHub和其他工具将其识别为Groovy,并启用所需的代码高亮显示。
8. 不要使用 Maven 作业类型
Jenkins 多年来一直提供 Maven 集成插件,允许用户通过 Jenkins 的“新建项目”菜单选择“Maven 项目”来创建 Maven 项目。虽然 Maven 作业类型提供了与 Maven 构建的更高水平集成,但有时由于这种深度集成,可能会引入不必要的复杂性。
考虑使用组织文件夹、多分支管道或管道作业,而不是 Maven 作业类型。这些替代方案在管理您的 Jenkins 作业和工作流程时提供了更多灵活性和简便性。
Jenkins 项目使用组织文件夹在 ci.jenkins.io 上构建 Jenkins 核心和 Jenkins 插件。Jenkins 管道可以轻松构建 Maven 项目,并为 Maven 用户提供更好的控制。
9. 避免资源冲突
可锁定资源
这个插件允许定义可锁定的资源(例如打印机、电话、计算机等),这些资源可以被构建使用。如果一个构建需要一个已经被锁定的资源,它将等待该资源释放。
当多个作业同时运行时,特别是当它们需要对某些资源或设置服务进行独占访问时,可能会发生冲突。为了防止干扰并确保顺利执行,有效管理资源访问至关重要。对于涉及数据库或网络服务的构建,实施防止冲突的措施是至关重要的。可锁定资源插件为Jenkins作业提供了细粒度的资源锁定功能。通过使用此插件,您可以确保在任何时候只有一个作业能够访问特定资源,从而避免冲突并确保正确的同步。在可锁定资源插件的资源锁定不足以解决问题的情况下,您可以使用限制并发构建插件进一步控制并发构建。该插件允许您限制可以同时运行的构建数量,提供额外的控制并防止对共享资源的过载。
通过利用这些插件,您可以有效管理资源冲突和并发性,确保Jenkins作业的顺利和可靠执行。
下面是一个使用资源锁的pipeline
echo 'Starting'
lock('SH_Printer_ColorA3_2342') {echo 'Do something here that requires unique access to the resource'// any other build will wait until the one locking the resource leaves this block
}
echo 'Finish'
10. 报告构建结果
图表和图形为项目状态和进展提供了有价值的见解,展示了趋势和模式。自动化测试结果,包括单元测试、集成测试和端到端测试,可以揭示脆弱性或不稳定性。覆盖率报告帮助识别没有执行自动化测试的领域。编译器警告消息通常是问题的第一指示。静态分析工具在报告有风险的代码或潜在安全风险的代码方面非常有效。性能测试结果帮助识别延迟或关注区域。
下一代警告插件提供了方便访问许多报告的途径,包括:
- 编译器警告和错误(如gcc、clang、javac或golang)
- 静态分析警告和错误(如spotbugs、checkstyle、pmd、lint、cpd或Simian)
- 代码覆盖报告