Rocky Linux 9系统下Jenkins Pipeline安装配置全攻略从环境准备到流水线构建一步到位
引言
Jenkins作为目前最流行的开源持续集成/持续部署(CI/CD)工具之一,其Pipeline功能为软件开发流程提供了强大的自动化能力。Rocky Linux作为CentOS的替代品,因其稳定性和兼容性受到越来越多企业的青睐。本文将详细介绍在Rocky Linux 9系统上安装配置Jenkins Pipeline的全过程,从环境准备到流水线构建,帮助读者一步到位地搭建完整的CI/CD环境。
1. 环境准备
1.1 系统要求
在开始安装Jenkins之前,确保你的Rocky Linux 9系统满足以下基本要求:
- 至少2GB RAM(推荐4GB以上)
- 至少10GB可用硬盘空间
- 稳定的网络连接
- 具有sudo权限的用户账户
1.2 系统更新
首先,确保系统是最新的,执行以下命令更新系统:
sudo dnf update -y
1.3 安装Java环境
Jenkins是基于Java开发的,需要先安装Java环境。Rocky Linux 9默认提供OpenJDK 11和OpenJDK 17,这里我们选择安装OpenJDK 11,因为它与Jenkins的兼容性更好:
# 安装OpenJDK 11 sudo dnf install java-11-openjdk-devel -y # 验证Java安装 java -version
如果安装成功,应该会显示类似以下的输出:
openjdk version "11.0.18" 2023-01-17 OpenJDK Runtime Environment (Red_Hat-11.0.18.0.10-2.el9_0) OpenJDK 64-Bit Server VM (Red_Hat-11.0.18.0.10-2.el9_0, mixed mode, sharing)
1.4 设置Java环境变量
为了确保系统能够正确识别Java环境,我们需要设置JAVA_HOME环境变量:
# 找出Java安装路径 readlink -f $(which java) # 输出应该类似于:/usr/lib/jvm/java-11-openjdk-11.0.18.0.10-2.el9_0.x86_64/bin/java # 我们需要去掉/bin/java部分,得到JAVA_HOME路径 # 编辑/etc/profile文件 sudo vi /etc/profile # 在文件末尾添加以下内容 export JAVA_HOME=/usr/lib/jvm/java-11-openjdk-11.0.18.0.10-2.el9_0.x86_64 export PATH=$JAVA_HOME/bin:$PATH # 使环境变量生效 source /etc/profile # 验证JAVA_HOME echo $JAVA_HOME
2. Jenkins安装
2.1 添加Jenkins仓库
Jenkins不在Rocky Linux的默认仓库中,我们需要手动添加Jenkins官方仓库:
# 下载Jenkins仓库文件 sudo wget -O /etc/yum.repos.d/jenkins.repo https://pkg.jenkins.io/redhat-stable/jenkins.repo # 导入Jenkins GPG密钥 sudo rpm --import https://pkg.jenkins.io/redhat-stable/jenkins.io.key
2.2 安装Jenkins
现在我们可以安装Jenkins了:
# 安装Jenkins sudo dnf install jenkins -y
2.3 启动Jenkins服务
安装完成后,启动Jenkins服务并设置开机自启:
# 启动Jenkins服务 sudo systemctl start jenkins # 设置Jenkins开机自启 sudo systemctl enable jenkins # 检查Jenkins服务状态 sudo systemctl status jenkins
如果Jenkins服务正常运行,你应该会看到类似以下的输出:
● jenkins.service - Jenkins Continuous Integration Server Loaded: loaded (/usr/lib/systemd/system/jenkins.service; enabled; vendor preset: disabled) Active: active (running) since Tue 2023-05-30 10:30:45 CST; 15s ago Main PID: 12345 (java) Tasks: 45 (limit: 2293) Memory: 1.1G CGroup: /system.slice/jenkins.service └─12345 /usr/bin/java -Djava.awt.headless=true -jar /usr/share/java/jenkins.war --webroot=/var/cache/jenkins/war --httpPort=8080
3. Jenkins基本配置
3.1 防火墙配置
如果你的系统启用了防火墙,需要开放Jenkins的默认端口8080:
# 开放8080端口 sudo firewall-cmd --permanent --add-port=8080/tcp # 重新加载防火墙配置 sudo firewall-cmd --reload
3.2 初始设置
现在,我们可以通过浏览器访问Jenkins了。打开浏览器,输入以下地址:
http://your-server-ip:8080
你将看到Jenkins的解锁页面。Jenkins在首次启动时会生成一个初始管理员密码,位置在/var/lib/jenkins/secrets/initialAdminPassword
。我们可以通过以下命令获取该密码:
sudo cat /var/lib/jenkins/secrets/initialAdminPassword
复制该密码并粘贴到浏览器中的”Administrator password”字段,然后点击”Continue”。
3.3 插件安装
接下来,Jenkins会询问你如何安装插件。你可以选择”Install suggested plugins”安装推荐的插件,或者选择”Select plugins to install”自定义安装。为了快速开始,我们选择”Install suggested plugins”。
安装过程可能需要几分钟,请耐心等待。
3.4 创建管理员用户
插件安装完成后,Jenkins会要求你创建第一个管理员用户。填写用户名、密码、全名和电子邮件地址,然后点击”Save and Continue”。
3.5 实例配置
最后,Jenkins会要求你配置实例URL。通常情况下,默认设置已经正确,直接点击”Save and Finish”即可。
完成以上步骤后,你将看到Jenkins的主页面,表示Jenkins已经成功安装并配置完成。
4. Pipeline基础概念
在开始创建Pipeline之前,我们需要了解一些基本概念:
4.1 什么是Pipeline
Jenkins Pipeline(或简称为”Pipeline”)是一套插件,支持实现和集成持续交付流水线到Jenkins。Pipeline提供了一组可扩展的工具,用于通过Pipeline DSL(领域特定语言)对简单到复杂的交付流水线进行建模。
4.2 Pipeline语法
Pipeline支持两种语法:
- 脚本式流水线(Scripted Pipeline):这是一种更传统、更灵活的语法,使用Groovy语言编写。
- 声明式流水线(Declarative Pipeline):这是一种更结构化、更简单的语法,提供了预定义的结构和更严格的语法检查。
对于初学者,推荐使用声明式流水线,因为它更易于理解和维护。
4.3 Pipeline核心概念
- Stage(阶段):一个Pipeline被划分为多个阶段,每个阶段代表一个逻辑步骤,如”构建”、”测试”和”部署”。
- Step(步骤):一个阶段包含多个步骤,每个步骤是一个单一的任务,如”编译代码”、”运行测试”等。
- Node(节点):一个节点是Jenkins环境的一部分,能够执行Pipeline。
- Agent(代理):指定整个Pipeline或特定阶段在Jenkins环境中执行的位置,如any、none、label、docker等。
5. 创建第一个Pipeline
5.1 创建Pipeline项目
- 在Jenkins主页面,点击”新建任务”。
- 输入任务名称,如”my-first-pipeline”。
- 选择”流水线”(Pipeline)类型,然后点击”确定”。
5.2 编写简单的Pipeline
在项目配置页面,向下滚动到”流水线”部分。在”定义”下拉菜单中选择”Pipeline script”,然后在下面的文本框中输入以下代码:
pipeline { agent any stages { stage('Hello') { steps { echo 'Hello World!' } } stage('Build') { steps { echo 'Building...' } } stage('Test') { steps { echo 'Testing...' } } stage('Deploy') { steps { echo 'Deploying...' } } } }
这是一个简单的声明式Pipeline,包含四个阶段:Hello、Build、Test和Deploy。每个阶段只输出一条简单的消息。
5.3 运行Pipeline
点击”保存”按钮保存配置,然后点击”立即构建”来运行Pipeline。你将看到Pipeline的执行过程,每个阶段都会依次执行。
5.4 查看构建结果
构建完成后,你可以点击构建历史中的构建号,然后点击”控制台输出”查看详细的执行日志。你应该能看到类似以下的输出:
Started by user admin Running in Durability level: MAX_SURVIVABILITY [Pipeline] Start of Pipeline [Pipeline] node Running on Jenkins in /var/lib/jenkins/workspace/my-first-pipeline [Pipeline] { [Pipeline] stage [Pipeline] { (Hello) [Pipeline] echo Hello World! [Pipeline] } [Pipeline] // stage [Pipeline] stage [Pipeline] { (Build) [Pipeline] echo Building... [Pipeline] } [Pipeline] // stage [Pipeline] stage [Pipeline] { (Test) [Pipeline] echo Testing... [Pipeline] } [Pipeline] // stage [Pipeline] stage [Pipeline] { (Deploy) [Pipeline] echo Deploying... [Pipeline] } [Pipeline] // stage [Pipeline] } [Pipeline] // node [Pipeline] End of Pipeline Finished: SUCCESS
6. 高级Pipeline配置
6.1 使用SCM管理Pipeline
在实际项目中,我们通常会将Pipeline代码存储在版本控制系统(如Git)中,而不是直接在Jenkins界面中编写。这样做的好处是可以对Pipeline进行版本控制,并且可以与项目代码一起管理。
下面是一个使用Git仓库中的Jenkinsfile的示例:
- 首先,在项目配置页面的”流水线”部分,将”定义”改为”Pipeline script from SCM”。
- 在”SCM”中选择”Git”。
- 输入你的Git仓库URL和凭证(如果需要)。
- 在”脚本路径”中输入”Jenkinsfile”(这是默认的Jenkinsfile文件名)。
然后,在你的Git仓库根目录创建一个名为Jenkinsfile的文件,内容如下:
pipeline { agent any stages { stage('Checkout') { steps { git 'https://github.com/yourusername/yourrepository.git' } } stage('Build') { steps { // 根据你的项目类型,添加适当的构建命令 sh 'mvn clean package' } } stage('Test') { steps { // 添加测试命令 sh 'mvn test' } } stage('Deploy') { steps { // 添加部署命令 echo 'Deploying to production...' } } } }
6.2 参数化构建
有时候,我们希望在构建Pipeline时能够传入一些参数,例如选择要部署的环境、指定构建版本等。Jenkins支持参数化构建,我们可以为Pipeline添加参数。
在项目配置页面,点击”General”选项卡,然后勾选”参数化构建过程”。点击”添加参数”按钮,你可以选择不同类型的参数,如字符串参数、选择参数、布尔参数等。
例如,我们可以添加一个选择参数,用于选择部署环境:
- 名称:DEPLOY_ENV
- 描述:选择要部署的环境
- 选项:
- dev
- staging
- prod
然后在Pipeline中,我们可以通过params.DEPLOY_ENV
来访问这个参数:
pipeline { agent any parameters { choice(name: 'DEPLOY_ENV', choices: ['dev', 'staging', 'prod'], description: '选择要部署的环境') } stages { stage('Build') { steps { echo "Building for ${params.DEPLOY_ENV} environment..." // 添加构建命令 } } stage('Test') { steps { echo "Testing in ${params.DEPLOY_ENV} environment..." // 添加测试命令 } } stage('Deploy') { steps { echo "Deploying to ${params.DEPLOY_ENV} environment..." // 根据环境执行不同的部署命令 script { if (params.DEPLOY_ENV == 'dev') { sh 'deploy-to-dev.sh' } else if (params.DEPLOY_ENV == 'staging') { sh 'deploy-to-staging.sh' } else if (params.DEPLOY_ENV == 'prod') { sh 'deploy-to-prod.sh' } } } } } }
6.3 使用Docker作为Agent
Jenkins Pipeline支持使用Docker容器作为执行环境,这样可以确保构建环境的一致性,并且可以轻松地使用不同的工具和依赖。
下面是一个使用Docker作为Agent的示例:
pipeline { agent { docker { image 'maven:3.8.4-openjdk-11' args '-v $HOME/.m2:/root/.m2' } } stages { stage('Build') { steps { sh 'mvn -B clean package' } } stage('Test') { steps { sh 'mvn test' } } } }
在这个示例中,我们使用maven:3.8.4-openjdk-11
Docker镜像作为执行环境,并将主机的.m2
目录挂载到容器中,以缓存Maven依赖。
6.4 并行执行阶段
有时候,我们希望某些阶段能够并行执行,以加快构建速度。Jenkins Pipeline支持并行执行阶段。
下面是一个并行执行测试阶段的示例:
pipeline { agent any stages { stage('Build') { steps { echo 'Building...' // 添加构建命令 } } stage('Test') { parallel { stage('Unit Tests') { steps { echo 'Running unit tests...' // 添加单元测试命令 } } stage('Integration Tests') { steps { echo 'Running integration tests...' // 添加集成测试命令 } } stage('Performance Tests') { steps { echo 'Running performance tests...' // 添加性能测试命令 } } } } stage('Deploy') { steps { echo 'Deploying...' // 添加部署命令 } } } }
在这个示例中,Test阶段包含三个并行执行的子阶段:Unit Tests、Integration Tests和Performance Tests。
7. 实战案例:构建一个Java Web应用的CI/CD流水线
让我们通过一个完整的实战案例,来演示如何使用Jenkins Pipeline构建一个Java Web应用的CI/CD流水线。
7.1 项目结构
假设我们有一个简单的Spring Boot Web应用,项目结构如下:
my-web-app/ ├── src/ │ ├── main/ │ │ ├── java/ │ │ │ └── com/ │ │ │ └── example/ │ │ │ └── MyWebAppApplication.java │ │ └── resources/ │ │ └── application.properties │ └── test/ │ └── java/ │ └── com/ │ └── example/ │ └── MyWebAppApplicationTests.java ├── pom.xml └── Jenkinsfile
7.2 Jenkinsfile内容
在项目根目录下创建Jenkinsfile,内容如下:
pipeline { agent any environment { // 定义环境变量 APP_NAME = 'my-web-app' DEPLOY_DEV_SERVER = 'dev-server.example.com' DEPLOY_STAGING_SERVER = 'staging-server.example.com' DEPLOY_PROD_SERVER = 'prod-server.example.com' } parameters { // 定义参数 choice(name: 'DEPLOY_ENV', choices: ['dev', 'staging', 'prod'], description: '选择要部署的环境') booleanParam(name: 'RUN_TESTS', defaultValue: true, description: '是否运行测试') } stages { stage('Checkout') { steps { // 检出代码 git 'https://github.com/yourusername/my-web-app.git' } } stage('Build') { steps { // 构建应用 sh 'mvn clean package -DskipTests' } post { success { // 构建成功后,保存构建产物 archiveArtifacts artifacts: 'target/*.jar', fingerprint: true } } } stage('Test') { when { // 只有当RUN_TESTS参数为true时才运行测试 expression { params.RUN_TESTS == true } } steps { // 运行测试 sh 'mvn test' } post { always { // 始终发布测试报告 publishTestResults testResultsPattern: '**/target/surefire-reports/*.xml' publishHTML([ allowMissing: false, alwaysLinkToLastBuild: true, keepAll: true, reportDir: 'target/site/jacoco', reportFiles: 'index.html', reportName: 'Coverage Report' ]) } } } stage('Deploy to Dev') { when { // 只有当选择部署到dev环境时才执行此阶段 expression { params.DEPLOY_ENV == 'dev' } } steps { // 部署到开发环境 sh "scp target/${APP_NAME}-*.jar user@${DEPLOY_DEV_SERVER}:/opt/apps/" sh "ssh user@${DEPLOY_DEV_SERVER} 'sudo systemctl restart ${APP_NAME}'" } } stage('Deploy to Staging') { when { // 只有当选择部署到staging环境时才执行此阶段 expression { params.DEPLOY_ENV == 'staging' } } steps { // 部署到测试环境 sh "scp target/${APP_NAME}-*.jar user@${DEPLOY_STAGING_SERVER}:/opt/apps/" sh "ssh user@${DEPLOY_STAGING_SERVER} 'sudo systemctl restart ${APP_NAME}'" } } stage('Deploy to Prod') { when { // 只有当选择部署到prod环境时才执行此阶段 expression { params.DEPLOY_ENV == 'prod' } } steps { // 部署到生产环境 input message: '确认部署到生产环境?', ok: '部署' sh "scp target/${APP_NAME}-*.jar user@${DEPLOY_PROD_SERVER}:/opt/apps/" sh "ssh user@${DEPLOY_PROD_SERVER} 'sudo systemctl restart ${APP_NAME}'" } } } post { success { // 构建成功后发送通知 emailext ( subject: "构建成功: ${env.JOB_NAME} - ${env.BUILD_NUMBER}", body: """ 构建成功: ${env.JOB_NAME} - ${env.BUILD_NUMBER} 构建URL: ${env.BUILD_URL} 部署环境: ${params.DEPLOY_ENV} """, to: "${env.CHANGE_AUTHOR_EMAIL}, dev-team@example.com" ) } failure { // 构建失败后发送通知 emailext ( subject: "构建失败: ${env.JOB_NAME} - ${env.BUILD_NUMBER}", body: """ 构建失败: ${env.JOB_NAME} - ${env.BUILD_NUMBER} 构建URL: ${env.BUILD_URL} 请检查控制台输出以获取更多信息。 """, to: "${env.CHANGE_AUTHOR_EMAIL}, dev-team@example.com" ) } } }
7.3 配置Jenkins项目
- 在Jenkins中创建一个新的Pipeline项目,命名为”my-web-app-pipeline”。
- 在”流水线”部分,将”定义”设置为”Pipeline script from SCM”。
- 在”SCM”中选择”Git”。
- 输入你的Git仓库URL和凭证(如果需要)。
- 在”脚本路径”中输入”Jenkinsfile”。
- 点击”保存”。
7.4 运行Pipeline
现在,你可以点击”立即构建”来运行Pipeline。在构建页面,你可以选择要部署的环境,以及是否运行测试。
Pipeline将按照以下顺序执行:
- 检出代码
- 构建应用
- 运行测试(如果选择了RUN_TESTS)
- 根据选择的环境部署应用
如果选择部署到生产环境,Pipeline会在部署前等待人工确认。
7.5 查看构建结果
构建完成后,你可以:
- 查看控制台输出,了解构建过程的详细信息。
- 在”构建产物”部分下载构建的JAR文件。
- 在”测试结果”部分查看测试报告。
- 在”覆盖率报告”部分查看代码覆盖率报告。
8. 常见问题及解决方案
8.1 Jenkins启动失败
问题:Jenkins服务无法启动,查看日志显示”Starting Jenkins Exception in thread “main” java.lang.UnsupportedClassVersionError”。
解决方案:这通常是由于Java版本不兼容导致的。确保你安装了Jenkins支持的Java版本。Jenkins 2.357及更高版本需要Java 11或更高版本。你可以通过以下命令检查Java版本:
java -version
如果Java版本不符合要求,请安装合适的Java版本并更新JAVA_HOME环境变量。
8.2 权限问题
问题:Pipeline执行时出现权限错误,如”Permission denied”。
解决方案:这通常是由于Jenkins用户没有足够的权限执行某些操作。你可以尝试以下解决方案:
- 确保Jenkins用户有执行相关命令的权限。
- 如果需要sudo权限,可以修改sudoers文件,为Jenkins用户添加免密码sudo权限:
# 编辑sudoers文件 sudo visudo # 添加以下内容,允许jenkins用户免密码执行所有命令 jenkins ALL=(ALL) NOPASSWD: ALL
- 如果是文件权限问题,确保Jenkins用户有读写相关文件的权限:
# 修改文件所有者为jenkins用户 sudo chown -R jenkins:jenkins /path/to/file
8.3 插件安装失败
问题:在安装插件时出现错误,如”Failed to download plugin”。
解决方案:这通常是由于网络问题或Jenkins插件服务器不可用导致的。你可以尝试以下解决方案:
- 检查网络连接是否正常。
- 尝试使用代理服务器(如果需要)。
- 手动下载插件并安装:
# 下载插件 wget https://updates.jenkins.io/download/plugins/plugin-name/plugin-version.hpi # 将插件复制到Jenkins插件目录 sudo cp plugin-version.hpi /var/lib/jenkins/plugins/ # 重启Jenkins服务 sudo systemctl restart jenkins
8.4 Pipeline语法错误
问题:Pipeline执行时出现语法错误,如”WorkflowScript: 1: expecting ‘}’, found “ @ line 1, column 1”。
解决方案:这通常是由于Pipeline脚本语法错误导致的。你可以尝试以下解决方案:
- 使用Jenkins提供的Pipeline Linter工具检查语法。在项目配置页面的”流水线”部分,点击”流水线语法”链接,然后使用”流水线语法”工具验证你的脚本。
- 确保你的Pipeline脚本符合声明式流水线的语法要求。声明式流水线必须以
pipeline
开头,并且包含agent
、stages
等必需部分。 - 检查括号、引号等是否匹配。
8.5 构建超时
问题:Pipeline执行时间过长,导致构建超时。
解决方案:你可以尝试以下解决方案:
- 增加构建超时时间。在Pipeline脚本中添加
options
指令:
pipeline { agent any options { timeout(time: 1, unit: 'HOURS') // 设置超时时间为1小时 } stages { // ... } }
- 优化构建过程,减少不必要的步骤。
- 使用并行执行阶段,加快构建速度。
9. 总结
本文详细介绍了在Rocky Linux 9系统上安装配置Jenkins Pipeline的全过程,从环境准备到流水线构建,涵盖了以下内容:
- 环境准备:包括系统要求、系统更新、Java环境安装等。
- Jenkins安装:包括添加Jenkins仓库、安装Jenkins、启动Jenkins服务等。
- Jenkins基本配置:包括防火墙配置、初始设置、插件安装、创建管理员用户等。
- Pipeline基础概念:介绍了Pipeline的基本概念和语法。
- 创建第一个Pipeline:详细介绍了如何创建和运行一个简单的Pipeline。
- 高级Pipeline配置:包括使用SCM管理Pipeline、参数化构建、使用Docker作为Agent、并行执行阶段等。
- 实战案例:通过一个完整的Java Web应用CI/CD流水线示例,展示了如何在实际项目中使用Jenkins Pipeline。
- 常见问题及解决方案:介绍了一些常见问题及其解决方法。
通过本文的指导,你应该能够在Rocky Linux 9系统上成功安装配置Jenkins Pipeline,并构建自己的CI/CD流水线。Jenkins Pipeline是一个功能强大的工具,通过它可以实现软件开发的自动化,提高开发效率和软件质量。希望本文能够帮助你快速上手Jenkins Pipeline,并在实际项目中发挥作用。