Компания
63,54
рейтинг
17 июля 2012 в 17:28

Разработка → Автомасштабирование в Amazon Web Services: EC2 + CloudWatch

Добрый день!

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

В качестве инициатора маштабирования будет выступать Cloud Watch. Метрикой будет наша кастомная метрика Load Average.

Итак, начнём-с. Первое, как тру линуксоид, я советую и рекомендую использовать в настройке автоскейлинга утилиты командной строки (Command Line Tools — CLT) по следующим причинам:
  • из CLT можно сделать всё;
  • удобнее копипастить в консоль, чем кликать мышкой.


Подготовимся к работе и настроим свой терминал, скачав и распаковав следующие тулзы:


Сертификаты pk-***.pem и cert-***.pem положим в /opt/aws/keys.

Теперь сконфигурируем профиль bash, вставив следующие строки в .bash_profile:

.bash_profile
export JAVA_HOME=/usr/java/latest

export EC2_CERT=/opt/aws/cert-***.pem
export EC2_PRIVATE_KEY=/opt/aws/pk-***.pem

export EC2_HOME=/opt/aws/ec2
export PATH=$PATH:$EC2_HOME/bin

export AWS_CLOUDWATCH_HOME=/opt/aws/mon
export PATH=$PATH:$AWS_CLOUDWATCH_HOME/bin

export AWS_ELB_HOME=/opt/aws/elb
export PATH=$PATH:$AWS_ELB_HOME/bin

export AWS_AUTO_SCALING_HOME=/opt/aws/as
export PATH=$PATH:$AWS_AUTO_SCALING_HOME/bin


Итак, после этого список доступных команд расширится до нужного количества.

1. Начнём с создания балансировщика:
$ elb-create-lb  testlb --headers --listener "lb-port=80,instance-port=8080,protocol=http" --listener "lb-port=443,instance-port=8443,protocol=tcp" --availability-zones us-east-1c
DNS_NAME  DNS_NAME
DNS_NAME  testlb-1678377526.us-east-1.elb.amazonaws.com

Здесь:
testlb — название ЛБ
«lb-port=80,instance-port=8080,protocol=http» — внешний порт ЛБ и внутренний порт сервера. С HTTPS та же ситуация.

2. Будем считать, что у нас есть уже готовый к работе инстанс с ID i-12345678. Установим наш инстанс под ЛБ:
$ elb-register-instances-with-lb testlb --instances i-12345678
INSTANCE_ID  i-12345678

Теперь инстанс доступен по адресу ЛБ.

3. Снимем образ (Amazon Machine Image — AMI) с рабочего инстанса:
$ ec2-create-image i-12345678 --no-reboot -n 'Image Name' -d 'Image Description'
ami-87654321

4. С полученным ami создадим старт-конфиг (Launch Config)
$ as-create-launch-config testlc -i ami-87654321 --key=keypair --group mygroup --instance-type m1.large
OK-Created launch config

Здесь:
keypair — пара ключей, с помощью которой вы логинитесь;
mygroup — секьюрити группа, в которой будут подыматься серверы.

5. Создадим автоскейлинг группу с только что созданным конфигом:
$ as-create-auto-scaling-group testsg -l testlc --availability-zones us-east-1c --min-size 0 --max-size 2 --load-balancers testlb
OK-Created AutoScalingGroup

Здесь:
testlc — нами созданный конфиг;
us-east-1c — зона, в которой будут подыматься инстансы;
0 и 2 — минимальный и максимальный размеры группы соответственно;
testlb — имя вашего балансировщика, под которым будет поднята вся группа.

Итак, готова группа масштабирования и балансировщик.

Теперь нужно настроить CloudWatch алармы. Автомасштабирование, основанное не CloudWatch работает через политикуpolicy, которая задаётся. Примером политики является увеличение кол-ва интансов на 1. Т.е. сначала мы задаём политику, потом мы создаём аларм, который, например, срабатывает при Load Average больше 5 на протяжении минуты.

6. Ну вот политика скейл апа:
$ as-put-scaling-policy ScaleUpPolicy --auto-scaling-group testsg --adjustment=1 --type ChangeInCapacity --cooldown 120
arn:aws:autoscaling:us-east-1:278634951321:scalingPolicy:2f3482d2-ca6c-4653-970c-eb68a593cf26:autoScalingGroupName/testsg:policyName/ScaleUpPolicy

