Docker, часть 2

Знакомство с Ansible

Недавно (тройку месяцев назад), я поработал с DevOps командой, почти каждый участник которой, негативно относился к docker. По причинам:

  • docker правит iptables (хотя можно отключить в daemon.json)
  • docker бажный и в проде запускать его не будем
  • если docker daemon падает, то соответственно, падают все контейнеры с инфрастуктурой
  • в docker нет необходимости
  • зачем docker если, есть Ansible и виртуальные машины

На той же работе я и познакомился с еще одним инструментом — Ansible. Когда-то я слышал о нем, но не пробовал писать свои плейбуки. А теперь я начал писать свои таски и тут мое видение поменялось окончательно! Потому что я понял: у Ansible есть модули для запуска тех же docker контейнеров, сборок образов, сетей и пр., при этом контейнеры можно запустить не только локально, но и на удаленных серверах! Моему восторгу не было предела — я нашел НОРМАЛЬНЫЙ инструмент и выбросил свои Makefile и docker-compose файлы, они были заменены на yaml таски. Был уменьшен код за счет использования конструкций типа , , etc.

ОБНОВЛЕНИЕ 7 февраля 2019: Команды управления

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

Обратите внимание, что это изменение вводит только две смены имени команды — в большинстве случаев это просто означает добавлениеилив команду. Отображение командВот

Заворачивать

Если вы только начинаете работать с Docker, это три наиболее важные команды:

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

— Построить образ.

— Нажмите на изображение в удаленном реестре.

Вот большой список основных команд Docker:

How to run SQL server in a Docker container

How to run SQL server in a Docker container

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

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

Присоединить к контейнеру

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

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

Чтобы лучше понять, как работает команда давайте запустим новый отдельный контейнер Nginx, используя официальный образ Nginx.

Опция указывает Docker связать порт 8080 контейнера с портом 80 на хост-компьютере.

Перечислите контейнеры, чтобы убедиться, что контейнер my_nginx работает:

Присоедините к контейнеру, используя идентификатор или имя контейнера:

Команда по умолчанию для образа nginx, которая выполняется при запуске контейнера, установлена ​​в . Когда вы запускаете команду ваш терминал подключается к процессу .

Откройте в своем браузере, и вы сможете наблюдать результаты процесса nginx в режиме реального времени.

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

Чтобы отсоединиться от контейнера, не останавливая его, используйте комбинацию . Нажатие останавливает контейнер.

Если запущенные процессы, к которым вы подключаетесь, принимают ввод, вы можете отправить ему инструкции.

Получить снаряд в контейнер

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

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

Это создаст контейнер с именем «my_mysql».

Чтобы выполнить команду внутри контейнера, выполните следующую команду:

Параметр обозначает интерактивный, а указывает Docker выделить псевдо-устройство TTY. Команда выведет список всех файлов и каталогов в каталоге контейнера :

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

Команда ниже создаст новый сеанс Bash внутри контейнера:

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

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

Вывод будет выглядеть примерно так:

Вывод

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

докер

Что такое скрытая сеть Wi-Fi или скрытый SSID? Как найти и подключиться к скрытым сетям Wi-Fi в Windows 10? Как сделать вашу беспроводную сеть скрытой? Это сообщение отвечает на все такие вопросы.

Узнайте, как подключиться к бесплатной услуге VPN на вашем Mac, и наслаждайтесь контентом со всего мира, даже если он ограничен в вашей стране.

Узнайте, как подключиться к FTP-серверу в Mac прямо из Finder через Macfusion.

Docker-gc — удаление ненужных контейнеров и образов

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

Docker-gc может запускаться в виде скрипта или контейнера. Мы воспользуемся вторым вариантом. Запустим docker-gc, чтобы узнать, какие контейнеры и образы можно удалить.

Чтобы docker-gc мог взаимодействовать с Docker через его API, мы подмонтировали сокет-файл Docker. Для поиска контейнеров и образов, которые можно удалить, запустим docker-gc с переменной окружения DRY_RUN=1. При этом никаких изменений на диске сделано не будет. Всегда лучше сначала убедиться, что docker-gc не собирается удалить ничего лишнего. Вот вывод этой команды:

Если вы согласны с предложенным docker-gc планом очистки, запустите ту же команду, но теперь уже без DRY_RUN.

В выводе будут перечислены удаленные docker-gc контейнеры и образы.

