大家好,又见面了,我是你们的朋友全栈君。
最近在制作给kubernetes jenkins plugin调用的jenkins slave(默认情况下,kubernetes jenkins插件使用的是jenkinsci/jnlp-slave)容器镜像,以供自动创建的pod使用。对这个镜像的需求是:希望在pod运行的容器内,执行docker命令,完成docker build, push等一些操作,即docker in docker。
首先,需要在容器的镜像里面也安装docker包。然后,通过挂载宿主机的/var/run/docker.sock文件,可以在容器内使用docker命令,而且是跟在当前的宿主机上执行一样。
但是制作的jenkins-slave容器里使用的账号是非root账号jenkins,导致对/var/run/docker.sock没有访问权限,报错如下:
通常,为了使非root用户能够执行docker命令,解决办法是:将该用户添加到docker组。
代码语言:javascript复制usermod -G docker jenkins
这种方法,在宿主机上配置后,用jenkins用户运行docker是没有问题的,但是容器里面执行docker命令还是报错。分析原因应该是:容器里和宿主机上的docker组的id不一样导致的。 容器里:
宿主机上:
如上试验发现,容器里docker的组id是996,宿主机上的则为989。这就尴尬了。。。难道就只有用root用户运行了吗?
后来想到通过su命令,jenkins账号可以切换到root命令,于是想到了一种方案。设脚本docker2内容如下:
代码语言:javascript复制#!/bin/bash
echo "your_password" | su - root -c "/usr/bin/docker $*"
用这个脚本替代原有的docker命令,这样在执行docker命令之前先完成root用户切换,再执行docker命令。如:docker2 ps就等价于执行了原生的docker ps命令。
不过,这样明文写了容器的root密码在脚本里,可能会不太安全。如果不想这样,可以直接用root用户来运行jenkins slave的容器。但这样jenkins slave的进程也将是按root用户运行了。
另外,实现docker in docker必须要docker里也安装docker包吗? 试验使用docker镜像里没有再安装docker包的镜像,只是通过挂载宿主机的/usr/bin/docker, /var/run/docker.sock来运行容器。发现在该容器里执行docker命令时会出现类似如下的报错:
代码语言:javascript复制/usr/bin/docker: error while loading shared libraries: libltdl.so.7: cannot open shared object file: No such file or directory
也就是说,在执行docker命令时,并不是一个docker二进制文件就可以通过/var/run/docker.sock来跟宿主机的docker进程交互,还依赖一些其它的库包。在docker里再安装docker包的目的就是为了给docker提供一个完整的运行环境。
备注: 试验用的docker版本是17.03.2-ce,安装了docker包的容器镜像比没安装的镜像大小会多出100M。
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/145782.html原文链接:https://javaforall.cn