Як налаштувати самостійно розгорнутий Sentry в Elastic Beanstalk (AWS)

від Марина Хуберман

Наша команда в 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 загалом.

Архітектура

Запропонована кінцева архітектура виглядає наступним чином:

pic

Архітектура високого рівня для самостійно розгорнутого 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 для розгортання застосунку.

Кінець

pic

Тепер, коли ви встановили самостійно розгорнутий Sentry, пора налаштувати інтеграції з вашими улюбленими додатками і зв'язати їх, щоб почати отримувати повідомлення про помилки. Сподіваємося, що ми зможемо повернутися до вас незабаром і поділитися нашим досвідом та порадами для найкращого використання цієї системи. Але наразі ми просто хочемо подякувати вам за те, що пройшли весь шлях до кінця. Якщо вам сподобався цей блог, будь ласка, дайте свою оцінку, поставивши лайк і поділившись ним!

Перекладено з: How to setup self-hosted Sentry in Elastic Beanstalk (AWS)

Leave a Reply

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