Сбор метрик для мониторинга работы контейнеров в среде Docker

Попробуйте Облачный VPS с установленным Docker

Где скачать образы для Docker?

Итак, для того, чтобы начать работать с системой виртуализации Docker, необходимо скачать образы или так называемые images контейнеров. Их существует огромное количество, различных сборок, урезанные и полноценные, функциональные и не очень, кастомные и официальные. Так что же это такой за ресурс, который содержит в себе все эти имаги? Называется он  . Сразу скажу, что на главной странице данного сайта (кстати он официальный), можете не пытаться ввести что-то в строке поиска, потому что поиск нерабочий. Может это связано с версией браузера или с еще чем-либо, но лично у меня он не работает. Поэтому на главной странице в самой верхней строке нажимаем кнопку Explore и переходим на страницу с образами:

На этой странице сразу видны образы, и кстати именно на этой странице, поиск уже работает:

С поиском вроде разобрались. Что остается? Остается узнать команду для того, чтобы скачать образы для Docker. Для того, чтобы получить тот или иной образ вам достаточно зайти в любой из репозиториев, где вы – во-первых: получите полную информацию об образе, его особенностях и деталях. Во-вторых узнаете команду для скачивания самого образа. Для примера я зайду в самый первый репозиторий kafka от wurstmeister (нет, это не реклама :)), что мы тут увидим:

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

Примечание: если вам необходимо запускать установку с повышенными правами или прав просто не хватает, не забывайте писать sudo перед любой командой.

Нажимаем Enter и ждем окончания скачивания:

Весь процесс, занял менее минуты.

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

Плюсы контейнеризации docker

Абстрагирование приложение  от хоста

Задумка в контейнера – полная стандартизация. Контейнер соединяется с хостом определенным интерфейсом, контейнеризорованное приложение не зависит от архитектуры или ресурсов хоста. Для хоста же контейнер некий «черный ящик», не имеет значение что в нем.

Маштабирование

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

Управление версиями и зависимостями

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

Изолирование среды

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

Использование слоев

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

Читайте также:  iOS 15: поддерживаемые устройства, функции и дата выпуска!

Компоновка

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

Ограничим память

Первое, что может прийти на ум — это ограничить размер самого Docker-контейнера. Создадим простое приложение на Spring Boot и запустим контейнер, поставив ограничение памяти 150 мегабайт. Вот пример команды на хосте с одним гигабайтом памяти:

$ docker run -it —rm —name mycontainer150 -p 8080:8080 -m 150M rafabene/java-container:openjdk

В приложении заранее был создан rest-метод, который загружает память до отказа объектами типа String. Вызовем его:

$ curl http://`docker-machine ip docker1024`:8080/api/memory

Вызванный метод возвращает что-то вроде «Выделено более чем 80% памяти (219.8 MiB) из максимально доступных JVM (241.7 MiB) «.

Но отсюда два вопроса:

1. Почему максимальный размер для JVM 241 мегабайт?

2. Если мы выше указали, что контейнеру доступно только 150 мегабайт памяти, то почему приложение потребляет почти 220?

Первое, что нужно помнить о максимальном размере кучи (max heap size) у JVM, это то, что размер по умолчанию будет занимать 1/4 памяти. И второе — когда мы при запуске контейнера выше указывали флаг «-m 150M», то докер зарезервировал 150 мегабайт в оперативной памяти и 150 мегабайт в Swap. Поэтому-то приложение и не рухнуло и отработало как нужно. Но при этом вы должны понимать, что увеличение памяти в контейнере — это не решение проблемы. Всегда может случиться ситуация, когда Java-приложение может выйти за рамки лимита, и тогда процесс будет убит.

Технология контейнеризации Docker

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

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

Единственный процесс vs множество процессов

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

Чтобы запустить простое многоуровневое веб-приложение в Docker, вам понадобится PHP контейнер, Nginx контейнер (веб-сервер), MySQL контейнер (для процесса базы данных) и несколько контейнеров данных для того, чтобы хранить таблицы баз данных и другую информацию приложения.

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

У однопроцессных контейнеров также есть ограничения. Например, вы не можете запускать агенты, скрипты регистрации или автоматически запускаемые SSH-процессы внутри контейнера. Также нелегко незначительно обновлять однопроцессный контейнер на уровне приложения. Вам придется запускать новый обновленный контейнер.

Бесструктурность vs структурность

Контейнеры Docker сделаны так, чтобы быть более бесструктурными, чем LXC.

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

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

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

Читайте также:  iOS 12.5 для старых моделей iPhone с поддержкой уведомлений о COVID-19

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

Портативность

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

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

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

Вопросы и ответы

Что такое Докер?

Определение Докера в Википедии звучит так:

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

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

Что такое контейнер?

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

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

Вопросы и ответы

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

Почему я должен использовать их?

Взлет Докера был по-настоящему эпичным. Не смотря на то, что контейнеры сами по себе — не новая технология, до Докера они не были так распространены и популярны. Докер изменил ситуацию, предоставив стандартный API, который сильно упростил создание и использование контейнеров, и позволил сообществу вместе работать над библиотеками по работе с контейнерами. В статье, опубликованной в The Register в середине 2014 говорится, что Гугл поддерживает больше двух миллиардов контейнеров в неделю.

