容器内执行docker命令


大部分情况下,Docker通过主机(host)来查看和控制容器,

其实还有其他的方式,API和容器内部,这里我们主要讲在容器内部执行docker命令。

要实现这样的操作,有几个条件:

  1. 主机的/var/run/docker.sock文件挂载到容器中
  2. 主机的/usr/bin/docker文件挂载到容器中
  3. 容器中的用户有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文件的只有两个:

  • UID0root用户
  • GID999docker用户组。

根据这两个,我们有了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(不同镜像构建出来的容器用户不一定一样),后面的999docker用户组的GID

如果用Host当前用户的UID和GID,可以用id命令:

--user $(id -u):$(id -g)

这里,我们不能用环境变量$UID$GID,也不能用$(whoami),因为容器中并不知道你的用户名,会提示:I have no name!这样的信息。

参考资料:

« »

发表评论

电子邮件地址不会被公开。 必填项已用*标注

昵称 *