我有一个非常特定的开发环境用例。在某些代码中,我启动了一个容器以刮取页面并检索在容器中运行的服务(Gitlab)的令牌。
现在,我希望对运行此代码的代码进行Dockerize。具体来说,是这样的:
out, err := exec.Output("docker", "run", "--net=host", "--rm", "-e", "URL=http://127.0.0.1:8081", "-e", "USER=root", "-e", "PWD=adminadmin", "some image")
但是,在容器中运行此代码时,显然我的代码会抛出panic: exec: "docker": executable file not found in $PATH
,因为在容器中无法识别docker
。
如何在Docker容器中安装Docker?我可以以某种方式与主机绑定吗?这种情况应该发生在Dockerfile
中,还是可以通过我用来旋转它的docker-compose.yml
文件来定义这种行为?
我在OSX上。 which docker
的输出为/usr/local/bin/docker
答案 0 :(得分:2)
是的,有可能,它在docker中被称为docker或DinD。
甚至不必介意自己安装docker-docker的official dind image带有广泛的标签。
答案 1 :(得分:0)
所以,我刚在docker for windows
的Mac上尝试过:
docker-compose.yaml:
version: '3'
services:
app:
image: ubuntu:16.04
volumes:
- /usr/local/bin/docker:/usr/local/bin/docker
- /var/run/docker.sock:/var/run/docker.sock
command: docker version
执行:
MAC-MINI:try guest$ docker-compose up
Starting try_app_1 ... done
Attaching to try_app_1
app_1 | Client: Docker Engine - Community
app_1 | Version: 18.09.2
app_1 | API version: 1.39
app_1 | Go version: go1.10.8
app_1 | Git commit: 6247962
app_1 | Built: Sun Feb 10 04:11:44 2019
app_1 | OS/Arch: linux/amd64
app_1 | Experimental: false
app_1 |
app_1 | Server: Docker Engine - Community
app_1 | Engine:
app_1 | Version: 18.09.2
app_1 | API version: 1.39 (minimum version 1.12)
app_1 | Go version: go1.10.6
app_1 | Git commit: 6247962
app_1 | Built: Sun Feb 10 04:13:06 2019
app_1 | OS/Arch: linux/amd64
app_1 | Experimental: false
try_app_1 exited with code 0
使用docker守护进程和主机的docker客户端似乎都可以。
如果您打算使用从主机挂载的docker client
,也可以使用静态二进制文件,请参见how to install static binary
更新:
此外,我尝试运行一个真实的容器,而不仅仅是像下面的docker version
:
services:
app:
image: ubuntu:16.04
volumes:
- /usr/local/bin/docker:/usr/local/bin/docker
- /var/run/docker.sock:/var/run/docker.sock
command: docker run --rm hello-world
It's still ok as next:
$ docker-compose up
Recreating try_app_1 ... done
Attaching to try_app_1
app_1 | Unable to find image 'hello-world:latest' locally
app_1 | latest: Pulling from library/hello-world
app_1 | 1b930d010525: Pulling fs layer
app_1 | 1b930d010525: Download complete
app_1 | 1b930d010525: Pull complete
app_1 | Digest: sha256:6540fc08ee6e6b7b63468dc3317e3303aae178cb8a45ed3123180328bcc1d20f
app_1 | Status: Downloaded newer image for hello-world:latest
app_1 |
app_1 | Hello from Docker!
app_1 | This message shows that your installation appears to be working correctly.
app_1 |
app_1 | To generate this message, Docker took the following steps:
app_1 | 1. The Docker client contacted the Docker daemon.
app_1 | 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
app_1 | (amd64)
app_1 | 3. The Docker daemon created a new container from that image which runs the
app_1 | executable that produces the output you are currently reading.
app_1 | 4. The Docker daemon streamed that output to the Docker client, which sent it
app_1 | to your terminal.
app_1 |
app_1 | To try something more ambitious, you can run an Ubuntu container with:
app_1 | $ docker run -it ubuntu bash
app_1 |
app_1 | Share images, automate workflows, and more with a free Docker ID:
app_1 | https://hub.docker.com/
app_1 |
app_1 | For more examples and ideas, visit:
app_1 | https://docs.docker.com/get-started/
app_1 |
try_app_1 exited with code 0
根据@PierreB的建议进行的第二次更新,以添加有关如何使用静态二进制文件的更多信息:
从https://download.docker.com/下载,选择一个适合您目标映像的软件包,例如,如果目标映像是linux,则从here下载。
将二进制文件解包到当前文件夹,您会看到名称为docker
的Docker客户端,它是一个独立的二进制文件。
将docker-compose.yaml更改为next,以将该静态二进制文件从主机安装到容器:
services:
app:
image: ubuntu:16.04
volumes:
- ./docker:/usr/local/bin/docker
- /var/run/docker.sock:/var/run/docker.sock
command: docker run --rm hello-world
答案 2 :(得分:0)
这里发生了2种不同的事情:
为了在运行中的容器中安装客户端,您似乎使用了基于debian的golang映像,您可以:apt-get update && apt-get install -yq docker
在这一点上,如果您尝试执行docker run
命令,您将得到类似:
docker: Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?.
这意味着您现在必须为Docker客户端提供一个工作的docker服务器。如Efrat Levitan's answer中所述,可以通过运行另一个容器(称为服务)并运行dind
(docker中的docker)来完成此操作。然后,您将必须定义变量DOCKER_HOST: tcp://<docker_server_address>:2375/
。地址将取决于您的设置以及如何启动容器。
另一种方法可以替换主机docker套接字(不建议这样做,因为它可能会导致数据损坏)。
要了解其中的含义,您可能需要阅读Jérôme Petazzoni's article有关docker中的docker的信息。