Docker для начинающих: с нуля до кластера на AWS / Хабр

Содержание

Основы Docker за Х часов и Y дней / Хабр

0. Вступление


Цель данной статьи собрать в небольшую кучку основную информацию, минимально достаточную для того, чтобы начать работать с докер на ежедневной основе и удалить с рабочей машины локально установленные apache, mysql, virtualenv, python3, mongodb, memchaced, redis, php5, php7 и весь остальной зоопарк, который мы используем при разработке, и который зачастую еще и конфликтует между собой от версии к версии.

А еще я в автобусе и ближайшие 7 часов мне все равно делать будет нечего. Ну и вдобавок я наконец-то соберу в одном месте ссылки и команды, за которыми мне самому периодически приходится лезть в документацию, например — как на маке добавить IP алиас к локалхосту: sudo ifconfig lo0 alias 10.200.10.1/24 (зачем это надо будет сказано позже)

Статья называется так, как называется, потому что я не смог более-менее точно подсчитать сколько нужно времени на поставленную задачу. У меня на это ушло примерно 6 часов в течение 3 дней. Во многом, потому что в тот момент я работал фулл тайм в офисе и осваивал докер, так сказать, без отрыва от производства.

У вас может уйти меньше дней или больше часов, зависит от того, как интенсивно вы будете вникать.

Но мое личное мнение – лучше все же не пытаться “ворваться” за один день. Просто потому что если Вы никогда не имели с этим дело, то в конце первого дня у вас будет где-то вот такая голова


И лучше в этот момент остановиться, переварить информацию, может даже поспать.

1. Теория


Если Вы ранее имели дело с виртуальными машинами и такими инструментами как virtualbox, vmware, vagrant и подобными штуками – лучше забудьте о них.
Лично моей ошибкой была попытка работать с докер как с виртуальной машиной. Докер – средство виртуализации процессов, а не систем. Важное правило – каждому процессу свой виртуальный контейнер.

Контейнер следует воспринимать как отдельный процесс и наоборот. Например не следует пихать в один контейнер mysql и redis. Или еще хуже всю связку apache+php+mysql.

Основные термины

Image (образ) – собранная подсистема, необходимая для работы процесса, сохраненная в образе.
Container (контейнер) – процесс, инициализированный на базе образа. То есть контейнер существует только когда запущен. Это как экземпляр класса, а образ это типа класс. Ну я думаю идея понятна.
Host (хост) – среда, в которой запускается докер. Проще говоря – ваша локальная машина.
Volume – это дисковое пространство между хостом и контейнером. Проще – это папка на вашей локальной машине примонтированная внутрь контейнера. Меняете тут меняется там, и наоборот, миракл.
Dockerfile – файл с набором инструкций для создания образа будущего контейнера
Service (сервис) – по сути это запущенный образ (один или несколько контейнеров), дополнительно сконфигурированный такими опциями как открытие портов, маппинг папок (volume) и прочее. Обычно это делается при помощи docker-compose.yml файла.
Docker-compose
(докер-композ, чаще композер, но не путать с php composer) – тулза, облегчающая сборку и запуск системы состоящей из нескольких контейнеров, связанных между собой.
Build (билд, билдить) – процесс создания образа из набора инструкций в докерфайле, или нескольких докерфайлов, если билд делается с помощью композера
В данной статье позже (завтра) я опишу процесс сборки связки nginx+mysql+php7-fpm с примерами и описаниями dockerfile и docker-compose файлов.
Вкратце о том, как работает билдинг образов

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

Обычно докерфайл начинается с инструкции FROM, которая указывает с какого пакета/образа из хаба начать.

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

Затем наиболее часто встречающиеся команды:
RUN – выполняет команду внутри образа.
ADD – берет файлы с хоста и кладет внутрь образа.
А также COPY, EXPOSE, ENTRYPOINT, CMD — обо всем этом Вы узнаете в процессе.

Сейчас внимание. Докер выполняет инструкции из докерфайла последовательно поверх предыдущего результата. Таким образом организовано хранение кеша.
Не поняли? Сейчас покажу. Вот простейший докерфайл:

FROM ubuntu:latest
MAINTAINER igor
RUN apt-get update
RUN apt-get install nginx
ADD ./nginx.conf /etc/nginx/
EXPOSE 80
CMD [nginx]

Как докер его билдит:

1. качаем образ ubuntu с тегом latest, сохраняем его с ID=aaa
2. берем образ aaa, прописываем ему maintainer=igor, сохраняем его с ID=aab

3. берем образ aab, запускаем контейнер и выполняем внутри команду “apt-get update”, останавливаем контейнер, получившийся в результате образ сохраняем с ID=aac
4. берем образ aaс, запускаем контейнер и выполняем внутри команду “apt-get install nginx”, останавливаем контейнер, получившийся в результате образ сохраняем с ID=aad
5. берем образ aad, запускаем контейнер и копируем файл ./nginx.conf (путь указывается относительно папки в которой находится dockerfile) внутрь контейнера по пути /etc/nginx/, останавливаем контейнер, получившийся в результате образ сохраняем с ID=aae
….

уже понятнее?

