最近尝试升级 Jenkins,但升级后无法启动。经过排查,发现原因是 JDK 版本过低:旧版本使用的是 JDK 8,而新版本需要 JDK 17。为了省去升级 JDK 的麻烦,索性直接将其迁移到容器版本,一劳永逸地解决了环境依赖问题。
准备工作
目录权限
- Jenkins容器版本内部使用jenkins用户运行,用户ID为
1000
,所以Jenkins数据目录也需要设置为1000
- 可以使用命令
id 1000
查看具体的用户名称,我的1000用户名是debian
- 还需要将
debian
用户加入docker用户组,以便有docker客户端的执行权限
完整的命令为:
# 查看id 1000对应的用户
id 1000
# debian这个用户加入docker用户组
usermod -aG docker debian
# 立即刷新用户组权限
newgrp docker
# 设置jenkins_home目录权限
chown -R debian:docker ./jenkins_home
Docker安装Jenkins
为了方便后续维护,xiaoz选择使用Docker Compose安装Jenkins,docker-compose.yaml
内容如下:
version: '3.8'
services:
jenkins:
container_name: jenkins
image: jenkins/jenkins:lts-jdk17
ports:
- "8080:8080"
- "50000:50000"
volumes:
- ./jenkins_home:/var/jenkins_home
- /var/run/docker.sock:/var/run/docker.sock # 挂载 Docker Socket
- /usr/bin/docker:/usr/bin/docker
- /usr/libexec/docker/cli-plugins:/usr/libexec/docker/cli-plugins
restart: unless-stopped
user: "1000:994"
参数含义如下:
./jenkins_home:/var/jenkins_home
:将本机的./jenkins_home
目录挂载到容器内,用于持久存储数据,请根据实际情况修改为您的路径。/var/run/docker.sock:/var/run/docker.sock
:将Docker进程挂载到Jenkins容器内,便于后续自动化可以使用Docker/usr/bin/docker:/usr/bin/docker
:将Docker客户端挂载到Jenkins容器内(因为Jenkins容器是没有安装Docker客户端的)/usr/libexec/docker/cli-plugins:/usr/libexec/docker/cli-plugins
:将Docker插件映射到容器内,不然后续无法使用Buildxuser: "1000:994"
:对应用户ID和用户组ID,第一个用户ID必须是1000
,否则会出现权限问题,994
是用户组,对应Docker用户组的ID
然后输入命令docker-compose up -d
启动容器,一切顺利的话访问:http://IP:8080
即可打开Jenkins
使用Buildx
Docker Buildx 是一个扩展工具,用于增强 Docker 的构建功能,支持多平台构建(如 ARM、x86 等)、并行构建和高级缓存管理,帮助用户更高效地创建和管理容器镜像。如果您不需要构建跨平台镜像,可以暂时不使用Buildx!
先在宿主执行下面的命令:
# 查看buildx版本
docker buildx version
# 创建一个新的 Buildx 构建器实例
docker buildx create --name multiarch --driver docker-container --bootstrap
# 切换到指定的 Buildx 构建器实例
docker buildx use multiarch
# 显示 Buildx 构建器的详细信息
docker buildx inspect --bootstrap
执行完毕后再去容器里面执行一遍:docker exec -it jenkins /bin/bash
,还是上面的命令:
# 查看buildx版本
docker buildx version
# 创建一个新的 Buildx 构建器实例
docker buildx create --name multiarch --driver docker-container --bootstrap
# 切换到指定的 Buildx 构建器实例
docker buildx use multiarch
# 显示 Buildx 构建器的详细信息
docker buildx inspect --bootstrap
这样就可以使用buildx构建跨平台镜像了,比如:
docker buildx build --platform linux/amd64,linux/arm64 -t ${IMAGE_NAME}:${VERSION} . --push
推送Docker镜像
宿主上的Docker和Jenkins容器内部的Docker配置文件位置不一样,即使您宿主上已经登录Docker,Jenkins容器内还需要再次执行一遍登录。
需要在Jenkins容器内执行:
# 登录Docker
docker login
登录后数据会持久保存到jenkins_home
,所以这个只需要操作一次,后续不用每次都登录。
结语
容器化安装Jenkins相比直接在宿主机上安装会面临更多挑战,尤其是在使用Docker Buildx构建跨平台镜像时。尽管Jenkins官方推荐使用DIND
(Docker-in-Docker)模式来连接Docker,但在实践中发现Buildx在DIND
模式下存在诸多问题,最终为了简化流程,只能选择通过sock
模式运行,虽然安全性可能有所降低,但具体方案仍需根据业务需求进行评估。