від Марина Хуберман
Наша команда в Emi використовує Sentry як основне програмне забезпечення для моніторингу помилок, що допомагає нам не лише діагностувати та виправляти помилки, а й дозволяє налаштовувати сповіщення про аномалії за допомогою попереджень та статистичних правил сповіщень.
Про Elastic Beanstalk
Elastic Beanstalk — це чудовий варіант для початку роботи з мікросервісами в AWS: це низьковитратна альтернатива CloudFormation, оскільки вона бере на себе розгортання застосунку та надання сервісів (балансування навантаження, автомасштабування та моніторинг стану).
Sentry, самостійне розгортання vs. Cloud
Для нашої реалізації Sentry ми обрали версію для самостійного розгортання (раніше називалась on-premise), оскільки вона набагато дешевша, а також пропонує майже всі можливості, які є в хмарній версії. Крім того, самостійне розгортання Sentry є відкритим кодом, що означає, що:
- код доступний на GitHub, що дуже зручно, якщо офіційна документація не зовсім зрозуміла.
- Відкрита команда Sentry на GitHub буде допомагати вирішувати питання (у 2021 році ми повідомили про проблеми з оновленням версії Postgres, і досвід був чудовим, працюючи разом з ними для вирішення цього питання).
Попередні вимоги
У цьому пості ми пояснимо, як налаштувати застосунок Sentry для самостійного розгортання за допомогою одноекземплярного середовища Elastic Beanstalk на платформі Docker для Amazon Linux 2, тому вам знадобиться хоча б базове розуміння Docker, Elastic Beanstalk та/або AWS загалом.
Архітектура
Запропонована кінцева архітектура виглядає наступним чином:
Архітектура високого рівня для самостійно розгорнутого Sentry, що працює в середовищі Elastic Beanstalk
Налаштування Sentry для самостійного розгортання
Форк репозиторію Sentry
Ми радимо використовувати GitHub репозиторій getsentry/onpremise
як основний та працювати в окремій гілці, потім оновлювати її на нові гілки релізів для оновлення.
Ви можете використовувати цей фрагмент .git/config
як посилання:
[remote "getsentry"]
url = https://github.com/getsentry/onpremise.git
fetch = +refs/heads/*:refs/remotes/getsentry/*
[branch "releases/20.11.1"]
remote = getsentry
merge = refs/heads/releases/20.11.1
[branch "master"]
remote = origin
merge = refs/heads/master
Налаштування середовища Elastic Beanstalk
Створіть нове одноекземплярне середовище Elastic Beanstalk з платформою Docker для Amazon Linux 2. Зважайте, що розмір екземпляра залежатиме від обсягу, але принаймні тип екземпляра t2.medium буде необхідний для розгортання. Ось як повинен виглядати ваш файл Dockerrun.aws.json
:
{
"AWSEBDockerrunVersion": "3",
"Image": {
"Update": "false"
}
}
Налаштування Postgres
Самостійне розгортання Sentry використовує локальну базу даних Postgres, яка працює в контейнері Docker разом з усім іншим. Це не зовсім підходить для надійності та масштабування, тому ми вирішили перенести екземпляр Postgres на RDS.
Наступні кроки є необов'язковими, але сильно рекомендовані.
файл docker-compose.yml:
@@ -11,7 +11,6 @@ x-sentry-defaults: &sentry_defaults
image: sentry-onpremise-local
depends_on:
- redis
- - postgres
- memcached
- smtp
- snuba-api
@@ -61,13 +62,6 @@ services:
nofile:
soft: 10032
hard: 10032
- postgres:
- << : *restart_policy
- image: 'postgres:9.6'
- environment:
- POSTGRES_HOST_AUTH_METHOD: 'trust'
- volumes:
- - 'sentry-postgres:/var/lib/postgresql/data'
zookeeper:
<< : *restart_policy
image: 'confluentinc/cp-zookeeper:5.5.0'
@@ -233,8 +227,6 @@ services:
volumes:
sentry-data:
external: true
- sentry-postgres:
- external: true
sentry-redis:
external: true
sentry-zookeeper:
файл install.sh:
@@ -140,7 +140,6 @@ fi
echo ""
echo "Створення томів для постійного зберігання..."
echo "Створено $(docker volume create --name=sentry-data)."
- echo "Створено $(docker volume create --name=sentry-postgres)."
@@ -267,27 +271,6 @@ for topic in $NEEDED_KAFKA_TOPICS; do
fi
done
-# Дуже наївно перевіряємо, чи є існуючий том sentry-postgres та версія PG в ньому
-if [[-n "$(docker volume ls -q --filter name=sentry-postgres)" && "$(docker run --rm -v sentry-postgres:/db busybox cat /db/PG_VERSION 2>/dev/null)" == "9.5"]]; then
- docker volume rm sentry-postgres-new || true
- # Якщо це дані Postgres 9.5, починаємо оновлювати їх до 9.6 в новому тому
- docker run --rm \
- -v sentry-postgres:/var/lib/postgresql/9.5/data \
- -v sentry-postgres-new:/var/lib/postgresql/9.6/data \
- tianon/postgres-upgrade:9.5-to-9.6
-
- # Позбуваємося старого тому, оскільки перейменуємо новий в старий
- docker volume rm sentry-postgres
- docker volume create --name sentry-postgres
- # В Docker немає команди для перейменування томів, тому копіюємо вміст зі старого в новий
- # Також додаємо рядок `host all all all trust`, оскільки `tianon/postgres-upgrade:9.5-to-9.6`
- # не робить цього автоматично.
- docker run --rm -v sentry-postgres-new:/from -v sentry-postgres:/to alpine ash -c \
- "cd /from ; cp -av . /to ; echo 'host all all all trust' >> /to/pg_hba.conf"
- # Нарешті, видаляємо новий старий том, оскільки ми всі в sentry-postgres тепер
- docker volume rm sentry-postgres-new
-fi@@ -267,27 +271,6 ## for topic in $NEEDED_KAFKA_TOPICS; do
fi
done
Увімкнення розширення citext
Sentry використовує стовпці без урахування регістру в Postgres, що активується за допомогою розширення citext. На щастя, це розширення доступне в RDS, тому вам потрібно лише активувати його, виконавши наступний запит до бази даних:
CREATE EXTENSION citext;
Налаштування тому для Clickhouse
Clickhouse зберігає інформацію про події, тому, щоб уникнути втрати даних при кожному розгортанні чи заміні екземпляра, створіть зовнішній том для зберігання, а потім налаштуйте зону доступності Elastic Beanstalk, щоб вона збігалася з тією самою зоною, що й том, для можливості прикріплення.
Тепер додайте наступний .ebextension для керування монтуванням томів:
commands:
01clear-if-unmounted:
command: if ! mount | grep /var/lib/docker/volumes/sentry-clickhouse > /dev/null; then rm -rf /var/lib/docker/volumes/sentry-clickhouse; fi
02attach-volume:
command: aws ec2 attach-volume --region us-east-1 --volume-id $VOLUME_ID --instance-id $(curl -s http://169.254.169.254/latest/meta-data/instance-id) --device /dev/sdh
ignoreErrors: true
03wait:
command: sleep 10
04trymount:
command: |
mkdir -p /var/lib/docker/volumes/sentry-clickhouse
mount /dev/sdh /var/lib/docker/volumes/sentry-clickhouse
ignoreErrors: true
05format-if-not-already:
command: if find /var/lib/docker/volumes/sentry-clickhouse/ -maxdepth 0 -empty | read v; then mkfs -t ext3 /dev/sdh; fi
Не забувайте замінити $VOLUME_ID
на правильний ID тому (це буде щось на зразок vol-XXXXXX
).
Змінні середовища для веб-контейнера
Ми додали конфігураційні файли Sentry до системи контролю версій і внесли в них зміни, щоб використовувати змінні середовища для чутливих параметрів замість хардкодованих значень. Процес трохи складний, але працює бездоганно.
Видаліть наступні записи з .gitignore
-sentry/sentry.conf.py
-sentry/config.yml
Зміни для використання змінних середовища
Додайте імпорт os для отримання змінних середовища в файлі sentry/sentry.config.py:
from sentry.conf.server import * # NOQA
+ import os
І завантажте змінні середовища для підключення до бази даних:
- "ENGINE": "sentry.db.postgres",
- "NAME": "postgres",
- "USER": "postgres",
- "PASSWORD": "",
- "HOST": "postgres",
- "PORT": "",
+ "ENGINE": os.environ.get('DB_ENGINE'),
+ "NAME": os.environ.get('DB_NAME'),
+ "USER": os.environ.get('DB_USER'),
+ "PASSWORD": os.environ.get('DB_PASSWORD'),
+ "HOST": os.environ.get('DB_HOST'),
+ "PORT": os.environ.get('DB_PORT'),
Змініть автогенерацію та хардкодинг SECRET_KEY
на використання змінної середовища замість цього. У файлі install.sh:
# Закоментуйте це, щоб уникнути збереження секретних ключів у версіонованих конфігураціях
# if grep -xq "system.secret-key: '!!changeme!!'" $SENTRY_CONFIG_YML ; then
# echo ""
# echo "Генерація секретного ключа..."
# # Це для уникнення помилок при використанні секретного ключа в sed нижче
# # Зверніть увагу, що потрібно встановити LC_ALL=C через BSD tr та sed, які завжди намагаються декодувати
# # будь-яке передане значення. Дякуємо https://stackoverflow.com/a/23584470/90297
# SECRET_KEY=$(export LC_ALL=C; head /dev/urandom | tr -dc "a-z0-9@#%^&*(-_=+)" | head -c 50 | sed -e 's/[\/&]/\\&/g')
# sed -i -e 's/^system.secret-key:.*$/system.secret-key: '"'$SECRET_KEY'"'/' $SENTRY_CONFIG_YML
# echo "Секретний ключ записано в $SENTRY_CONFIG_YML"
# fi
# встановіть секретний ключ з змінної середовища в config.yml
sed -i -e 's,^system.secret-key:.*$,system.secret-key: '"'$SECRET_KEY'"',' sentry/config.yml
echo "Секретний ключ записано в $SENTRY_CONFIG_YML"
Додайте свої змінні до середовища Beanstalk у AWS
# підключення до бази даних
DB_HOST
DB_NAME
DB_USER
DB_PASSWORD
DB_PORT
DB_ENGINE
# секретний ключ Sentry
SECRET_KEY
# URL Sentry, має починатися з http:// або https://
ROOT_URL
# Для сповіщень по email
MAIL_FROM
MAIL_PORT
MAIL_HOST
MAIL_USERNAME
MAIL_PASSWORD
MAIL_USE_TLS
Хуки Elastic Beanstalk
Додайте наступний файл до .platform/confighooks/prebuild/
та .platform/hooks/prebuild/
, щоб створити новий файл .env_eb
під час розгортання.
Це потрібно для копіювання змінних середовища Elastic Beanstalk в директорію staging, де docker-compose може їх підхопити.
#!/bin/bash
cp /opt/elasticbeanstalk/deployment/env.list .env_eb
Змінна середовища для веб-контейнера
Далі додайте це як файл змінних середовища для веб-контейнера в файлі docker-compose.yml:
environment:
SENTRY_CONF: '/etc/sentry'
SNUBA: 'http://snuba-api:1218'
env_file:
- .env_eb
Примітка: Це обхідний шлях, оскільки Sentry має свій власний файл .env, який використовується install.sh, і Elastic Beanstalk не створюватиме файл .env автоматично, якщо цей файл вже існує.
Налаштування попереднього хука для виконання скрипту установки
Виконайте скрипт установки в раніше створеному хуці в .platform/hooks/prebuild/
:
#!/bin/bash
cp /opt/elasticbeanstalk/deployment/env.list .env_eb
# Виконати установку LTS релізу Sentry без запитів до користувача
SENTRY_IMAGE=getsentry/sentry:20.11.1 ./install.sh --no-user-prompt
wait
Налаштування перевірки стану Elastic Beanstalk
Встановіть /_health/
як шлях для перевірки стану вашого середовища Elastic Beanstalk в консолі AWS та додайте наступний файл як .ebextension для дозволу затриманих перевірок стану:
Resources:
AWSEBAutoScalingGroup:
Type: "AWS::AutoScaling::AutoScalingGroup"
Properties:
HealthCheckType: "ELB"
HealthCheckGracePeriod: "600"
Додаткові налаштування для Kafka
Збільште таймаут сокету Kafka, щоб уникнути проблем з перевіркою стану:
- "socket.timeout.ms": 1000,
+ "socket.timeout.ms": 10000,
Розгортання
Переконайтеся, що у вас встановлено Elastic Beanstalk CLI на вашому комп'ютері, потім ініціалізуйте середовище Beanstalk локально за допомогою eb init
, і використовуйте команду eb deploy
для розгортання застосунку.
Кінець
Тепер, коли ви встановили самостійно розгорнутий Sentry, пора налаштувати інтеграції з вашими улюбленими додатками і зв'язати їх, щоб почати отримувати повідомлення про помилки. Сподіваємося, що ми зможемо повернутися до вас незабаром і поділитися нашим досвідом та порадами для найкращого використання цієї системи. Але наразі ми просто хочемо подякувати вам за те, що пройшли весь шлях до кінця. Якщо вам сподобався цей блог, будь ласка, дайте свою оцінку, поставивши лайк і поділившись ним!
Перекладено з: How to setup self-hosted Sentry in Elastic Beanstalk (AWS)