У docker-gc есть еще несколько опций. Чтобы получить более подробную информацию об этой утилите, рекомендую почитать соответствующую документацию.

Отладка .NET приложения запущенного в контейнере

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

Далее запустим redis и подключим его к ранее созданной сети. Благодаря параметру процесс в контейнере будет запущен в фоновом режиме

Далее с помощью Visual Studio 2019 создадим новый проект ASP.NET Core Web API, который будет использован для демонстрации отладки

Добавим для взаимодействия с Redis пакет StackExchange.Redis через Package Manager Console

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

Добавим в проект файл RandomWeatherService.cs, где будет находится служба для выдачи не очень точного прогноза

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

Зарегистрируем созданные службы в классе Startup

И наконец, изменим созданный автоматически единственный контроллер WeatherForecastController следующим образом

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

В результате получим следующую структуру проекта

Если по какой-то невероятной причине Вам понадобятся исходники, то они здесь

Запустим наше приложение в контейнере под отладкой

После того как контейнер будет запущен, также подключим его к сети mynet

После убедимся, что все необходимые контейнеры находятся в одной сети

Далее установим Breakpoint в единственном методе контроллера и пошлем запрос через Postman, или через любой браузер

Кстати, используемый порт в Вашем случае может отличаться и его можно посмотреть в окне Containers

Результат в окне Postman

Дополнительно убедимся, что значение зафиксировано в redis, подключившись с помощью консоли redis-cli

Хорошо, все сработало, как и задумано!

Каскадно-объединённая файловая система?

Третье важное отличие между реализациями контейнеров Linux и Windows заключается в способе, которым обе операционные системы используют технологию Docker “копирование-при-записи”. Так как множество приложений Windows полагается на семантику NTFS, для команды Microsoft было сложно создать полноценную реализацию каскадно-объединённой файловой системы в Windows

Для таких функций, как журналы USN и транзакции, это, к примеру, потребовало бы совершенно новой реализации. Поэтому в текущей версии контейнеров в Windows Server 2016 нет настоящей каскадно-объединённой файловой системы. Вместо этого текущая реализация создаёт новый виртуальный диск NTFS для каждого контейнера. Чтобы эти виртуальные диски оставались небольшими, различные объекты файловой системы на этом виртуальном NTFS диске на самом деле являются символическими ссылками на настоящие файлы файловой системы хоста. Как только вы изменяете файлы внутри контейнера, эти файлы сохраняются на виртуальное блочное устройство, а в момент, когда вы хотите зафиксировать этот слой изменений, изменения забираются из виртуального блочного устройства и сохраняются в нужном месте файловой системы хоста контейнера.

Docker Stack

С файлом docker-compose третьей версии в одном файле можно определить стек сервисов целиком, включая стратегию развертывания, и выполнить развертывание одной командой deploy. Основным отличием третьей версии файла docker-compose от второй стало появление параметра deploy в описании каждого сервиса. Этот параметр определяет способ развертывания контейнеров. Файл docker-compose для тестовой системы мониторинга приведен ниже:

В нашем стеке 3 сервиса, которые описаны ниже.

influx

Здесь мы будем использовать образ influxdb. Для постоянного хранилища создадим том influx, который будет монтироваться в папку контейнера /var/lib/influxdb. Нам нужна только одна копия InfluxDB, которая будет размещена на хосте manager. Сервер docker запущен на этом же хосте, поэтому команды для контейнера могут выполняться здесь же. Поскольку обоим оставшимся сервисам нужна influxDB, мы добавим в описание этих сервисов ключ depends_on со значением influx.

grafana

Будем использовать образ grafana/grafana и пробросим 3000-й порт контейнера на 80-й порт хоста. Маршрутная сетка позволяет подключаться к grafana через 80-й порт любого хоста, входящего в рой. Для постоянного хранения данных создадим еще один том под названием grafana. Он будет монтироваться в папке контейнера /var/lib/grafana. Grafana также развернем на хосте manager.

cadvisor

Чтобы настроить cAdvisor, придется поработать чуть больше, чем с предыдущими сервисами. Более подробная информация доступна по этой ссылке. Выбор значения hostname в этом случае — задача непростая. Мы собираемся установить агенты на каждой ноде, и этот контейнер будет собирать метрики ноды и работающих на ней контейнеров. Когда cAdvisor посылает метрики в InfluxDB, он устанавливает тег machine, который содержит имя контейнера с cAdvisor. Его значение должно соответствовать ID ноды, на которой он запущен. В стеках Docker можно использовать шаблоны в именах. Более подробную информацию можно найти . Мы дали контейнерам имена, содержащие ID ноды, на которой они запущены, и таким образом сможем определить, откуда пришла метрика. Это достигается использованием следующего выражения .