Google Trends для слова ‘Docker’

В дополнение к продолжительному росту Докера, компания-разработчик Docker Inc. была оценена в два с лишним миллиарда долларов! Благодаря преимуществам в эффективности и портативности, Докер начал получать все больше поддержки, и сейчас стоит во главе движения по контейнеризации (containerization). Как современные разработчики, мы должны понять этот тренд и выяснить, какую пользу мы можем получить из него.

Чему меня научит это пособие?

Это единое и полное пособие по всем аспектам работы с Докером. Кроме разъяснения мифов о Докере и его экосистеме, оно позволит вам получит небольшой опыт по сборке и деплою собственных веб-приложений в облаке. Мы будем использовать Amazon Web Services для деплоя статичных сайтов, и два динамических веб-приложения задеплоим на EC2 с использованием Elastic Beanstalk и Elastic Container Service. Даже если вы никогда ничего не деплоили, это пособие даст вам все необходимое.

Читайте также:  Поднятая целина: Осваиваем и обустраиваем консоль

Метрики сети

Метрики сети напрямую не учитываются контрольными группами. Этому есть хорошее объяснение: сетевые интерфейсы существуют в контексте сетевых пространств имен. Ядро могло бы собирать метрики о количестве пакетов и байтов, отправленных и полученных группой процессов, но эти показатели были бы бесполезны. Пользователю обычно нужны метрики по каждому интерфейсу. Но так как процессы в отдельной контрольной группе могут относиться к множеству сетевых пространств имен, эти показатели будет сложно интерпретировать – множество сетевых пространств имен означает множество интерфейсов lo, множество интерфейсов eth0 и так далее; поэтому собрать показатели сети с контрольных групп нелегко.

Вместо этого можно собирать метрики сети из других источников.

IPtables

Достаточно подробный учет могут делать IPtables (или фреймворк netfilter, для которого iptables является просто интерфейсом).

Например, можно задать правило учета исходящего HTTP-трафика на веб-сервере:

$ iptables -I OUTPUT -p tcp —sport 80

Здесь нет флага -j или -g, поэтому правило считает только соответствующие пакеты и переходит к следующему правилу.

Затем, можно проверить значения счетчиков с помощью:

$ iptables -nxvL OUTPUT

Счетчики учитывают пакеты и байты. Если необходимо задать такие метрики для трафика контейнера, можно выполнить цикл for, чтобы добавить две цепочки iptables для каждого IP-адреса контейнера в цепочке FORWARD.

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

Счетчики на уровне интерфейса

Так как каждый контейнер имеет виртуальный интерфейс Ethernet, возможно, вам захочется проверить напрямую счетчики TX и RX этого интерфейса. Каждый контейнер в вашем хосте связан с виртуальным интерфейсом Ethernet с именем, например, vethKk8Zqi. К сожалению, сложно определить, какой интерфейс к какому контейнеру относится.

На сегодня лучше всего проверять метрики из контейнеров. Для этого вы можете запустить исполнительный файл из среды хоста в сетевом пространстве имен контейнера, используя ip-netns.

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

Формат команды следующий:

$ ip netns exec <nsname> <command…>

Например:

$ ip netns exec mycontainer netstat -i

ip-netns находит контейнер mycontainer с помощью псевдофайлов пространств имен. Каждый процесс относится к одному сетевому пространству имен, одному пространству имен PID, одному пространству имен mnt и так далее. Эти пространства имен описываются в /proc/<pid>/ns/*. Например, сетевое пространство имен PID 42 отображается в псевдофайл /proc/42/ns/net.

При запуске ip netns exec mycontainer … ожидается, что /var/run/netns/mycontainer будет одним из таких псевдофайлов. (Допускаются ссылки).

Иными словами, для выполнения команды внутри сетевого пространства имен контейнера необходимо:

  • Определить PID любого процесса в контейнере, данные которого мы хотим получить;
  • Создать ссылку из /var/run/netns/<somename> к /proc/<thepid>/ns/net;
  • Выполнить ip netns exec <somename> …..

Заново просмотрите раздел «Перечисление групп» для того чтобы понять, как найти контрольную группу, для которой вы хотите хотите измерить статистику сети. Затем вы можете просмотреть псевдофайл с именем «tasks» в контрольной группе, который содержит все PID в группе (и, следовательно, в контейнере). Выберите любой из PID.

В общем, если “короткий ID” контейнера содержится в переменной окружения $CID, то можно сделать следующее:

$ TASKS=/sys/fs/cgroup/devices/docker/$CID*/tasks $ PID=$(head -n 1 $TASKS) $ mkdir -p /var/run/netns $ ln -sf /proc/$PID/ns/net /var/run/netns/$CID $ ip netns exec $CID netstat -i

докер-пауза

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

Синтаксис

docker unpause ContainerID

Параметры

  • ContainerID — это идентификатор контейнера, для которого необходимо приостановить процессы в контейнере.

Возвращаемое значение

ContainerID запущенного контейнера.

пример

sudo docker unpause 07b0b6f434fe

Приведенная выше команда отключит процессы в работающем контейнере: 07b0b6f434fe

Выход

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