Здесь:
--adjustment=1 — +1 хост к группе
--cooldown 120 — на протяжении 2 минут все алармы будут игнорироваться и новые инстансы подняты не будут

7. Ну и аларм для скейл апа:
$ mon-put-metric-alarm HighLoadAvAlarm --comparison-operator GreaterThanOrEqualToThreshold --evaluation-periods 1 --metric-name LoadAverage --namespace CustomMetric --period 60 --statistic Average --threshold 5 --alarm-actions arn:aws:autoscaling:us-east-1:278634951321:scalingPolicy:2f3482d2-ca6c-4653-970c-eb68a593cf26:autoScalingGroupName/testsg:policyName/ScaleUpPolicy
OK-Created Alarm

Здесь:
--comparison-operator GreaterThanOrEqualToThreshold — оператор >= чем трешхолд.
--evaluation-periods 1 — срабатывает с первого раза
--metric-name LoadAverage --namespace CustomMetric — наша кастомная метрика
--period 60 — минута на срабатывание
--statistic Average — подсчитывается среднее значение
--threshold 5 — Load Average не больше 5, помните?
--alarm-actions — какая политика.

8. Политика скейл дауна:
$ as-put-scaling-policy ScaleDownPolicy --auto-scaling-group testsg --adjustment=-1 --type ChangeInCapacity --cooldown 420
arn:aws:autoscaling:us-east-1:278634951321:scalingPolicy:2f3482d2-ca6c-4653-970c-eb68a593cf26:autoScalingGroupName/testsg:policyName/ScaleDownPolicy

Здесь кулдаун больше. После даунскейла инстансы группа не даунскейлится ещё минимум 6 минут. Ну и adjustment=-1.

9. Аларм для скейл дауна:

$ mon-put-metric-alarm LoLoadAvAlarm --comparison-operator LessThanThreshold --evaluation-periods 1 --metric-name LoadAverage --namespace CustomMetric --period 120 --statistic Average --threshold 3 --alarm-actions arn:aws:autoscaling:us-east-1:278634951321:scalingPolicy:2f3482d2-ca6c-4653-970c-eb68a593cf26:autoScalingGroupName/testsg:policyName/ScaleDownPolicy
OK-Created Alarm

Здесь аларм срабатывает, если больше 2 минут Load Average был меньше 3.

Ну вот и всё. Итак, теперь в зависимости от нагрузки, наша скейл группа сможет разрастаться до 3х инстансов и 1 всегда будет жив. Здесь рассмотрен простейший пример автоскейлинга. Естественно, можно менять условия и баловаться с цифрами по своему усмотрению.
Автор: @korjik
EPAM
рейтинг 63,54

