容器化部署 Jenkins 教程

完整的 Jenkins 容器化部署实战指南

推荐 Jenkins 版本:2.411


一、概述

Jenkins 是一款开源的持续集成/持续交付(CI/CD)工具,通过容器化部署可以快速搭建、便于迁移、避免环境污染。本教程使用 Docker 以单节点方式部署 Jenkins,并通过挂载 Docker socket 让 Jenkins 容器能够调用宿主机的 Docker,实现 "Docker in Docker"(DooD)的构建场景。

架构说明

复制代码
┌──────────────────────────────────────────────┐
│                 宿主机 (Host)                  │
│                                              │
│   ┌────────────────────────────────────────┐  │
│   │         Jenkins Container              │  │
│   │                                        │  │
│   │   - Web UI :8080  ──> 映射宿主机 :9123  │  │
│   │   - Agent 端口 :50000 ──> 映射宿主机    │  │
│   │   - /var/jenkins_home ──> /home/jenkins│  │
│   │   - 调用宿主机 Docker (通过 socket 挂载)│  │
│   └────────────────────────────────────────┘  │
│                                              │
└──────────────────────────────────────────────┘

二、环境准备

1. 系统要求

项目 要求
操作系统 Linux(CentOS 7+ / Ubuntu 18+)
Docker 20.10+
内存 建议 ≥ 2GB
磁盘 建议 ≥ 10GB(Jenkins 数据目录)
端口 9123、50000 未被占用

2. 检查 Docker 环境

bash 复制代码
docker --version
docker info

若 Docker 未安装,请先安装 Docker 引擎并启动服务:

bash 复制代码
sudo systemctl start docker
sudo systemctl enable docker

三、部署步骤

步骤 1:创建数据持久化目录

Jenkins 容器内的数据默认存放在 /var/jenkins_home,需要将其挂载到宿主机以实现持久化。

bash 复制代码
mkdir /home/jenkins
sudo chown -R 1000:1000 /home/jenkins

说明:

  • 1000:1000 是 Jenkins 容器内部默认用户的 UID/GID。
  • 若不修改属主,容器以 root 运行时挂载目录可能权限不一致,导致写入失败或数据混乱。

步骤 2:拉取 Jenkins 镜像

bash 复制代码
docker pull jenkins:latest

如需指定版本(推荐 2.411):

bash 复制代码
docker pull jenkins/jenkins:2.411

注意:官方 jenkins:latest 镜像在新版本中已被废弃,建议使用 jenkins/jenkins:ltsjenkins/jenkins:2.411 获取长期支持版本。

步骤 3:创建并启动 Jenkins 容器

bash 复制代码
docker run -d \
  --name jenkins \
  -u root \
  -p 9123:8080 \
  -p 50000:50000 \
  -v /home/jenkins:/var/jenkins_home \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -v /usr/bin/docker:/usr/bin/docker \
  -e JAVA_OPTS="-Dhudson.model.DirectoryBrowserSupport.CSP=\"default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline';\"" \
  jenkins:latest
参数详解
参数 说明
-d 后台运行容器
--name jenkins 容器命名为 jenkins
-u root 以 root 用户运行容器(便于挂载 Docker socket)
-p 9123:8080 将容器内 Jenkins Web UI 的 8080 端口映射到宿主机的 9123
-p 50000:50000 Jenkins Agent 通信端口,用于 master/agent 架构
-v /home/jenkins:/var/jenkins_home 挂载 Jenkins 数据目录到宿主机,实现持久化
-v /var/run/docker.sock:/var/run/docker.sock 挂载宿主机 Docker socket,让容器可调用宿主机 Docker
-v /usr/bin/docker:/usr/bin/docker 挂载 Docker 客户端到容器中
-e JAVA_OPTS="..." 设置 JVM 参数,解决 Jenkins CSP 安全策略问题
jenkins:latest 使用的镜像名称和标签

步骤 4:查看初始管理员密码

bash 复制代码
docker exec jenkins cat /var/jenkins_home/secrets/initialAdminPassword

输出示例:

复制代码
2b3f4a5c6d7e8f9a0b1c2d3e4f5a6b7c

请务必妥善保存该密码,首次登录时需要使用。

步骤 5:浏览器访问 Jenkins

在浏览器中输入:

复制代码
http://{宿主机IP}:9123

例如:http://192.168.1.100:9123

