Jenkins 自动化构建
Jenkins 是最流行的开源自动化服务器,支持持续集成(CI)和持续交付(CD)。本节涵盖 Jenkins 的安装、配置、流水线编写、插件生态和最佳实践。
环境要求
| 组件 | 最低要求 | 推荐配置 |
|---|---|---|
| CPU | 2 核 | 4 核以上 |
| 内存 | 2 GB | 8 GB 以上 |
| 磁盘 | 50 GB | 200 GB SSD |
| JDK | OpenJDK 11 | OpenJDK 17 |
| OS | Ubuntu 20.04+ / CentOS 8+ | Ubuntu 22.04 LTS |
安装 Jenkins
APT 安装(Ubuntu/Debian)
curl -fsSL https://pkg.jenkins.io/debian/jenkins.io-2023.key | sudo tee /usr/share/keyrings/jenkins-keyring.asc > /dev/null
echo deb [signed-by=/usr/share/keyrings/jenkins-keyring.asc] https://pkg.jenkins.io/debian binary/ | sudo tee /etc/apt/sources.list.d/jenkins.list
sudo apt update
sudo apt install openjdk-17-jdk -y
sudo apt install jenkins -y
sudo systemctl enable jenkins
sudo systemctl start jenkins
初始化管理员密码:
sudo cat /var/lib/jenkins/secrets/initialAdminPassword
访问 http://your-server:8080 完成初始化向导。
Docker 运行
docker run -d \
--name jenkins \
-p 8080:8080 -p 50000:50000 \
-v jenkins_home:/var/jenkins_home \
-e JAVA_OPTS="-Xmx2g" \
jenkins/jenkins:lts
Jenkins 流水线语法
Declarative Pipeline(声明式)
pipeline {
agent any
environment {
REGISTRY = 'registry.example.com'
APP_NAME = 'myapp'
}
options {
buildDiscarder(logRotator(numToKeepStr: '30'))
timeout(time: 1, unit: 'HOURS')
disableConcurrentBuilds()
}
stages {
stage('Checkout') {
steps {
checkout scm
}
}
stage('Build') {
steps {
sh 'make build'
}
}
stage('Test') {
steps {
sh 'make test'
}
post {
always {
junit 'target/surefire-reports/*.xml'
}
}
}
stage('Security Scan') {
steps {
sh 'trivy image --exit-code 0 --severity HIGH,CRITICAL ${REGISTRY}/${APP_NAME}:${BRANCH_NAME}'
}
}
stage('Build Image') {
steps {
sh '''
docker build -t ${REGISTRY}/${APP_NAME}:${BRANCH_NAME} .
docker push ${REGISTRY}/${APP_NAME}:${BRANCH_NAME}
'''
}
}
stage('Deploy to Staging') {
when { branch 'main' }
steps {
sh 'kubectl apply -f k8s/staging/ -n staging'
}
}
}
post {
success {
echo 'Pipeline succeeded!'
}
failure {
echo 'Pipeline failed!'
}
}
}
Scripted Pipeline(脚本式)
node('docker') {
stage('Clone') {
checkout scm
}
stage('Build') {
def image = docker.build("${REGISTRY}/${APP_NAME}:${BUILD_NUMBER}")
}
stage('Push') {
docker.withRegistry('https://registry.example.com', 'docker-hub-credentials') {
image.push()
}
}
}
Jenkinsfile 多分支配置
在 Git 仓库根目录创建 Jenkinsfile,Jenkins 自动发现并构建:
@Library('shared-library@main') _
pipeline {
agent { label 'kubernetes' }
options {
timestamps()
timeout(time: 30, unit: 'MINUTES')
}
stages {
stage('CI Checks') {
parallel {
stage('Unit Test') {
steps {
sh 'make test'
}
}
stage('Lint') {
steps {
sh 'make lint'
}
}
stage('Security Audit') {
steps {
sh 'make security-audit'
}
}
}
}
stage('Build & Push') {
steps {
script {
def image = buildImage()
pushImage(image)
}
}
}
stage('Deploy') {
steps {
sh 'make deploy-${BRANCH_NAME}'
}
}
}
post {
always {
cleanWs()
}
}
}
凭据管理
在 Manage Jenkins → Credentials 中配置:
| 类型 | 用途 |
|---|---|
| Username with password | Git 仓库、Docker Registry |
| SSH Username with private key | Git SSH 认证 |
| Secret file | 证书文件、配置文件 |
| Secret text | API Token、环境变量 |
在流水线中使用:
pipeline {
stages {
stage('Deploy') {
withCredentials([
usernamePassword(credentialsId: 'docker-hub', usernameVariable: 'DOCKER_USER', passwordVariable: 'DOCKER_PASS'),
string(credentialsId: 'kubeconfig', variable: 'KUBECONFIG')
]) {
sh '''
echo $DOCKER_PASS | docker login -u $DOCKER_USER --password-stdin
kubectl apply -f deployment.yaml
'''
}
}
}
}
Kubernetes 动态 Agent
配置 Kubernetes Pod Template 作为动态 Agent:
pipeline {
agent {
kubernetes {
label 'jenkins-agent'
defaultContainer 'jnlp'
yaml '''
apiVersion: v1
kind: Pod
metadata:
name: jenkins-agent
spec:
containers:
- name: builder
image: maven:3.9-eclipse-temurin-17
command: [sleep]
args: [infinity]
resources:
requests:
cpu: "1"
memory: "2Gi"
limits:
cpu: "2"
memory: "4Gi"
- name: docker
image: docker:24-dind
securityContext:
privileged: true
volumeMounts:
- name: docker-socket
mountPath: /var/run/docker.sock
volumes:
- name: docker-socket
hostPath:
path: /var/run/docker.sock
'''
}
}
stages {
stage('Build') {
steps {
container('builder') {
sh 'mvn clean package -DskipTests'
}
}
}
stage('Docker Build') {
steps {
container('docker') {
sh 'docker build -t myapp:${BUILD_NUMBER} .'
}
}
}
}
}
常用插件推荐
| 插件名称 | 功能 |
|---|---|
| Pipeline | 流水线支持 |
| Kubernetes | Kubernetes 动态 Agent |
| Git | Git 版本控制 |
| Docker | Docker 构建支持 |
| JUnit | 测试报告 |
| Blue Ocean | 现代化流水线视图 |
| Slack Notification | Slack 通知 |
| Pipeline: Stage View | 阶段视图 |
| Configuration as Code | 配置即代码 |
| Role-based Authorization Strategy | 基于角色的权限 |
Blue Ocean 可视化流水线
安装 Blue Ocean 插件后,访问 http://your-jenkins/blue 可获得现代化的流水线可视化界面,支持图形化编辑器和实时的流水线执行视图。
故障排除
常见问题
Jenkins 启动失败:检查端口占用 netstat -tlnp | grep 8080,确保 JDK 版本兼容。
Agent 连接不上:检查 JNLP 端口 50000 是否开放,验证 Agent 密钥。
权限不足:在 Configure Global Security 中设置合适的授权策略。
流水线卡住:检查超时设置,查看 system log 是否有死锁或资源耗尽。
# 查看 Jenkins 日志
sudo journalctl -u jenkins -f
# 重启 Jenkins
sudo systemctl restart jenkins
# 清除缓存
sudo rm -rf /var/lib/jenkins/cache/
sudo systemctl restart jenkins
性能优化
- 并行阶段:使用
parallel块加速构建
- 增量构建:配置 Gradle/Maven 增量构建
- Agent 池化:使用 Kubernetes 动态创建/销毁 Agent
- 缓存优化:挂载 Maven/npm 本地仓库
- 只读 Agent:使用标签隔离不同类型的构建任务
备份策略
# 备份 JENKINS_HOME
tar -czf jenkins-backup-$(date +%Y%m%d).tar.gz /var/lib/jenkins
# 备份配置(推荐使用 Configuration as Code)
jenkins-cli get-config > jenkins-config.xml
下一步
- ArgoCD GitOps 部署 — 了解 GitOps 持续部署
- Tekton 流水线 — 云原生流水线框架
- Jenkins ShareLib — 共享库复用流水线逻辑