Статьи

Руководство по Docker: игра с контейнерами (простые примеры)

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

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

Развертывание вашего программного обеспечения становится намного проще после Docker, где вам не нужно беспокоиться об отсутствии конфигурации системы или необходимого условия.

Docker VS Виртуальная машина

Если вы используете какие-либо виртуальные машины для запуска своей работы внутри нее, зачем вам нужен Docker для запуска вашей работы внутри нее? Что ж…

Основное различие между ними заключается в том, что Docker — это изолированный процесс, который выполняется в вашей собственной ОС, тогда как виртуальная машина — это полностью изолированная ОС, которая работает поверх вашей основной ОС, и для ее загрузки требуется больше времени. Таким образом, Docker имеет преимущества перед виртуальными машинами, такими как:

  • Скорость загрузки
  • Требуются небольшие аппаратные ресурсы, в отличие от виртуальных машин.
  • Запуск нескольких контейнеров Docker одновременно в одной и той же ОС.
  • Вы можете изменить свой контейнер и развернуть его или передать определение файла Docker другу, чтобы начать работать в той же среде.

На самом деле, Docker не является заменой виртуальным машинам, он решает конкретные проблемы.

Предположим, что вашему приложению нужны 3 или более сервисов, которые работают в разных операционных системах, поэтому вместо запуска 3 виртуальных машин на одном хосте вы можете без проблем запустить 3 контейнера на одном хосте. Звучит здорово!!

Запустите свой контейнер

Перед началом убедитесь, что Docker установлен правильно и готов принять ваши команды. Введите следующую команду в новом окне терминала:

1
$ docker -v

Приведенная выше команда выводит версию Docker, установленную на вашем ПК:

1
Docker version 17.12.0-ce-rc2, build f9cde63

Время запустить контейнер:

1
$ docker container run alpine echo "Hello World"

Когда вы запускаете вышеупомянутую команду в первый раз, вы должны увидеть вывод в окне терминала, похожий на этот:

01
02
03
04
05
06
07
08
09
10
11
Unable to find image 'alpine:latest' locally
  
latest: Pulling from library/alpine
  
2fdfe1cd78c2: Pull complete
  
Digest: sha256:ccba511b...
  
Status: Downloaded newer image for alpine:latest
  
Hello World

Это было легко, не так ли? Попробуйте запустить ту же команду еще раз:

1
$ docker container run alpine echo "Hello World"

Во второй, третий или n-й раз, когда вы запускаете указанную выше команду, вы должны видеть только этот вывод в вашем терминале:

1
$ Hello World

Теперь, когда вы успешно запустили контейнер, пришло время проанализировать, что именно произошло. Посмотрите на следующую команду:

1
$ docker container run alpine echo "Hello World"

Эта команда содержит несколько частей. Прежде всего, у вас есть слово докер. Это имя интерфейса командной строки Docker ( CLI ), используемого для взаимодействия с механизмом Docker, отвечающим за запуск контейнеров.

Далее у вас есть слово «контейнер», которое указывает на контекст, с которым вы работаете.

Далее идет фактическая команда, которую вы хотите выполнить в данном контексте, которая выполняется.

Теперь вам также нужно указать Docker, какой контейнер запускать. В данном случае это так называемый альпийский контейнер.

Наконец, вам нужно определить, какой процесс или задача должны выполняться внутри контейнера, когда он выполняется. Это последняя часть команды, эхо «Hello World».

Запустите процесс внутри контейнера

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

1
$ docker container run centos ping -c 5 127.0.0.1

Это вывод:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
Unable to find image 'centos:latest' locally
latest: Pulling from library/centos
85432449fd0f: Pull complete
Digest: sha256:3b1a65e9a05...
Status: Downloaded newer image for centos:latest
PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data.
64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.022 ms
64 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.019 ms
64 bytes from 127.0.0.1: icmp_seq=3 ttl=64 time=0.029 ms
64 bytes from 127.0.0.1: icmp_seq=4 ttl=64 time=0.030 ms
64 bytes from 127.0.0.1: icmp_seq=5 ttl=64 time=0.029 ms
  
--- 127.0.0.1 ping statistics ---
5 packets transmitted, 5 received, 0% packet loss, time 4103ms

В предыдущем примере используемое вами изображение контейнера — centos, а процесс, который вы выполняете внутри контейнера centos, — это ping -c 5 127.0.0.1, который пингует адрес обратной связи пять раз, пока не остановится.

  • Первая строка выглядит следующим образом:
1
Unable to find image 'centos:latest' locally

Это говорит о том, что Docker не нашел изображение с именем centos: latest в локальном кэше системы. Итак, Docker знает, что он должен извлечь изображение из некоторого реестра, где хранятся изображения контейнера.

По умолчанию ваша среда Docker настроена таким образом, что изображения извлекаются из Docker Hub по адресу hub.docker.com. Это выражается во второй строке следующим образом:

1
latest: Pulling from library/centos
  • Следующие три строки вывода следующие:
1
85432449fd0f: Pull completeDigest: sha256:3b1a65e9a05...Status: Downloaded newer image for centos:latest

Это говорит о том, что Docker успешно вытащил изображение, centos: latest, из Docker Hub.

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

Возможно, вы также заметили, что последнее ключевое слово встречалось несколько раз. Каждое изображение имеет версию (также называемую тегом), и если вы не укажете версию явно, то Docker автоматически примет ее как последнюю версию.

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

Запуск контейнера случайных кавычек

Для запуска контейнера случайных кавычек вам понадобится алгоритм, который генерирует случайные кавычки. API, который генерирует эти бесплатные случайные кавычки, можно найти по адресу https://talaikis.com/random_quotes_api/ .

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