页面会显示解锁界面,将步骤 4 获取的初始密码粘贴进去,点击继续。

步骤 6:安装插件与创建管理员

  1. 选择插件方案

    • 推荐选择 "安装推荐插件"(Install suggested plugins),自动安装常用插件(Git、Pipeline、Credentials 等)。
    • 也可选择 "选择插件来安装",按需定制。
  2. 等待插件安装完成,过程可能持续数分钟。

  3. 创建管理员用户:填写用户名、密码、全名、邮箱,点击 "保存并完成"。

  4. 实例配置 :确认 Jenkins URL(默认为 http://{宿主机IP}:9123/),用于邮件通知和构建链接。点击 "保存并完成"。

  5. 开始使用 Jenkins:点击 "开始使用 Jenkins" 即可进入主界面。


四、关键配置说明

1. CSP(Content Security Policy)问题

Jenkins 默认对 HTML 等内容有严格的安全策略,会导致某些插件页面(如 HTML Publisher、Allure Report)无法正常显示样式或脚本。

通过 JAVA_OPTS 设置 CSP 规则解决该问题:

bash 复制代码
-e JAVA_OPTS="-Dhudson.model.DirectoryBrowserSupport.CSP=\"default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline';\""

策略解析:

  • default-src 'self':默认只允许加载同源资源
  • script-src 'self' 'unsafe-inline' 'unsafe-eval':允许同源脚本、内联脚本和 eval
  • style-src 'self' 'unsafe-inline':允许同源样式和内联样式

若需完全关闭 CSP(仅测试环境推荐),可使用:

-Dhudson.model.DirectoryBrowserSupport.CSP=""

2. Docker in Docker (DooD) 模式

通过挂载宿主机的 Docker socket 和 Docker 客户端,Jenkins 容器内的构建任务可以直接调用宿主机的 Docker,实现:

  • 在 Pipeline 中构建、推送镜像
  • 运行容器化测试
  • 避免在容器内安装完整的 Docker Daemon

安全提示: 挂载 /var/run/docker.sock 等同于赋予容器 root 级别的宿主机访问权限,请仅在可信环境使用。


五、常用运维操作

1. 容器管理

bash 复制代码
# 查看容器状态
docker ps | grep jenkins

# 启动 / 停止 / 重启
docker start jenkins
docker stop jenkins
docker restart jenkins

# 查看日志
docker logs -f jenkins
docker logs --tail 200 jenkins

# 进入容器
docker exec -it jenkins /bin/bash

2. 备份与恢复

Jenkins 数据全部存放在 /home/jenkins,备份该目录即可:

bash 复制代码
# 备份
sudo tar -czf jenkins_backup_$(date +%Y%m%d).tar.gz -C /home jenkins

# 恢复
sudo systemctl stop jenkins 2>/dev/null || docker stop jenkins
sudo tar -xzf jenkins_backup_YYYYMMDD.tar.gz -C /home
docker start jenkins

3. 升级 Jenkins

bash 复制代码
docker stop jenkins
docker rm jenkins
docker pull jenkins/jenkins:2.411
# 重新执行步骤 3 的 docker run 命令,数据目录保留即可

4. 查看与修改配置

主要配置文件位于宿主机 /home/jenkins/

文件/目录 作用
config.xml Jenkins 全局配置
jobs/ 所有 Job 定义
users/ 用户信息
plugins/ 已安装插件
secrets/ 密钥与凭据
workspace/ 构建工作空间

六、常见问题排查

Q1:访问 http://IP:9123 显示空白或 502

排查思路:

  1. 检查容器是否启动:docker ps -a | grep jenkins

  2. 检查端口是否监听:ss -tunlp | grep 9123

  3. 查看容器日志:docker logs jenkins

  4. 检查防火墙是否放行 9123 端口:

    bash 复制代码
    # CentOS
    sudo firewall-cmd --add-port=9123/tcp --permanent
    sudo firewall-cmd --reload
    # Ubuntu
    sudo ufw allow 9123/tcp

Q2:容器启动失败,日志报权限错误

解决:

bash 复制代码
sudo chown -R 1000:1000 /home/jenkins
# 或以 root 运行(已在脚本中指定 -u root)

Q3:插件页面样式错乱、JS 不执行

原因: Jenkins CSP 策略拦截。

解决: 确认 docker run 时已添加 JAVA_OPTS 参数。若已运行容器,需重启容器使参数生效:

bash 复制代码
docker rm -f jenkins
# 重新执行 docker run 命令

Q4:Pipeline 中无法使用 docker 命令

排查:

  1. 确认挂载了 /var/run/docker.sock/usr/bin/docker

  2. 进入容器测试:

    bash 复制代码
    docker exec -it jenkins docker version
  3. 若宿主机 Docker 路径不是 /usr/bin/docker,需调整为实际路径:

    bash 复制代码
    which docker  # 查找实际路径

Q5:时区不正确,构建时间偏差

解决: 挂载时区文件并设置环境变量:

bash 复制代码
-v /etc/localtime:/etc/localtime:ro \
-e TZ=Asia/Shanghai \

七、完整一键部署脚本

将以下内容保存为 create_jenkins.sh 即可一键部署:

bash 复制代码
#!/bin/bash

# 建议jenkins版本:Version 2.411

mkdir -p /home/jenkins
sudo chown -R 1000:1000 /home/jenkins

# 创建容器(增加 JAVA_OPTS 解决 CSP 问题)
docker run -d \
  --name jenkins \
  -u root \
  -p 9123:8080 \
  -p 50000:50000 \
  -v /home/jenkins:/var/jenkins_home \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -v /usr/bin/docker:/usr/bin/docker \
  -e TZ=Asia/Shanghai \
  -e JAVA_OPTS="-Dhudson.model.DirectoryBrowserSupport.CSP=\"default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline';\"" \
  jenkins/jenkins:2.411

# 等待 Jenkins 启动
echo "等待 Jenkins 启动..."
sleep 20

# 输出访问信息
echo "========================================"
echo "浏览器访问: http://$(hostname -I | awk '{print $1}'):9123"
echo "初始密码:"
docker exec jenkins cat /var/jenkins_home/secrets/initialAdminPassword
echo "========================================"

执行:

bash 复制代码
chmod +x create_jenkins.sh
sudo ./create_jenkins.sh

八、安全加固建议

项目 建议
端口暴露 生产环境使用 Nginx 反向代理并启用 HTTPS
防火墙 仅开放必要端口,限制访问 IP
用户权限 创建非 root 管理员,禁用默认 admin
凭据管理 使用 Credentials 插件而非明文存储
备份策略 定期备份 /home/jenkins,异机存放
插件更新 关注 CVE 公告,及时升级不安全插件
Agent 通信 生产环境使用 JNLP4 over TLS,禁用明文端口

九、总结

通过本教程,你已完成以下事项:

  1. 使用 Docker 部署 Jenkins 单节点
  2. 配置数据持久化与 Docker-in-Docker 构建能力
  3. 解决 CSP 安全策略导致的前端显示问题
  4. 掌握容器日常运维、备份、升级操作
  5. 熟悉常见问题的排查与解决思路

下一步可以:

  • 配置 Agent 节点实现分布式构建
  • 集成 GitLab / GitHub Webhook 实现 CI 自动触发
  • 编写 Jenkinsfile 实现 Pipeline as Code
  • 集成 SonarQube、Allure、Harbor 等工具链

相关推荐
重生的黑客14 小时前
Linux 进程程序替换与自定义 Shell:从 exec 函数族到命令行解释器
linux·运维·服务器·shell
北极糊的狐14 小时前
阿里云服务器-命令2-Linux 系统实时资源监视器 top 命令详解(进程级实时资源监控)
linux·运维·服务器
三言老师15 小时前
clear与history历史命令管理实操
linux·运维·服务器·网络·centos
味悲16 小时前
Linux 环境下 DNS 服务器搭建
linux·运维·服务器
greenbbLV16 小时前
中小公司积分商城选型:SaaS与私有化优劣对比分析
大数据·运维·人工智能
holidaypenguin16 小时前
前端 Docker 开发与生产部署指南
docker·容器
feasibility.17 小时前
wsl安装Ubuntu方法(含网络不稳定处理)
linux·运维·windows·ubuntu
汽车网络安全爱好者17 小时前
Public Key Infrastructure(二)— 深入理解 X.509 证书:从 RFC 5280 到 OpenSSL 实践
运维·服务器·算法·网络安全·汽车·密码学·可信计算技术
江湖有缘17 小时前
保姆级教程:使用Docker一键部署Hoodik轻量级安全云盘
安全·docker·容器
落叶飘飘s18 小时前
彩笔运维勇闯机器学习--梯度下降法
运维·人工智能·机器学习