Мы также добавим в cadvisor несколько параметров командной строки. Параметр logtostderr перенаправляет сгенерированные cadvsior логи в stderr, что упрощает отладку. Флаг docker_only говорит, что нас интересуют лишь контейнеры docker. Следующие три параметра определяют место в хранилище, где необходимо разместить собранные метрики. Мы попросим cAdvisor положить их в базу данных cadvisor на сервере InfluxDB, слушающем на influx:8086. Это позволит настроить отправку метрик на influx-сервис нашего стека. Внутри стека все порты открыты (exposed), поэтому их не нужно указывать отдельно.

Прописанные в файле тома нужны cAdvisor для сбора метрик с хоста и докера. Для развертывания cadvisor мы будем использовать режим global. Это даст уверенность, что на каждой ноде роя выполняется лишь один экземпляр сервиса cadvisor.

В конце файла у нас есть ключ volumes, в котором указаны тома influx и grafana. Поскольку оба тома будут размещены на хосте manager, для них мы пропишем драйвер local.

Для развертывания стека сохраните размещенный выше файл под именем docker-stack.yml и выполните следующую команду:

Она запустит сервисы стека monitor. Первый запуск команды может занять некоторое время, поскольку ноды должны загрузить образы контейнеров. Вам также потребуется создать в InfluxDB базу данных для хранения метрик под названием cadvisor.

Выполнение команды может завершиться неудачей с сообщением, что контейнер influx не существует. Причина ошибки в том, что контейнер еще не готов. Подождите немного и выполните команду еще раз. Мы можем выполнять команды в сервисе influx, поскольку он запущен на хосте manager и мы используем установленный здесь docker. Чтобы выяснить ID контейнера с InfluxDB, можно воспользоваться командой , а для создания базы данных с именем cadvisor надо выполнить команду .

Чтобы вывести список сервисов стека, выполните . Вывод команды будет выглядеть примерно так:

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

3: Взаимодействие с образами Docker

В разделе Containers нажмите 2, чтобы перейти в раздел Images.

Этот раздел предлагает более простой доступ к команде docker image inspect. В dry есть также удобные сочетания клавиш, которые вы можете увидеть в навигационной панели:

  • Ctrl + D (Remove Dangling): повисшие тома – это тома, на которые больше не ссылается ни один контейнер, и потому избыточны. Обычно в Docker в командной строке эта операция включает в себя команду docker volume rm и флаг dangling=true плюс целевые тома данных.
  • Ctrl + E (Remove): эквивалент docker rmi, позволяет удалять образы, если ни один из контейнеров на основе этих образов не активен.
  • Ctrl + F (Force Remove): позволяет принудительно удалять выбранный образ, как команда docker rmi –force.
  • I (History): отображает те же данные, что и Show Image History в разделе Containers.

2: Взаимодействие с контейнерами Docker

Запустите dry, чтобы получить доступ к дашбордам в терминале:

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

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

В любое время вы можете нажать F5 для обновления экрана dry при возникновении ошибок с его рендерингом.

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

Если вы используете стек контейнеров WordPress, MariaDB и PHPMyAdmin (из требований), вы увидите эти три только что созданных контейнера.

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

Это отобразит информацию о контейнере в верхней части экрана (его порты, сетевые ссылки и IP-адрес контейнера).

Выбрав контейнер, вы также увидите новый список доступных опций:

  • Fetch logs – эквивалент команды Docker Engine (docker logs). Она полезна при устранении неполадок и ошибок в контейнерах.
  • Kill container, которая позволяет убить контейнер, если он не отвечает или не может завершить работу правильно.
  • Remove container, которая помогает удалить ненужные контейнеры.
  • Inspect container – эквивалент команды docker container inspect.
  • Restart останавливает и перезапускает контейнер (это гораздо быстрее, чем вводить команды Docker Engine для перезапуска и запроса состояния контейнера).
  • Show image history выводит список команд, использованных для запуска контейнера. Эти «слои» генерируются во время процесса сборки образа и являются результатом команд  действий, перечисленных в файле Dockerfile. С помощью этой опции можно увидеть, как именно был сгенерирован контейнер с использованием базового образа Docker.
  •  Stats + Top включает в себя разную информацию (использование ЦП, потребление памяти, входящий и исходящий сетевой трафик, работа файловой системы, общие идентификаторы процесса и время безотказной работы контейнера). Также эта опция включает в себя список процессов, который функционально идентичен выводу top.
  • Stop останавливает контейнер. Вы можете использовать F2, чтобы в списке Containers отображались включенные и остановленные контейнеры (currently stopped and active). Перезапустить остановленный контейнер можно с помощью опции Restart.