1
2
3
4
5
6
while :
do
    wget -qO- https://talaikis.com/api/quotes/random
    printf 'n'
    sleep 5
done

Остановите скрипт, нажав Ctrl + C. Вот вывод:

1
{"quote":"Martha Stewart is extremely talented. He

Каждый ответ представляет собой строку в формате JSON с цитатой, ее автором и категорией.

Теперь запустите это в альпийском контейнере в качестве демона в фоновом режиме. Для этого вам нужно сжать предыдущий скрипт в одну строку и выполнить его с использованием синтаксиса /bin/sh -c "..." . Выражение Docker будет выглядеть следующим образом:

1
$ docker container run -d --name quotes alpine \   /bin/sh -c "while :; do wget -qO- https://talaikis.com/api/quotes/random; printf '\n'; sleep 5; done"

В вышеприведенном выражении вы использовали два новых параметра командной строки: -d и –name. -D указывает Docker запускать процесс, запущенный в контейнере, как демон Linux . Параметр –name может использоваться, чтобы дать контейнеру явное имя.

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

Такие имена могут быть boring_borg или angry_goldberg. Довольно смешно, не правда ли?

Одним из важных выводов является то, что имя контейнера должно быть уникальным. Убедитесь, что контейнер цитат запущен и работает:

1
$ docker container ls -l

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

Перечисление контейнеров

Поскольку вы продолжаете запускать контейнеры с течением времени, вы в конечном итоге получите их в своей системе. Чтобы узнать, что в данный момент выполняется на вашем хосте, вы можете использовать команду container ls следующим образом:

1
$ docker container ls

Это перечислит все в настоящее время работающие контейнеры

По умолчанию Docker выводит семь столбцов со следующими значениями:

колонка Описание
ID контейнера Уникальный идентификатор контейнера. Это SHA-256.
Образ Имя изображения контейнера, из которого создается этот контейнер.
Статус Состояние контейнера (создан, перезапущен, запущен, удален, приостановлен, завершен или мертв).
Порты Список портов контейнера, которые были сопоставлены с хостом.
имена Имя, назначенное этому контейнеру (возможно несколько имен).

Если вы хотите перечислить все контейнеры, определенные в вашей системе, вы можете использовать параметр командной строки -a или –all следующим образом:

1
$ docker container ls -a

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

Иногда вы можете просто перечислить идентификаторы всех контейнеров. Для этого у вас есть параметр -q:

1
$ docker container ls -q

Вы можете спросить, где это полезно. Вот пример:

1
$ docker container rm -f $(docker container ls -a -q)

Приведенная выше команда удаляет все контейнеры, определенные в настоящее время в системе, включая остановленные. Команда rm означает удаление, и это будет объяснено далее в руководстве.

В предыдущем разделе вы использовали параметр -l в команде list. Попробуйте использовать справку Docker, чтобы узнать, что означает параметр -l. Вы можете вызвать справку для команды list следующим образом:

1
$ docker container ls -h

Остановка и запуск контейнеров

Иногда вам может понадобиться временно остановить работающий контейнер. Попробуйте это с контейнером кавычек с этой командой:

1
$ docker container run -d --name quotes alpine \   /bin/sh -c "while :; do wget -qO- https://talaikis.com/api/quotes/random; printf '\n'; sleep 5; done"

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

1
$ docker container stop quotes

Когда вы попытаетесь остановить контейнер кавычек, вы, вероятно, заметите, что до его выполнения требуется некоторое время (около 10 секунд). Почему это так? Docker отправляет сигнал Linux SIGTERM основному процессу, работающему внутри контейнера.

Если процесс все еще не завершается сам, Docker ждет 10 секунд перед отправкой SIGKILL, который принудительно убивает процесс и завершает контейнер.

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

Как вы получаете идентификатор контейнера?

Есть несколько способов сделать это. Ручной подход — перечислить все запущенные контейнеры и найти тот, который вы ищете в списке. Просто скопируйте его идентификатор оттуда.

Более автоматизированным способом является использование сценариев оболочки и переменных среды . Например, если вы хотите получить идентификатор контейнера кавычек, вот пример:

1
$ export CONTAINER_ID = $(docker container ls | grep quotes | awk '{print $1}')

Здесь мы использовали AWK, чтобы получить первое поле, которое является идентификатором контейнера. Теперь вместо имени контейнера вы можете использовать переменную $ CONTAINER_ID в своем выражении:

1
$ docker container stop $CONTAINER_ID

Как только вы остановите контейнер, его статус изменится на «Выход».

Вы можете перезапустить остановленный контейнер с помощью команды запуска контейнера docker.

Удаление контейнеров

Когда вы запустите команду docker container ls -a, вы увидите довольно много контейнеров, которые находятся в состоянии Exited.

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

1
$ docker container rm <container ID>

Кроме того, вы также можете использовать эту команду:

1
$ docker container rm <container name>

Иногда удаление работающего контейнера не работает; если вы хотите форсировать удаление, вы можете использовать параметр командной строки -f или –force.

Контейнерирование изменило способ работы отрасли, снизив затраты на техническое обслуживание более чем на 50% и время выхода на рынок примерно на 90%. Кроме того, контейнеры делают приложения более безопасными, а не запускают их вне контейнеров.

Если вы нашли это руководство полезным и хотите больше узнать о контейнерах Docker, вы можете прочитать больше в Learn Docker — Основы Docker 18.x , в котором объясняются все критические концепции, связанные с контейнеризацией и оркестровкой.

Продолжают возвращаться. Спасибо.

Опубликовано на Java Code Geeks с разрешения Мохтара Эбрагима, партнера нашей программы JCG . Смотрите оригинальную статью здесь: Учебное пособие по Docker: игра с контейнерами (простые примеры)

Мнения, высказанные участниками Java Code Geeks, являются их собственными.