Подтвердить что ты не робот

Как изящно закрыть или удалить экземпляры AWS из группы ELB

У меня есть облако экземпляров сервера, запущенных на Amazon, используя их балансировщик нагрузки для распространения трафика. Теперь я ищу хороший способ изящно масштабировать сеть, не вызывая ошибок соединения на стороне браузера.

Насколько я знаю, любые соединения экземпляра будут грубо завершены при удалении из балансировки нагрузки.

Я хотел бы иметь способ сообщить свой экземпляр, как за одну минуту до его закрытия, или для того, чтобы балансировщик нагрузки прекратил отправлять трафик на умирающий экземпляр, но не прекратил существующие подключения к нему.

Мое приложение node.js работает на Ubuntu. У меня также есть специальное программное обеспечение, работающее на нем, поэтому я предпочитаю не использовать множество PAAS, предлагающих хостинг node.js.

Спасибо за любые подсказки.

4b9b3361

Ответ 1

В этой идее используется способность ELB обнаруживать нездоровый node и удалять его из пула, но он полагается на поведение ELB, как и ожидалось в приведенных ниже предположениях. Это то, что я хотел проверить для себя, но еще не успел. Я буду обновлять ответ, когда я это сделаю.

Обзор процесса

Следующая логика может быть завершена и запущена во время закрытия node.

  • Блокировать новые HTTP-соединения с узломX, но продолжать разрешать существующие соединения
  • Подождите, пока существующие соединения не будут слиты, либо путем мониторинга существующих подключений к вашему приложению, либо путем обеспечения "безопасного" количества времени.
  • Инициировать завершение работы экземпляра nodeX EC2 с использованием API-интерфейса EC2 или абстрактных скриптов.

"безопасно" в соответствии с вашим приложением, которое может быть невозможно определить для некоторых приложений.

Предположения, которые необходимо протестировать

Мы знаем, что ELB удаляет из него нездоровые экземпляры пула. Я ожидал бы, что это будет изящно, так что:

  • Новое соединение с недавно закрытым портом будет изящно перенаправлено на следующий node в пуле
  • Если node отмечен "Плохо", уже установленные соединения с этим node не затронуты.

возможные тестовые примеры:

  • Пожарные HTTP-соединения на ELB (например, от завитка script), регистрирующие результаты во время сценария, открывающего закрытие одного из узлов HTTP-порты. Вам нужно будет поэкспериментировать, чтобы найти приемлемое количество времени, которое позволяет ELB всегда определять состояние изменение.
  • Поддерживать длительный сеанс HTTP (например, загрузка файла), блокируя новые HTTP-соединения, долгий сеанс, надеюсь, будет продолжаться.

1. Как заблокировать HTTP-соединения

Использовать локальный брандмауэр на узлеX, чтобы блокировать новые сеансы, но продолжать разрешать установленные сеансы.

Например, таблицы IP:

iptables -A INPUT -j DROP -p tcp --syn --destination-port <web service port>

Ответ 2

Я знаю, что это старый вопрос, но следует отметить, что Amazon недавно добавила поддержку connection draining, а это означает, что когда экземпляр удаляется из loadbalancer, экземпляр завершает запросы, которые выполнялись до экземпляр был удален из loadbalancer. Никакие новые запросы не будут перенаправлены на экземпляр, который был удален. Вы также можете предоставить тайм-аут для этих запросов, то есть все запросы, которые будут работать дольше, чем окно тайм-аута, будут завершены в конце концов.

Чтобы включить это поведение, перейдите на вкладку Instances вашего loadbalancer и измените поведение connection draining.

Ответ 3

Рекомендуемый способ распределения трафика с вашего ELB - иметь равное количество экземпляров в нескольких зонах доступности. Например:

ELB

  • Экземпляр 1 (us-east-a)
  • Экземпляр 2 (us-east-a)
  • Экземпляр 3 (us-east-b)
  • Экземпляр 4 (us-east-b)

Теперь есть два интересующих API ELB, которые позволяют программно (или через панель управления) отделять экземпляры:

  • Отменить регистрацию экземпляра
  • Отключить зону доступности (которая впоследствии отключает экземпляры в этой зоне)

Руководство разработчика ELB содержит раздел, описывающий последствия отключения зоны доступности. Замечание в этом разделе представляет особый интерес:

Ваш балансировщик всегда распределяет трафик на все включенные Зоны доступности. Если все экземпляры в зоне доступности снят с учета или нездоровый до того, как эта зона доступности отключена для балансировки нагрузки все запросы, отправленные в эту зону доступности будет работать до тех пор, пока DisableAvailabilityZonesForLoadBalancer не потребует этого Зона доступности.

Интересно отметить, что это может означать, что если вы вызываете DisableAvailabilityZonesForLoadBalancer, ELB может мгновенно начать отправлять запросы только в доступные зоны - возможно, это приведет к 0 простоям при выполнении обслуживания на серверах с отключенной доступностью зона.

Вышеупомянутая "теория" нуждается в детальном тестировании или подтверждении от инженера облачных вычислений Amazon.

Ответ 4

Похоже, что здесь уже было несколько ответов, и некоторые из них имеют хорошие советы. Но я думаю, что в целом ваш дизайн испорчен. Независимо от того, насколько вы совершенны, вы создаете свою процедуру выключения, чтобы убедиться, что соединение с клиентами закрыто, прежде чем закрыть сервер, который вы по-прежнему уязвимы.

  • Сервер может потерять мощность.
  • Аппаратный сбой приводит к сбою сервера.
  • Соединение может быть закрыто сетевой проблемой.
  • Клиент теряет интернет или Wi-Fi.

Я мог бы продолжить список, но я хочу сказать, что вместо того, чтобы система всегда работала правильно. Предназначен для обработки отказов. Если вы создадите систему, которая может обрабатывать сервер, теряя мощность в любое время, тогда вы создали очень надежную систему. Это не проблема с ELB, это проблема с текущей архитектурой системы.

Ответ 5

Я не могу комментировать причину моей низкой репутации. Вот некоторые фрагменты, которые я разработал, которые могут быть очень полезны для кого-то там. Он использует инструмент aws cli для проверки того, когда экземпляр был удален из соединений.

Вам нужен экземпляр ec2 с предоставленным сервером python за ELB.

from flask import Flask
import time

app = Flask(__name__)

@app.route("/")
def index():
    return "ok\n"

@app.route("/wait/<int:secs>")
def wait(secs):
    time.sleep(secs)
    return str(secs) + "\n"

if __name__ == "__main__":
    app.run(
        host='0.0.0.0',
        debug=True)

Затем выполните следующую команду script с локальной рабочей станции в сторону ELB.

#!/bin/bash

which jq >> /dev/null || {
   echo "Get jq from http://stedolan.github.com/jq"
}

# Fill in following vars
lbname="ELBNAME"
lburl="http://ELBURL.REGION.elb.amazonaws.com/wait/30"
instanceid="i-XXXXXXX"

getState () {
    aws elb describe-instance-health \
        --load-balancer-name $lbname \
        --instance $instanceid | jq '.InstanceStates[0].State' -r
}

register () {
    aws elb register-instances-with-load-balancer \
        --load-balancer-name $lbname \
        --instance $instanceid | jq .
}

deregister () {
    aws elb deregister-instances-from-load-balancer \
        --load-balancer-name $lbname \
        --instance $instanceid | jq .
}

waitUntil () {
    echo -n "Wait until state is $1"
    while [ "$(getState)" != "$1" ]; do
        echo -n "."
        sleep 1
    done
    echo
}

# Actual Dance
# Make sure instance is registered. Check latency until node is deregistered

if [ "$(getState)" == "OutOfService" ]; then
    register >> /dev/null
fi

waitUntil "InService"

curl $lburl &
sleep 1

deregister >> /dev/null

waitUntil "OutOfService"

Ответ 6

Оговорка, которая не обсуждалась в существующих ответах, заключается в том, что ELB также используют записи DNS с 60-секундными TTL для балансировки нагрузки между несколькими узлами ELB (каждый из которых имеет один или несколько ваших экземпляров, прикрепленных к нему).

Это означает, что если у вас есть экземпляры в двух разных зонах доступности, у вас, вероятно, есть два IP-адреса для вашего ELB с 60-кратным TTL на своих A-образцах. Когда вы удаляете окончательные экземпляры из такой зоны доступности, ваши клиенты "могут" все еще использовать старый IP-адрес в течение как минимум минуты - неисправные DNS-преобразователи могут вести себя намного хуже.

В другое время ELB носят несколько IP-адресов и имеют одну и ту же проблему, когда в одной зоне доступности у вас очень много экземпляров, которые слишком много для одного сервера ELB. ELB в этом случае также создаст другой сервер и добавит свой IP-адрес в список записей A с 60-секундным TTL.