Налаштування Prometheus в Amazon EC2 через ElasticBeanstalk та Docker

pic

Що таке ElasticBeanstalk? Це один з сервісів Amazon, який допомагає розробникам розгортати додатки. Тепер кожен хмарний хостинг хоче бути сучасним і підтримувати Docker, і ElasticBeanstalk є одним із таких. Розробники замінюють рецепти Chef на Dockerfile і навіть не замислюються, чому.

Найкращі практики Docker передбачають запуск лише одного процесу. Однак часто нам потрібен не один процес, а кілька, як-от додаток, база даних, фонові робітники тощо. До 24 березня 2015 року ElasticBeanstalk не підтримував багатоконтейнерне середовище на одному екземплярі. Платформа Multi-container Docker відрізняється від інших платформ, які пропонує ElasticBeanstalk. Вона замінила кастомні bash-скрипти на команди Elastic Container Service. І це чудово!

Prometheus — це система моніторингу. Чому я обрав саме Prometheus для опису того, як працює ElasticBeanstalk? Тому що вона містить кілька модулів, написаних за допомогою різних технологій.

Давайте пограємо.

  1. Запустіть Prometheus на локальній машині¹.
  2. Налаштуйте додаток і середовище ElasticBeanstalk².
  3. Налаштуйте Prometheus³.
  4. Додайте панель Prometheus (Rails додаток та Mysql).
  5. Додайте Nginx з HTTP Basic Auth.
  6. Додайте Prometheus Pushgateway.

Запуск Prometheus на локальній машині

Якщо ви не знайомі з Docker, додаткову інформацію можна знайти в Посібнику користувача Docker.


pic

$ boot2docker start   
$ eval "$(boot2docker shellinit)"  
$ docker run -d -p 9090:9090 prom/prometheus  
$ open http://"$(boot2docker ip)":9090

Ви повинні побачити сторінку статусу Prometheus. Спробуйте пограти з графіком та запитами Prometheus. За замовчуванням Prometheus отримує власні метрики. Це було справді просто. Не забудьте зупинити процес після:

$ docker ps  
$ docker stop 

pic

Створення додатка ElasticBeanstalk

$ mkdir prometheus  
$ cd prometheus  
$ brew install aws-elasticbeanstalk  
$ eb init  
$ eb create dev-env  
$ eb open

Це створить зразковий веб-додаток prometheus, наданий ElasticBeanstalk. Більше інформації про команди eb можна знайти тут та посібник із встановлення. Є два рівні: Web і Worker. Я надаю перевагу використанню Worker, навіть для веб-додатків, які не вимагають однакової IP-адреси. Створення рівня Web та призначення Elastic Load Balancer або Elastic IP залежить від вашого вибору.

Після цього можна налаштувати додаток через веб-інтерфейс. Збережіть конфігурацію через меню налаштувань середовища. Щоб отримати доступ до збережених конфігурацій, створіть команду config .

$ eb config list  
$ eb config get   
$ vim .elasticbeanstalk/saved_configs/.cfg.yml  
$ eb config put 

Це корисна функція, якщо ви хочете помістити конфігурацію в репозиторій і створити нові середовища на основі цих конфігурацій. Локальна копія конфігурації знаходиться в .elasticbeanstalk/saved_configs

$ eb create other-env --cfg 

Зразок конфігурації:

Окей, у нас є порожня директорія, додаток EB та середовище з зразковим додатком. Для багатоконтейнерного Docker-додатку потрібен файл Dockerrun.aws.json.
У цьому файлі ми описуємо всі наші контейнери та те, як вони зв’язані. Більше інформації про формат Multi Container Docker Configuration.

Ось Dockerrun.aws.json для створення та запуску prometheus, як ми це робимо на локальній машині:

Конфігурація зрозуміла, за винятком параметра essential. Цей параметр потрібен для позначення контейнера як важливого, і якщо під час деплою будь-який контейнер з увімкненим параметром essential вийде з ненульовим кодом помилки, деплой буде скасовано.

Давайте зробимо локальний тест для цієї конфігурації. Так, це одна з найбільш крутих функцій від eb, запуск контейнерів у локальному середовищі за допомогою того ж самого docker та docker-compose.

