Перевод.
Полный курс (который категорически рекомендую) доступен на katacoda.com тут>>>.
- Шаг 1 – запуск контейнера
- Шаг 2 – просмотр запущенных контейнеров
- Шаг 3 – порты
- Шаг 4 – случайные порты
- Шаг 5 – подключение каталогов
- Шаг 6 – запуск контейнера в foreground
Содержание
Шаг 1 – запуск контейнера
В Docker все контейнеры запускаются из Docker-образов. Эти образы содержат в себе все необходимое для запуска процесса – хост не требует никакой дополнительной конфигурации.
Что бы запустить контейнер – вы можете собрать его самостоятельно, либо, как предполагается в этом сценарии – использовать уже созданный образ, созданный Docker Inc и сообществом.
Готовые образы можно найти в https://registry.hub.docker.com, либо с помощью команды docker search <image-name>
. Например, что бы найти образ Redis – можно использовать команду docker search -s 1 redis
:
$ sudo docker search -s 1 redis [sudo] password for setevoy: NAME DESCRIPTION STARS OFFICIAL AUTOMATED redis Redis is an open source key-value store th... 2715 [OK] sameersbn/redis 35 [OK] torusware/speedus-redis Always updated official Redis docker image... 31 [OK] bitnami/redis Bitnami Redis Docker Image 25 [OK] anapsix/redis 11MB Redis server image over AlpineLinux 6 [OK] webhippie/redis Docker images for redis 5 [OK] williamyeh/redis Redis image for Docker 3 [OK] clue/redis-benchmark A minimal docker image to ease running the... 3 [OK] unblibraries/redis Leverages phusion/baseimage to deploy a ba... 2 [OK] kampka/redis A Redis image build from source on top of ... 1 [OK] greytip/redis redis 3.0.3 1 [OK] servivum/redis Redis Docker Image 1 [OK] vguardiola/gentoo-redis Redis server 1 [OK] miko2u/redis Redis 1 [OK]
Опция -s 1
тут – указывает на необходимость вывести результаты c минимум +1 рейтинга.
Задача
Требуется запустить один контейнер, фоновым процессом, из официального образа Redis. После того, как образ будет найдет в registry – его можно запустить командой docker run <options> <image-name>
. По умолчанию – Docker запускает процесс в интерактивном режиме. Что бы запустить его в фоне – используется опция -d
.
Сейчас у вас не будет локальной копии образа, поэтому он будет загружен из Docker-репозитория. При повторном запуске – будет использоваться локальный образ.
Примечание
У всех контейнеров есть имя и ID для использования в Docker-командах. Вы можете указать своё имя для запускаемого контейнера с помощью опции --name
, например – --name redis
.
Решение
Находим образ:
$ sudo docker search -s 1 redis [sudo] password for setevoy: NAME DESCRIPTION STARS OFFICIAL AUTOMATED redis Redis is an open source key-value store th... 2715 [OK] ...
Запускаем, используя -d
для запуска в бекграунде, и --name
– с именем контейнера:
$ sudo docker run -d --name redis redis:latest Unable to find image 'redis:latest' locally latest: Pulling from redis c289280e4ecc: Pull complete ... e2b295164860: Pull complete Digest: sha256:9097f82c009bcaa732776da3e2a6b638a32c565a6b00bb55e74d0215c526d3c6 Status: Downloaded newer image for redis:latest cf363ff9714d2ef17bc05e297d0d8db3043f9e27cd7348fad146b8d97f0db731
Шаг 2 – просмотр запущенных контейнеров
Команда docker ps
позволяет получить список всех запущенных в настойщий момент контейнеров с указанием образа, использованого для запуска контейнера.
Например, что бы увидеть контейнер, запущенный в предыдущем сценарии – выполните:
$ sudo docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES cf363ff9714d redis:latest "docker-entrypoint.s 24 seconds ago Up 23 seconds 6379/tcp redis
Кроме того – это команда выводит имя контйнера и его ID, которые могут быть использованы для получения информации о контейнере.
Команда docker inspect <friendly-name|container-id>
предоставляет еще больше деталей о контейнере, включая его IP, примонтированные разделы, состоянии и т.д:
# docker inspect cf363ff9714d [{ "AppArmorProfile": "", "Args": [ "redis-server" ], "Config": { "AttachStderr": false, "AttachStdin": false, "AttachStdout": false, "Cmd": [ "redis-server" ...
Отформатировать вывод можно с помощью jq
:
# docker inspect cf363ff9714d | jq '.[0] | {Image: .Image, ExposedPorts: .Config.ExposedPorts, IP: .NetworkSettings.IPAddress}' { "IP": "172.17.0.1", "ExposedPorts": { "6379/tcp": {} }, "Image": "e2b29516486046b11cda7665fc9ea7c7f4025e280b8e33ade5acd26f78b51ebb" }
Команда docker logs <friendly-name|container-id>
– выведет сообщения, которые контейнер пишет в STDERR
и STDOUT
:
# docker logs cf363ff9714d 1:C 15 Sep 08:39:17.030 # Warning: no config file specified, using the default config. In order to specify a config file use redis-server /path/to/redis.conf _._ _.-``__ ''-._ _.-`` `. `_. ''-._ Redis 3.2.3 (00000000/0) 64 bit .-`` .-```. ```\/ _.,_ ''-._ ( ' , .-` | `, ) Running in standalone mode |`-._`-...-` __...-.``-._|'` _.-'| Port: 6379 | `-._ `._ / _.-' | PID: 1 `-._ `-._ `-./ _.-' _.-' |`-._`-._ `-.__.-' _.-'_.-'| | `-._`-._ _.-'_.-' | http://redis.io `-._ `-._`-.__.-'_.-' _.-' |`-._`-._ `-.__.-' _.-'_.-'| | `-._`-._ _.-'_.-' | `-._ `-._`-.__.-'_.-' _.-' `-._ `-.__.-' _.-' `-._ _.-' `-.__.-' 1:M 15 Sep 08:39:17.032 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128. 1:M 15 Sep 08:39:17.032 # Server started, Redis version 3.2.3 1:M 15 Sep 08:39:17.032 # WARNING overcommit_memory is set to 0! Background save may fail under low memory condition. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect. 1:M 15 Sep 08:39:17.032 # WARNING you have Transparent Huge Pages (THP) support enabled in your kernel. This will create latency and memory usage issues with Redis. To fix this issue run the command 'echo never > /sys/kernel/mm/transparent_hugepage/enabled' as root, and add it to your /etc/rc.local in order to retain the setting after a reboot. Redis must be restarted after THP is disabled. 1:M 15 Sep 08:39:17.032 * The server is now ready to accept connections on port 6379
Шаг 3 – порты
Каждый контейнер является абсолютно независмым от других, и работает изолированно от других контейнеров. Если требуется получить доступ к сервису в контейнере снаружи – вам необходимо открыть порт, который будет привязан к конкретному контейнеру. После привязки порта – вы сможете получить доступ к службе так же, как если бы она работала не в контейнере – а в операционной системе хост-машины.
Указать порты во время запуска контейнера можно с помощью опции -p
. Например – сервис Redis отркывает для доступа порт 6379. Если вы хотите привязать этот порт контейнера к хосту – укажите -p 6379:6379
.
Задача
Запустите новый контейнер с Redis в фоном режиме, с именем redis и портом хост-машины 6379, привязанном к порту 6379 контейнера.
Примечание
По умолчанию – порт на хосте будет привязан к IP 0.0.0.0, т.е. – всем IP-адресам машины. Вы можете указать точный IP во время указания порта, например - -p 127.0.0.1:6379:6379
.
Решение
Получаем IP хоста:
# ip a s | grep eth0 | tail -n 1 | cut -d " " -f 8 10.11.100.255
Запускаем контейнер:
# docker run -d -p 10.11.100.255:6379:6379 --name redis-6379 redis 8064560e8fcaf2f5d899889851ef04a95af82f898f561888c2798ed0a0b32077
Проверяем:
# docker inspect cf363ff9714d | jq '.[0] | {ExposedPorts: .Config.ExposedPorts}' { "ExposedPorts": { "6379/tcp": {} } }
# netstat -anp | grep 6379 tcp 0 0 10.11.100.255:6379 0.0.0.0:* LISTEN 11329/docker-proxy
Шаг 4 – случайные порты
Выше мы рассмотрели как привязать контейнер к определённому порту хоста. Этот подход позволяет с легкостью получить доступ к приложению, но имеет существенный недостаток – таким образом можно запустить только одно приложение.
Одно из преимуществ контейнеров – это то, что вы можете разделить конфигурацию приложения (например – на каком порту контейнера запускать сервис) от настроек хоста (например – какой порт на хост-машине привязать к контейнеру).
Аналогично с привязкой чётко заданного порта – если вы запустите контейнер с опцией -p 6379
– Docker привяжет случайный порт хоста к этому порту. Это позволяет запускать несколько одинаковых сервисов на одном и том же хосте, без необходимости изменять настройки службы, такие как его локальный порт.
Задача
Запустить Redis как в предыдущей задаче, но дать Docker самому выбрать порт хост-машины.
Вы можете использовать команду docker port redis 6379
, что бы узнать привязанный порт хоста. Кроме того – docker ps
так же выводит такую информацию.
Решение
Запускаем Redis:
# docker run -d -p 6379 --name redis-random-port redis e5a53cc4a41c6a336e734a8f2d9d82c7d4af27096d9dc7ace74bd83c033794e4
Проверяем порты:
# docker port redis-random-port 6379 0.0.0.0:32768
# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES e5a53cc4a41c redis:latest "docker-entrypoint.s 39 seconds ago Up 38 seconds 0.0.0.0:32768->6379/tcp redis-random-port
Шаг 5 – подключение каталогов
Мы уже рассмотрели – как запустить контейнер, и выполнить привязку портов. Следующий шаг – начиться работать с данными в контейнерах.
Конейнеры разработаны так, что бы быть неизменяемыми. Любые данные, которые должны быть сохранены посте остановки контейнера – должны храниться на хост-машине. Это достигается с помощью монтирования каталогов хоста внутрь контейнеров.
Привязка директорий (так же называемых “разделы“, volumes) в Docker схожа с привязкой портов – с помощью опции -v
. Когда директория (раздел) примонтирована таким образом к запущенному контейнеру – вы можете получить доступ к файлам в этой директории прямо из этого контейнера, а любые изменения в этих файлах, выполненные из контейнера – будут сохранены на хост-машине. Этот подход позволяет вам изменять или обновлять контейнеры без утраты данных в них.
Задача
Официальный образ redis хранит логи и данные в каталоге /data
. Запустите контейнер, который примонтирует каталог /data
контейнера к каталогу /home/username/data
.
Примечание
В можете использовать переменные, например $PWD -
что бы указать текущий каталог.
Решение
Запускаем контейнер (каталог $HOME/data
будет создан автоматически, если его нет):
# docker run -d -p 6379 --name redis-mapped-volume -v $HOME/data:/data redis 43ffb6cfcaf20a7f6faae8fe152e0699de58af854cea08bcddcf5d8f63722782
Проверяем каталог:
# ls -l /home/setevoy/data/ total 0
Добавим файл:
# echo "testfile" > /home/setevoy/data/testfile.txt # cat /home/setevoy/data/testfile.txt testfile
Проверяем в контейнере:
# docker exec 43ffb6cfcaf cat /data/testfile.txt testfile
Шаг 6 – запуск контейнера в foreground
Некоторые контейнеры, такие как сервера баз данных, лучше всего запускать в фоновом режиме. Однако Docker не ограничен только запуском таких служб. Контейнеры могут запускать любые службы точно так же, как это можно сделать на самом хосте.
Ранее мы использовали опцию -d
, что бы запустить процесс в бекграунде. Без неё – контейнер будут запущен в интерактивном (foreground) режиме.
Если мы хотим взаимодействовать с контейнером (например – полуить доступ к его консоли), вместо того, что бы только видеть его output – добавьте опции -ti
.
Кроме того, что контейнеры могут быть запущены в foreground и background режимах – как правило вы можете изменить команду, которая будет выполнена при запуске контейнера (CMD и ENTRYPOINT для Dockerfile
мы рассмотрим позже). Например, вы можете запустить Ubuntu и выполнить в ней какую-то системную команду – либо запустить интерпретатор bash
.
Пример
Команда docker run ubuntu ps
запустит контейнер с Ubuntu и выполнит команду ps
для отображения всех процессов в контейнере:
# docker run ubuntu ps PID TTY TIME CMD 1 ? 00:00:00 ps
Или – можно запустить консоль в контейнере:
# docker run -ti ubuntu root@6085fa2ab86b:/# uname -a Linux 6085fa2ab86b 4.2.0-42-generic #49~14.04.1-Ubuntu SMP Wed Jun 29 20:22:11 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux
Продолжение тут.