Комментарии (17)

  • +1
    Да это просто счастье какое то.
    • +1
      Стараюсь. Задавайте вопросы, может тем для селдующих статей получим.
  • 0
    спасибо за подробный материал.

    вопросы:
    — есть ли смысл измерять период кулдауна в минутах, если инстанс оплачивается почасово?
    — в силу архитектурных особенностей системы (возможно неудачной архитектуры) наши инстансы немного отличаются друг от друга (то есть просто клонировать один и тот же не получится). зато у нас есть 8 подготовленных и остановленных инстансов, которые по крону включаются/выключаются в пиковое время (особенности проекта — в 95% случаев врем пиковой нагрузки предсказуемо). реально ли при помощи автоскейлинга не клонировать инстансы, а включать/выключать инстансы находящиеся в пуле?
    • 0
      Коммент ниже. Ошибся линком.
  • 0
    1. Смысл есть, ведь тушится хост, который бежит дольше всего. Я обычно использую 15+ минут.

    2. Вы ведь можете использовать разыне скейлинг группы под одним/разными балансерами. И по крону можете слать команду

    $ as-update-autoscaling-group groupname --desired-capacity 2;

    Либо же использовать кастомную метрику и в определённое время слать в эту метрику, например, 1, и это будет инициировать скейлинг.
    • 0
      спасибо. теперь понятно с какой стороны начинать копать
      • 0
        Рад помочь!
  • 0
    Сделал вроде также, но почему-то не работает как надо.
    Делал так
    as-update-auto-scaling-group API-scaling-group --min-size 0 --max-size 0 --region us-east-1

    as-describe-auto-scaling-groups

    as-delete-auto-scaling-group API-scaling-group --region us-east-1

    as-describe-launch-configs

    as-delete-launch-config API-LC-2012-07-30

    as-create-launch-config API-LC-2012-07-31 -i ami-8977dfe0 --key=key_name --group=ras --instance-type m1.large

    as-create-auto-scaling-group API-scaling-group --launch-configuration API-LC-2012-07-31 --availability-zones us-east-1d --min-size 0 --max-size 2 --load-balancers API

    as-put-scaling-policy ScaleUpPolicy --auto-scaling-group API-scaling-group --adjustment=1 --type ChangeInCapacity --cooldown 120
    >> arn:aws:autoscaling:us-east-1:044676192710:scalingPolicy:c09aa605-93bb-4e19-82cf-09eec2658d95:autoScalingGroupName/API-scaling-group:policyName/ScaleUpPolicy

    as-put-scaling-policy ScaleDownPolicy --auto-scaling-group API-scaling-group --adjustment=-1 --type ChangeInCapacity --cooldown 420
    >> arn:aws:autoscaling:us-east-1:044676192710:scalingPolicy:ee91ee8e-304b-48ce-9b4e-18504afc5a3e:autoScalingGroupName/API-scaling-group:policyName/ScaleDownPolicy

    mon-put-metric-alarm HighLoadAvAlarm --comparison-operator GreaterThanOrEqualToThreshold --evaluation-periods 1 --metric-name CPUUtilization --namespace «AWS/EC2» --period 60 --statistic Average --threshold 80 --alarm-actions arn:aws:autoscaling:us-east-1:044676192710:scalingPolicy:c09aa605-93bb-4e19-82cf-09eec2658d95:autoScalingGroupName/API-scaling-group:policyName/ScaleUpPolicy --dimensions «AutoScalingGroupName=API-scaling-group» --region us-east-1

    mon-put-metric-alarm LoLoadAvAlarm --comparison-operator LessThanThreshold --evaluation-periods 1 --metric-name CPUUtilization --namespace «AWS/EC2» --period 120 --statistic Average --threshold 20 --alarm-actions arn:aws:autoscaling:us-east-1:044676192710:scalingPolicy:ee91ee8e-304b-48ce-9b4e-18504afc5a3e:autoScalingGroupName/API-scaling-group:policyName/ScaleDownPolicy --dimensions «AutoScalingGroupName=API-scaling-group» --region us-east-1


    В результате я имею 2 аларма со статусом «INSUFFICIENT_DATA' at 2012/08/07 15:14 UTC. Reason: Insufficient Data: 1 datapoint was unknown.»
    При этом, если я запускаю политику вручную при помощи as-execute-policy, то масштабирование происходит нормально (один инстанс добавляется, а через некоторое время срабатывает LoLoadAvAlarm и инстанс терминейтится). Кроме того, при ручном запуске мои алармы приобретают нормальный статус (OK и ALARM). Однако после того, как последний динамический инстанс умирает — оба аларма снова переходят в состояние INSUFFICIENT_DATA. Что я делаю не так?

    Лог метрик
    Date Type Description
    2012-08-07 15:12 UTC No Data Alarm updated from ALARM to INSUFFICIENT_DATA. Reason: Insufficient Data: 1 datapoint was unknown.
    2012-08-07 15:11 UTC Action Failed to execute action arn:aws:autoscaling:us-east-1:044676192710:scalingPolicy:c09aa605-93bb-4e19-82cf-09eec2658d95:autoScalingGroupName/API-scaling-group:policyName/ScaleUpPolicy.
    2012-08-07 15:10 UTC Action Failed to execute action arn:aws:autoscaling:us-east-1:044676192710:scalingPolicy:c09aa605-93bb-4e19-82cf-09eec2658d95:autoScalingGroupName/API-scaling-group:policyName/ScaleUpPolicy.
    2012-08-07 15:09 UTC Action Failed to execute action arn:aws:autoscaling:us-east-1:044676192710:scalingPolicy:c09aa605-93bb-4e19-82cf-09eec2658d95:autoScalingGroupName/API-scaling-group:policyName/ScaleUpPolicy.
    2012-08-07 15:08 UTC Action Failed to execute action arn:aws:autoscaling:us-east-1:044676192710:scalingPolicy:c09aa605-93bb-4e19-82cf-09eec2658d95:autoScalingGroupName/API-scaling-group:policyName/ScaleUpPolicy.
    2012-08-07 15:07 UTC Action Failed to execute action arn:aws:autoscaling:us-east-1:044676192710:scalingPolicy:c09aa605-93bb-4e19-82cf-09eec2658d95:autoScalingGroupName/API-scaling-group:policyName/ScaleUpPolicy.
    2012-08-07 15:06 UTC Action Failed to execute action arn:aws:autoscaling:us-east-1:044676192710:scalingPolicy:c09aa605-93bb-4e19-82cf-09eec2658d95:autoScalingGroupName/API-scaling-group:policyName/ScaleUpPolicy.
    2012-08-07 15:06 UTC Alarm Alarm updated from OK to ALARM. Reason: Threshold Crossed: 1 datapoint (71.24) was greater than or equal to the threshold (40.0).
    2012-08-07 14:56 UTC OK Alarm updated from ALARM to OK. Reason: Threshold Crossed: 1 datapoint (0.225) was not greater than or equal to the threshold (40.0).
    2012-08-07 14:43 UTC Action Failed to execute action arn:aws:autoscaling:us-east-1:044676192710:scalingPolicy:c09aa605-93bb-4e19-82cf-09eec2658d95:autoScalingGroupName/API-scaling-group:policyName/ScaleUpPolicy.
    2012-08-07 14:43 UTC Alarm Alarm updated from OK to ALARM. Reason: Threshold Crossed: 1 datapoint (63.59) was greater than or equal to the threshold (40.0).
    2012-08-07 14:42 UTC OK Alarm updated from ALARM to OK. Reason: Threshold Crossed: 1 datapoint (21.96) was not greater than or equal to the threshold (40.0).
    2012-08-07 14:41 UTC Action Failed to execute action arn:aws:autoscaling:us-east-1:044676192710:scalingPolicy:c09aa605-93bb-4e19-82cf-09eec2658d95:autoScalingGroupName/API-scaling-group:policyName/ScaleUpPolicy.
    2012-08-07 14:40 UTC Action Successfully executed action arn:aws:autoscaling:us-east-1:044676192710:scalingPolicy:c09aa605-93bb-4e19-82cf-09eec2658d95:autoScalingGroupName/API-scaling-group:policyName/ScaleUpPolicy.
    2012-08-07 14:40 UTC Alarm Alarm updated from OK to ALARM. Reason: Threshold Crossed: 1 datapoint (73.62) was greater than or equal to the threshold (40.0).
    2012-08-07 14:39 UTC OK Alarm updated from INSUFFICIENT_DATA to OK. Reason: Threshold Crossed: 1 datapoint (2.21) was not greater than or equal to the threshold (40.0).
    2012-08-07 14:15 UTC Modify Alarm «HighLoadAvAlarm» updated.
    2012-08-07 11:41 UTC Modify Alarm «HighLoadAvAlarm» updated.
    • 0
      Дименшен попробуйте убрать. Глюкает иногда.
  • 0
    Напишите статью про тоже самое только для mysql масштабирования.
    • 0
      Это масштабирование подходит для всего. Что имеется в виду под mysql масштабирванием?
      • –1
        Ну mysql же там надо либо реплику либо кластер ndb
  • 0
    Можно использовать MultiAZ RDS. Не пойиу вас.
    • 0
      RDS крайне закрыт от прямого управления, пока что не готов его использовать.
      • 0
        Это SааS…
  • 0
    Вот только не пойму, а нас крутиться приложение, как оно клoнируется и работает с теме же настройками что и на оригинале? если мне нужно проверять логи для каждого истанса, как узнать на какой из них я попадаю.
    • 0
      Само никак, это как бы ваши проблемы, можно с ами единого запускать, можно каждый раз деплоить, можно общий сторедж.
      Ну как бы заходите на конкретный инстанс, там никакой не однозначности нет.

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

Самое читаемое Разработка