Невозможно подключиться к демону Docker без -v /var/run/docker.sock:/var/run/docker.sock

Я пытаюсь запустить докер внутри контейнера докеров, а в контейнере есть приложение 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

Я создал образ докера (newdockerimage), используя указанный выше файл Dockerfile и создав контейнер, используя docker run -d --privileged -v /var/run/docker.sock:/var/run/docker.sock -v /var/lib/docker:/var/lib/docker newdockerimage.

Я могу установить докер внутри контейнера, но все образы докеров, которые находятся в хост-системе, также используются внутри контейнера из-за объема (/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

Пожалуйста, помогите мне! Как я могу запустить докер внутри контейнера без совместного использования тома (без копирования образов докеров хост-системы)

2 ответа

Решение

Когда вы отменяете значение по умолчанию CMD Docker-dind - пользователем node app.jsтогда он не запустит службу Docker. так что в результате вы получите

Cannot connect to the Docker daemon

Потому что докер не запущен в вашем контейнере.

Таким образом, обходной путь - запустить докер в фоновом режиме, а ваше приложение узла - на переднем плане.

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

Запуск Docker внутри контейнера Docker технически возможен, но обычно не рекомендуется. Описание Docker Hub дляdockerimage содержит много документации, и ее важно прочитать. Я также обычно не считаю лучшей практикой доступ к сокету Docker изнутри контейнера, если это не является абсолютно необходимым, и, как правило, вы не должны пытаться запускать две программы в одном образе. Я бы настоятельно рекомендовал использовать другой подход к вашей проблеме более высокого уровня: это не стандартная и не простая установка.

Есть два способа получить доступ к разъему DinD. Он публикует его через TCP-over-TLS на порт 2376, или, если вы запускаете контейнер внутри вложенного Docker, "хост-системой" для целей привязки монтирования является контейнер DinD.

(Но подождите: разве сетевой HTTP-доступ к сокету Docker не является катастрофой безопасности? Здесь есть два смягчающих фактора: поскольку он находится внутри хоста Docker, существует уровень NAT/ брандмауэра, и вы не можете получить доступ к этому вложенному сокету Docker, если вы опубликуйте его; и хотя вы можете использовать его для получения неограниченного корневого доступа, он только над вложенным контейнером DinD и его содержимым.)

Первое, что вам нужно сделать, это переписать свой Dockerfile, чтобы он стал стандартным образом Node. Не следует продлеватьdocker image, потому что это не образ Docker, это образ приложения Node.

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
Другие вопросы по тегам