环境说明:CentOS 7 / Rocky Linux 9 / Ubuntu 20.04+
软件版本:Jenkins 2.426+ | JDK 17 | Docker 24+ | Kubernetes 1.28+
目标读者:DevOps 工程师 / 后端开发 / 运维工程师
一、CI/CD 架构概览
1.1 经典 CI/CD 流程
┌─────────────────────────────────────────────────────────────────────────┐
│ Jenkins Master Server │
│ (任务调度 / Web UI / 配置管理) │
└─────────────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────────┐
│ Jenkins Agent (Build Node) │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ Checkout │ → │ Build │ → │ Test │ → │ Package │ │
│ │ 代码拉取 │ │ 编译构建 │ │ 单元测试 │ │ 镜像打包 │ │
│ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │
│ │ │ │
│ └────────────── ▼ ────────────────────────────────┘ │
│ ┌──────────┐ │
│ │ Deploy │ │
│ │ 部署发布 │ │
│ └──────────┘ │
└─────────────────────────────────────────────────────────────────────────┘
│
▼
┌──────────────────┐
│ Kubernetes │
│ / Docker Host │
└──────────────────┘
│
▼
┌──────────────────┐
│ 生产环境 │
│ Production │
└──────────────────┘
1.2 Jenkins 核心组件说明
| 组件 | 作用 | 端口 |
|---|---|---|
| Jenkins Master | 任务调度、API 服务、Web UI | 8080 / 443 |
| Jenkins Agent | 执行流水线任务,可水平扩展 | 随机 |
| Plugin | 扩展 Jenkins 功能(Git/Docker/K8s 等) | – |
| Pipeline | 流水线即代码,定义构建流程 | – |
| Credential | 安全存储密钥(密码/Token/SSH Key) | – |
1.3 硬件推荐配置
| 环境 | Master 配置 | Agent 配置 |
|---|---|---|
| 小型团队(<10人) | 2核/4GB | 2核/4GB |
| 中型团队(10-50人) | 4核/8GB | 4核/8GB × 2 |
| 大型团队(50+人) | 8核/16GB | 8核/16GB × N |
二、安装 Jenkins
2.1 环境要求
| 项目 | 要求 |
|---|---|
| 操作系统 | CentOS 7+ / Ubuntu 18+ / Rocky Linux 9 |
| JDK | JDK 11 / JDK 17(推荐 JDK 17) |
| 内存 | ≥ 4 GB(生产环境建议 8 GB+) |
| 磁盘 | ≥ 50 GB(根据项目数量动态增长) |
| 网络 | 可访问外网(下载插件/依赖) |
2.2 安装 JDK 17
# CentOS / Rocky Linux
sudo yum install -y java-17-openjdk java-17-openjdk-devel
# Ubuntu / Debian
sudo apt update
sudo apt install -y openjdk-17-jdk openjdk-17-jre
# 验证安装
java -version
# 设置 JAVA_HOME
echo "export JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64" >> ~/.bashrc
source ~/.bashrc
echo $JAVA_HOME
2.3 安装 Jenkins(CentOS / Rocky Linux)
# 1. 添加 Jenkins 官方 yum 源
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-2023.key
# 2. 安装 Jenkins
sudo yum install -y jenkins
# 3. 配置 Jenkins 运行环境(JDK 17)
sudo sed -i 's/JENKINS_JAVA_CMD=/JENKINS_JAVA_CMD=\/usr\/lib\/jvm\/java-17-openjdk-amd64\/bin\/java/' /etc/sysconfig/jenkins
# 4. 启动并设置开机自启
sudo systemctl daemon-reload
sudo systemctl start jenkins
sudo systemctl enable jenkins
# 5. 检查状态
sudo systemctl status jenkins
# 6. 查看初始管理员密码
sudo cat /var/lib/jenkins/secrets/initialAdminPassword
2.4 安装 Jenkins(Ubuntu / Debian)
# 1. 添加 Jenkins 官方 GPG 密钥
curl -fsSL https://pkg.jenkins.io/debian/jenkins.io-2023.key | sudo tee /usr/share/keyrings/jenkins-keyring.asc > /dev/null
# 2. 添加 apt 源
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
# 3. 安装 Jenkins
sudo apt update
sudo apt install -y jenkins
# 4. 启动并设置开机自启
sudo systemctl start jenkins
sudo systemctl enable jenkins
# 5. 查看初始管理员密码
sudo cat /var/lib/jenkins/secrets/initialAdminPassword
2.5 防火墙配置
# CentOS / Rocky
sudo firewall-cmd --permanent --add-port=8080/tcp
sudo firewall-cmd --permanent --add-port=50000/tcp # Agent 通信端口
sudo firewall-cmd --reload
sudo firewall-cmd --list-ports
# Ubuntu
sudo ufw allow 8080/tcp
sudo ufw allow 50000/tcp
sudo ufw reload
2.6 访问 Jenkins Web UI
打开浏览器访问:http://<服务器IP>:8080
首次访问引导步骤:
┌─────────────────────────────────────────────────────────────────────┐
│ Welcome to Jenkins! │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ 解锁 Jenkins │
│ ───────────────── │
│ │
│ 要完成设置,请将以下密码粘贴到管理员密码字段: │
│ │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ a1b2c3d4e5f6... │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │
│ [继续] │
│ │
│ 密码文件位置:/var/lib/jenkins/secrets/initialAdminPassword │
│ │
└─────────────────────────────────────────────────────────────────────┘
后续引导步骤:
步骤 1 → 安装插件(选择"安装推荐插件")
步骤 2 → 创建第一个管理员用户
步骤 3 → 配置 Jenkins URL(保持默认即可)
步骤 4 → 开始使用 Jenkins!
⏱️ 耐心等待:插件安装可能需要 5-10 分钟,请勿刷新页面。
三、基础配置
3.1 安装必备插件
进入 Dashboard → Manage Jenkins → Manage Plugins
在 Available 标签中搜索并安装以下插件:
| 插件名称 | 用途 |
|---|---|
| Git | 代码仓库拉取 |
| Pipeline | 流水线即代码(必装) |
| Docker Pipeline | Docker 构建与推送 |
| Kubernetes CLI | K8s 部署 |
| Config File Provider | 配置文件管理 |
| Role-based Authorization Strategy | 基于角色的权限管理 |
| Email Extension Plugin | 邮件通知 |
| 钉钉通知插件 | 钉钉群机器人告警 |
3.2 配置系统时间(时区)
# 设置时区为 Asia/Shanghai
sudo timedatectl set-timezone Asia/Shanghai
sudo timedatectl status
# 验证 Jenkins 时区
# Dashboard → Manage Jenkins → Script Console
println(new Date().format('yyyy-MM-dd HH:mm:ss', TimeZone.getTimeZone('Asia/Shanghai')))
3.3 配置邮件通知
进入 Dashboard → Manage Jenkins → System
找到 Jenkins Location 和 E-mail Notification 部分:
┌─────────────────────────────────────────────────────────────────┐
│ 系统配置 │
├─────────────────────────────────────────────────────────────────┤
│ │
│ Jenkins URL: http://192.168.1.100:8080/ │
│ 系统管理员邮件地址: admin@example.com │
│ │
│ ── E-mail Notification ────────────────────────────────────── │
│ │
│ SMTP 服务器: smtp.exmail.qq.com │
│ SMTP 端口: 465 │
│ ☑ 使用 SSL (QQ企业邮箱/163邮箱推荐 465端口) │
│ │
│ 用户名: jenkins@example.com │
│ 密码: ****************** │
│ │
│ [Test Configuration] 测试配置是否正确 │
│ │
└─────────────────────────────────────────────────────────────────┘
3.4 配置钉钉告警(可选)
# 1. 在钉钉群 → 群设置 → 智能群助手 → 添加机器人
# 2. 选择"自定义机器人",获取 Webhook 地址
# 3. 在 Jenkins 中安装"钉钉通知插件"
# 4. 配置钉钉机器人安全设置(关键词或签名)
四、权限管理:配置用户与角色
4.1 安装角色管理插件
安装 Role-based Authorization Strategy 插件。
4.2 启用角色策略
进入 Dashboard → Manage Jenkins → Security
授权策略 → 选择 "Role-Based Strategy"
4.3 创建角色
进入 Dashboard → Manage Jenkins → Manage and Assign Roles
创建全局角色:
| 角色名 | 权限 |
|---|---|
| global-admin | 全部权限 |
| global-developer | Job创建/构建/查看 |
| global-viewer | 仅查看权限 |
创建项目角色(按项目隔离):
| 角色名 | Pattern | 说明 |
|---|---|---|
| project-frontend | frontend-.* | 匹配所有 frontend- 开头的 Job |
| project-backend | backend-.* | 匹配所有 backend- 开头的 Job |
4.4 分配角色
| 用户 | 分配角色 |
|---|---|
| admin | global-admin |
| dev-zhang | global-developer + project-frontend |
| dev-li | global-developer + project-backend |
| tester-wang | global-viewer |
五、Agent 节点配置(分布式构建)
5.1 Agent 节点简介
当构建任务增多时,单个 Master 无法承载,通过添加 Agent 节点实现水平扩展。
5.2 在 Master 上添加 Agent
方式一:通过 Web UI 添加
进入 Dashboard → Manage Jenkins → Nodes → New Node
┌─────────────────────────────────────────────────────────────────┐
│ 新建节点 │
├─────────────────────────────────────────────────────────────────┤
│ │
│ 节点名称: build-agent-01 │
│ 类型: ☉ Permanent Agent │
│ │
│ ── 配置 ───────────────────────────────────────────────────── │
│ │
│ 执行器数量: 2 (并发构建数) │
│ 根目录: /home/jenkins/agent │
│ 标签: java-builder linux │
│ 用法: 尽可能使用此节点 │
│ │
│ 启动方式: ☉ 通过 Java Web Start 启动 Agent │
│ ○ 通过 SSH 启动现有 Agent │
│ ○ 通过相关 Java 程序启动 Agent │
│ │
└─────────────────────────────────────────────────────────────────┘
**方式二:通过 SSH 启动 Agent(推荐)
# 在 Agent 节点上安装 JDK
sudo yum install -y java-17-openjdk
# 在 Master 节点上生成 SSH 密钥
ssh-keygen -t rsa -C "jenkins-master"
ssh-copy-id jenkins@<agent-ip>
# 在 Master Jenkins UI 中配置 SSH 连接
# Manage Jenkins → Manage Nodes → New Node
# 启动方式选择 "通过 SSH 启动"
# Host: <agent-ip>
# Credentials: 添加 SSH 密钥凭据
5.3 配置 Agent 标签
// 在 Pipeline 中指定运行节点
pipeline {
agent {
label 'java-builder' // 只在带此标签的节点运行
}
// ...
}
六、流水线语法:Declarative Pipeline
6.1 流水线基础结构
// Jenkinsfile(放在项目根目录)
pipeline {
// 全局参数
agent any // 可指定: any / none / label 'xxx' / docker 'xxx'
environment {
APP_NAME = 'my-app'
REGISTRY = 'registry.example.com'
}
options {
timeout(time: 1, unit: 'HOURS') // 超时设置
timestamps() // 日志带时间戳
buildDiscarder(logRotator(30)) // 保留30天构建历史
}
stages {
stage('代码拉取') {
steps {
checkout scm
}
}
stage('编译构建') {
steps {
sh './mvnw clean package'
}
}
stage('单元测试') {
steps {
sh './mvnw test'
}
post {
always {
junit 'target/surefire-reports/*.xml'
}
}
}
stage('代码扫描') {
steps {
sh 'sonar-scanner'
}
}
stage('构建镜像') {
steps {
sh '''
docker build -t ${REGISTRY}/${APP_NAME}:${BUILD_NUMBER} .
docker build -t ${REGISTRY}/${APP_NAME}:latest .
'''
}
}
stage('推送到仓库') {
steps {
sh '''
docker login ${REGISTRY} -u ${DOCKER_USER} -p ${DOCKER_PASS}
docker push ${REGISTRY}/${APP_NAME}:${BUILD_NUMBER}
docker push ${REGISTRY}/${APP_NAME}:latest
'''
}
}
stage('部署到测试环境') {
when {
branch 'develop'
}
steps {
sh "kubectl apply -f k8s/ -n test"
}
}
stage('部署到生产环境') {
when {
branch 'main'
}
steps {
input message: '确认部署到生产环境?', ok: '确认部署'
sh "kubectl apply -f k8s/ -n prod"
}
}
}
post {
always {
echo '流水线执行完成'
cleanWs() // 清理工作空间
}
success {
echo '✅ 构建成功!'
dingTalk notify: 'success'
}
failure {
echo '❌ 构建失败!'
dingTalk notify: 'failure'
mail to: 'dev-team@example.com',
subject: "Jenkins构建失败: ${APP_NAME} #${BUILD_NUMBER}",
body: "构建失败,请检查日志: ${BUILD_URL}"
}
}
}
6.2 常用语法速查
参数化构建
pipeline {
agent any
parameters {
string(name: 'BRANCH', defaultValue: 'main', description: '代码分支')
choice(name: 'ENV', choices: ['dev', 'test', 'prod'], description: '部署环境')
booleanParam(name: 'SKIP_TEST', defaultValue: false, description: '跳过测试?')
password(name: 'DEPLOY_TOKEN', description: '部署密钥')
}
stages {
stage('构建') {
steps {
echo "分支: ${params.BRANCH}, 环境: ${params.ENV}"
sh "mvn clean package -DskipTests=${params.SKIP_TEST}"
}
}
}
}
并行执行
stages {
stage('并行构建') {
parallel {
stage('构建前端') {
steps {
sh 'cd frontend && npm install && npm run build'
}
}
stage('构建后端') {
steps {
sh 'cd backend && ./mvnw clean package'
}
}
}
}
}
条件执行
stage('部署生产') {
when {
allOf {
branch 'main'
environment name: 'DEPLOY_ENABLED', value: 'true'
}
}
steps {
sh 'kubectl apply -f k8s/'
}
}
矩阵式构建(Matrix)
pipeline {
agent none
stages {
stage('矩阵构建') {
matrix {
axes {
axis {
name 'PLATFORM'
values 'linux', 'windows', 'macos'
}
axis {
name 'ARCH'
values 'amd64', 'arm64'
}
}
stages {
stage('构建') {
steps {
echo "构建平台: ${PLATFORM}, 架构: ${ARCH}"
sh "make build PLATFORM=${PLATFORM} ARCH=${ARCH}"
}
}
}
}
}
}
}
七、实战场景一:Java Maven 项目
7.1 项目结构
my-springboot-app/
├── src/
├── pom.xml
├── Jenkinsfile
├── Dockerfile
└── k8s/
├── deployment.yaml
└── service.yaml
7.2 Jenkinsfile
pipeline {
agent {
docker {
image 'maven:3.9-eclipse-temurin-17'
args '-v /root/.m2:/root/.m2'
}
}
environment {
APP_NAME = 'my-springboot-app'
REGISTRY = 'harbor.example.com'
}
stages {
stage('代码拉取') {
steps {
checkout scm
}
}
stage('编译') {
steps {
sh 'mvn clean compile -DskipTests'
}
}
stage('单元测试') {
steps {
sh 'mvn test'
}
post {
always {
junit 'target/surefire-reports/*.xml'
publishHTML target: [
reportDir: 'target/site/jacoco',
reportFiles: 'index.html',
reportName: 'Jacoco Report'
]
}
}
}
stage('打包') {
steps {
sh 'mvn package -DskipTests'
}
}
stage('构建 Docker 镜像') {
steps {
script {
def imageTag = "${env.BUILD_NUMBER}"
docker.build("${APP_NAME}:${imageTag}", "-f Dockerfile .")
}
}
}
stage('推送镜像') {
steps {
script {
docker.withRegistry('https://harbor.example.com', 'harbor-credential') {
def imageTag = "${env.BUILD_NUMBER}"
docker.image("${APP_NAME}:${imageTag}").push()
docker.image("${APP_NAME}:${imageTag}").push('latest')
}
}
}
}
stage('部署到 K8s') {
when {
branch 'main'
}
steps {
script {
sh """
kubectl set image deployment/${APP_NAME} \
${APP_NAME}=harbor.example.com/${APP_NAME}:${env.BUILD_NUMBER} \
-n production
"""
}
}
}
}
post {
success {
echo '🎉 构建并部署成功!'
}
failure {
echo '❌ 构建失败,请检查日志'
}
}
}
7.3 Dockerfile
FROM eclipse-temurin:17-jre-alpine
LABEL maintainer="devops@example.com"
WORKDIR /app
COPY target/my-springboot-app-*.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "/app/app.jar"]
八、实战场景二:Node.js 前端项目
8.1 Jenkinsfile
pipeline {
agent {
docker {
image 'node:20-alpine'
}
}
environment {
APP_NAME = 'my-vue-app'
REGISTRY = 'registry.example.com'
}
stages {
stage('安装依赖') {
steps {
sh 'npm config set registry https://registry.npmmirror.com'
sh 'npm install'
}
}
stage('代码检查') {
steps {
sh 'npm run lint'
}
}
stage('单元测试') {
steps {
sh 'npm run test:unit'
}
post {
always {
junit 'coverage/junit.xml'
}
}
}
stage('构建生产包') {
steps {
sh 'npm run build'
}
}
stage('SonarQube 扫描') {
environment {
SONAR_TOKEN = credentials('sonar-token')
}
steps {
sh '''
sonar-scanner \
-Dsonar.host.url=http://sonarqube:9000 \
-Dsonar.projectKey=${APP_NAME} \
-Dsonar.sources=src \
-Dsonar.javascript.lcov.reportPaths=coverage/lcov.info
'''
}
}
stage('部署到 Nginx') {
when {
branch 'main'
}
steps {
sh '''
rsync -avz --delete dist/ user@web-server:/var/www/html/
'''
}
}
}
post {
cleanup {
sh 'npm cache clean --force'
}
}
}
九、实战场景三:Docker 多阶段构建
9.1 项目结构
my-golang-app/
├── cmd/
│ └── server/
│ └── main.go
├── Dockerfile
├── Jenkinsfile
└── docker-compose.yml
9.2 多阶段构建 Dockerfile
# 第一阶段:构建
FROM golang:1.21-alpine AS builder
WORKDIR /build
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -o app ./cmd/server
# 第二阶段:运行
FROM alpine:latest
RUN apk --no-cache add ca-certificates tzdata
WORKDIR /app
COPY --from=builder /build/app .
COPY --from=builder /build/configs ./configs
EXPOSE 8080
USER nobody
ENTRYPOINT ["./app"]
CMD ["--config", "./configs/config.yml"]
9.3 Jenkinsfile(使用 BuildKit)
pipeline {
agent any
environment {
REGISTRY = 'harbor.example.com'
IMAGE_NAME = 'my-golang-app'
}
stages {
stage('构建镜像') {
steps {
script {
def imageTag = "${env.BUILD_NUMBER}"
def fullImage = "${REGISTRY}/${IMAGE_NAME}:${imageTag}"
sh """
export DOCKER_BUILDKIT=1
docker build -t ${fullImage} .
docker tag ${fullImage} ${REGISTRY}/${IMAGE_NAME}:latest
"""
}
}
}
stage('安全扫描') {
steps {
sh '''
docker run --rm -v /var/run/docker.sock:/var/run/docker.sock \
aquasec/trivy image --severity HIGH,CRITICAL \
${REGISTRY}/${IMAGE_NAME}:${BUILD_NUMBER}
'''
}
}
stage('推送镜像') {
steps {
script {
docker.withRegistry("https://${REGISTRY}", 'harbor-credential') {
docker.image("${REGISTRY}/${IMAGE_NAME}:${env.BUILD_NUMBER}").push()
docker.image("${REGISTRY}/${IMAGE_NAME}:latest").push()
}
}
}
}
}
}
十、实战场景四:Kubernetes 持续部署
10.1 Kubernetes 部署清单
k8s/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
labels:
app: my-app
spec:
replicas: 3
selector:
matchLabels:
app: my-app
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
template:
metadata:
labels:
app: my-app
version: v1
spec:
containers:
- name: my-app
image: harbor.example.com/my-app:latest
imagePullPolicy: Always
ports:
- containerPort: 8080
resources:
requests:
memory: "256Mi"
cpu: "100m"
limits:
memory: "512Mi"
cpu: "500m"
livenessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /ready
port: 8080
initialDelaySeconds: 5
periodSeconds: 5
k8s/service.yaml
apiVersion: v1
kind: Service
metadata:
name: my-app-svc
spec:
type: ClusterIP
selector:
app: my-app
ports:
- port: 80
targetPort: 8080
k8s/ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-app-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- host: myapp.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: my-app-svc
port:
number: 80
10.2 Jenkins K8s 部署流水线
pipeline {
agent any
environment {
KUBECONFIG = credentials('kubeconfig-prod')
REGISTRY = 'harbor.example.com'
APP_NAME = 'my-app'
}
stages {
stage('拉取代码') {
steps {
checkout scm
}
}
stage('构建镜像') {
steps {
script {
def version = "${env.BUILD_NUMBER}"
def image = "${REGISTRY}/${APP_NAME}:${version}"
sh """
docker build -t ${image} .
docker push ${image}
"""
}
}
}
stage('更新 K8s 镜像') {
steps {
script {
def version = "${env.BUILD_NUMBER}"
def image = "${REGISTRY}/${APP_NAME}:${version}"
sh """
kubectl set image deployment/${APP_NAME} ${APP_NAME}=${image} -n production
kubectl rollout status deployment/${APP_NAME} -n production
kubectl rollout history deployment/${APP_NAME} -n production
"""
}
}
}
stage('健康检查') {
steps {
sh '''
sleep 10
kubectl exec -n production deployment/${APP_NAME} -- wget -qO- http://localhost:8080/health
'''
}
}
}
post {
success {
echo '✅ 部署成功!'
}
failure {
echo '❌ 部署失败,执行回滚!'
sh '''
kubectl rollout undo deployment/${APP_NAME} -n production
'''
}
}
}
十一、凭据管理
11.1 添加凭据类型
进入 Dashboard → Manage Jenkins → Credentials → System → Global credentials
| 凭据类型 | 用途 |
|---|---|
| 用户名 + 密码 | Git 仓库、Docker Registry |
| SSH 用户名 + 私钥 | Git SSH 拉取、SSH 部署 |
| Secret 文件 | kubeconfig、证书文件 |
| Secret 文本 | API Token、密钥字符串 |
| 证书 | TLS 证书 |
11.2 在 Pipeline 中使用凭据
pipeline {
agent any
stages {
stage('Git 拉取') {
steps {
git credentialsId: 'git-ssh-key', // SSH 私钥凭据
url: 'git@github.com:org/repo.git'
}
}
stage('推送镜像') {
steps {
script {
docker.withRegistry('https://harbor.example.com', 'harbor-credential') {
docker.image('my-app').push()
}
}
}
}
stage('K8s 部署') {
steps {
withCredentials([file(credentialsId: 'kubeconfig', variable: 'KUBECONFIG')]) {
sh 'kubectl apply -f k8s/'
}
}
}
stage('SonarQube') {
environment {
SONAR_TOKEN = credentials('sonar-token-secret')
}
steps {
sh 'sonar-scanner -Dsonar.token=$SONAR_TOKEN'
}
}
}
}
十二、Blue Ocean 可视化流水线
Blue Ocean 是 Jenkins 原生的可视化流水线编辑器,适合不熟悉代码的同学。
12.1 安装 Blue Ocean
Dashboard → Manage Jenkins → Manage Plugins → Available
搜索并安装 Blue Ocean 插件。
12.2 访问 Blue Ocean
安装后,点击顶部菜单 Open Blue Ocean
┌─────────────────────────────────────────────────────────────────┐
│ Blue Ocean │
│ │
│ Activity Pipeline Favorites Settings │
│ ──────────────────────────────────────────────────────────── │
│ │
│ Run in Personal Folder │
│ ───────────────────────────────────────────────────────────── │
│ │
│ ● my-springboot-app #42 Success 2m ago │
│ ● my-springboot-app #41 Success 5m ago │
│ ● my-springboot-app #40 Failed 12m ago │
│ ○ my-vue-app #88 Running 正在执行 │
│ │
│ 流水线执行可视化(节点+阶段+步骤 树状图) │
│ │
└─────────────────────────────────────────────────────────────────┘
十三、常见问题排错
❌ 问题 1:Jenkins 启动失败,端口被占用
# 排查
sudo ss -tlnp | grep 8080
# 解决方案:杀死占用进程或修改 Jenkins 端口
sudo vi /etc/sysconfig/jenkins
# 修改 JENKINS_PORT="8081"
sudo systemctl restart jenkins
❌ 问题 2:插件安装失败(网络原因)
# 检查外网连接
curl -I https://updates.jenkins.io
# 如果在内网环境,配置国内镜像
# Dashboard → Manage Jenkins → Plugin Manager → Advanced
# Update Site URL 改为: https://mirrors.tuna.tsinghua.edu.cn/jenkins/updates/update-center.json
# 重启 Jenkins
sudo systemctl restart jenkins
❌ 问题 3:Git 拉取失败(Permission denied)
# 排查 1:检查 SSH 密钥
ssh -T git@github.com
# 排查 2:检查凭据
# Dashboard → Manage Jenkins → Credentials
# 确认 Git SSH 凭据已正确配置
# 排查 3:检查 Known Hosts
ssh-keyscan github.com >> ~/.ssh/known_hosts
❌ 问题 4:Docker 构建失败(BuildKit 问题)
# 解决方案 1:关闭 BuildKit
export DOCKER_BUILDKIT=0
docker build ...
# 解决方案 2:在 Pipeline 中显式关闭
sh 'export DOCKER_BUILDKIT=0 && docker build ...'
# 解决方案 3:修改 daemon.json
sudo vi /etc/docker/daemon.json
# 添加 "features": {"buildkit": false}
sudo systemctl restart docker
❌ 问题 5:K8s 部署失败(ImagePullBackOff)
# 排查 1:确认镜像存在
docker images | grep my-app
# 排查 2:检查 K8s secret
kubectl get secret -n production
kubectl describe secret <secret-name> -n production
# 排查 3:重新创建 docker registry secret
kubectl create secret docker-registry harbor-credential \
--docker-server=harbor.example.com \
--docker-username=admin \
--docker-password=Harbor12345 \
-n production
# 排查 4:手动拉取测试
docker pull harbor.example.com/my-app:latest
❌ 问题 6:Pipeline 卡在 Waiting for executor
# 排查 1:检查节点是否在线
# Dashboard → Manage Jenkins → Nodes
# 排查 2:检查并发数限制
# Dashboard → Manage Jenkins → System
# "最大并发构建数" 设置过高可能导致资源耗尽
# 排查 3:增加 Agent 节点
❌ 问题 7:邮件通知发送失败
# 排查 1:测试 SMTP 连接
telnet smtp.exmail.qq.com 465
# 排查 2:检查 Jenkins 系统日志
# Dashboard → Manage Jenkins → System Log
# 排查 3:确认发件人邮箱与 Jenkins 配置一致
❌ 问题 8:流水线脚本语法报错
// 错误示例:使用了 Groovy 关键字作为变量名
def stage = "build" // ❌ stage 是关键字
// 正确写法
def stageName = "build" // ✅
// 使用 Declarative Validator 检查
// https://jenkins.io/doc/book/pipeline/syntax/#declarative-steps
十四、安全加固建议
14.1 启用 HTTPS
# 使用 Let's Encrypt 免费证书
sudo yum install -y certbot python3-certbot-nginx
# 获取证书
sudo certbot --nginx -d jenkins.example.com
# 修改 Jenkins 启动参数
sudo vi /etc/sysconfig/jenkins
# JENKINS_HTTPS_PORT=443
# JENKINS_HTTPS_KEYSTORE=/etc/letsencrypt/live/jenkins.example.com/keystore.jks
# JENKINS_HTTPS_KEYSTORE_PASSWORD=yourpassword
14.2 禁止用户注册
进入 Dashboard → Manage Jenkins → Security
☑ 允许用户注册: ❌ 取消勾选
安全矩阵: 配置 admin 权限
14.3 流水线安全
// 在 Jenkinsfile 中禁止不安全的功能
pipeline {
options {
// 禁止使用 script{} 块(Scripted Pipeline)
disableBuiltinIngestPipeline()
}
}
14.4 定期备份
# 创建备份脚本
vi /opt/backup-jenkins.sh
#!/bin/bash
BACKUP_DIR=/opt/jenkins-backup
JENKINS_HOME=/var/lib/jenkins
mkdir -p $BACKUP_DIR/$(date +%Y%m%d)
# 备份配置
tar -czf $BACKUP_DIR/$(date +%Y%m%d)/jenkins-config.tar.gz $JENKINS_HOME/*.xml
tar -czf $BACKUP_DIR/$(date +%Y%m%d)/jenkins-plugins.tar.gz $JENKINS_HOME/plugins
tar -czf $BACKUP_DIR/$(date +%Y%m%d)/jenkins-users.tar.gz $JENKINS_HOME/users
# 保留 30 天
find $BACKUP_DIR -type d -mtime +30 -exec rm -rf {} \;
echo "备份完成: $(date)"
# 添加定时任务
crontab -e
# 每天凌晨 3 点备份
0 3 * * * /opt/backup-jenkins.sh >> /var/log/jenkins-backup.log 2>&1
十五、总结
部署完成检查清单
✅ Jenkins 安装成功(:8080 可访问)
✅ 插件安装完成(Git / Pipeline / Docker / K8s)
✅ 邮件通知配置成功(测试邮件发送成功)
✅ 凭据配置完成(Git / Harbor / K8s)
✅ 角色权限配置完成(admin / developer / viewer)
✅ Agent 节点配置完成(如需分布式构建)
✅ 第一个流水线运行成功
✅ 钉钉/邮件告警通知正常
进阶学习路径
| 阶段 | 学习内容 |
|---|---|
| 入门 | 基础流水线语法、参数化构建、邮件通知 |
| 进阶 | Blue Ocean、分布式构建、权限管理 |
| 熟练 | K8s 部署、SonarQube 集成、Helm Chart |
| 精通 | Jenkins X / Tekton、GitOps、多集群管理 |
附录:快速命令速查
# Jenkins 服务管理
sudo systemctl start jenkins
sudo systemctl stop jenkins
sudo systemctl restart jenkins
sudo systemctl status jenkins
# 重置管理员密码
sudo cat /var/lib/jenkins/secrets/initialAdminPassword
# 手动安装插件
sudo cp plugin.hpi /var/lib/jenkins/plugins/
sudo chown jenkins:jenkins /var/lib/jenkins/plugins/*.hpi
# 查看构建日志
tail -f /var/log/jenkins/jenkins.log
# Groovy 脚本控制台(重置密码等)
# http://jenkins:8080/script
# 重载配置(无需重启)
curl -X POST http://localhost:8080/reload














暂无评论内容