Що таке ElasticBeanstalk? Це один з сервісів Amazon, який допомагає розробникам розгортати додатки. Тепер кожен хмарний хостинг хоче бути сучасним і підтримувати Docker, і ElasticBeanstalk є одним із таких. Розробники замінюють рецепти Chef на Dockerfile
і навіть не замислюються, чому.
Найкращі практики Docker передбачають запуск лише одного процесу. Однак часто нам потрібен не один процес, а кілька, як-от додаток, база даних, фонові робітники тощо. До 24 березня 2015 року ElasticBeanstalk не підтримував багатоконтейнерне середовище на одному екземплярі. Платформа Multi-container Docker відрізняється від інших платформ, які пропонує ElasticBeanstalk. Вона замінила кастомні bash-скрипти на команди Elastic Container Service. І це чудово!
Prometheus — це система моніторингу. Чому я обрав саме Prometheus для опису того, як працює ElasticBeanstalk? Тому що вона містить кілька модулів, написаних за допомогою різних технологій.
Давайте пограємо.
- Запустіть Prometheus на локальній машині¹.
- Налаштуйте додаток і середовище ElasticBeanstalk².
- Налаштуйте Prometheus³.
- Додайте панель Prometheus (Rails додаток та Mysql)⁴.
- Додайте Nginx з HTTP Basic Auth⁵.
- Додайте Prometheus Pushgateway⁶.
Запуск Prometheus на локальній машині
Якщо ви не знайомі з Docker, додаткову інформацію можна знайти в Посібнику користувача Docker.
$ 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
Створення додатка 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
, і ви побачите щось подібне до:
Оновіть сторінку статусу 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
Це все, друзі
Михайло Нікіточкін — головний інженер-програміст. Слідкуйте за ним на LinkedIn або GitHub.
Якщо вам сподобалась ця стаття, рекомендуємо прочитати наші останні технічні статті та найпопулярніші технічні статті.
Перекладено з: Setup Prometheus in Amazon EC2 via ElasticBeanstalk and Docker