使用Docker部署Jenkins遇到的一些问题
文章目录
Jenkins使用Docker部署会出现一些问题。比如我要在容器里面的
Jenkins
用docker-compose构建其他服务,就会出问题,因为jenkins在docker里面,无法与docker daemon通信,这是第一个问题,这个问题有两种解决方案:1.
docker in docker
. 2.
docker outside docker
。第一种方案就是在jenkins容器里面安装一个完整的docker。第二种方案就是想办法与外部的docker daemon进行通信。这里选择第二种方法,因为第一种方案实践起来可能比较麻烦,会有很多问题,比如网络,管理等问题
第二种方法遇到的问题就是权限问题。
权限的问题有两种处理方式:1.使用privileged特殊容器权限 2.在容器内将
jenkins
用户加入docker用户组
总结遇到的问题:
- 无法与外部docker daemon通信
- 使用docker sock 通信的权限处理问题
-
使用
privileged
特殊容器权限的问题
如何与docker daemon通信
与外部docker daemon进行通信也有两种方法,一种是使用docker-compose context,一种是docker scok。第一种方法可以实现docker daemon与docker daemon之间通信。第二种是通过docker daemon预留的套接字接口,与docker daemon进行通信。根据场景,这里选择了第二种方法。
首先,需要将docker sock挂载到容器,这个很简单,只要添加挂载代码就行
volumes:
- /var/run/docker.sock:/var/run/docker.sock
接下来在Jenkins中使用docker-compose部署其他服务时会遇到另一个问题,权限问题:
permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock
docker daemon访问权限处理方式
这个权限处理有两种方式:1.使用
privileged
特殊容器权限。2. 在容器创建并将
jenkins
加入用户组
我一开始使用的是第一种方法,这种方法很简单,只需要在
jenkins
的
docker-compose
文件添加下面两个参数
services:
jenkins:
build: .
restart: always
container_name: jenkins
ports:
- 8080:8080
volumes:
- /var/run/docker.sock:/var/run/docker.sock
# privileged: true # 添加这一行
# user: root # 添加这一行
使用privileged参数后出现的问题
主要的问题是在
Jenkins
从
gogs
拉取项目的时候报错:
> git rev-parse --resolve-git-dir /var/jenkins_home/workspace/snowball/.git # timeout=10
Fetching changes from the remote Git repository
> git config remote.origin.url http://gogs:3000/leon/snowball.git # timeout=10
ERROR: Error fetching remote repo 'origin'
Caused by: hudson.plugins.git.GitException: Command "git config remote.origin.url http://gogs:3000/leon/snowball.git" returned status code 128:
虽然它提示是
128
代码,以为是权限问题,但实际上我将仓库改为公开后,仍然会提示这个问题,但是我从
terminal
进入容器是可以正常使用
clone
命令拉取代码的,折腾了一段时间,确实搞不明白是什么原理。但是发现只要将
privileged
和
user
注释掉就可以正常运行。
于是开始尝试第二种方法
将jenkins用户加入docker用户组
非常简单,只需要在Dockerfile中加入两行代码,并指定用户:
RUN groupadd docker
RUN usermod -a -G docker jenkins
USER jenkins
至此,问题解决。
安全风险问题
其实这两种方法都有安全风险问题。因为这样做就相当于给
Jenkins
加了一个权限,
Jenkins
可以通过
docker sock
与
docker daemon
进行通讯,从而操作其他容器。因此在使用时需要权衡这种方法。