Docker - Является ли отображение тома файла сокета переопределением? - PullRequest
1 голос
/ 02 ноября 2019

Ниже приведен фрагмент кода изображения Дженкинса, взятый из здесь :

# Install Docker Engine
RUN apt-key adv --keyserver hkp://pgp.mit.edu:80 --recv-keys 58118E89F3A912897C070ADBF76221572C52609D && \
    echo "deb https://apt.dockerproject.org/repo ubuntu-trusty main" | tee /etc/apt/sources.list.d/docker.list && \
    apt-get update -y && \
    apt-get purge lxc-docker* -y && \
    apt-get install docker-engine=${DOCKER_ENGINE:-1.10.2}-0~trusty -y && \
    usermod -aG docker jenkins && \
    usermod -aG users jenkins

, который устанавливает механизм докера в образе Дженкинса. Насколько я понимаю, var/run/docker.sock создается с контейнером Jenkins из-за установки механизма докера.


Ниже приведен синтаксис сопоставления томов , взятый из здесь :

volumes:
  - jenkins_home:/var/jenkins_home
  - /var/run/docker.sock:/var/run/docker.sock

, который запускает контейнер jenkins (выше) на хосте EC2.

На хосте EC2 также запущен демон Docker.

Итак, на хосте EC2 работает демон Docker. Существует также демон docker, работающий в контейнере Docker (Jenkins)


С этим синтаксисом (/var/run/docker.sock:/var/run/docker.sock) в docker-compose (см. Выше) для файлов сокетов,

Имеет ли демон Dockerв контейнере Jenkins переопределить свой собственный файл сокета с файлом сокета, присутствующим в хосте EC2? Если да ... каково это значение?

Ответы [ 2 ]

2 голосов
/ 02 ноября 2019

/var/run/docker.sock в контейнере - это сокет Docker хоста, и ничего больше. Это связано с тем, что:

  1. Контейнер Docker не запускает никаких программ, кроме тех, которые явно запущены в его точке входа и / или команде, и это почти всегда просто одна прикладная программа.
  2. Предположительно, вы не пытаетесь запустить демон Docker, поэтому он установлен, но не работает.
  3. Файлы сокетов Unix не будут созданы, пока демон не запустится и bind (2) сокет для конкретного файла.
  4. Опция docker run -v всегда будет «проталкивать» содержимое хоста в контейнер, и это происходит до запуска любого из процессов контейнера.

Таким образом, в описываемом вами сценарии это не может быть ничем иным, кроме сокета Docker хоста, потому что нет второго демона Docker.


Скажем, дляради аргумента, что вы действительно запускаете второго демона таким образом.

Порядок операций здесь: (1) Docker устанавливает файловую систему контейнера, (2) Docker запускает команду entrypoint, (3) точка входа запускает демон, (4) демон пытается создать файл сокета. В момент запуска демона его файл сокета уже будет существовать. Я полагаю, что это вызовет сбой вызова bind (2) с EADDRINUSE, и демон не запустится. Надеемся, что это приведет к сбою запуска вашего контейнера.

Вы могли бы по праву захотеть запустить демон в контейнере, который публикует сокет Unix, к которому вы хотите получить доступ с хоста. Для этого вам нужно смонтировать каталог в контейнер и навести на него демон. Вероятно, это не может быть /var/run с обеих сторон (на хосте /var/run есть много вещей; при монтировании каталога скрывается существующее содержимое в контейнере, и вы также можете захотеть /var/run контейнера). Это должен быть каталог, а не имя файла сокета, так как Docker создаст пустой каталог, если он не существует; что-то будет существовать в контейнере по этому пути, и привязка завершится неудачей.

Поэтому, если вы хотите запустить гипотетический демон foo внутри контейнера, он будет выглядеть примерно как

docker run \
  --name foo \                   # container name
  -v $PWD/socket:/socket \       # bind mount a directory
  foo \                          # image name
  food \                         # command to run in the container
    --foreground \               # don't daemonize; keep the container alive
    --bind fd://socket/foo.sock  # put the socket in the shared directory

На хосте вам нужно установить FOO_SOCKET_PATH=$PWD/socket/foo.sock или иным образом указать на этот конкретный файл.

1 голос
/ 02 ноября 2019

Из документов :

Docker-engine является клиент-серверным приложением

Обратите внимание, что при установке docker-engine выустановить docker-daemon (сервер) и docker cli (клиент).

Это означает, что если демон docker не запущен, вы все равно сможете запускать команды docker cli:

docker info
Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?

Изображение Дженкинса, которым вы поделились, не имеет инструкций по запуску Docker Engine. Поэтому я предполагаю, что он не работает внутри контейнера.

/var/run/docker.sock:/var/run/docker.sock том сопоставляет сокет механизма докера узла докера с контейнером.

Таким образом, команды docker cli запускаются в контейнере и управляют механизмом докера. на хосте докера.

Это имеет смысл, если вы выполняете CI / CD на вашем хосте из контейнера Jenkins.

Конвейеры Jenkins могут использовать команды docker, docker-compose и docker swarm для запуска тестов, создания артефактов и развертывания новых версий приложений.

...