【问题标题】:Cannot connect to the Docker daemon without -v /var/run/docker.sock:/var/run/docker.sock没有 -v /var/run/docker.sock:/var/run/docker.sock 无法连接到 Docker 守护进程
【发布时间】:2019-10-30 06:37:04
【问题描述】:

我正在尝试在 docker 容器中运行 docker,并且容器具有 nodeJs 应用程序。

这是我的 Dockerfile

FROM docker:dind   
WORKDIR /app  
RUN apk add --update nodejs nodejs-npm  
COPY . /app  
RUN npm install  
CMD node app.js  
EXPOSE 4000

我使用上面的 Dockerfile 构建了 docker 镜像(newdockerimage)并使用docker run -d --privileged -v /var/run/docker.sock:/var/run/docker.sock -v /var/lib/docker:/var/lib/docker newdockerimage 创建了容器。

我可以在容器内安装 docker,但 由于体积的原因,主机系统上的所有 docker 映像也在容器内共享 (/var/run/docker.sock)

如果我在运行容器时不使用音量 -v /var/run/docker.sock:/var/run/docker.sock,我会遇到以下错误:- Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running? 因为容器将是节点应用程序(因为那是入口点),所以覆盖 docker:dind 入口点

请帮帮我!如何在不共享卷的情况下在容器内运行 docker(不复制主机系统的 docker 映像)

【问题讨论】:

    标签: docker dockerfile docker-volume docker-in-docker


    【解决方案1】:

    当您将 Docker-dind 的默认 CMD 覆盖为 node app.js 时,它将不会启动 Docker 服务。所以结果你会得到

    Cannot connect to the Docker daemon
    

    因为 docker 没有在你的容器中运行。

    所以解决方法是在后台启动 docker,在前台启动你的节点应用程序。

    FROM docker:dind   
    WORKDIR /app  
    RUN apk add --update nodejs nodejs-npm  
    COPY app.js /app  
    RUN npm install express
    CMD nohup dockerd &> output & sleep 1 && node app.js  
    EXPOSE 4000
    

    构建镜像并启动容器

    docker run -it --privileged --name test --rm my-docker-dind
    

    【讨论】:

    • 我尝试了您的建议,但得到了相同的错误响应root@ip-*.*.*.*:/home/ubuntu# docker exec -it 1de2a6d8ae23 /bin/sh /app # docker version Client: Docker Engine - Community Version: 19.03.4 API version: 1.40 Go version: go1.12.10 Git commit: 9013bf583a Built: Fri Oct 18 15:49:05 2019 OS/Arch: linux/amd64 Experimental: false Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?
    • 重建镜像了吗?你分配--privileged了吗?你运行的命令应该是docker run -it --privileged --name test --rm my-docker-dind 然后docker exec -it test ash 然后输入docker ps
    • 是的,我重建映像并启动容器,例如 docker run -it --privileged --name test --rm mydockerimage-name
    • docker exec -it test ash -c "docker ps" 这应该可以工作。
    • root@ip---- :/home/ubuntu# docker exec -it test ash -c "docker ps" 无法连接unix:///var/run/docker.sock 上的 Docker 守护进程。 docker 守护进程是否正在运行?
    【解决方案2】:

    在 Docker 容器中运行 Docker 在技术上是可行的,但通常不推荐。 Docker Hub description for the docker image 有很多文档,通读它很重要。我通常也不认为从容器内部访问 Docker 套接字是一种最佳实践,除非它是绝对必要的,并且作为一般规则,您不应该尝试在一个单独的程序中运行两个程序图片。我强烈考虑对您的更高级别问题采取其他方法:这既不是标准也不是简单的设置。

    有两种方法可以访问 DinD 套接字。它通过 TCP-over-TLS 在端口 2376 上发布它,或者如果您在嵌套的 Docker 中运行容器,则用于绑定挂载的“主机系统”是 DinD 容器。

    (但是等等:对 Docker 套接字的网络 HTTP 访问不是安全灾难吗?这里有两个缓解措施:因为它在主机 Docker 内部,所以有一层 NAT/防火墙,您无法访问嵌套的 Docker socket 除非你发布它;虽然你可以使用它来获得不受限制的 root 访问权限,但它只适用于嵌套的 DinD 容器及其内容。)

    您应该做的第一件事是将 Dockerfile 重写为标准的 Node 映像。它不应该扩展 docker 镜像,因为它不是 Docker 镜像,而是节点应用程序镜像。

    FROM node:12
    WORKDIR /app
    COPY . .
    RUN npm install
    CMD node app.js
    EXPOSE 4000
    

    启动 DinD,作为一个单独的容器:

    mkdir certs
    docker network create myapp
    docker run \
      --privileged \
      --net myapp \
      --name docker
      -e DOCKER_TLS_CERTDIR=/certs \
      -v $PWD/certs:/certs \
      -d \
      docker:dind
    

    现在您可以在主机 Docker 上启动一个容器,并给它一个指向嵌套 Docker 的指针

    docker build -t myapp .
    docker run
      --net myapp \
      --name myapp \
      -e DOCKER_HOST=tcp://docker:2376 \
      -e DOCKER_TLS_VERIFY=1 \
      -e DOCKER_CERT_PATH=/certs \
      -v $PWD/certs/client:/certs \
      myapp
    

    或者,您可以在 DinD 设置中运行此容器。

    # Add to the `docker run ... docker:dind` startup
    # -p 127.0.0.1:22376:2376
    export DOCKER_HOST=tcp://localhost:22376
    export DOCKER_TLS_VERIFY=1
    export DOCKER_CERT_PATH=$PWD/certs/client
    
    # These run inside the DinD Docker
    docker build -t myapp .
    docker network create myapp-dind
    docker run
      --net myapp-dind \
      --name myapp \
      -v /var/run/docker.sock:/var/run/docker.sock \
      myapp
    
    # Return to the host Docker
    unset DOCKER_HOST DOCKER_TLS_VERIFY DOCKER_CERT_PATH
    

    【讨论】:

      猜你喜欢
      • 2021-12-06
      • 1970-01-01
      • 2017-08-13
      • 1970-01-01
      • 2022-07-07
      • 2017-11-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多