«1. Обзор

Мы знаем, что Docker — это мощный инструмент для простого создания, развертывания и запуска приложений.

В учебнике «Образы и контейнеры» мы обсуждали, как образы Docker создаются с использованием слоев. Мы также обсуждали, что первым уровнем обычно является операционная система.

Итак, можно ли подключиться к операционной системе контейнера? Да, это. А теперь мы научимся это делать.

2. Подключение к существующему контейнеру

Если мы хотим подключиться к существующему контейнеру, у нас должен быть любой контейнер в рабочем состоянии. Для этого мы должны проверить статус контейнера в нашей системе с помощью команды docker ps:

$ docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                  PORTS               NAMES
4b9d83040f4a        hello-world         "/hello"            8 days ago          Exited (0) 8 days ago                       dazzling_perlman

Поскольку у нас нет запущенных контейнеров, давайте в качестве примера запустим контейнер RabbitMQ:

$ docker run -d rabbitmq:3

После того, как контейнер запущен, мы увидим это из другого вызова docker ps:

$ docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                                NAMES
b7a9f5eb6b85        rabbitmq:3          "docker-entrypoint.s…"   25 minutes ago      Up 25 minutes       4369/tcp, 5671-5672/tcp, 25672/tcp   trusting_bose

Теперь подключиться к этому контейнеру так же просто, как выполнить:

$ docker exec -it b7a9f5eb6b85 sh

На данный момент у нас есть интерактивная оболочка внутри контейнера:

    docker exec сообщает Docker, что мы хотим выполнить команду в работающем контейнере. Аргумент -it означает, что команда будет выполняться в интерактивном режиме — он сохраняет STIN открытым b7a9f5eb6b85 — идентификатор контейнера sh — команда, которую мы хочу выполнить

Давайте изучим операционную систему нашего только что созданного контейнера:

$ cat /etc/*-release
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=18.04
DISTRIB_CODENAME=bionic
DISTRIB_DESCRIPTION="Ubuntu 18.04.4 LTS"
NAME="Ubuntu"
VERSION="18.04.4 LTS (Bionic Beaver)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 18.04.4 LTS"
VERSION_ID="18.04"
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
VERSION_CODENAME=bionic
UBUNTU_CODENAME=bionic

Кажется, это Bionic Beaver Ubuntu. Если мы проверим инструкцию FROM в файле RabbitMQ Dockerfile, мы поймем, что этот образ создан с использованием Ubuntu 18.04.

Отключиться от контейнера можно командой exit или просто CTRL+d.

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

3. Запуск контейнеров в интерактивном режиме

Если мы попытаемся запустить новый контейнер операционной системы, например Ubuntu 18.04, мы увидим, что он не остается в живых:

$ docker run ubuntu:18.04
$ docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                     PORTS                                NAMES
08c26636709f        ubuntu:18.04        "/bin/bash"              10 seconds ago      Exited (0) 7 seconds ago                                        heuristic_dubinsky
b7a9f5eb6b85        rabbitmq:3          "docker-entrypoint.s…"   About an hour ago   Up About an hour           4369/tcp, 5671-5672/tcp, 25672/tcp   trusting_bose

Пока Контейнер RabbitMQ все еще работает, а Ubuntu остановлен. Следовательно, мы не можем подключиться к этому контейнеру с помощью команды docker exec.

Способ избежать этого — запустить этот контейнер в интерактивном режиме:

$ docker run -it ubuntu:18.04

Итак, теперь, когда мы внутри контейнера, мы можем проверить тип оболочки:

$ echo $0
/bin/bash

На самом деле, это удобно использовать аргумент –rm, когда мы запускаем контейнер в интерактивном режиме. Он обязательно удалит контейнер, когда мы выйдем:

$ docker run -it --rm ubuntu:18.04

4. Продолжайте работу контейнера

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

Если мы столкнемся с одной из этих ситуаций, вероятно, потому что что-то не так, и это нужно исправить.

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

$ docker run -d ubuntu:18.04 tail -f /dev/null

С помощью этой команды мы запускаем новый контейнер в автономном/фоновом режиме (-d) и выполняем хвост Команда -f /dev/null внутри контейнера. В результате это заставит наш контейнер работать вечно.

Теперь нам просто нужно подключиться с помощью команды docker exec так же, как мы видели раньше:

$ docker exec -it CONTAINER_ID sh

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

5. Заключение

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