如果没有-v /var/run/docker.sock,则无法连接到Docker守护程序:/var/run/docker.sock

时间:2019-10-30 06:37:04

标签: docker dockerfile docker-volume docker-dind

我正在尝试在docker容器中运行docker且容器具有nodeJs App。

这是我的 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安装在容器内,但是由于体积(/var/run/docker.sock),主机系统上的所有docker镜像也在容器内共享

如果我在运行容器时不使用卷-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镜像)

2 个答案:

答案 0 :(得分:1)

当您用CMD覆盖默认的Docker-dind node app.js时,它将不会启动Docker服务。因此,您将得到

Cannot connect to the Docker daemon

因为泊坞窗未在您的容器中运行。

因此,解决方法是在后台启动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

enter image description here

答案 1 :(得分:0)

从技术上讲,可以在Docker容器中运行Docker,但通常不建议这样做。 Docker Hub description for the docker image有很多文档,请务必仔细阅读。我通常也不认为从容器内部访问Docker套接字是一种最佳实践,除非它是绝对必要的,并且通常来说,您不应该尝试在单个程序中运行两个程序图片。我会强烈考虑采用其他方法来解决您的更高级别的问题:这既不是标准也不是简单的设置。

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

(但是,等等:网络HTTP对Docker套接字的访问是否会造成安全性灾难?这里有两个缓解措施:由于它位于主机Docker内部,因此存在一层NAT /防火墙,并且您无法访问该嵌套的Docker。套接字,除非您发布它;虽然可以使用它来获得不受限制的根访问,但它只能在嵌套的DinD容器及其内容上进行。

您应该做的第一件事是将Dockerfile重写为标准Node映像。它不应扩展docker映像,因为它不是Docker映像,而是Node-application映像。

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