Важно! Опции Kill container и Remove container выполняются без подтверждения, будьте осторожны. Нажмите клавишу Esc, чтобы вернуться в корневой раздел дашборда Containers

Теперь нужно рассмотреть раздел Images

Нажмите клавишу Esc, чтобы вернуться в корневой раздел дашборда Containers. Теперь нужно рассмотреть раздел Images.

Повторение — мать учения

Теперь все вышеизложенное — но на примере демонстрационного приложения Hello World. Считаем, что демона мы на своем компе уже поселили, ссылка на установку — чуть выше по тексту.

Выполняем команду docker run hello-world и видим следующий результат:

Давайте разбираться.

Первое что произошло после команды «докер, запусти образ с именем hello-world», это попытка найти его локально и запустить.

Попытка не увенчалась успехом (у меня была чистая установка докера), причем, обратите внимание, искался образ не hello-world, а hello-world:latest.Через двоеточие указывается тег — что-то вроде версии или модификации образа. Если его не указать, будет искаться самая свежая версия с общепринятым тегом latest

Тогда докер решает поискать этот образ на docker hub`е и скачать его оттуда.https://hub.docker.com/_/hello-world

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

А далее видим следующие строки:

Тут нам сообщают хэш образа и статус, говорящий, что загружен новый образ. Также в этот момент выводится и приветствие с сообщением. Но перед этим происходит еще кое-что.

А именно — из только что скачанного образа был создан контейнер. Если перевести на язык ООП, создался объект sleepy_antonelli (контейнер) экземпляр класса hello-world (образа). Sleepy_antonelli — это рандомно сгенерированное имя контейнера, поскольку мы не указали его явно.

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

Собственно, это тут и написано (вместе с призывом не останавливаться на достигнутом и ссылкой на документацию). Но давайте проверим сами.

Если выполнить команду docker images, мы увидим скачанный образ.

А если выполнить команду docker ps -a — флаг «a» показывает все образы, даже те, что остановлены в данный момент — то увидим и сам контейнер, как раз с именем  sleepy_antonelli.

Имена можно задавать и самим, но нам пока это не нужно, поэтому докер сам генерирует для имени два рандомных слова. Также тут видны его ID, образ, с которого он был сделан, команду, ради которой был запущен (в данном случае — написать приветствие), когда был создан, код завершения работы (0 — это штатное завершение) со временем, порты (в данном случае они никак не пробрасывались, потому и пусто) и, наконец, имя.

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

Но важно помнить, что образ — это шаблон. Он создается один раз и не меняется, а контейнеры можно модифицировать индивидуально

Это то же самое, что получить с завода (образа) 10 одинаковых контейнеров для перевозок грузов, но перекрасить каждый в разный цвет, повесить разные замки, и по-разному назвать.

Google Cloud: Google Container Engine

Как мы говорили раньше, не существует никакой известной стабильной комбинации: операционная система + дистрибутив + версия докера, поэтому не существует стабильной экосистемы для запуска на ней Kubernetes. Это — проблема.

Но существует потенциальный вокрэраунд: Google Container Engine. Он хостится на Kubernetes (и Docker) как сервис, часть Google Cloud.

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

Они уже предлагают этот серивис, что означает — они придумали обходные пути для починки проблем Докера. Поэтому самым простым способом иметь контейнеры, которые будут работать в продакшене (ну, или будут работать вообще), может оказаться использование Google Container Engine.

Цель: перейти на Google Cloud, начиная с филиалов, не привязанных к AWS. Игнорирвать оставшуюся часть перечисленных здесь задач, т.к. они становятся нерелевантными.

Google Container Engine: еще одна причина, почему Google Cloud — это будущее, и AWS — это прошлое (в т.ч. на 33% более дешевые инстансы со в 3 раза большей скоростью и IOPS в среднем).

Disclaimer (прочитайте, прежде чем комментировать!)

Небольшой кусочек контекста потерялся где-то между строк. Мы — небольшая контора с несколькими сотнями серверов. По сути, мы делаем финансовую систему, которая перемещает миллионы долларов в день (или миллиарды — в год).

Честно сказать, у нас были ожидания выше среднего, и мы воспринимаем проблемы с продакшеном довольно (слишком?) серьезно.

В общем, это «нормально», что у вас никогда не было этих проблем, если вы не используете докер на больших масштабах в продакшене, или не использовали его достаточно долго.

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

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

Часть 0.1 Сравнение с VM

  1. независимость — контейнер может быть перемещен на любую ОС с docker-службой на борту и контейнер будет работать. (Официально — да, по факту, не уверен что совместимость такая радужная, как пони, радуга и бабочки. Если у вас есть иной опыт — прошу поделиться)
  2. самодостаточность — контейнер будет выполнять свои функции в любом месте, где бы его не запустили.
  1. Внутри контейнера находится минимально необходимый набор софта, необходимый для работы вашего процесса. Это уже не полноценная ОС, которую надо мониторить, следить за остатком места итд итп.
  2. Используется другой подход к виртуализации. почитать об этом. Я имею ввиду сам прицип — там нет привычной хостовой ОС.
  3. Следует особо относиться к контейнеру и генерируемым им данным. Контейнер это инструмент обработки данных, но не инструмент их хранения. Как пример — контейнер — это гвоздезабивающая машина, подаваемые на вход данные — доска и гвоздь, результат работы — забить гвоздь в доску. При этом доска с гвоздем не остается частью той самой гвоздезабивающей машины, результат отдельно, инструмент отдельно. Выходные данные не должны сохраняться внутри контейнера (можно, но это не docker-way). Поэтому, контейнер это либо worker (отработал, отчитался в очередь), либо, если это, например, веб-сервер, то нужно использовать внешние тома. (все это очень просто, не стоит в этом моменте грустить).

Зачем программисту холодильник

Кто сказал: «Не люблю пить теплое»? Убираем емкость подальше и смотрим на принципиальную схему девайса:

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

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

У нас два пути: купить второй холодильник или разделить тот, что у нас есть, на две камеры с датчиками температуры на входе, чтобы управлять клапаном подачи хладагента внутрь. Ура, мы только что изобрели двухкамерный холодильник. А заодно — разобрались с тем, для чего программистам понадобились виртуальные машины и докер. 

Проекты, которые мы делаем, не сильно отличаются от продуктов в холодильнике — каждому нужны свои условия. Для одного — PHP 7.4, база MySQL 7.6, Sphinx и мейлер на Golang. Для другого — нода 12 версии, Angular 7 и база MySQL 8.0. Проектов может быть не один десяток. Установить это все на одну машину — все равно, что запихнуть все продукты в одну камеру холодильника. 

Нужно как-то изолировать один проект (продукт) от другого. На помощь приходит или виртуальная машина (еще один холодильник), или докер (вторая камера со своими настройками). Давайте немного изменим схему нашего устройства:

Включаем воображение и смекалку, поехали!

Итак, у нас есть квартира (компьютер) со своей инфраструктурой, от которой нам требуется электричество (жесткий диск, сетевая плата, процессор, etc). Для установки второго холодильника (виртуальной машины) нам нужен разветвитель розеток (hypervisor). Довольно просто, но мы видим, что для изоляции мяса от напитков нам потребовалось два комплекта оборудования (Guest OS), хотя по факту условия хранения определяет только датчик, управляющий клапаном к капиллярной системе (bins/lib). 

В случае, когда мы физически разделяем холодильную и морозильную камеры (container engine), нам не нужна вторая розетка (hypervisor) и место для второго холодильника (полноценная Guest OS). Мы получили два независимых контейнера — каждый со своими условиями (bins/lib), которые подходят нужному продукту (app).

Утилита Docker

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

$ docker опции команда опции_команды аргументы

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

  • -D — включить режим отладки;
  • -H — подключиться к серверу, запущенному на другом компьютере;
  • -l — изменить уровень ведения логов, доступно: debug,info,warn,error,fatal;
  • -v — показать версию;
  • —help вывести справку по команде или утилите в целом;

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

  • attach — подключиться к запущенному контейнеру;
  • build — собрать образ из инструкций dockerfile;
  • commit — создать новый образ из изменений контейнера;
  • cp — копировать файлы между контейнером и файловой системой;
  • create — создать новый контейнер;
  • diff — проверить файловую систему контейнера;
  • events — посмотреть события от контейнера;
  • exec — выполнить команду в контейнере;
  • export — извлечь содержимое контейнера в архив;
  • history — посмотреть историю изменений образа;
  • images — список установленных образов;
  • import — создать контейнер из архива tar;
  • info — посмотреть информацию о системе;
  • inspect — посмотреть информацию о контейнере;
  • kill — остановить запущенный контейнер;
  • load — загрузить образ из архива;
  • login — авторизация в официальном репозитории Docker;
  • logout — выйти из репозитория Docker;
  • logs — посмотреть логи контейнера;
  • pause — приостановить все процессы контейнера;
  • port — подброс портов для контейнера;
  • ps — список запущенных контейнеров;
  • pull — скачать образ контейнера из репозитория;
  • push — отправить образ в репозиторий;
  • restart — перезапустить контейнер;
  • rm — удалить контейнер;
  • run — выполнить команду в контейнере;
  • save — сохранить образ в архив tar;
  • search — поиск образов в репозитории по заданному шаблону;
  • start — запустить контейнер;
  • stats — статистика использования ресурсов контейнером;
  • stop — остановить контейнер;
  • top — посмотреть запущенные процессы в контейнере;
  • unpause — проложить выполнение процессов в контейнере.

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

  • -e — переменные окружения для команды;
  • -h — имя хоста контейнера;
  • -i — интерактивный режим, связывающий stdin терминала с командой;
  • -m — ограничение памяти для команды;
  • -u — пользователь, от имени которого будет выполнена команда;
  • -t — связать tty с контейнером для работы ввода и вывода;
  • -v — примонтировать директорию основной системы в контейнер.

Теперь, когда мы рассмотрели все основы, приведем несколько примеров работы с контейнерами. Это очень просто.

Что такое Docker

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

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

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

Преимущества контейнеров:

Синтаксис и опции docker run

Синтаксис команды docker run похож на синтаксис других команд Linux и выглядит следующим образом:

$ docker run опции образ команда

Утилите обязательно надо передать образ, на основе которого будет создан контейнер. Образ может быть локальным или указывать на образ, который надо загрузить из сети. Мы рассмотрим это в примерах ниже. Опции позволяют настроить контейнер и параметры его запуска более детально. Сама команда позволяет переопределить программу, которая выполняется после запуска контейнера. Например, выполнив /bin/bash, вы можете подключится к самому контейнеру.

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

  • -d — запускает контейнер в фоновом режиме;
  • -t — прикрепляет к контейнеру псевдо-TTY-консоль;
  • -i — выводит в терминал STDIN поток контейнера;
  • —name — имя контейнера, по которому потом можно будет к нему обращаться;
  • —dns — устанавливает DNS-серверы для контейнера;
  • —network — тип сети для контейнера, может принимать такие значения: bridge (используется по умолчанию), none, host. Также можно передать идентификатор сети Docker, к которой надо подключится;
  • —add-host — добавляет строчку в /etc/hosts;
  • —restart — указывает, когда надо перезапускать контейнер. Возможные значения: no, on-failure, always, unless-stopped;
  • —rm — удаляет контейнер после завершения его работы;
  • -m, —memory — количество оперативной памяти, доступное Docker-контейнеру;
  • —memory-swap — объём памяти раздела подкачки, доступный в контейнере;
  • —cpus — количество ядер процессора, доступных в контейнере;
  • —shm-size — размер файла /dev/shm;
  • —device — позволяет монтировать устройства из папки /dev в контейнер;
  • —entrypoint — позволяет переопределить скрипт, который выполняется при запуске контейнера, перед запуском основной команды;
  • —expose — позволяет пробросить несколько портов из контейнера в хост-систему;
  • -P — пробрасывает все порты контейнера в хост-систему;
  • -p — переносит все порты контейнера в хост-систему без смены номера порта;
  • —link — позволяет настроить связь контейнеров Docker;
  • -e — добавляет переменную окружения в контейнер;
  • -v, —volume — позволяет монтировать папки хоста в контейнер;
  • -w — изменяет рабочую директорию контейнера.

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

Рейтинг
( Пока оценок нет )
Понравилась статья? Поделиться с друзьями:
Ваша ОС
Добавить комментарий

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!: