скачать книгу бесплатно
Облачная экосистема
Евгений Сергеевич Штольц
В этой книге главный Архитектор Департамента Архитектуры компетенций Cloud Native в Сбербанк делится знанием и опытом с читателем созданием и перехода на облачную экосистему, так и созданием и адаптацией приложений под неё. В книге автор старается провести читателя по пути, минуя ошибки и сложности. Для этого демонстрируется практическое применение и даются пояснения, чтобы читатель смог ими воспользоваться как инструкцией для учебных и рабочих целей. Читателем может быть как разработчики разных уровней, так и специалисты по экосистеме, желающие не потерять актуальность своих умений в уже изменившимся мире.
Евгений Штольц
Облачная экосистема
Аннотация
В книге на практике рассматриваются более 70 (76) инструментов:
* платформы Google Cloud Platform, Amazone WEB Services, Microsoft Azure;
* консольные утилиты: cat, sed, NPM, node, exit, curl, kill, Dockerd, ps, sudo, grep, git, cd, mkdir, rm, rmdir, mongos, Python, df, eval, ip, mongo, netstat, oc, pgrep, ping, pip, pstree, systemctl, top, uname, VirtualBox, which, sleep, wget, tar, unzip, ls, virsh, egrep, cp, mv, chmod, ifconfig, kvm, minishift;
* стандартные инструменты: NGINX, MinIO, HAProxy, Docker, Consul, Vagrant, Ansible, kvm;
* инструменты DevOps: Jenkins, GitLab CI, BASH, PHP, Micro Kubernetes, kubectl, Velero, Helm, "http нагрузочное тестирование";
* облачные Traefic, Kubernetes, Envoy, Istio, OpenShift, OKD, Rancher,;
* несколько языков программирования: PHP, NodeJS, Python, Golang.
Контейнеризация
История развития инфраструктуры
Limoncelli (автор "The Practice of Cloud System Administration"), работавший долгое в Google Inc, считает, что 2010 год – год перехода от эры традиционного интернет к эре облачных вычислений.
* 1985-1994 – время мэйнфреймов (больших компьютеров) и внутрикорпоративного обмена данных, при котором
можно легко планировать нагрузку
* 1995-2000 – эра появления интернет-компаний,
* 2000-2003
* 2003-2010
* 2010-2019
Увеличение производительно отдельно машины меньше, чем прирост стоимости, например, увеличении производительности в 2 раза приводит к увеличению стоимости существенно большей, чем в 2 раза. При этом, каждое следующее увеличении производительности обходится кратно дороже. Следовательно, каждый новый пользователь обходился дороже.
Позже, в период 2000-2003 годах, смогла сформироваться экосистема, предоставляющая принципиально другой подход:
* появление распределённых вычислений;
* появление маломощных массовой аппаратуры;
* созревание OpenSource решений, позволяющие устанавливать программное обеспечение на множество машин, не связанное связкой лицензия процессор;
* созревание телекоммуникационной инфраструктуры;
* увеличении надёжности за счёт распределения точек отказов;
* возможность наращивания производительности при потребности в будущем за счёт добавления новых компонентов.
Следующим этапом слала унификация, наибольшее проявлявшаяся в 2003—2010 годах:
* предоставление в дата центре не места в шкафу (power-location), а уже унифицированного железа закупленного оптом для всего цента;
* экономия на ресурсах;
* виртуализация сети и компьютеров.
Следующую веху положил Amazon в 2010 году и ознаменовал эру облачных вычислений. Этап характеризуется строительством масштабных дата центов с заведомым избытком по мощностям для получения меньшей стоимости вычислительных мощностей за счёт опта в расчёте на экономию для себя и выгодную продажу их избытка в розницу. Такой подход применяется не только к вычислительной мощности, инфраструктуре, но и программному обеспечению, формирую его как сервисы для удешевления их использования за счёт их продажи в розницу как большим компаниям, так и начинающим.
Необходимость однотипности окружения
Обычно начинающие разработчики, разрабатывающие под Linux, предпочитают работать из-под Windows, чтобы не изучать незнакомую ОС и набивать на ней свои шишки, ведь раньше всё было далеко не всё так просто и так отлажено. Часто разработчики вынуждены работать из-под Windows из-за корпоративных пристрастий: 1C, Directum и другие системы работают только на Windows, и вся остальная, а главное сетевая, инфраструктура заточена под эту операционную систему. Работа из Windows приводит к большим потерям рабочего времени как разработчиков, так и DevOps на устранения как мелких, так и крупных отличий в операционных системах. Эти отличия начинают проявляться от самых простых задач, например, что может быть проще сверстать страничку на чистом HTML. Но неправильно настроенный редактор поставит в BOM и переводы строк, принятые в Windows: "\n\r" вместо "\n"). BOM при склейке шапки, тела и подвала страницы создаст отступы между ними, они не будут видны в редакторе, так как эти они образуются байтами метаинформации о типе файла, в Linux которые не имеют такого значения и воспринимаются как перевод отступ. Другие переводы строк в GIT не позволяет увидеть сделанные вами отличие, ведь отличие в каждой строке.
Теперь возьмём Front разработчика. С первого взгляда, что сложного, ведь JS (JavaScript), HTML и CSSнативно интерпретируются браузером. Раньше делалась вёрстка всех разных страниц – проверялась дизайнером и заказчиком и отдавалась PHP разработчику на интеграцию с фреймворком или cms. Для того, чтобы не править шапку на каждой страницы, а потом долго выяснять, когда они начали отличаться и какая из них правильнее использовался HAML. HAML добавляет дополнительный синтаксис в HTML, чтобы избежать булирования: циклы, подключения файлов, в нашем случае единую шапку и подвал страницы. Но он требует специальной программы, перегоняющий HTML в чистый HTML. В MS Windows это решается установкой программы компилятора и подключением её к IDE, благо все эти возможности есть в IDE WEBStorm. С CSSи его размером, дублями, зависимостями и поддержкой для разных браузеров всё гораздо сложнее – там использовался LESS, а сейчас возглавил более функциональный SASS и библиотеками поддержки разных браузеров, который требует компилятора RUBY и подобная связка, обычно, с первого раза не работает. А для JS использовался CoffeScript. Всё это нужно прогонять через программы сжатия и валидации (валидировать HTML обычно не нужно).
Когда проект начинает расти и перестаёт быть отдельными страницами с "JS вставками", а становится SPA (Single Page Application, одно страничными веб приложениями), где всё создаётся JS, и уже сборщиков (Galp, Grunt), менеджеров пакетов и NodeJS не собирается, сложностей становится всё больше. Все эти программы бесплатные и изначально разрабатывались для Linux, предназначены для работы из консоли BASH и под Windows ведёт себя не всегда хорошо и трудно автоматизируются в графических интерфейсах, не смотря на старания IDE разработчиков. Поэтому, многие WEB разработчики перешли с MS Windows на MacOS, который является ответвление UNIX систем, в него изначально встроен BASH.
Docker как легковесные виртуальные машины
Изначально, проблема изоляции положений и проектов решалась виртуализацией – системным программный обеспечением, которое эмулирует на определённом уровне среду, которой может быть аппаратное обеспечение (компьютер как набор компонентов, таких как процессор, оперативная память, сетевое устройство и другие при необходимости) или, реже, операционная система. Системный администратор выбирает объём оперативной памяти (не более свободной), процессор, сетевое устройство. Устанавливает операционную систему и, при необходимости, драйвера, устанавливает необходимые программы. Если нужно рабочее место для второго разработчика – совершает те же действия. Для установки программ смотрит в каталог /bin первого и устанавливает недостающие. И тут возникает первая тихая проблема, пока не проявившаяся, что программы устанавливаются разных версий, но это будет головной болью уже разработчиков, если у одного разработчика наработает, а у другого нет, или головной болью этого сисадмина – если у разработчика работает, на продакшне – нет.
С ростом числа рабочих мест, добавляются следующие проблемы:
* Вам доступно менее 30% производительности от родительской системы, ведь все команды, которые должен выполнять процессор, выполняются программой виртуализации. Повысить производительность позволяет режим процессора VT-X, при котором процессор напрямую выполняет команды из виртуального окружения, а в случаи несовместимости – кидает исключение. Правда эти броски в сотни раз затратней обычных команд, поэтому взрослые системы виртуализации (VirtualBox, VMVare, и другие) стараются отфильтровать и модифицировать потенциально несовместимые команды, что позволяет существенно повысить производительность.
* Каждое рабочее место приходится создавать заново, для этого системный администратор пишет скрипт автоматизирующий этот процесс, но он естественно не идеален, и его приходя постоянно актуализировать, вносить патчи несовместимостей того, что устанавливали программисты.
* Линейное увеличение занимаемого дискового пространства от числа контейнеров, и экспоненциальное от версий продукта, при том, что один инстанс занимает очень много места. То есть, каждая песочница содержит инстанс эмуляции программы, образ операционной системы, все установленные программы и код разработчика, что весьма немало. Единственное, что одно – установка самой виртуальной машины, и то, только в рамках одного физического сервера. Например, если разработчиков у нас 10, то и размер будет в 10 раз больше, при 3 версиях продукта – в 30.
Все эти недостатки для WEB призван решить Docker. Здесь и далее мы будем говорить о Docker для Linux, и не будем рассматривать несколько отличающиеся реализацию ядра у FreeBSD, и реализацию для Windows 10 Professional, внутри которой закупается либо урезанное ядро Linux, либо независимая разработка контейнеризации Windows. Основная идея заключается не в создании прослойки (виртуализации аппаратного обеспечения, своей ОС и гипервизора), а в разграничении прав. Вы не множите поставить в контейнер MS Windows, но можете поставить и RedHut, и Debian, так как ядро одно, а отличии в файлах, создавая песочницу (отдельный каталоги и запрещая выходить за его приделы) с этими файлами. Также, мы говорим о WEB решениях, так как для нативных решений могут возникнуть проблемы, когда программе не обходимо иметь монопольный доступ из контейнера (песочницы Docker) к ядру ОС, например, для нативной отрисовки окон. Также можно ограничить объём памяти, процессорного времени, количества процессов.
Легковесная виртуализация или невесомая изоляция – взгляд на реализацию Docker
Давайте взглянем на историю появления предпосылок появления Docker, именно предпосылок, так как сам Docker не реализует ни изоляции, ни тем более виртуализации, а организует работу с ней с первой. В отличии от виртуализации напоминающей ангар со своим миром и своим фундаментом, на который можно наложить, что душе пожелает, например, выдаём и лужайку, то для изоляции можно провести аналогию с забором. Изоляция появлялась в ядре Linux постепенно, частями, отвечающих за разные уровни, а параллельно появлялись программы обеспечивающие интерфейс и концепцию применения этой изоляции в реальных проектах. Изоляция состоит из 6 типов ограничения ресурсов.
Первым в ядро была изоляция файловой системы, позволяющий создать песочницу с помощью команды chroot ещё в 1979 году, из вне песочница видна полностью, но при переходе внутрь папка, над которой выполнена команда становится корневой, и вернуться уже не удастся. Следующий было разграничение процессов, так песочница существует и хостовая система, пока существует процесс с pid (номером) 1. Для песочницы он свой, вне песочницы он обычный процесс. Далее подтянулись стальные разграничения CGroups: групп пользователей, памяти и другие. Всё это существует в ядре любого Linux, независимо от того, установлен Docker или нет у вас. На всём протяжении истории принимались попытки, OpenSource и коммерческие, создавать контейнера, разрабатывая функционал самими и подобные решения находили своих пользователей, но они не проникли в широкие массы. Docker в начале своего существования использовал довольно стабильное, но сложное в использовании решение контейнеризации LXC. Постепенно он заменил LXC на нативные CGroup. Также Docker поддерживает солёность своего образа (об этом далее), но сам её не реализует, а использует UnuonFS (UFS).
Docker и дисковое пространство
Поскольку Docker не реализует функционал, а использует заложенный в ядро Linux, и не имеет под капотом графического интерфейса, сам он занимает очень мало места.
Поскольку контейнер использует ядро хостовой ОС, то в базовом образе (обычно ОС) содержатся только дополняющие его пакеты. Так Docker образ Debian занимает 125Mb, а ISO образ – 290Mb. Для проверки, что используется одно ядро в контейнере выведем о нём информацию: uname -a или cat /proc/version, а информацию о самом окружении контейнера cat /etc/ussue
Docker создаёт образ на основе инструкции в файле Dockerfile, который может находиться удалённо или локально, и по нему может быть создан в любой момент. Поэтому, если вы не используете образ в данный момент, то можно удалить его. Исключением является образ, созданный на основе контейнера командой Docker commit, но так создавать не очень правильно, и всегда можно выделить из образа Dockerfile командой Docker history и удалить образ. Преимуществом хранения образов является то, что не требуется ожидать, пока он создаётся: скачивается ОС и библиотеки.
Сам Docker использует образ под названием Image, который создаётся на основе инструкций в файле Dockerfile. При создании нескольких контейнеров на его основе место практически не увеличивается, так как контейнер – всего лишь процесс и конфиг настроек. При изменении файлов в контейнере сами файлы не сохраняются, а сохраняются внесённые изменения, который будут удалены после переброски контейнера. Это гарантирует в 99% случаев полностью идентичное окружение, и как следствие не важно помещать подготовительные операции, общие для всех контейнеров по установке специфичных программ в образ, побочным эффектом, которого является отсутствии их дублирования. Чтобы иметь возможность сохранять данные используется монтирование папок и файлов к хостовой (родительской) системе. Поэтому вы можете на обычном компьютере запустить сто и более контейнеров, при этом не увидите изменения в свободном местное на диске. При этом, если разработчики пользуются гит, а как же без него, и часто копятся, то может отпасть необходимость в монтировании папок с исходным кодом.
Образ докеров не представляет из себя монолитный образ вашего продукта, а – слоёный пирог образов, слои которого кэшируется. Это позволяет значительно сэкономить время на создание образа. Кэширование можно отключить ключом команды build –no-cache=true, если Docker не распознаёт, что данные изменяемы. Докер может увидеть изменения в инструкции ADD, добавляющий файл из хостовой системы в контейнер по хэшу файла. Так, если вы создадите два контейнера, один с NGINX, а другой с MySQL, оба которых основаны на ОС Ubuntu 14.04, то будет существовать три слоя образа: MySQL, NGINX и Ubuntu. Сдали образа можно посмотреть командой Docker history. Также это работает и для ваших проектов – при копировании в Ваш образ 2 версий кода командой ADD с вашим продуктом, у вас будет 3 слоя и два образа: базовый, с кодом первой версии и кодом второй версии, независимо от количества контейнеров. Количество слоёв ограниченно 127. Важно заметить, что при клонировании проекта нужно указать версию, а не просто git clone, а git clone –branch v1 и git clone –branch v2, иначе Docker закэширует слой, создаваемый командой Git Clone и при создании второго образа мы получим тоже самое.
Docker не занимает ресурсы, а лишь их ограничивает, если это задано в настройках при создании контейнера (для памяти ключ m, для процессора – c). Поскольку Docker поддерживает разные файловые системы контейнеризации, настраивать, унифицированного интерфейса нет. Но, в любом случае, потребляется ресурс столько, сколько требуется, а не столько сколько выделено, как в виртуальных машинах.
Такая забота о занимаемом дисковом пространстве и невесомость самих контейнеров влечёт безответственность в скачивании образов и создании контейнеров.
Сборка мусора контейнером
За счёт того, что контейнер даёт намного большие возможности, чем виртуальная машина, ситуация осложняется оставление мусора после работы Docker. Проблема решается просто запуском сборщика мура, появившегося в версии 1.13 или более сложно для более ранних версий написанием нужно Вам скрипта.
Так же, как просто создать контейнере docker run name_image, также просто его и удалить docker rm -f id_container. Часто для того, чтобы просто поэкспериментировать, удобно запустить контейнер в интерактивном режиме docker run -ti name_image bash и мы стразу же окажемся в контейнере. Когда мы выйдем из него Cntl+D, он будет остановлен. Для того, чтобы поле выхода он был автоматически удалён используйте параметр –rm. Но, поскольку контейнеры столь невесомы, их так просто создать, их часто бросают и не удаляют, что приводит к их стремительному росту. Посмотреть на работающие можно командой docker ps, а и на остановленные – docker ps -a. Для предотвращения этого используйте сборщик мусора docker containers prune, который появился в версии 1.13 и который удалит все остановленные контейнера. Для более ранних версий используйте скрипт docker rm $(docker ps -q -f status=exited). Если её запуск для Вас не желателен, скорее всего вы неправильно используете Docker, так как запасть контейнер из образа практически также быстро и просто, как и восстановить его работу. Если в контейнере нужно сохранять состояние, то для этого используется монтирование папок или томов.
Чуть более сложная ситуация обстоит с образами. При создании контейнера, если нет образа, он будет скачен. Поскольку, один образ может являться для нескольких контейнеров, то при удалении самого контейнера он не удаляется. Его придётся удалять вручную docker rmi name_image, а если он используется – просто будет выдано предупреждение. За экономию дискового пространства приходится платить тем, что Docker не может просто определить, нужен образ ещё или нет. С версии 1.13 он может, с помощью команды docker imgae prune -a может проанализировать, какие образа не используются контейнерами и их удалить. Здесь нужно быть более осторожным, если Docker не может получить образ снова, но допущение подобной ситуации не очень правильно. Одной такой ситуацией является создание кластерного образа, при этом конфиг Dockerfile, описывающий процесс его создания, был утерян, в противном случае из Dockerfile можно получить образ командой docker build name_image. Правильно же сразу же принять меры и восстановить Dockerfile из образа, посмотрев на команды создающие образа с помощью Docker history name_image. Второй ситуаций является создание образа из работающего контейнера командой Docker commit, а не из Dockerfile, так активно популяризуемого, но также активно осуждаемого.
Так как образ состоит из слоёв, совместно используемых в разных образах, то в разных нештатных ситуациях эти слои остаются. Поскольку отдельно мы их использовать не можем, то безопасно их удалить командой docker image prune.
Для сохранения результатов работы контейнера можно примонтировать папку хостовой машины к папке контейнера. Мы можем явно указать папку на хостовой машине, например, docker run -v /page_host:/page_container nama_image, или дать возможность сгенерировать её docker run -v /page_container nama_image. Для удаления сгенерированных папок (томов), которые уже не используются контейнерами введите команду Docker volume prune. Для сборки неиспользуемых сетей, также есть свой сборщик мусора.
Также есть единый сборщик мусора, по факту, просто объединяющий специализированные в один с логически совместимыми параметрами docker system prune. Имеется тенденция его ставить в крон. Можно также посмотреть на занимаемое место всеми контейнерами, всеми образами и всеми томами с помощью команды docker system df, а также без группировки – docker system df -v.
Многие проблемы, описанные здесь созданием мусора, решаются программой Docker-compose. К тому же она существенно упрощает жизнь, если только вы не запустили контейнера разово для экспериментов. Так команда Docker-compose up запускает контейнера, а docker-compose down -v их удаляет, также удаляются все зависимости между ними. Все параметры запуска контейнера описываются в Docker-compose.YML, а также связи между ними. Благодаря этому, при изменении параметров запуска контейнеров не нужно заботиться, чтобы удалить старые и создать новые, не нужно прописывать все параметры контейнеров – просто запасть с параметром up, и она либо пересоздаст, либо обновит конфигурацию контейнера.
Для недопущения захламления системы в Docker имеется встроенное настраиваемое ограничение на количество контейнеров и образов, напоминающее о необходимости производить чистку системы запуском сборщика мусора.
Экономия времени на создание контейнера
Мы уже познакомились в предыдущей теме об образах, об их слоях и кэшировании. Давайте рассмотрим их с точки зрения времени создания контейнера. Почему же это столь важно, ведь по аналогии с виртуализацией, системный администратор запустил создание контейнера и пока он передаёт его программисту, к этому времени он уже точно соберётся. Важно заметить, что много с тех пор изменилось, а именно поменялись принципы и требования к экосистеме и её использования. Так, например, если раньше разработчик, разработав и проверив свой код на своём рабочем месте отправлял его QA менеджеру для тестирования на соответствии бизнес-требованиям, и уже когда дойдёт очередь у него к этому коду, тестировщик на своём рабочем месте запустит этот код и проверит. Теперь инфраструктурой занимается DevOps, который налаживает непрерывный процесс доставки разработанных программистами фич, а контейнеры создают в автоматическом режиме при каждом отправкой, в ветку продакшна для проведения автоматического тестирования. При этом, чтобы работа одних тестов не влияла на работу других, под каждый тест создаётся отдельный контейнер, а зачастую тесты идут параллельно, чтобы моментально показать результат разработчику, пока он помнит, что он сделал и не переключил своё внимание на другую задачу.
Для стандартных программы: не нужно устанавливать, не нужно поддерживать
Мы, часто используем огромного количество готовых решений. При выборе решения, мы сталкиваемся с дилеммой: с одной стороны оно более универсальное и более проверенное, чем мы можем себе позволить сделать, с другой оно достаточно сложное, чтобы самим разобраться как правильно его установить и настроить, чтобы установить все зависимости, разрешить конфликты, настроить на первоначальное использование. Теперь установка и настройка стала гораздо проще, стандартизированный, во многом отсутствуют низкоуровневые проблемы. Но прежде, чем продолжать, давайте отвлечёмся и посмотрим на процесс от начала получения до начала использования приложения в рамках истории:
* В те времена, когда все программы писались на ассемблере, программы распространялись по почте, у уже пользователи устанавливали и тестировали, ведь тестирование в компаниях не было предусмотрено. В случае возникновения проблем, пользователь сообщал компании разработчику о проблемах и после их устранения, получал по почте уже исправленную версию на диске. Процесс очень долгий и пользователь сам тестировал.
* Во время распространения на дисках уже компании писали свои программные продукты на более высокоуровневых языках, проверяли под разные версии ОС. Здесь и далее будем рассматривать свободное ПО. Программа уже содержала MakeFile, который сам компилировал программу и её устанавливал.
* С появление интернета массово ПО устанавливается с помощью пакетных менеджеров, при выходе которых, из удалённого репозитория ОС оно скачивается и устанавливается. Он старается следить и поддерживать совместимость совместимость программ. Дальнейшее изучение и использование программы: как запустить, как настроить, как понять что она работает ложится на пользователя или системного администратора.
* С появлением Docker Hub и WEB приложения скачиваются и запускаются контейнером. Его, обычно, для начальной работы не нужно настраивать.
Для контейнеров и образов в целом у сервера можно настроить объёма свободно места и занимаемого пространства. По умолчания для всех контейнеров и образов отводится 10G, при этом из этого объёма должно оставаться как dm.min_free_space=5%, но лучше поместить в конфиг, который возможно придётся создать как /etc/docker/daemon.json:
{
"storage-opts": [
"dm.basesize=50G",
"dm.min_free_space=5%",
]
}
Можно ограничить ресурсы, потребляемые контейнером в его настройках:
* -m 256m – максимальный размер потребления оперативной памяти (здесь 256Mb);
* -c 512 – вес приоритета на использование процессора (по умолчанию 1024);
* —cpuset="0,1" – номера разрешённых к использованию ядер процессора.
Передача и распространение продукта
Для передачи проекта, например, заказчику, и распространения между разработчиками и серверами можно использовать установочные скрипты, архивы, образа и контейнера. Каждый из этих способов распространения проекта имеет свои особенности, недостатки и преимущества. Давайте о них поговорим и сравним.
строк, но главное, что у неё есть специальный режим, включаемый ключом -p, который выводит динамически нужно нам количество строк, при поступлении новых – обновляет вывод, например, docker logs name_container | tail -p.
Когда приложений становится слишком много, чтобы вручную мониторить их работу по отдельности целесообразно логи приложений централизовать. Для централизации могут быть использованы многочисленные программы, которые собирают логи от разных сервисов и направляют их в центрально хранилище, например, Fluentd. Для хранения логов удобно использовать ElasticSearch, просто записывая их в поисковик. Очень желательно, чтобы логи были в структурированном формате – JSON. Это позволит их сортировать, отбирать нужные, выявлять тенденции с помощью встроенных агрегатных функций, проводить анализ и прогнозирование, а не только поиск по тексту. Для анализа веб-интерфейс Kubana, в ходящий в состав стека Elastic.
Не только для долгоиграющих приложений важно логирование. Так для тестовых контейнеров, удобно получить вывод пройденных тесто. Так можно сделать, прописав в Dockerfile в секции CMD: NPM run, который прогонит тесты.
Хранилище образов:
* публичный и приватный Docker Hub (http://hub.docker.com)
* для закрытых и секретных проектов можно создать собственное хранилище образов. Образ называется registry
Docker для создания приложений и одноразовые работы
В отличии от виртуальных машин запуск, которых сопряжён с значительными человеческими и вычислительными затратами Docker часто применяется для выполнения одноразовых действий, когда программное обеспечение требуется запустить разово, и желательно не тратить усилии на установку и удаление его. Для этого запускается контейнер, который примонтирован к папке с нашим приложением, который выполняет над ним требуемые действия и после их выполнения удаляется. В качестве примера можно проект на JavaScript, для которого нужно провести сборку и выполнить тесты. При этом сам проект не использует NodeJS, а содержит только конфиги сборщика, например, WEBPack-ка, и написанные тесты. Для этого запускаем контейнер сборки в итеративном режиме, в котором можно управлять процессом сборки, если потребуется и после выполнения сборки контейнер остановится и само удалится, например, можно запустить в корне приложение что-то подобное: docker run -it –rm -v $(pwd):app node-build. Аналогичным образом можно провести тесты. В результате приложение собрано и протестировано на тестовом сервере, но при этом программное обеспечение не требующееся для его работы на продакшн сервере не буде усыновлено и потреблять ресурсы, и может быть перенесено на продакшн сервер, например с помощью контейнера. Чтобы не писать документацию на запуске сборки и тестированию можно положить два соответствующих конфига Docker-compose-build.yml и Docker-compose-test.yml и вызывать их Docker-compose up -f ./docker-compose-build.
Управление и доступ
Мы управляем контейнерами с помощью команды Docker. Теперь, допустим, появилась необходимость управлять удалённо. Использовать VNC, SSH или другое для управления командой Docker, наверное, будет слишком трудоёмким если задача усложнится. Правильно, сперва будет разобраться, что из себя представляет Docker, ведь команда Docker и программа Docker не одно и тоже, а точнее команда Docker является консольным клиентом для управления клиент серверным приложение Docker Engine. Команда взаимодействует с сервером Docker Machine через Docker REST API, который и предназначен для удалённого взаимодействия с сервером. Но, в таком случае необходимо позаботиться об авторизации и SSL-шифровании трафика. Обеспечивается это созданием ключей, но в общем случае, если стоит задача централизованного управления, разграничения прав и обеспечения безопасности – лучше посмотреть в сторону продуктов, изначально обеспечивающих это и использующих Docker в качестве именно запуска контейнеров, а не как систему.
По умолчанию, для безопасности, клиент общается с сервером через Unix сокет (специальный файл /var/run/socket.sock), а не через сетевой сокет. Для работы через Unix сокет можно использовать указать программе отправки запросов curl его использовать curl –unix-socket /var/run/docker.sock http:/v1.24/containers/json, но это возможность поддерживается с версии curl 1.40, которая пока не поддерживается в CentOS. Для решения этой проблемы и взаимодействия между удалёнными серверами используем сетевой сокет. Для активации его останавливаем сервер systemctl stop docker и запускаем его с настройками dockerd -H tcp://0.0.0.0:9002 & (слушать всех на порту 9002, что не допустимо для продакшна). После запуска команда docker ps не будет работать, а будет docker -H 5.23.52.111:9002 ps или docker -H tcp://geocode1.essch.ru:9202 ps. По умолчанию Docker использует для http порт 2375, а для https – 2376. Чтобы не менять везде код и каждый раз не указывать сокет, пропишем его в переменных окружения:
export DOCKER_HOST=5.23.52.111:9002
Docker ps
Docker info