В продолжение статьи установка Docker из серии программного обеспечения для DevOPS.
Для запуска контейнера не обязательно предварительно скачивать образ. Если он доступен, то будет загружен автоматически. Давайте попробуем запустить контейнер с Ubuntu. Мы не будем указывать репозиторий, и будет скачан последний официальный образ, поддерживаемый Canonical.
$ docker run -it ubuntu root@d7402d1f7c54:/#
Помимо команды run, мы указали две опции: -i – контейнер должен запуститься в интерактивном режиме и -t – должен быть выделен псевдотерминал. Как видно из вывода, в контейнере мы имеем привилегии пользователя root, а в качестве имени узла отображается идентификатор контейнера. Последнее может быть справедливо не для всех контейнеров и зависит от разработчика контейнера. Проверим, что это действительно окружение Ubuntu:
root@d7402d1f7c54:/# cat /etc/*release | grep DISTRIB_DESCRIPTION DISTRIB_DESCRIPTION="Ubuntu 16.04.1 LTS"
Команду uname -a для подобных целей использовать не получится, поскольку контейнер работает с ядром хоста. В качестве одной из опций можно было бы задать уникальное имя контейнера, на которое можно для удобства ссылаться, помимо ID-контейнера. Она задается как —name <имя>. В случае если опция опущена, имя генерируется автоматически.
Автоматически генерируемые имена контейнеров не несут смысловой нагрузки, однако как интересный факт можно отметить, что имена генерируются случайным образом из прилагательного и имени известного ученого, изобретателя или хакера. В коде генератора для каждого имени можно найти краткое описание того, чем известен данный деятель.
Посмотреть список запущенных контейнеров можно командой docker ps. Для этого откроем второй терминал:
$ docker ps CONTAINER ID IMAGE COMMAND CREATED d7402d1f7c54 ubuntu "/bin/bash" 9 seconds ago STATUS PORTS NAMES Up 4 seconds romantic_heisenberg
В случае если необходимо запустить контейнер с процессом, не предполагающим интерактивное взаимодействие, например с демоном, используется опция -d. Так и поступим со следующим контейнером:
$ docker run -d mysql
Однако если отдать команду docker ps, контейнера, созданного из образа mysql, мы не обнаружим. Воспользуемся опцией -a, которая показывает все контейнеры, а не только запущенные:
$ docker ps -a CONTAINER ID IMAGE COMMAND d454844325da mysql "docker-entrypoint.sh" d7402d1f7c54 ubuntu "/bin/bash" CREATED STATUS PORTS About a minute ago Exited (1) About a minute ago 32 minutes ago Up 32 minutes NAMES peaceful_jones romantic_heisenberg
В качестве статуса значится Exited. Для того чтобы разобраться с причиной, можно обратиться к журналу:
$ docker logs peaceful_jones error: database is uninitialized and password option is not specified You need to specify one of MYSQL_ROOT_PASSWORD, MYSQL_ALLOW_EMPTY_PASSWORD and MYSQL_RANDOM_ROOT_PASSWORD
Очевидно, что при запуске контейнера не были указаны обязательные параметры. Ознакомиться с описанием переменных среды, необходимых для запуска контейнера, можно, найдя официальный образ MySQL на Docker Hub.
Повторим попытку, используя опцию -e, которая задает переменные окружения в контейнере:
$ docker run --name mysql-test -e MYSQL_ROOT_PASSWORD=docker -d mysql
При помощи следующей команды можно подключиться к работающему контейнеру:
$ docker exec -it mysql-test bash root@b8fda6aac249:/#
Последним параметром выступает команда, которую мы хотим исполнить внутри контейнера. В данном случае это командный интерпретатор Bash. Опции -it аналогичны по назначению использованным ранее в команде docker run.
Фактически после запуска этой команды в контейнер mysql-test добавляется еще один процесс – bash. Это можно наглядно увидеть при помощи команды pstree. Сокращенный вывод до команды docker exec:
# pstree -p systemd(1)─┬ ├─docker-current(879)─┬─mysqld(3026)─┬─{mysqld}(3124) │ │ ├─{mysqld}(3125) И после команды docker exec: # pstree -p systemd(1)─┬ ├─docker-current(879)─┬─bash(3163) │ ├─mysqld(3026)─┬─{mysqld}(3124) │ │ ├─{mysqld}(3125)
Также можно воспользоваться командой docker top, поскольку из полученного вывода pstree не очевидно, что процессы mysqld и bash принадлежат одному и тому же контейнеру:
# docker top mysql-test UID PID PPID C STIME TTY TIME CMD systemd+ 3026 879 0 11:03 ? 00:00:00 mysqld
Вывод после запуска команды docker exec:
# docker top mysql-test UID PID PPID C STIME TTY TIME CMD systemd+ 3026 879 0 11:03 ? 00:00:00 mysqld root 3163 879 3 11:09 pts/2 00:00:00 bash
Теперь посмотрим на вывод команды docker ps, которая покажет список запущенных контейнеров:
$ docker ps CONTAINER ID IMAGE COMMAND CREATED d3d4c9281249 mysql "docker-entrypoint.sh" 4 minutes ago STATUS PORTS NAMES Up 4 minutes 3306/tcp mysql-test
Мы видим, что в качестве команды, запущенной при старте контейнера, использовался скрипт docker-entrypoint.sh. Это достаточно распространенный способ инициализации программного обеспечения в контейнере. Если бы мы хотели в отладочных целях запустить контейнер, но вместо скрипта просто получить приглашение командной строки, мы бы модифицировали команду запуска уже известным вам образом:
$ docker run -it --name mysql-test2 -e MYSQL_ROOT_PASSWORD=docker mysql /bin/bash После чего можно было бы изучить стартовый скрипт: root@5c31ad53edb1:/# cat $(which docker-entrypoint.sh)
Обратите внимание на одинаковый для двух контейнеров вывод в столбце COMMAND команды docker ps:
$ docker ps -a CONTAINER ID IMAGE COMMAND CREATED 5c31ad53edb1 mysql "docker-entrypoint.sh" 2 minutes ago d3d4c9281249 mysql "docker-entrypoint.sh" 13 minutes ago STATUS PORTS NAMES Up 2 minutes 3306/tcp mysql-test2 Up 13 minutes 3306/tcp mysql-test
Однако команда pstree, запущенная в контейнере, покажет нам разницу в запуске контейнеров. Для mysql-test:
root@d3d4c9281249:/# pstree -p mysqld(1)-+-{mysqld}(93) |-{mysqld}(94)
…
и для mysql-test2:
root@5c31ad53edb1:/# pstree -p bash(1)---pstree(17)
Отсюда мы видим, что во втором случае база данных MySQL запущена не была.
Мы познакомились с внутренними механизмами контейнеров и запустили первый контейнер Docker.
Если у Вас есть необходимость в установке и поддержке контейнеризации, обращайтесь [email protected]