Rocky Linux 8.5部署Jenkins CI/CD系统实战指南

Rocky Linux 8.5部署Jenkins CI/CD系统实战指南 1. 项目概述在当今DevOps实践中Jenkins作为老牌自动化服务器依然占据重要地位。最近我在Rocky Linux 8.5上完整部署了一套支持容器化构建的Jenkins CI/CD系统过程中发现不少官方文档未提及的细节问题。本文将分享从系统准备到流水线优化的全流程实战经验特别针对混合架构环境下的常见痛点提供解决方案。2. 环境准备与基础安装2.1 Rocky Linux系统调优在安装Jenkins前需要对操作系统进行针对性优化# 禁用不必要的服务 sudo systemctl disable --now firewalld sudo dnf remove -y firewalld # 配置SWAP当物理内存8GB时建议 sudo dd if/dev/zero of/swapfile bs1M count4096 sudo chmod 600 /swapfile sudo mkswap /swapfile sudo swapon /swapfile echo /swapfile none swap sw 0 0 | sudo tee -a /etc/fstab # 修改文件描述符限制 echo * soft nofile 65535 | sudo tee -a /etc/security/limits.conf echo * hard nofile 65535 | sudo tee -a /etc/security/limits.conf注意生产环境请根据实际安全需求配置防火墙规则此处禁用仅用于简化测试环境配置2.2 Jenkins核心安装使用官方仓库安装最新LTS版本sudo dnf install -y wget sudo wget -O /etc/yum.repos.d/jenkins.repo \ https://pkg.jenkins.io/redhat-stable/jenkins.repo sudo rpm --import https://pkg.jenkins.io/redhat-stable/jenkins.io.key sudo dnf install -y jenkins java-11-openjdk-devel sudo systemctl enable --now jenkins安装后需检查关键目录权限sudo chown -R jenkins:jenkins /var/lib/jenkins sudo chmod 755 /var/log/jenkins3. 容器化构建环境配置3.1 Docker集成方案为支持容器化构建需要配置Docker-in-Docker方案sudo dnf config-manager --add-repohttps://download.docker.com/linux/centos/docker-ce.repo sudo dnf install -y docker-ce docker-ce-cli containerd.io sudo usermod -aG docker jenkins sudo systemctl restart docker jenkins在Jenkins全局配置中设置Docker路径Manage Jenkins - Configure System - 云 - Docker Docker Host URI: unix:///var/run/docker.sock3.2 Podman作为备选方案对于无root环境可选用Podmansudo dnf install -y podman sudo mkdir -p /home/jenkins/.local/share/containers sudo chown -R jenkins:jenkins /home/jenkins在Jenkinsfile中使用时需注意pipeline { agent any stages { stage(Build) { steps { sh podman build -t myapp . podman tag myapp localhost:5000/myapp podman push localhost:5000/myapp } } } }4. 多平台流水线实战4.1 混合架构构建方案针对ARM/x86混合环境使用buildx实现跨平台构建stage(Multi-arch Build) { steps { script { docker.withRegistry(https://registry.example.com, docker-creds) { docker.image(docker.io/docker/buildx:latest).inside(--privileged) { sh docker buildx create --use docker buildx build --platform linux/amd64,linux/arm64 \ -t ${IMAGE_NAME}:${BUILD_NUMBER} \ -t ${IMAGE_NAME}:latest \ --push . } } } } }4.2 动态节点分配策略在Jenkinsfile中实现智能节点选择def getBuilder(label) { def cloud Jenkins.instance.clouds.find { it.name docker-cloud } def template cloud.templates.find { it.labelString label } return template } pipeline { parameters { choice(name: ARCH, choices: [amd64, arm64], description: Target architecture) } agent none stages { stage(Build) { agent { docker { image docker:${params.ARCH arm64 ? arm64v8 : }/dind label ${params.ARCH}-builder args --privileged -v /var/run/docker.sock:/var/run/docker.sock } } steps { sh docker build -t app . } } } }5. 性能优化与安全加固5.1 JVM参数调优修改/etc/sysconfig/jenkins中的JAVA_OPTSJAVA_OPTS-Djava.awt.headlesstrue \ -Xms2g -Xmx4g \ -XX:MaxMetaspaceSize512m \ -XX:UseG1GC \ -XX:ParallelRefProcEnabled \ -XX:DisableExplicitGC \ -Djenkins.install.runSetupWizardfalse5.2 凭据安全存储使用HashiCorp Vault集成方案Library(vault-library) _ pipeline { environment { DB_PASSWORD vault( path: secret/data/jenkins, key: db_password ) } stages { stage(Deploy) { steps { sh echo $DB_PASSWORD | docker login -u _json_key --password-stdin registry.example.com } } } }6. 典型问题排查指南6.1 插件依赖冲突常见错误现象java.lang.NoSuchMethodError: org.jenkinsci.plugins.workflow.steps.StepContext.get解决方案进入Manage Jenkins - Script Console执行以下Groovy脚本检查冲突Jenkins.instance.pluginManager.plugins .findAll { it.isActive it.hasUpdate() } .each { println ${it.shortName}: ${it.version} - ${it.getUpdateInfo().version} }通过--plugins.txt文件批量降级插件版本6.2 容器内DNS解析失败在docker-agent模板中添加额外参数{ HostConfig: { Dns: [8.8.8.8, 114.114.114.114], DnsOptions: [timeout:2, attempts:2], NetworkMode: host } }7. 监控与日志方案7.1 Prometheus监控集成配置/etc/prometheus/jenkins.ymlscrape_configs: - job_name: jenkins metrics_path: /prometheus static_configs: - targets: [jenkins.example.com:8080]在Jenkins中安装Prometheus插件后调整采集间隔Manage Jenkins - Configure System - Prometheus Collection Interval: 15s Enable perBuildMetrics: true7.2 日志集中管理使用Fluentd转发日志到ELKplugin groupIdorg.jenkins-ci.plugins/groupId artifactIdfluentd-plugin/artifactId version0.10.0/version configuration hostfluentd.example.com/host port24224/port tagjenkins.${JOB_NAME}.${BUILD_NUMBER}/tag bufferSize1000/bufferSize /configuration /plugin8. 扩展功能实现8.1 自动伸缩构建节点使用Kubernetes插件动态创建podapiVersion: v1 kind: Pod metadata: labels: jenkins: agent spec: containers: - name: jnlp image: jenkins/inbound-agent:4.3-4 resources: limits: cpu: 2 memory: 4Gi requests: cpu: 500m memory: 1Gi - name: dind image: docker:dind securityContext: privileged: true volumeMounts: - name: docker-graph-storage mountPath: /var/lib/docker8.2 制品仓库集成配置Nexus3作为私有仓库withCredentials([usernamePassword( credentialsId: nexus-creds, usernameVariable: NEXUS_USER, passwordVariable: NEXUS_PASS )]) { sh curl -u $NEXUS_USER:$NEXUS_PASS \ -X POST http://nexus.example.com/service/rest/v1/components?repositorymaven-releases \ -H Content-Type: multipart/form-data \ -F maven2.groupIdcom.example \ -F maven2.artifactIdmyapp \ -F maven2.version1.0.0 \ -F maven2.asset1target/myapp.jar \ -F maven2.asset1.extensionjar }