Перейти к основному содержимому

Как попасть в оболочку контейнера Docker

· 4 мин. чтения

Задача: Медиана двух отсортированных массивов

Даны два отсортированных массива размерами n и m. Найдите медиану слияния этих двух массивов.
Временная сложность решения должна быть O(log(m + n)) ...

ANDROMEDA

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.

Мы можем отключиться от контейнера с помощью команды выхода или просто 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 ) и выполняем команду tail -f /dev/null внутри контейнера. В результате это заставит наш контейнер работать вечно.

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

$ docker exec -it CONTAINER_ID sh

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

5. Вывод

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