ID я тут написал условные, но важно помнить, что идентификаторы этих “промежуточных” образов напрямую связаны с самими инструкциями, с файлами которые добавляются инструкцией ADD и с ID родительского образа. То есть фактически перед выполнением каждого шага сначала вычисляется ID (хеш) образа, поиск такого ID в локальном кеше, и только если такого ID в кеше нет, тогда выполняется шаг и сохраняется в кеш, иначе – используется образ из кеша.

А также это значит, что если вы решите поменять команду например run apt-get install nginx на другую, то Хеш(ID) инструкции изменится и весь дальнейший кеш после этого использоваться не будет. Потому не удивляйтесь если после изменения одной буквы в имени maintainer’а у вас вся сборка будет пересобираться от самого начала.

Также исходя из описанного сценария выполнения команд становится понятно, почему не имеет смысла в инструкциях выполнять команды ничего не сохраняющие после своего выполнения – частый вопрос на stackoverflow — “я запустил что-то, а в следующей инструкции оно не запущено”. Например кто-то хочет активировать source env/bin/activate и в следующей инструкции выполнить pip install


RUN source /app/env/bin/activate
RUN pip install something

или другой пример – запустить монгодб и в следующей инструкции создать юзера/базу или выполнить импорт базы из файла (есть причины почему лучше так не делать, но сейчас не об этом)

RUN service mongodb start
RUN mongo db --eval 'db.createUser({user:"dbuser",pwd:"dbpass",roles:["readWrite","dbAdmin"]})'

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

RUN source /app/env/bin/activate \
&& pip install something

RUN service mongodb start \
&& RUN mongo db —eval ‘db.createUser({user:»»,…})’
но вообще, в связи с тем, что контейнеры изолированы, я не вижу большого смысла в использовании внутри средств типа nvm, virtualenv, rbenv and similar stuff. Просто ставьте что нужно и все.

Думаю для начала работы этой теории вполне достаточно.

2. Практика

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

Небольшое отступление для тех, кто читает это под виндой.

Вы серьезно?

Нет, это конечно же возможно и там на сайте есть установочные файлы и инструкции. И лично я ничего не имею против windows, когда речь о домашнем использовании в качестве медиастанции. Но если вы разрабатываете под виндой, то я одновременно и восхищаюсь вами и соболезную. Скажу откровенно, я сам под виндой докер не поднимал, только под убунту и под мак. Однако я слышал стоны коллеги из соседнего кабинета, который пытался, и у него даже получилось запустить сборку, но когда дело дошло до симлинок внутри volume, то все пошло прахом. Потому, если вы попали сюда в поиске рецептов, как работать с Docker под Windows, то у меня плохие новости, здесь вы их не найдете.

Итак, на данном этапе у вас уже установлен докер, и в панели задач радостно побулькивает блоками #синийкит (извините, не удержался). Теперь сходите вот по этой ссылке и пройдите туториал Get Started.

Теперь давайте представим, что мы разрабатываем веб сайт на php и будем его публиковать связкой nginx+php7-fpm+mysql.

Вот очень примитивный dockerfile для php сервиса:

FROM php:7-fpm
# Install modules
RUN apt-get update && apt-get install -y \
libfreetype6-dev \
libjpeg62-turbo-dev \
libmcrypt-dev \
libpng12-dev \
libicu-dev \
--no-install-recommends
RUN docker-php-ext-install mcrypt zip intl mbstring pdo_mysql exif \

&& docker-php-ext-configure gd --with-freetype-dir=/usr/include/ --with-jpeg-dir=/usr/include/ \
&& docker-php-ext-install gd

ADD ./php.ini /usr/local/etc/php/
ADD ./www.conf /usr/local/etc/php/

