Jenkins docker部署jenkins,共享宿主机docker资源

摘要:https://blog.csdn.net/zsd498537806/article/details/81132522
摘要2:https://segmentfault.com/a/1190000023261288

我们将 Jenkins 运行在容器中, 而 Jenkins CI 也需要运行 docker 的话, 就会遇到 docker in docker 的问题. 具体请参考: ~jpetazzo/Using Docker-in-Docker for your CI or testing environment? Think twice…

而我们知道, Docker 其实分为两部分: 服务端和客户端. 服务端通过 socket 套接字 或者监听端口接受客户端的命令. 具体可参考官方文档 Configure where the Docker daemon listens for connections.

也就是说如果我们在宿主机上运行了 docker 服务端的话, 我们在容器内可以只安装 docker 客户端, 然后通过 socket套接字 或者 ip+端口 的方式来直接使用宿主的docker 服务. 这样在容器内新建容器, 其实是在宿主机上新建容器.

因为 Docker 服务端和客户端默认使用 socket 套接字进行交互, 所以我们这里也使用 socket套接字 的方案, 即将宿主机的 /var/run/docker.sock 通过映射给 Jenkins 容器.

让容器使用宿主的docker

按照上面的思路, 我们在创建容器的 docker run 命令中增加如下 3 个参数:

-v /var/run/docker.sock:/var/run/docker.sock \
-v /usr/bin/docker:/usr/bin/docker 
-v /etc/docker:/etc/docker \

有关三者的说明

  • -v /var/run/docker.sock:/var/run/docker.sock, 通过映射主机的套接字文件到容器, 让容器内启动 docker * 的时候并不是启动容器内的容器(子容器), 而是启动主机上的容器(兄弟容器).
  • -v /usr/bin/docker:/usr/bin/docker, 让容器中直接使用宿主机的 docker 客户端.
  • -v /etc/docker:/etc/docker, 让容器中的 docker 客户端使用宿主机的 docker 配置文件, 包括国内镜像 (mirrors) 和 非ssl安全访问白名单 等配置.
解决访问宿主 socket 的权限问题

重启容器后, 我们通过 docker exec -it dao_jenkins_1 /bin/bash 命令进入容器, 执行 docker ps 验证 docker 命令是否可正常使用, 结果发现会遇到如下权限问题:

jenkins@f9fd87225ddb:/$ docker ps
Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Get http://%2Fvar%2Frun%2Fdocker.sock/v1.40/containers/json: dial unix /var/run/docker.sock: connect: permission denied

我们先看下 host 上 /var/run/docker.sock 的权限:

faceless@ttg12:~$ ll /var/run/docker.sock
srw-rw---- 1 root docker 0 Jul 16 10:17 /var/run/docker.sock=

可以看到 docker.sock 属于 root 用户 和 docker 组. 映射到容器内的权限为:

jenkins@5affdae1637b:/$ ls -al /var/run/docker.sock
srw-rw---- 1 root 128 0 Jul 16 10:17 /var/run/docker.sock

我们再在容器查看下 jenkins 用户的 user id 和 groupd id:

jenkins@5affdae1637b:/$ id
uid=1000(jenkins) gid=1000(jenkins) groups=1000(jenkins)

我们可以看到 jenkins 的用户id 为 1000, group id 也为 1000. 因此我们的解决方案也有 2 个:
方案一:在宿主机将 socket 文件的所有者改为 user id = 1000 的用户;
方案二:在给容器内的用户增加 group id = 128 的权限.
下面分别讲解.

1、修改宿主机 socket 文件权限设置
将 host 上 docker socket 的拥有者修改为运行 uid=1000 的用户, 或者直接将权限修改为其他人可读写666:

# 修改宿主机上 socket 的 owner 为 id=1000 的用户
sudo chown 1000 /var/run/docker.sock
# 或修改 sock 的权限为 666
sudo chmod 666 /var/run/docker.sock

这个方案无需重启容器, 直接在容器内运行 docker ps 可以看到能输出正常结果.

这个方案是网上大多数文章给出的方案. 但是该方案有一个比较的缺陷, 那就是如果宿主机或者 docker 重启, 会重新创建 docker.sock 文件, 其所有者会被重置为 root 用户, 所以我们又需要再执行上面的命令修改权限.

2、 给予容器 docker 组权限
第二个方案是, 我们给容器内的 jenkins 用户增加 id=128 的组权限. 而正好 docker run 很友好地提供 groupd-add 参数支持该操作.

官方文档 Additional groups🔗
–group-add: Add additional groups to run as
By default, the docker container process runs with the supplementary groups looked up for the specified user. If one wants to add more to that list of groups, then one can use this flag:
$ docker run --rm --group-add audio --group-add nogroup --group-add 777 busybox id
uid=0(root) gid=0(root) groups=10(wheel),29(audio),99(nogroup),777

也就是说我们可一个通过 group-add 参数给容器中的用户通过 group name 或者 group id 添加多个额外的用户组权限, 但是注意: 这个用户组是指容器内的用户组, 其 id 可能跟宿主机上的 id 不一致. 而我们要让容器内的用户拥有 host 的某个 group 权限, 需要通过 id 来赋权.

因此这里我们先看 host 上 docker 组的 id.

faceless@ttg12:~$ cat /etc/group | grep docker
[sudo] password for faceless:
docker:x:128:faceless

可以看到 docker 用户组 id 为 128. 因此我们在创建容器的时候加上 --group-add=128 即可让容器内的 jenkins 用户拥有 /var/run/docker.sock 文件的读写权限:

# 先移除旧容器
sudo docker rm -f dao_jenkins_1
# 重新创建容器
sudo docker run -d -p 8081:8080 -p 50001:50000 \
    -v /data2/jenkins/jenkins_home:/var/jenkins_home \
    -v /etc/localtime:/etc/localtime:ro \
    -v /var/run/docker.sock:/var/run/docker.sock \
    -v /etc/docker:/etc/docker \
    -v /usr/bin/docker:/usr/bin/docker \
    --restart=always  \
    --group-add=128 \
    --name dao_jenkins_1 \
    jenkins/jenkins:2.235.1-lts
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值