Це працює бездоганно. Створюється файл .elasticbeanstalk/docker-compose.yml, який використовується для запуску контейнерів. Ось більше допомоги для розуміння цього: Docker Compose.

Цей файл допоможе нам у майбутньому для налагодження. Наступний крок — деплой:

$ eb deploy

Зачекайте кілька хвилин і перевірте, що все завершилось без ERROR.

Налаштування Prometheus

Ми налаштували зразковий Prometheus з конфігурацією та налаштуваннями за замовчуванням. Давайте додамо власний конфігураційний файл, який зберігається поза контейнером з налаштуваннями за замовчуванням.

Перевірте параметр за замовчуванням CMD для Prometheus в https://registry.hub.docker.com/u/prom/prometheus/dockerfile. У поточній версії це виглядає так:

Нам потрібно змінити лише один параметр -config.file, щоб вказати на наш файл, а інші залишити незмінними. Припустимо, що наш конфігураційний файл буде розташовуватись у /opt/prometheus/prometheus.yml. У чистому Docker це виглядатиме так:

Цей файл відсутній. Для того, щоб поділитися нашою локальною папкою з Docker контейнером, потрібно додати специфічну опцію. Більше інформації можна знайти в Управлінні даними в контейнерах. Спрощена версія: docker run -v /path/local/folder:/path/container/folder.

Це повинно працювати. Давайте зупинимо його через docker stop, змінимо конфігурацію та знову запустимо. Ми повинні побачити нові налаштування на сторінці статусу. Після цього нам потрібно змінити параметр -storage.local.path, щоб вказати на локальний об'єм для збереження всіх даних на локальній машині.

Повертаємось до документації Dockerrun.aws.json в Multi Container Docker Configuration. Там є параметри volumes і mountPoints, які ми будемо використовувати для монтування папок, а також параметр command, щоб змінити стандартний контейнерний CMD на наш.

Додаємо до кореня конфігурації ключ volumes:

У цьому прикладі я додав 2 томи/папки, які будуть спільно використовуватись з контейнерами. Одна папка для конфігурації Prometheus, яку ми зберігаємо в git-репозиторії, а папка data буде зберігатись на об'ємі EBS EC2 інстансів. Таким чином, ми не втратимо дані після перезавантаження або перевстановлення. EB використовує /var/app/current для зберігання поточного робочого каталогу додатка. Наш останній код під час деплою знаходиться там.

У секції контейнера потрібно використати зареєстровану папку для монтування в правильну папку контейнера:

Додано атрибут command до контейнерної опції, щоб використовувати новий конфігураційний файл і папку для даних:

Результат виглядатиме так:

Тестуємо на локальній машині за допомогою eb local run, і ви побачите щось подібне до:

pic

Оновіть сторінку статусу Prometheus, і вона повинна використовувати наш власний конфігураційний файл. Є одна маленька хитрість: EB виявляє томи, які вказані на /var/app/current, і використовує поточну папку для пошуку папок, але не монтує папку даних, тому ваші дані будуть втрачені після кожного перезапуску. Щоб перевірити це, можна подивитись у .elasticbeanstalk/docker-compose.yml:

Отже, цей файл є корисним для налагодження вашого конфігураційного файлу.
І ви можете використовувати це з чистим інструментом Docker Composer.

Давайте зробимо деплой за допомогою eb deploy та налагоджуватимемо через eb logs.

Додаємо панель моніторингу Prometheus (Rails додаток та MySQL)

У нас є багато даних, тепер потрібно додати прості панелі моніторингу. PromDash — це чудовий маленький інструмент з приємними можливостями.

PromDash — це невеликий Rails додаток, що використовує MySQL базу даних. Це хороший приклад того, як налаштувати два Docker контейнери та зв'язати їх між собою.

Кожен Rails додаток вимагає вказати змінну середовища RAILS_ENV як production. Для PromDash також необхідно вказати URL MySQL бази даних. Додамо нову специфікацію контейнера для MySQL у наш Dockerrun.aws.json:

Після перевірки, що це працює, за допомогою eb local run. Тут я використав нову опцію environment. Ця опція є очевидною та простою. Тепер давайте додамо контейнер для PromDash:

Тут я додав ключ links з масивом імен контейнерів, які будуть використовуватись у цьому контейнері. Docker контейнер генерує нову IP-адресу при кожному запуску. І для того, щоб дізнатись IP-адресу пов'язаного контейнера, можна використовувати тільки ім’я хосту та змінні середовища, що базуються на імені лінку. Більше інформації в Linking containers together. Приклад того, як отримати IP-адресу, дивіться в PromDash Dockerfile.

Після запуску eb local run з'явиться багато інформації з контейнера MySQL, і тепер ми можемо перевірити сторінку:

$ open http://"$(boot2docker ip)":3000

Вона поверне Вибачте, але щось пішло не так. Оскільки база даних не налаштована, і немає таблиць. Нам потрібно додати скрипт міграції для виконання необхідних команд під час деплою та запуску. Для Rails потрібно виконати команду bin/rake db:create db:migrate для початкової настройки бази даних. Додамо новий контейнер на основі того ж самого образу PromDash, але замість запуску веб-сервера, будемо виконувати цю команду.

Додано опцію essential: false, щоб позначити цей контейнер як такий, що не має зупиняти всі інші контейнери після завершення своєї роботи. Наступною проблемою, з якою ми стикнемося, буде те, що MySQL ініціалізується кілька секунд, і наш завдання rake не може підключитися під час налаштування, і ми побачимо Mysql2::Error: Can't connect to MySQL server on '172.17.0.52' (111). Це нормально. Давайте додамо наш скрипт для виконання завдання rake після кількох секунд.

bin/delay.sh:

Тепер нам потрібно змонтувати нашу папку bin і обгорнути команду rake за допомогою delay.sh:

Спробуємо ще раз за допомогою eb local run, виглядає, що міграція почалася, але зупиняється після цього. EB local не підтримує опцію essential: false, оскільки вона стосується Docker Compose. Додамо новий обгортку bin/sleep.sh:

І оновимо параметр command:

Запускаємо eb local run, і здається, що все працює. Перевіряємо через: open http://"$(boot2docker ip)":3000. Починаємо деплой, щоб перевірити нашу конфігурацію на EB. (PS: Не забудьте змінити Security groups, щоб дозволити доступ до порту 3000, і видалити обгортки delay.sh та sleep.sh).

Додаємо Nginx з HTTP Basic Auth

Щоб додати контейнер Nginx, вам потрібно пройти схожими кроками, як для Rails додатка. Nginx повинен відкрити 2 порти: 80 для PromDash і 9090 для Prometheus додатка для доступу до API від promdash.

Видаляємо порти з контейнерів prometheus-app та rails-app. Створюємо конфігурацію сайту proxy/conf.d/default.conf:

Як бачите, в конфігурації upstream я використовую імена контейнерів як хост. Тому що Docker під час лінків створює для кожного пов’язаного контейнера запис в /etc/hosts з поточною IP-адресою.

Також створюємо файл proxy/conf.d/htpasswd для обмеження доступу. Як налаштувати HTTP аутентифікацію за допомогою Nginx.

Додаємо Prometheus Pushgateway

Prometheus опитує додатки для отримання метрик, але іноді неможливо досягти додатка. Є Push Gateway.
Приклад контейнера:

Перезапустіть додаток на локальній машині, і він повинен відкрити порт: open http://"$(boot2docker ip)":9091 з поточними метриками від додатків.

Застосунок Prometheus може комунікувати з шлюзом через link.

Після цього ми модифікуємо файл prometheus/prometheus.yml, додавши розділ scrape_configs:

Перезапустіть локальний додаток та перевірте сторінку стану Prometheus. Там ви повинні побачити новий кінцевий пункт http://prometheus-gateway:9091/metrics.

Остаточний файл Dockerrun.aws.json:

Приклад проекту в Github

pic

Це все, друзі

Михайло Нікіточкін — головний інженер-програміст. Слідкуйте за ним на LinkedIn або GitHub.

Якщо вам сподобалась ця стаття, рекомендуємо прочитати наші останні технічні статті та найпопулярніші технічні статті.

Перекладено з: Setup Prometheus in Amazon EC2 via ElasticBeanstalk and Docker

Leave a Reply

Your email address will not be published. Required fields are marked *