RUN apt-get purge -y g++ \
&& apt-get autoremove -y \
&& rm -r /var/lib/apt/lists/* \
&& rm -rf /tmp/*

EXPOSE 9000
CMD [«php-fpm»]
Вкратце человеческим языком:

  • за основу берем образ php:7-fpm из хаба
  • обновляем убунту, доставляем нужные нам php-extensions и инструменты, копируем (добавляем) конфиги php внутрь образа, удаляем все ненужное и открываем порт 9000, который будет слушать php-fpm
  • единственная незнакомая деталь сейчас это конструкция ADD но она очевидна: взять файл согласно первого аргумента и положить внутрь контейнера по пути указанному во втором аргументе. В первом аргументе может быть абсолютный путь, относительный путь, http или ftp url, а также этот путь может указывать на папку или архив. В случае архива он будет распакован. Подробнее смотрите в документации ADD и COPY.

С php разобрались, теперь нам нужно обозначить образы для сервисов nginx и mysql, а также собрать все сервисы в целостную систему.

В случае с nginx и mysql нам даже не нужно писать свои dockerfile, так как никаких дополнительных расширений нам ставить не нужно. Вот как будет выглядеть docker-compose.yml нашего проекта

app:
build: docker/php/Dockerfile
working_dir: /app
volumes:
- ./:/app
expose:
- 9000
links:
- db
nginx:
image: nginx:latest
ports:
- "80:80"
volumes:
- ./:/app

- ./docker/nginx/vhost.conf:/etc/nginx/conf.d/vhost.conf
links:
- app
db:
image: mysql:5.7
volumes:
- /var/lib/mysql
ports:
- "3306:3306"
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: dbname
MYSQL_USER: dbuser
MYSQL_PASSWORD: dbpassword

Здесь объявлены сервисы app, nginx, db. app собирается из нашего докерфайла, а остальные просто используют образы из хаба.

Директива volumes монтирует папки из хостмашины внурть контейнера, таким образом осуществляется конфигурирование nginx и сохранение данных бд при перезапуске.
Директива links связывает сервисы между собой, app связан с db, это значит что после запуска внутри контейнера app будет доступен хост “db”, и он будет указывать на соответствующий контейнер.

Все просто (ирония).

Есть довольно интересный темплейт yii2-starter-kit, в коробке которого можно найти неплохую реализацию описанной сборки php7-fpm nginx mysql а также mailcatcher.

Тем кому, как и мне, больше по душе python и django можно вообще не париться и все сделать по официальному туториалу от Docker — docs.docker.com/compose/django
плюс, после того как уже пришло понимание как это все работает, не составит особого труда переработать любую понравившуюся сборку под свои нужды.

Pitfalls

— MacOS. Доступ к сервису на хосте (к примеру mongo или mysql) из контейнера.
Из-за ограничений “Docker for Mac networking stack” нельзя “просто так взять и подключиться” к локалхост. Но есть два обходных пути:

а) официальный и простой (доступен в версии Docker начиная с 17.06) — использовать для подключения специальный DNS хост (доступно только в Docker for Mac) docker.for.mac.localhost. Источник.

б) добавить алиас IP к сетевому устройству lo0:
`sudo ifconfig lo0 alias 10.200.10.1/24`
и использовать этот адрес для подключения

— MongoDB. На маке нельзя монтировать внешний диск для данных. Причины описаны здесь
WARNING (Windows & OS X): The default Docker setup on Windows and OS X uses a VirtualBox VM to host the Docker daemon. Unfortunately, the mechanism VirtualBox uses to share folders between the host system and the Docker container is not compatible with the memory mapped files used by MongoDB

— Под Windows не работают симлинки в примонтированных томах. Ожидаемо, но очень неприятно узнавать об этом уже после того как все остальное заработало.

— Отличия entrypoint и command — вот тут подробно и понятно описана разница между entrypoint и command.

UPD дополнение от saskasa: На маке скорость записи из контейнера на диск хоста (добавленный как VOLUME) очень медленная, для понимания масштабов — примерно в 50-100 раз.

Понятные видеоуроки по Docker для начинающих

В данном видео ты познакомишься с Docker и узнаешь, что он из себя представляет. Какая разница между Doker-ом и обычной виртуальной машиной, для чего он может понадобиться – показано на подробном примере. Автор рассматривает проблемы интеграции нового софта конечному юзеру – очень интересная тема не только для разработчика.

Эта лекция посвящена процессу установки Docker и Docker-compose на ОС Windows. Сначала обсуждаются требования для установки софта. В примере все действия будут происходить в ОС Windows 10. Важный нюанс: автор разбирает вариант установки “с проблемами”, чтобы ты не вляпался при первой инсталляции.

На этом уроке автор поможет любителям Linux установить все необходимое на Ubuntu 18.04. Как и в случае с Windows, Ubuntu должна быть 64-битной и версии CE. Автор выполняет все подготовительные шаги по официальному мануалу, чтобы избежать неточностей. После того как установка Docker будет завершена, ты научишься управлять контейнерами внутри родительской системы.

Установка – это хорошо, но пора переходить к управлению. В этом видео ты познакомишься с основными командами для работы с Docker-контейнерами. Все команды нужно вводить под sudo, т. к. требуются привилегии суперпользователя, а можно это обойти, добавив нужного юзера в группу docker. Список команд внушительный и для каждой приводится пример.

Важно понимать, что речь идет не о контейнере, а именно об образе, который лежит на Docker HUB. Для дальнейшего обучения тебе нужно создать учетку, что позволит хранить образы, использовать и делиться. По умолчанию тебе выдают публичный и закрытый (private) репозиторий. Весь процесс создания образа рассматривается на понятном примере.

В предыдущем уроке ты создал образ, но если в нем нужно что-то изменить, придется повторять все действия сначала, а это чревато ошибками. Для автоматизации процесса используется Dockerfile, который воспроизводит все задокументированные тобой действия. Это обычный текстовый файл (хоть и очень похож на простенький специализированный sh-скрипт) с набором команд для создания образа.

В уроке используется два образа для демонстрации возможности соединения. Один из образов – MariaDB. Установка производится всего одной командой, включающей в себя обращение к Docker и к хост-машине. Второй образ ставится точно так же. После установки двух образов тебя ждет поучительная история о принципе работы сети.

Тут ты познакомишься с Docker-compose и научишься создавать проекты. Демонстрация работы будет на ОС Windows и Ubuntu. Рассматриваемый инструмент нужен для упрощения автоматизации вкупе с Dockerfile. Compose предназначен для быстрой настройки и запуска различных сред разработки Docker. Все конфиги хранятся в файликах с расширением .yaml. Очень полезный компонент, который освободит от сопровождения вспомогательных рабочих скриптов.

Автор объясняет, как запускать контейнеры с помощью Docker-compose и Dockerfile. Как обычно, все пошагово и доступно. Начинается с создания Dockerfile и указания ключа, т. к. любой контейнер обязан хранить в себе ключ image или build.

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

Лекция поможет понять разницу между контейнером и образом в Docker. Рецепт преобразования одной сущности в другую разбирается на примере мандарина. Вся суть магии в том, что одно преобразуется в другое и обратно автоматически силами Docker. Можно сказать, что образ тоже является контейнером, который хранит в себе все настройки и компоненты реального контейнера с ФС.

Этот видос познакомит тебя с ФС UnionFS и научит избегать типичных ошибок в процессе сборки образа. Каждый образ состоит из последовательности слоев. Docker использует UnionFS для объединения этих слоев в единую структуру. UnionFS настолько хитрая штука, что все файлы и директории (ветки) могут быть прозрачно наложены друг на друга для образования единой файловой системы.

Ты запустишь минимальный набор компонентов для старта Laravel в контейнере Docker-а. Для этой задачи тебе понадобятся PHP, MySQL и Composer. Сначала создаются пути к БД и проекту на хост-машине, т. е. локально, вне контейнера. Далее куча подготовительных шагов с билдами, правами и директориями. Но в конце тебя ждет автоустановка всего софта и больше тебе ничего не нужно делать.

Как тебе курс?

термины и концепции / Блог компании RUVDS.com / Хабр

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

→ Часть 1: основы
→ Часть 2: термины и концепции
→ Часть 3: файлы Dockerfile
→ Часть 4: уменьшение размеров образов и ускорение их сборки
→ Часть 5: команды
→ Часть 6: работа с данными

Термины экосистемы Docker


Я разбил термины, с которыми вы можете столкнуться в ходе работы с Docker, на две части. Думаю, это облегчит их запоминание. Первый блок терминов будет относиться к механизмам Docker. Второй — к средствам масштабирования решений, основанных на контейнерах.

Механизмы Docker


▍Платформа Docker



Docker

Платформа Docker (Docker Platform) — это программа, которая даёт нам возможность упаковывать приложения в контейнеры и запускать их на серверах. Платформа Docker позволяет помещать в контейнеры код и его зависимости. Как результат, системы, основанные на контейнерах, легко масштабировать, так как контейнеры можно переносить и воспроизводить.

▍Движок Docker



Движок

Движок Docker (Docker Engine) — это клиент-серверное приложение. Компания Docker разделила движок Docker на два продукта. Docker Community Edition (CE) — это бесплатное ПО, во многом основанное на опенсорсных инструментах.

Вероятно, вы будете пользоваться именно этой версией Docker. Docker Enterprise — это платная версия системы, дающая пользователям дополнительные возможности в области поддержки систем, управления ими и безопасности. Платная версия Docker даёт компании средства, необходимые для её существования.

▍Клиент Docker



Клиент Docker и другие механизмы экосистемы (взято из документации)

Клиент Docker (Docker Client) — это основное средство, которое используют для взаимодействия с Docker. Так, при работе с интерфейсом командной строки Docker (Docker Command Line Interface, CLI), в терминал вводят команды, начинающиеся с ключевого слова docker, обращаясь к клиенту. Затем клиент использует API Docker для отправки команд демону Docker.

▍Демон Docker


Демон Docker (Docker Daemon) — это сервер Docker, который ожидает запросов к API Docker. Демон Docker управляет образами, контейнерами, сетями и томами.

▍Тома Docker



Тома

Тома Docker (Docker Volumes) представляют собой наиболее предпочтительный механизм постоянного хранения данных, потребляемых или производимых приложениями.

▍Реестр Docker


Реестр Docker (Docker Registry) представляет собой удалённую платформу, используемую для хранения образов Docker. В ходе работы с Docker образы отправляют в реестр и загружают из него. Подобный реестр может быть организован тем, кто пользуется Docker. Кроме того, поставщики облачных услуг могут поддерживать и собственные реестры. Например, это касается AWS и Google Cloud.

▍Хаб Docker


Хаб Docker (Docker Hub) — это самый крупный реестр образов Docker. Кроме того, именно этот реестр используется при работе с Docker по умолчанию. Пользоваться хабом Docker можно бесплатно.

▍Репозиторий Docker


Репозиторием Docker (Docker Repository) называют набор образов Docker, обладающих одинаковыми именами и разными тегами. Теги — это идентификаторы образов.

Обычно в репозиториях хранятся разные версии одних и тех же образов. Например, Python — это имя популярнейшего официального репозитория Docker на хабе Docker. А вот Python:3.7-slim — это версия образа с тегом 3.7-slim в репозитории Python. В реестр можно отправить как целый репозиторий, так и отдельный образ.

Теперь поговорим о терминах экосистемы Docker, имеющих отношение к масштабированию.

Масштабирование решений, основанных на контейнерах


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

▍Сеть Docker



Сеть Docker (взято из документации)

Сетевые механизмы Docker (Docker Networking) позволяют организовывать связь между контейнерами Docker. Соединённые с помощью сети контейнеры могут выполняться на одном и том же хосте или на разных хостах. Подробности о сетевой подсистеме Docker можно почитать здесь.

▍Docker Compose


Docker Compose — это инструмент, который упрощает развёртывание приложений, для работы которых требуется несколько контейнеров Docker. Docker Compose позволяет выполнять команды, описываемые в файле docker-compose.yml. Эти команды можно выполнять столько раз, сколько потребуется. Интерфейс командной строки Docker Compose упрощает взаимодействие с многоконтейнерными приложениями. Этот инструмент устанавливается при установке Docker.

▍Docker Swarm



Рой пчёл

Docker Swarm — это решение, предназначенное для управления контейнерными развёртываниями (то есть, как говорят, для оркестрации контейнеров). В этом материале из официального учебного курса по Docker можно найти сведения о Docker Swarm. Мне хотелось бы порекомендовать вам не тратить время на изучение Docker Swarm в том случае, если у вас нет на то веской причины.

▍Сервисы Docker


Сервисы Docker (Docker Services) — это различные части распределённого приложения. Вот что о них говорится в документации:

Сервисы — это всего лишь «контейнеры в продакшне». В пределах сервиса выполняется лишь один образ, но сервис определяет то, как именно выполняется образ. В частности, речь идёт о том, какие порты должны использоваться, сколько реплик контейнера должно выполняться для того, чтобы сервис обеспечивал бы необходимую вычислительную мощность, и так далее. Масштабирование сервисов предусматривает изменение количества экземпляров контейнера, в которых работает некая программа, благодаря чему сервису выделяется столько системных ресурсов, сколько ему требуется для решения некоей задачи.

Сервисы Docker позволяют масштабировать контейнеры в пределах нескольких демонов Docker, благодаря им существует и технология Docker Swarm.

Краткий перечень терминов


Давайте, буквально в двух словах, повторим только что представленные вам термины:

Механизмы Docker:

  1. Платформа Docker — ПО, благодаря которому можно работать с контейнерами.
  2. Движок Docker — клиент-серверное приложение (CE или Enterprise).
  3. Клиент Docker — программа, которая позволяет взаимодействовать с демоном Docker посредством CLI.
  4. Демон Docker — сервер Docker, отвечающий за управление ключевыми механизмами системы.
  5. Тома Docker — хранилище информации, используемое в контейнерах.
  6. Реестр Docker — удалённое хранилище образов.
  7. Хаб Docker — самый крупный реестр Docker, используемый по умолчанию.
  8. Репозиторий — коллекция образов Docker с одним и тем же именем.

Масштабирование:
  1. Сетевая подсистема Docker — среда, которая позволяет организовывать взаимодействие контейнеров.
  2. Docker Compose — технология, упрощающая работу с многоконтейнерными приложениями.
  3. Docker Swarm — средство для управления развёртыванием контейнеров.
  4. Сервисы Docker — контейнеры в продакшне.

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

Этот термин относится не к самой платформе Docker, а к технологии, которая очень часто используется совместно с Docker.

Kubernetes



Kubernetes

Kubernetes — это технология, которая позволяет автоматизировать развёртывание и масштабирование контейнеризированных приложений, а также управление ими. Это — бесспорный лидер рынка средств для оркестрации контейнеров. Если вам нужен инструмент для работы с группами контейнеров, для масштабирования решений, основанных на них, используйте не Docker Swarm, а Kubernetes. Kubernetes не является частью Docker. Они с Docker, скорее, похожи на лучших друзей.

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

Итоги: печём пончики с Docker


Помните, как в прошлый раз мы сравнивали платформу Docker с духовкой, которую устанавливают в кухне? Сейчас самое время установить Docker на вашей «кухне» и что-нибудь приготовить.

Docker можно запускать локально на Linux, Mac и Windows. Если вы пользуетесь Mac или Windows, вы можете установить свежую версию Docker Desktop отсюда. Вместе с этой программой, кстати, устанавливается и Kubernetes. Если вы устанавливаете Docker на другой платформе, то загляните сюда для того, чтобы найти подходящую версию.

После установки Docker взгляните на первые две части официального руководства.

В следующий раз мы продолжим разговор о Docker. В частности, поговорим о файлах Dockerfile.

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

Как я запускал Докер внутри Докера и что из этого получилось / Хабр

Всем привет! В своей предыдущей статье, я обещал рассказать про запуск Докера в Докере и о практических аспектах применения этого занятия. Настало время выполнить свое обещание. Опытный девопс, пожалуй, возразит, что тем кому нужен Докер внутри Докера, просто пробрасывают сокет Докер демона из хоста внутрь контейнера и этого хватит в 99% случаев. Но не спешите кидать в меня печеньки, ведь речь пойдет о реальном запуске Докера внутри Докера. У этого решения много возможных областей применения и об одном из них эта статья, так что усаживайтесь поудобнее и выпрямите руки перед собой.



Начало

Все началось дождливым сентябрьским вечером, когда я чистил арендованную за $5 машинку на Digital Ocean, которая намертво повисла из-за того что Докер заполонил своими образами и контейнерами все 24 гигабайта доступного дискового пространства. Ирония была в том, что все эти образы и контейнеры были транзиентными и нужны были лишь для того чтобы тестировать работоспособность моего приложения каждый раз когда выходила новая версия какой-либо библиотеки или фреймворка. Я пробовал писать шелл-сркипты и настраивать расписание крон для очистки мусора, но это не спасло: каждый раз все неминуемо заканчивалось тем, что дисковое пространство моего сервера оказывалось съеденным а сервер зависшим (в лучшем случае). В какой-то момент я наткнулся на статью про то как запускать Jenkins в контейнере и как он может создавать и удалять сборочные конвееры через проброшенный в него сокет докер демона. Идея мне приглянулась, но я решил пойти дальше и попробовать поэкспериментировать с непосредственным запуском Докера внутри Докера. Мне тогда казалось вполне логичным решением выкачивать докер образы и создавать контейнеры всех приложений которые мне нужны для тестирования внутри другого контейнера (давайте назовем его staging контейнер). Идея заключалась в том, чтобы запускать staging контейнер с флагом -rm, что автоматически удаляет весь контейнер со всем его содержимым при его остановке. Я покопался с докер образом от самого Докера (https://hub.docker.com/_/docker), но оно оказалось слишком громоздким и мне так и не удалось заставить его работать так как мне нужно и мне хотелось пройти весь путь самому.


Практика. Шишки

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


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

    docker run --privileged -it docker:18.09.6

    Обратите внимание на версию контейнера, шаг вправо или в лево и ваш ДинД превращается в тыкву. На самом деле, все ломается довольно часто с выходом новой версии.
    Мы должны сразу попасть в шелл.


  2. Пробуем узнать, какие контейнеры запущены (Ответ: никакие), но давайте выполним команду все-равно:

    docker ps

    Вы будете немного удивлены, но оказывается Докер демон даже не запущен:

    error during connect: Get http://docker:2375/v1.40/containers/json: dial tcp: lookup docker on 
    192.168.65.1:53: no such host

  3. Давайте запустим его самостоятельно:

    dockerd &

    Еще одна неприятная неожиданность:

    failed to start daemon: Error initializing network controller: error obtaining controller instance: failed 
    to create NAT chain DOCKER: Iptables not found

  4. Устанавливаем пакеты iptables и bash (в баше всяко работать приятнее чем в sh):

    apk add --no-cache iptables bash

  5. Запускаем bash. Наконец-то мы снова в привычном шелле


  6. попробуем запустить Докер еще раз:

    dockerd &

    Мы должны увидеть длинную простыню логов заканчивающуюся:

    INFO[2019-11-25T19:51:19.448080400Z] Daemon has completed initialization          
    INFO[2019-11-25T19:51:19.474439300Z] API listen on /var/run/docker.sock

  7. Нажимаем Enter. Мы снова в баше.


Начиная с этого момента мы можем пробовать запускать другие контейнеры внутри нашего Докер контейнера, но что если мы хотим поднять еще один Докер контейнер внутри нашего Докер контейнера или что-то пойдет не так и контейнер «вылетит»? Начинать все с начала.


Собственный DinD контейнер и новые эксперименты


Чтобы не повторять вышеописанные шаги снова и снова я создал собственный DinD контейнер:

https://github.com/alekslitvinenk/dind

Рабочее DinD решение дало мне возможность запускать Докер внутри Докера рекурсивно и проводить более смелые эксперименты.
Один такой (удачный) эксперимент с запуском MySQL и Nodejs я собираюсь сейчас описать.
Самые нетерпеливые могут посмотреть как это было здесь


Итак, начнем:


  1. Запускаем DinD в интерактивном режиме. В данной версии DinD нам нужно вручную замапить все порты которые могут использовать наши дочерние контейнеры (я над этим уже работаю)

    docker run --privileged -it \
    -p 80:8080 \
    -p 3306:3306 \
    alekslitvinenk/dind

    Мы попадаем в баш, откуда можем сразу приступать к запуску дочерних контейнеров.


  2. Запускаем MySQL:

    docker run --name mysql -e MYSQL_ROOT_PASSWORD=strongpassword -d -p 3306:3306 mysql

  3. Подключаемся к базе данных так же как мы бы подключались к ней локально. Убеждаемся что все работает.


  4. Запускаем второй контейнер:

    docker run -d --rm -p 8080:8080 alekslitvinenk/hello-world-nodejs-server

    Обратите внимание, что порт мапинг здесь будет именно 8080:8080, так как мы уже замапили порт 80 из хоста в родительский контейнер на порт 8080.


  5. Идем на localhost в браузере, убеждаемся что сервер отвечает «Hello World!».


В моем случае эксперимент с вложенными Докер контейнерами оказался довольно положительным и я продолжу развивать проект и использовать его для стейджинга. Мне кажется, что это гораздо более легковесное решение чем тот же Kubernetes и Jenkins X. Но это мое субъективное мнение.

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

P.S. Если вы считаете данный проект полезным, то пожалуйста поставьте ему звездочку на ГитХабе, сделайте форк и расскажите друзьям.

Edit1 Исправил ошибки, сделал фокус на 2 видео

Введение

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

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

Скачали Docker?

Если вы еще не скачали и не установили Docker, то перейдите по ссылке Загрузка Docker.

Готовы приступить к работе с Docker?

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

Что вы узнаете и научитесь делать

Вы узнаете как:

  • устанавливать Docker на вашу платформу
  • запускать образ программного обеспечения в контейнере
  • искать образы на Docker Hub
  • создавать свой собственный образ и запускать его в контейнере
  • зарегистрировать Docker Hub аккаунт и репозиторий для образа
  • создать образ самостоятельно
  • загружать свой образ на Docker Hub для использования другими разработчиками

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

Особенности

Это руководство предназначено для начинающих работу с Docker, и подходит для Mac, Windows, Linux или Docker Toolbox (для более старых систем Mac и Windows).

Если вы используете Docker Toolbox, вы можете использовать Quickstart Terminal для выполнения команд в предварительно сконфигурированной среде вместо открытия терминала командной строки.

Если вы используете Docker для Mac, Windows или Linux, то вы можете использовать стандартную командную строку для выполнения Docker команд.

Какие навыки потребуются?

Приступая к уроку используйте Docker CLI Engine команды, введенные в командной строке окна терминала. Вы не обязаны быть гуру командной строки, но вы должны знать как запустить свою любимую оболочку или терминал, и как запускать основные команды в этой среде. Желательно (но не обязательно) знать как перемещаться по дереву каталогов, управлять файлами, просматривать список процессов и т.д.


Комментарии:

Комментариев нет, желаете стать первым?

Docker Tutorial для начинающих

  • Home
  • Testing

      • Back
      • Agile Testing
      • BugZilla
      • Cucumber
      • Database Testing
      • 0003
      • 9A JUnit
      • LoadRunner
      • Ручное тестирование
      • Мобильное тестирование
      • Mantis
      • Почтальон
      • QTP
      • Назад
      • Центр качества (ALM)
      • RPA
      • SAP Testing
      • Управление тестированием Soap
      • TestLink
  • SAP

      • Назад
      • ABAP
      • 900 03 APO
      • Начинающий
      • Basis
      • BODS
      • BI
      • BPC
      • CO
      • Назад
      • CRM
      • Crystal Reports
      • MMO
      • HAN
      • Назад
      • PI / PO
      • PP
      • SD
      • SAPUI5
      • Безопасность
      • Менеджер решений
      • Successfactors
      • SAP Tutorials

  • Web
  • AngularJS
  • ASP.Net
  • C
  • C #
  • C ++
  • CodeIgniter
  • СУБД
  • JavaScript
  • Назад
  • Java
  • JSP
  • Kotlin
  • Linux
  • Linux
  • Kotlin
  • Linux
  • js
  • Perl
  • Назад
  • PHP
  • PL / SQL
  • PostgreSQL
  • Python
  • ReactJS
  • Ruby & Rails
  • Scala
  • SQL
  • 000
  • SQL
  • 000 0003 SQL 000 0003 SQL 000
  • UML
  • VB.Net
  • VBScript
  • Веб-службы
  • WPF
  • Обязательно учите!

      • Назад
      • Бухгалтерский учет
      • Алгоритмы
      • Android
      • Блокчейн
      • Business Analyst
      • Создание веб-сайта
      • CCNA
      • Облачные вычисления
      • 00030003 COBOL
          9000 Compiler
            9000 Встроенные системы
          • 00030002 9000 Compiler
            • Ethical Hacking
            • Учебники по Excel
            • Программирование на Go
            • IoT
            • ITIL
            • Jenkins
            • MIS
            • Сети
            • Операционная система
            • 0003
            • Назад
            • Управление проектами Обзоры
            • Salesforce
            • SEO
            • Разработка программного обеспечения
            • VB A
        • Big Data

            • Назад
            • AWS
        .

        Docker для начинающих — Linux

        В этой лабораторной работе мы рассмотрим некоторые основные команды Docker и простой рабочий процесс сборки и запуска. Мы начнем с запуска простых контейнеров, а затем воспользуемся Dockerfile для создания собственного приложения. Наконец, мы рассмотрим, как использовать bind mounts для изменения работающего контейнера, как если бы вы активно разрабатывали с помощью Docker.

        Сложность : Новичок (не знаком с Docker)

        Время : примерно 30 минут

        Задачи :

        Задача 0: предварительные условия

        Для выполнения этой лабораторной работы вам потребуется все следующее:

        • Клон репозитория GitHub лаборатории.
        • DockerID.

        Клонировать репозиторий GitHub лаборатории

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

          git clone https://github.com/dockersamples/linux_tweet_app
          

        Убедитесь, что у вас есть DockerID

        Если у вас нет DockerID (бесплатный логин, используемый для доступа к Docker Hub), посетите Docker Hub и зарегистрируйтесь.Это понадобится вам для последующих шагов.

        Задача 1. Запустить несколько простых контейнеров Docker

        Есть разные способы использования контейнеров. К ним относятся:

        1. Для запуска одной задачи: Это может быть сценарий оболочки или настраиваемое приложение.
        2. В интерактивном режиме: Это подключает вас к контейнеру аналогично тому, как вы подключаетесь по SSH к удаленному серверу.
        3. В фоновом режиме: Для долгосрочных сервисов, таких как веб-сайты и базы данных.

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

        Выполнить отдельную задачу в контейнере Alpine Linux

        На этом этапе мы собираемся запустить новый контейнер и сказать ему, что нужно запустить команду hostname . Контейнер запустится, выполнит команду hostname и выйдет.

        1. Выполните следующую команду в консоли Linux.

            docker container run alpine имя хоста
            

          Выходные данные ниже показывают, что образ alpine: latest не может быть найден локально.Когда это происходит, Docker автоматически извлекает из Docker Hub.

          После извлечения изображения отображается имя хоста контейнера ( 888e89a3b36b в примере ниже).

            Невозможно найти изображение "alpine: latest" локально
           последнее: Извлечение из библиотеки / alpine
           88286f41530e: вытягивание завершено
           Дайджест: sha256: f006ecbb824d87947d0b51ab8488634bf69fe4094959d935c0c103f4820a417d
           Статус: загружено более новое изображение для alpine: последнее
           888e89a3b36b
            
        2. Docker поддерживает работу контейнера до тех пор, пока процесс, который он запустил внутри контейнера, все еще выполняется.В этом случае процесс hostname завершается сразу после записи вывода. Это означает, что контейнер останавливается. Однако Docker не удаляет ресурсы по умолчанию, поэтому контейнер все еще существует в состоянии Exited .

          Список всех контейнеров.

            док-контейнер ls - все
            

          Обратите внимание, что ваш контейнер Alpine Linux находится в состоянии Exited .

            КОНТЕЙНЕР ИДЕНТИФИКАЦИЯ ИЗОБРАЖЕНИЕ КОМАНДА СОЗДАНО СОСТОЯНИЕ ИМЕНА ПОРТОВ
           888e89a3b36b alpine "hostname" 50 секунд назад Завершился (0) 49 секунд назад awesome_elion
            

          Примечание: ID контейнера — это имя хоста, отображаемое контейнером.В приведенном выше примере это 888e89a3b36b .

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

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

        Вы можете запустить контейнер на основе версии Linux, отличной от той, которая запущена на вашем хосте Docker.

        В следующем примере мы собираемся запустить контейнер Ubuntu Linux поверх хоста Alpine Linux Docker (Play With Docker использует Alpine Linux для своих узлов).

        1. Запустите контейнер Docker и получите доступ к его оболочке.

            docker container run --interactive --tty --rm ubuntu bash
            

          В этом примере мы даем Docker три параметра:

          • --interactive говорит, что вам нужен интерактивный сеанс.
          • --tty выделяет псевдотерминал.
          • --rm сообщает Docker, что нужно продолжить и удалить контейнер, когда он завершит выполнение.

          Первые два параметра позволяют вам взаимодействовать с контейнером Docker.

          Мы также указываем контейнеру запускать bash в качестве основного процесса (PID 1).

          Когда контейнер запустится, вы перейдете в оболочку bash с приглашением по умолчанию root @ : / # .Докер прикреплен к оболочке в контейнере, передавая ввод и вывод между вашим локальным сеансом и сеансом оболочки в контейнере.

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

          ls / отобразит содержимое корневого каталога в контейнере, ps aux покажет запущенные процессы в контейнере, cat / etc / issue покажет, какой дистрибутив Linux запущен в контейнере, в данном случае Ubuntu 18.04.3 LTS.

            л.с /
            
            пс доп.
            
            cat / etc / issue
            
        3. Введите exit , чтобы выйти из сеанса оболочки. Это завершит процесс bash , что приведет к завершению работы контейнера.

            выход
            

          Примечание: Поскольку мы использовали флаг --rm при запуске контейнера, Docker удалил контейнер при его остановке.Это означает, что если вы запустите еще один докер-контейнер ls --all , вы не увидите контейнер Ubuntu.

        4. Ради интереса, давайте проверим версию нашей хост-машины.

            cat / etc / issue
            

          Вы должны увидеть:

            Добро пожаловать в Alpine Linux 3.8
           Ядро \ r на \ m (\ l)
            

        Обратите внимание, что наша хост-виртуальная машина работает под управлением Alpine Linux, но мы смогли запустить контейнер Ubuntu.Как упоминалось ранее, распределение Linux внутри контейнера не обязательно должно совпадать с распределением Linux, запущенным на хосте Docker.

        Однако контейнеры Linux требуют, чтобы на хосте Docker работало ядро ​​Linux. Например, контейнеры Linux не могут работать непосредственно на хостах Windows Docker. То же самое и с контейнерами Windows — они должны работать на хосте Docker с ядром Windows.

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

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

        Запустить контейнер MySQL в фоновом режиме

        Фоновые контейнеры используются для запуска большинства приложений. Вот простой пример использования MySQL.

        1. Запустите новый контейнер MySQL с помощью следующей команды.

            запуск контейнера докера \
           --detach \
           --name mydb \
           -e MYSQL_ROOT_PASSWORD = мой-секрет-pw \
           mysql: последний
            
          • --detach запустит контейнер в фоновом режиме.
          • - имя назовет его mydb .
          • -e будет использовать переменную среды для указания пароля root (ПРИМЕЧАНИЕ: это никогда не должно выполняться в производственной среде).

          Поскольку образ MySQL не был доступен локально, Docker автоматически извлек его из Docker Hub.

            Невозможно найти изображение 'mysql: latest' locallatest: извлечение из библиотеки / mysql
           aa18ad1a0d33: вытягивание завершено
           fdb8d83dece3: Извлечение завершено
           75b6ce7b50d3: Потяните завершено
           ed1d0a3a64e4: Вытягивание завершено
           8eb36a82c85b: вытягивание завершено
           41be6f1a1c40: Потяните завершено
           0e1b414eac71: Извлечение завершено
           914c28654a91: Вытягивание завершено
           587693eb988c: вытягивание завершено
           b183c3585729: Вытягивание завершено
           315e21657aa4: вытягивание завершено
           Дайджест: sha256: 0dc3dacb751ef46a6647234abdec2d4  
        .
  • Добавить комментарий

    Ваш адрес email не будет опубликован. Обязательные поля помечены *