大部分情况下,Docker通过主机(host)来查看和控制容器,
其实还有其他的方式,API和容器内部,这里我们主要讲在容器内部执行docker命令。
要实现这样的操作,有几个条件:
- 主机的
/var/run/docker.sock
文件挂载到容器中 - 主机的
/usr/bin/docker
文件挂载到容器中 - 容器中的用户有docker执行权限(默认情况下只有root用户和docker用户组有这个权限)
1 配置
如下是一个例子:
$ docker run --rm -it \ -v /var/run/docker.sock:/var/run/docker.sock \ -v /usr/bin/docker:/usr/bin/docker \ ubuntu \ /bin/bash
这里我们用ubuntu镜像创建一个容器,创建完成后直接进入容器内部执行:
# docker ps
这是可以的,我们可以看到列出了所有的容器,说明我们已经实现了在容器中控制Host中的docker。
经测试,同样的步骤alpine容器会提示
/bin/sh: docker: not found
错误,暂不知道原因和解决办法。
2 权限问题
不过呢,如果我们用php-fpm,mysql这样的镜像,就会遇到这样的权限错误:
Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Post http://%2Fvar%2Frun%2Fdocker.sock/v1.39/images/create?fromImage=python&tag=2-alpine: dial unix /var/run/docker.sock: connect: permission denied script returned exit code 1
这是因为容器内部的用户没有执行docker的权限!!!
那么,我们可以先看看谁有这个权限:
$ stat /var/run/docker.sock ... Access: (0660/srw-rw----) Uid: ( 0/ root) Gid: ( 999/ docker) ...
这里我们标出权限相关的一行,可以看到,能Access文件/var/run/docker.sock
文件的只有两个:
-
UID
为0
的root
用户 -
GID
为999
的docker
用户组。
根据这两个,我们有了2个解决办法:
2.1 指定容器用root用户
docker run --rm -it \ --user root\ -v /var/run/docker.sock:/var/run/docker.sock \ -v /usr/bin/docker:/usr/bin/docker \ mysql \ /bin/bash
2.2 设置容器中的用户为docker
用户组
docker run --rm -it \ --user "999:999"\ -v /var/run/docker.sock:/var/run/docker.sock \ -v /usr/bin/docker:/usr/bin/docker \ mysql \ /bin/bash
其中,--user
中冒号前的999
是容器用户的UID
(不同镜像构建出来的容器用户不一定一样),后面的999
是docker
用户组的GID
。
如果用Host当前用户的UID和GID,可以用id
命令:
--user $(id -u):$(id -g)
这里,我们不能用环境变量$UID
或$GID
,也不能用$(whoami)
,因为容器中并不知道你的用户名,会提示:I have no name!
这样的信息。
参考资料: