龙芯3B6000服务器上基于Docker部署Jenkins的完整实践指南
最近在帮一个团队做国产化环境下的持续集成方案,他们用的是一台龙芯 3B6000 的服务器。说实话,一开始听到“在龙芯上用 Docker 跑 Jenkins”这个需求,我脑子里闪过的第一个念头是:这会不会是个“缝合怪”组合?毕竟,龙芯的 LoongArch 架构、Docker 的容器化、Jenkins 的自动化,这三者凑一起,听起来就像要把三个不同世界的规则手册拼成一本。
但真正上手后,我发现事情比想象中有趣,也更有代表性。这不仅仅是一次简单的软件安装,更像是一次对“在非主流架构上构建标准化工程能力”的完整压力测试。你会遇到从 CPU 指令集、操作系统适配、容器运行时到应用配置的完整链路问题。而解决这些问题的过程,恰恰能帮你把 Jenkins 和 Docker 的理解,从“会用”推进到“懂为什么这么用”的层面。
所以,这篇文章不会是一份简单的“apt-get install”清单。我想和你聊聊,在龙芯 3B6000 这样的平台上,如何系统性地思考和完成 Jenkins 的 Docker 化部署。我们会从最底层的环境适配开始,一步步走到一个稳定、可维护的 CI/CD 流水线。过程中那些关于镜像、网络、存储和权限的“坑”,才是真正有价值的部分。
1. 先别急着docker run:理解龙芯平台的特殊性
很多人一上来就找 Jenkins 的 Docker 镜像,然后docker run,结果大概率会碰壁。在龙芯 3B6000 上,第一步必须是认清战场环境。这不是 X86,也不是 ARM,而是 LoongArch。
1.1 架构差异是根本:为什么通用镜像不工作
你从 Docker Hub 上直接拉取的jenkins/jenkins:lts镜像,默认是为linux/amd64或linux/arm64构建的。龙芯 3B6000 的 LoongArch 架构(通常标识为loong64)与它们指令集不兼容。直接运行会导致类似exec format error的错误。
这引出了第一个核心认知:在异构平台上,软件生态的完备性直接决定了部署的复杂度。对于 Jenkins 这种复杂的 Java 应用,我们需要的不是一个简单的二进制文件,而是一整套包含正确架构的 JRE、依赖库和 Jenkins 本身的运行时环境。
怎么办?你有三条路:
- 寻找官方或社区提供的
loong64镜像:这是最理想的情况。幸运的是,随着龙芯生态的完善,一些基础镜像和流行软件的 LoongArch 版本已经开始出现。你需要去 Docker Hub 或其他镜像仓库搜索带有loong64标签的镜像。 - 基于 LoongArch 的基础镜像自行构建:如果没有现成的 Jenkins 镜像,你需要从龙芯提供的 LoongArch 版本的基础操作系统镜像(如
loongnix、openanolis/loong64等)开始,自己编写 Dockerfile,安装 JDK,再安装 Jenkins。这考验你对 Dockerfile 和 Jenkins 依赖的理解。 - 使用
binfmt_misc与 QEMU 进行跨架构模拟:这是一种取巧但可能有性能损耗和兼容性风险的方法。通过在宿主机上注册 QEMU 用户态模拟器,让 Docker 能够运行非本机架构的镜像。对于学习和测试可以,但对于生产环境的 CI/CD 服务器,我不推荐。
我们的主攻方向应该是前两条。在开始之前,先用命令确认你的系统架构:
uname -m如果输出是loongarch64,那么你就站在了正确的起点上。
1.2 操作系统与内核:确保容器引擎的基石稳固
Docker 的运行依赖于 Linux 内核的特定功能,如命名空间、控制组(cgroup)和存储驱动。龙芯的主流发行版(如 Loongnix、Anolis OS LoongArch 版)通常已经包含了这些支持。
但在安装 Docker 之前,最好做一次快速检查:
- 内核版本:
uname -r,确保不是过于陈旧的版本。 - cgroup 支持:检查
/proc/filesystems是否包含cgroup和cgroup2。现代 Docker 更倾向于 cgroup v2。 - 存储驱动:龙芯平台常用的
overlay2驱动需要内核支持。可以grep overlay /proc/filesystems确认。
这些检查是为了避免 Docker 安装后无法启动,或者容器运行出现一些底层错误。一个稳定的宿主系统,是容器化一切的前提。
1.3 网络与存储规划:提前想好,避免后期搬家
在物理服务器或虚拟机上部署服务,我们通常会规划 IP、磁盘挂载。在容器化部署时,这个思维习惯同样重要,甚至更重要,因为容器是“临时”的,数据需要持久化。
- 网络模式:Jenkins 作为 CI/CD 大脑,需要被构建节点(Agent)和开发人员访问。最简单的就是使用 Docker 的
bridge网络,并通过-p参数将容器的 8080 端口映射到宿主机的某个端口(如 8080)。如果需要更复杂的网络隔离或使用宿主网络,需要提前规划。 - 数据持久化:Jenkins 的所有配置、任务、插件、构建日志都必须存储在容器之外,否则容器一删除,一切归零。我们必须通过 Docker 的
-v或--mount参数,将宿主机的目录挂载到容器内的/var/jenkins_home。这个宿主机目录的权限、磁盘空间和备份策略,都需要事先考虑。
把环境特殊性、网络和存储这三个问题想清楚,我们才能写出一个真正能用的docker run命令,而不是一个跑起来就报错或数据丢失的“一次性玩具”。
2. 实战部署:从拉取镜像到服务就绪
理论清晰后,我们进入动手环节。假设我们选择最理想的路径:找到了一个可用的loong64架构的 Jenkins 镜像。
2.1 获取与验证镜像
首先,搜索并拉取镜像。镜像名称可能因来源而异,例如:
docker pull jenkins/jenkins:lts-loong64 # 或者来自某个特定的仓库 # docker pull registry.example.com/jenkins:loongarch64拉取完成后,强烈建议验证其架构:
docker image inspect jenkins/jenkins:lts-loong64 --format='{{.Architecture}}'确认输出是loong64或loongarch64。
注意:如果找不到官方
loong64镜像,你可能需要基于openanolis/loong64或cr.loongnix.cn/library/loongnix这类基础镜像自行构建。这需要你熟悉 Jenkins 的安装流程和依赖,并编写一个多阶段的 Dockerfile 来优化镜像大小。
2.2 准备持久化存储与首次运行
在宿主机上创建一个目录用于存放 Jenkins 的所有数据,并确保当前用户有读写权限(因为容器内 Jenkins 进程通常以jenkins用户运行,UID 通常是 1000)。
sudo mkdir -p /var/jenkins_home sudo chown -R 1000:1000 /var/jenkins_home # 将所有权赋予 UID 1000 # 如果不确定,也可以放宽权限,但生产环境不建议 777 # sudo chmod 777 /var/jenkins_home现在,运行你的第一个 Jenkins 容器:
docker run -d \ --name my-jenkins \ -p 8080:8080 \ -p 50000:50000 \ -v /var/jenkins_home:/var/jenkins_home \ -v /var/run/docker.sock:/var/run/docker.sock \ jenkins/jenkins:lts-loong64解释一下参数:
-d: 后台运行。--name: 给容器起个名字,方便管理。-p 8080:8080: 将容器内 Jenkins Web 界面的 8080 端口映射到宿主机 8080。-p 50000:50000: 映射 JNLP 端口,用于连接基于 Java 的构建代理(Agent)。-v /var/jenkins_home:/var/jenkins_home:最关键的一步,将宿主机目录挂载到容器内,实现数据持久化。-v /var/run/docker.sock:/var/run/docker.sock:可选但强大。这将宿主机的 Docker 守护进程套接字挂载到容器内,使得 Jenkins 容器可以直接调用宿主机的 Docker 命令(即所谓的 “Docker-out-of-Docker” 或 “DooD”)。这样,你的 Jenkins Pipeline 就可以创建和管理其他 Docker 容器(用于构建、测试),这在 CI/CD 中非常常见。但请注意安全风险,这相当于给了 Jenkins 容器很高的宿主机权限。- 最后的
jenkins/jenkins:lts-loong64是你的镜像名。
2.3 初始解锁与插件安装
容器运行后,访问http://<你的服务器IP>:8080。你会看到 Jenkins 的解锁页面。
- 获取初始密码:通过
docker logs my-jenkins命令查看容器日志,找到类似Jenkins initial password is: xxxxxxxxxxxxxxxxxxxxxx的行,复制密码填入 Web 页面。 - 安装推荐插件:接下来 Jenkins 会建议安装一批常用插件。在龙芯环境下,这里可能遇到第一个挑战。由于网络和架构原因,从 Jenkins 官方更新中心下载插件可能会很慢,甚至失败。建议选择“安装推荐插件”,但要有耐心。如果某些插件反复失败,可以后续在“插件管理”中单独安装。
- 创建管理员用户:按照提示完成初始管理员账户设置。
至此,一个最基本的 Jenkins 服务已经在你的龙芯 3B6000 上跑起来了。但这只是万里长征第一步,一个能看的管理界面,离一个可用的 CI/CD 引擎还差得远。
3. 配置优化与核心问题排查
服务起来后,真正的工程化工作才开始。你需要把它配置得稳定、高效、安全。
3.1 插件管理:网络与架构兼容性
插件是 Jenkins 的灵魂,也是问题高发区。
- 更新站点:默认的官方更新站点可能较慢。你可以考虑更换为国内的镜像源(如清华、华为镜像源)。在“插件管理” -> “高级” -> “升级站点”中修改 URL。但请注意,镜像源的插件索引更新可能有延迟。
- 架构兼容性:绝大多数 Jenkins 插件是纯 Java 的
.jpi或.hpi文件,与 CPU 架构无关,这是好消息。但极少数插件可能包含原生(Native)库(例如某些通过 JNI 调用本地代码的插件)。这类插件在 LoongArch 上很可能无法工作。安装时需留意错误信息。通常,核心的 Git、Pipeline、Docker 等插件都没有问题。 - 离线安装:如果网络问题无法解决,可以手动从 Jenkins 插件官网 下载插件
.hpi文件,然后在“高级”选项卡中通过“上传插件”进行离线安装。
3.2 性能与资源调优
龙芯 3B6000 的性能与同代 X86 处理器有差异,合理的资源限制很重要。
- JVM 参数:Jenkins 是 Java 应用,可以通过环境变量调整其内存。在
docker run时添加:
这里将最大堆内存设为 2GB,初始堆内存 512MB。请根据你的服务器实际内存调整(例如 8GB 内存的机器,给 Jenkins 分配 4GB 是合理的)。-e JAVA_OPTS="-Xmx2048m -Xms512m" - Docker 资源限制:使用
--cpus、--memory等参数限制容器资源,防止单个容器耗尽主机资源。docker run -d --name my-jenkins --cpus="2.0" --memory="4g" ...
3.3 常见问题与排查链路
部署过程中,你大概率会遇到一些问题。别慌,按这个顺序排查:
现象:容器启动后立即退出。
- 排查:
docker logs my-jenkins看最后几行错误信息。最常见的是:- 权限问题:
/var/jenkins_home目录权限不对,Jenkins 用户无法写入。用ls -la /var/jenkins_home检查,并用chown修正。 - 端口冲突:宿主机 8080 端口已被占用。用
netstat -tlnp | grep 8080检查,修改-p参数映射到其他端口,如-p 8081:8080。 - 架构错误:镜像架构不匹配。用
docker image inspect确认。
- 权限问题:
- 排查:
现象:能访问网页,但非常卡顿,或插件安装失败。
- 排查:
- 网络:在容器内
docker exec -it my-jenkins bash,然后ping www.baidu.com或curl -I https://updates.jenkins.io,检查网络连通性。 - 资源:用
docker stats my-jenkins查看容器 CPU 和内存使用情况,判断是否资源不足。 - 磁盘 I/O:如果宿主机磁盘性能差,也会导致 Jenkins 响应慢。检查
/var/jenkins_home所在磁盘的利用率(df -h)和 IO 等待(iostat)。
- 网络:在容器内
- 排查:
现象:Pipeline 中执行 Docker 命令失败(如果挂载了 Docker Socket)。
- 排查:
- 在 Jenkins Pipeline 的
sh步骤中,运行docker version或docker info,看是否正常。 - 检查容器内
/var/run/docker.sock的文件权限,确保 Jenkins 进程(通常是jenkins用户)有访问权限。有时需要将 Jenkins 用户加入宿主机的docker组(通过在 Dockerfile 中创建用户并指定 GID),或者在宿主机上调整/var/run/docker.sock的权限(不推荐,有安全风险)。
- 在 Jenkins Pipeline 的
- 排查:
4. 从“能用”到“好用”:构建龙芯原生 CI/CD 流水线
Jenkins 部署成功只是拿到了入场券。在龙芯平台上,CI/CD 流水线的构建有其特殊意义——你很可能是在为一个 LoongArch 架构的软件项目进行构建和测试。这意味着你的构建环境(Agent)也需要是 LoongArch 的。
4.1 构建节点的选择:静态 Agent 与 Docker 动态 Agent
- 静态 Agent(常驻节点):在另一台(或同一台)龙芯机器上部署一个 Jenkins Agent,将其注册到 Jenkins Master。这种方式稳定,适合需要固定环境或大量依赖的构建任务。你需要准备 LoongArch 版本的 JDK、Maven/Gradle、Node.js 等工具链。
- Docker 动态 Agent(推荐):这是更云原生、更灵活的方式。利用前面提到的 Docker Socket 挂载,在 Jenkins Pipeline 中,使用
docker或dockerfile代理,动态启动一个基于 LoongArch 镜像的容器来执行构建步骤。
例如,一个简单的 Jenkinsfile 可能如下:
pipeline { agent { docker { image 'openanolis/loong64:8' // 使用一个LoongArch的基础镜像 args '-v /tmp:/tmp' // 可以挂载一些必要卷 } } stages { stage('Build') { steps { sh 'uname -m' // 这里应该输出 loongarch64 sh 'java -version' // 在这里执行你的编译命令,例如 mvn clean package } } } }这种方式能确保每次构建都在一个纯净、一致的 LoongArch 环境中进行,非常适合自动化。
4.2 镜像仓库与依赖加速
在龙芯生态中,软件源和镜像仓库是另一个需要关注的点。
- 基础镜像:寻找可靠的 LoongArch 基础镜像源,如
cr.loongnix.cn(龙芯开源镜像站)、openanolis等。 - 依赖代理:对于 Maven、NPM、Pip 等依赖下载,配置国内镜像源或公司内部代理至关重要,能极大提升构建速度。这些配置可以写在构建容器的 Dockerfile 里,或者通过 Jenkins 的“全局工具配置”注入环境变量。
4.3 安全与维护建议
- 定期备份
/var/jenkins_home:这是你的全部身家。使用tar或rsync定期备份整个目录到异地。 - 升级策略:Jenkins 和插件定期有安全更新。升级前,务必在测试环境验证,并完整备份。对于 Docker 部署,升级通常意味着:拉取新镜像,停止旧容器,用新镜像启动并挂载原有的数据卷。
- 控制权限:谨慎使用 Docker Socket 挂载。如果不需要在 Pipeline 中动态创建容器,就不要挂载。如果必须挂载,要严格控制 Jenkins 项目的权限,避免执行任意危险的 Docker 命令。
- 监控:监控 Jenkins 容器的资源使用(CPU、内存、磁盘)、日志中的错误信息,以及构建队列的长度。
在龙芯 3B6000 上通过 Docker 部署 Jenkins,最终交付的不仅仅是一个自动化工具。它是一套验证过的、在国产化平台上构建现代软件工程能力的可行路径。从克服架构差异,到配置持久化存储,再到构建真正可用的 LoongArch 原生流水线,每一步都在加深你对容器化、基础设施即代码和持续集成的理解。
当你看到第一个为 LoongArch 平台编译的软件包通过这条流水线自动构建、测试并发布时,你就会明白,所有的前期折腾都是值得的。这不再是简单的技术移植,而是在一个新的计算基石上,重建高效、标准的开发运维工作流。