Docker – это не страшно, это очень интересная штука. Единственное, рассказать о нем за 40 минут доклада нереально, поэтому погружение будет поверхностным. Я сначала кратко расскажу теорию, а потом покажу, как я с ним работаю.
Будем говорить:
-
о том, что такое Docker, какие у него основные элементы и как им управлять;
-
зачем Docker нужен – в каких задачах используется, когда и откуда пришел;
-
я попытаюсь объяснить, что это не сложно, это интересно;
-
философия Docker состоит в том, что все объекты должны находиться в определенных местах – это значит, что все наши сервисы должны иметь свой домик, который является контейнером Docker.
Что такое Docker
Docker – программное обеспечение, которое позволяет быстро создавать изолированное окружение на вашем хосте. Это некая разновидность виртуализации.
Основное отличие между виртуальными машинами и Docker в том, что контейнеры Docker не включают прослойку операционной системы, а запускаются на ядре хостовой операционной системы, и за счет этого позволяют достигать более быстрых запусков и меньших объемов.
Если мы возьмем виртуальную машину на базе Hyper-V, VirtualBox или еще какого-нибудь инструмента виртуализации, накатим на нее ОС, которая весит от 200 мб для Linux до 12 Гб для Windows, то вся эта махина будет запускаться долго и медленно. При этом изоляция у нее выше по сравнению с Docker.
Но Docker запускается не так – он создает изолированное пространство относительно вашей хостовой операционной системы, и в нем начинают работать ваши сервисы.
Docker так и завоевал популярность во всем мире, как самый удобный инструмент виртуализации. Тот же самый Kubernetes под капотом тоже использует виртуализацию Docker. А на базе Kubernetes и такой контейнерной виртуализации построено подавляющее большинство веб-сервисов и веб-платформ.
Изучать Docker в любом случае нужно для собственного развития. И в плане использования в 1С он тоже сильно помогает.
Контейнер и образ
Давайте разделим Docker на две основные части: образ и контейнер.
Давайте вспомним, когда мы покупали ПО на дисках. Образ – это и есть лазерный диск, слепок вашего программного обеспечения. Образ у вас один. Он может находиться у вас, в облаке, вы можете его собрать из исходников.
У диска есть дорожки, а у образа – слои. Каждая команда, которая формирует этот образ, накладывает в образе свой слой. Это позволяет в дальнейшем экономить дисковое пространство за счет переиспользования слоев нескольких образов. Допустим, у вас есть 3-4 образа, каждый из которых использует в качестве первого слоя операционную систему Ubuntu. С Docker вам не надо в вашей системе хранить несколько слоев с Ubuntu: вам достаточно одного слоя, который будут использовать все образы. Это называется переиспользование.
Когда вы начинаете запускать свое приложение на базе образа, вы запускаете контейнер – это, по факту, экземпляр приложения, сущность, которая предоставляет вам сервис.
Контейнер с точки зрения концепции Docker – некая сущность, которая живет недолго. Он должен родиться, поработать, и в дальнейшем уничтожиться. Все данные которые необходимо сохранить, монтируются к контейнеру в качестве подключаемых разделов.
Linux vs Windows
Где работает эта магия?
Родной операционной системой для docker является OS Linux, но время не стоит на месте и в текущий момент есть возможность запускать контейнеры и на операционной системе Windows/ Причем, появились и контейнеры на базе операционной системы Windows
В настоящее время в Windows реализована функция WSL2 – поддержка Windows Subsystem for Linux. Она поддерживается с версии сборки 19041 и позволяет полноценно работать с Linux-оболочкой в ОС Windows.
Если вы хотите попробовать поработать с Docker на Windows, есть два варианта:
-
поставить виртуальную машину с Linux на Windows и устанавливать Docker в нем;
-
либо поставить WSL2 и разобраться, как в ней работать с Docker. В WSL2 решено большое количество проблем, она работает более стабильно. Если вы работаете в VS Code – там есть классные плагины поддержки WSL прямо внутри среды. Вы можете работать с файловой системой виртуальной машины внутри VS Code.
Рекомендация простая - если работаете на Windows – используйте WSL2.
В продуктивной среде, правильнее работать с Docker на Linux – так как его родная операционная система, и на ней будет минимальное количество проблем.
Еще один момент, который стоит отметить: контейнеры бывают двух вариантов – на базе образов операционных систем Windows и Linux.
В интернете размещено большое количество уже собранных образов и исходников для Linux-контейнеров.
Windows-контейнеры тоже появляются, но там есть свои проблемы:
-
Windows-контейнеры не содержат графической оболочки, поэтому работа с приложениями, имеющими завязку на GUI, будет вызывать проблемы. Например, при запуске клиента 1С вы не увидите, что происходит внутри контейнера и дополнительная установка, например, VNC проблему не решит.
-
Windows требует, чтобы версия ОС хоста соответствовала версии ОС контейнера. Если вы хотите запустить контейнер на основе новой сборки Windows, убедитесь, что у вас есть эквивалентная сборка хоста
-
Требования наличия лицензии на запуск. Вы не можете использовать образ контейнера, если у вас нет лицензии на соответствующую версию ОС
Стоит отметить, что на текущий момент Windows позволяет запускать как линуксовые, так и Windows-контейнеры, но на OS Linux можно запустить только Linux-контейнеры.
Для Linux разработано большое количество уже готовых образов под различные нужды, поэтому найти что-то полезное не представляется сложностью.
Docker Registry
Где хранятся образы.
Если вы собрали образ из исходников сами, он будет храниться у вас на локальной машине. Или образ можно скачать из Docker Registry – это хаб, предназначенный для хранения образов. Они хранятся там в виде слоев, чтобы экономить пространство.
-
Образы бывают публичные и приватные. Публичные – доступные всем без ограничений. Приватные – те, к которым требуется авторизованный доступ.
-
Docker Registry можно развернуть у себя, чтобы собирать и хранить образы у себя.
-
Docker Registry позволяет экономить время при развертывании окружения на разных машинах. При развертывании контейнера не требуется его каждый раз пересобирать, что в некоторых случаях может занимать достаточно больше время.
Docker Compose
Помимо основной команды Docker есть утилита Docker-compose, которая позволяет манипулировать группой контейнеров и запускать их одним скриптом.
На слайде показан пример из официального репозитория GitLab: здесь через командную строку запускается Docker-контейнер GitLab.
Сложность запуска контейнера Docker как утилиты командной строки в том, что мы не можем хранить параметры и команду запуска в виде кода. Если вам нужно одновременно развернуть несколько связанных контейнеров, команда может быть достаточно большой. Причем нужно будет четко понимать какой из сервисов нужно запустить раньше, какой позже. Убедиться, что сервис уже готов принимать подключения перед запуском последующего. это очень удобно делать в ручную. Когда производится запуск множества групп контейнеров, этот квест существенно усложняется – нам приходиться манипулировать в голове кучей параметров, пытаясь понять, в каком месте мы ошиблись, почему это не работает.
Поэтому и придумали Docker Compose – файлик в формате YAML, который описывает запуск контейнера и сервисов, взаимосвязь этих контейнеров между собой.
Вы берете готовый Docker Compose либо открываете текстовый редактор и декларативно описываете, как должен выглядеть ожидаемое вами развертывание.
В тексте Docker Compose описываете:
-
все способы взаимодействия сервисов между собой;
-
дополнительные параметры (используемые порты, устанавливаемые образы);
-
монтирование разделов, устройств, сокетов и прочего с хостовой ОС.
После того как манифест docker-compose будет готов, сервис запускается одной командой:
docker-compose up -d
Эти файлики Docker Compose вы можете хранить в своей инфраструктуре и так же их версионировать, меняя какие-то параметры.
Правила работы с Docker
Есть правила работы с Docker, к которым надо стремиться.
-
Стараться выделять каждому сервису свой контейнер. Утилита RAS должна жить в своем контейнере, не должно быть одновременно и сервер 1С и RAS, это неправильно. Nginx тоже должен жить в своем контейнере, Traefik – тоже.
-
Контейнер должен быть максимально легким, в нем не должно храниться временных файлов, и не должен быть основан на тяжелых ОС. Нужно выбирать все самое маленькое и легкое, чтобы экономить дисковое пространство и быстро запускать. Если сервис горизонтально масштабируется в 100 раз, то 100 Мб лишнего места уже займет достаточно большое дисковое пространство.
-
Стараться подробно описывать версии устанавливаемых приложений внутри образа. Это необходимо для того, что бы при последующей сборке образа мы гарантированно получили идентичное окружение, а не отличную версию из за того, что обновились зависимости. В некоторых случаях это может вызвать серьезные проблемы в работе контейнера.
-
Желательно, чтобы образы могли взаимодействовать между собой. Странно будет, если будет существовать контейнер, который не взаимодействует ни с хостовой системой, ни между собой. По факту, это мертворожденный контейнер, он сам по себе висит, что-то делает, но куда выдает данные и с кем обменивается непонятно.
-
Следите за тем, чтобы после вашей работы старые данные и старые контейнеры после работы удалялись. Система должна быть чистой. Для правильного Docker-хоста на хосте должно быть установлено минимальное количество программ.
Практика
Перейдем к технической части. Давайте я покажу, что у меня стоит. На этой машине установлен Docker 19 версия, одна из самых последних. Операционная система Ubuntu.
Traefik
В первую очередь, я использую Traefik – что это такое, более подробно можно прочитать на сайте https://doc.traefik.io/traefik/.
Traefik – это реверс-прокси, который позволяет нам публиковать ресурсы в интернете. Это альтернатива Nginx, обладающая немного более богатыми возможностями. Основная преимущество Traefik – он может в автоматическом режиме публиковать уже развернутые контейнеры в интернете.
Traefik слушает два порта: 80 и 443. Все входящие запросы на эти порты он анализирует через свои правила и смотрит, относительно какого URL идет обращение. И в зависимости от URL запросы заворачиваются на контейнеры, которым установлен определенный лейбл.
Дополнительным плюсом является то, что Traefik с коробки может работать с сертификатами выписанными Letsencript, как для основного домена, так и поддоменов любого уровня.
Разворачивание контейнера с Jenkins
Это выглядит так – у нас есть файл docker-compose.yml, который поднимает сервис Jenkins.
Traefik просматривает все существующие Docker-контейнеры и ищет лейблы. Если он находит лейбл с указанием traefik.enable=true, он включается и начинает маршрутизировать трафик, который на него идет.
В частности, публикует этот сервис по от указанному URL.
Чтобы запустить Jenkins, мне нужно вызвать команду:
docker-compose up -d
Контейнер с Jenkins запустился и работает, а на сайте ci.demoncat.ru выводится приглашение Jenkins.
Как видите, я развернул Jenkins с нуля за 20 минут – все запустилось одной командой.
Разворачивание контейнера с GitLab
Теперь я хочу запустить контейнер с GitLab. Файл Docker-compose.yml для него скачан с репозитория https://github.com/sameersbn/docker-gitlab, найденного в Google. Я только настроил в нем параметры и добавил сюда лейблы для Traefik.
Также с помощью команды docker-compose up -d я могу могу этот контейнер поднять.
Здесь запускается сразу несколько сервисов: Redis, Postgre, GitLab. У них есть определенный набор переменных, с помощью которых они взаимодействуют.
И есть виртуальная сеть proxy, которая взаимодействует с ними и Traefik. Внутри этой сети как раз и проходит маршрутизация Traefik.
Если мы зайдем на сайт git.demoncat.ru, который прописан в переменной GITLAB_HOST_RULE, у нас откроется GitLab. Здесь тоже никакой магии нет.
Разворачивание контейнера с сервером 1С:Предприятия
В репозитарии https://github.com/thedemoncat/onec-images-docs я собрал коллекцию своих образов для развертывания платформы 1С:Предприятие. Причем скачивание платформы будет происходить во время сборки образа и от вас понадобиться только логин/пароль к https://releases.1c.ru/
Теперь возьмем образ 1С, который вы можете без проблем развернуть у себя из репозитория https://github.com/thedemoncat/onec-instance/. При развертывании в среде wsl2 нужно сделать несколько больше действий, для того чтобы получить доступ к платформе. Подробнее можно почитать в readme.md
Этот репозиторий нужно обязательно клонировать с сабмодулями командой:
git clone --recursive https://github.com/TheDemonCat/onec-instance.git
Дело в том, что здесь два репозитория подключены в качестве сабмодулей, без их загрузки ничего не запустится.
Внутри репозитория есть файл-пример env.example.
Его нужно скопировать, скопированный файл назвать .env и указать в нем свой логин-пароль от ИТС.
На OS Linux запускаю сборку образов и запуск сервера командой:
./onec_instance.sh start
На Linux дополнительно потребуется указать пароль суперпользователя, чтобы произошла запись в файла в hosts. Иначе при подключении к 1С-ке вы получите проблему несоответствия принадлежности клиента и сервера.
На OS Windows нужно в ручную прописать IP адрес виртуальной машины wsl2 в файл hosts.
В качестве примера я создам чистую серверную базу:
-
Кластер серверов 1С:Предприятие: onec_server
-
Имя информационной базы в кластере: test
-
Тип СУБД: PostgreSQL
-
Сервер баз данных: db
-
Имя базы данных: test
-
Пользователь баз данных: postgres
-
Пароль пользователя баз данных оставляем пустым
Нажимаю ОК и жду, пока база создастся. Несколько секунд – и все, база рабочая, можно играться.
Таким образом можно разворачивать быстрые 1С-окружения. Фишка репозитория в том, что можно указать версию платформы, она выкачается и соберется в нужной версии.
Разворачивание контейнера с PGAdmin
Чтобы быстро развернуть PGAdmin, клонируем репозиторий https://github.com/khezen/compose-postgres.
Внесем изменения в файл docker-compose.yml.
-
Секция postgres нам здесь не нужна, мы ее отсюда удаляем.
-
Порты закомментируем,
-
Вставим настройки для Traefik.
-
Имя внешней сети у меня называется proxy.
Больше ничего менять не будем.
Теперь поднимаю контейнер по команде:
docker-compose up -d
Логи от каждого контейнера можно посмотреть по команде:
docker-compose logs -f
Переходим по адресу pgadmin.demoncat.ru – открывается PGAdmin.
Таким образом работает Docker и его взаимосвязь между различными сервисами.
Этих сервисов очень много. Вы можете зайти на https://hub.docker.com/ и здесь есть огромное количество образов на все случаи жизни, которые вы можете посмотреть, скопировать и переделать под себя.
Вопросы
Я знаю, что Hyper-V на Windows не уживается со всеми остальными гипервизорами, типа VirtualBox. А как проявляет себя WSL2?
Действительно, Hyper-V и VirtualBox между собой конфликтуют. У Docker в Windows есть поддержка экспериментальных функций, которая позволяет не создавать виртуальную машину в гипервизоре, а использовать линуксовый движок ядра. Но как это работает, я сказать точно сказать не могу, потому что я очень редко использую Docker на Windows – он не работает на нем стабильно. Можно использовать Docker на Windows для тестов, можно поиграться, а на продуктив ставить пока что, к сожалению, не стоит.
UPD: Недавно узнал, что на последних версиях wsl2 уже не конфликтует с другими гипервизорами. Но не проверял.
Эталонная база очень большая – 250 Гб. Если я эту базу упакую в Docker, где будет сидеть еще и 1С и все остальное окружение, как такого монстра разворачивать?
База – это все-таки данные. Я знаю примеры, когда люди упаковывают базу именно в Docker и потом его поднимают. Но я не пробовал упаковывать такие огромные базы в сам контейнер. Мне кажется, лучше сделать так – данные базы будут храниться в каком-то именованном volume, а в контейнере понимается сервис – тот же postgres. И он подцепляет в качестве источника данных этот именованный volume вовнутрь. Таким вариантом можно сделать, но тут другой вопрос – Docker подразумевает, что нужно быстро создать новое окружение и что-то на нем потестить, а как быстро создать новую копию базы на 250 Гб я пока не знаю.
*************
Данная статья написана по итогам доклада (видео), прочитанного на онлайн-митапе "DevOps в 1С: Тестирование и контроль качества решений на 1С".