2016-10-09 6 views
1

Я использую user_data для начальной настройки хостов, используемых в ECS для запуска контейнеров. Я хочу, чтобы сообщить AWS ECS о переносе контейнеров на вновь созданные хосты после обновления user_data. Как я могу это сделать?Как заставить AWS ECS переносить контейнеры в другую ПГС?

Я использую Terraform для развертывания инфраструктуры AWS.

ответ

4

Я не думаю, что ECS имеет встроенный способ сделать это. В результате обычно требуется довольно утомительный ручной процесс & (хотя он может быть написан сценарием). Существует несколько различных способов сделать это, но это, как правило, самый простой:

  1. Внесите ваши изменения в user_data.
  2. Пробег terraform apply.
  3. Для каждого EC2 инстанции в вашем ASG, который имеет старую user_data:
    1. Terminate, что EC2 инстанции. Вы можете сделать это через AWS CLI или через веб-консоль EC2.
    2. Через некоторое время ASG автоматически запустит новый экземпляр EC2 с новым user_data, чтобы заменить завершенный экземпляр EC2.
    3. Через некоторое время ECS автоматически запустит новые копии любых задач ECS, которые были запущены на завершенном экземпляре EC2.

После того, как вы прошли через этот процесс, все экземпляры в ГАС будет запущен новый user_data. Обратите внимание, что это может быть сделано с нулевым временем простоя для ваших задач ECS до тех пор, как:

  1. Есть по крайней мере, 2 копии каждого ECS задачи, каждая из которых на отдельной EC2 инстанции в вашем ASG.
  2. Вы ожидаете достаточно времени между завершающими экземплярами EC2 для задач ECS для перезапуска.

Если вы не можете удовлетворить эти требования, у вас может быть некоторое время простоя, или вам может потребоваться использовать более беспорядочный вариант, который предполагает удвоение размера ASG, ожидая новых экземпляров EC2 (которые будут иметь новый user_data) для развертывания в ASG, удваивая количество задач ECS, ожидая развертывания этих новых задач ECS (они, как правило, будут развертываться на новых экземплярах EC2), а затем уменьшая каждую пополам (теоретически, старый Задачи ECS и старые экземпляры EC2 будут прекращены, оставив только новые).

1

Хотя Yevgeniy «s answer правильно в том, что нет никакого способа, чтобы получить Terraform непосредственно перенести контейнеры на новые экземпляры в случае, если экземпляры воссозданы есть гораздо чище вариант для вас, используя ресурс терраформировать в lifecycle configuration.

Предполагая, что вы используете AutoScaling группы обратно ваш ECS хостов вы можете сделать что-то вроде этого:

data "aws_ami" "ubuntu" { 
    most_recent = true 
    filter { 
    name = "name" 
    values = ["ubuntu/images/ebs/ubuntu-trusty-14.04-amd64-server-*"] 
    } 
    filter { 
    name = "virtualization-type" 
    values = ["paravirtual"] 
    } 
    owners = ["099720109477"] # Canonical 
} 

resource "aws_launch_configuration" "as_conf" { 
    name_prefix = "terraform-lc-example-" 
    image_id = "${data.aws_ami.ubuntu.id}" 
    instance_type = "t1.micro" 

    lifecycle { 
    create_before_destroy = true 
    } 
} 

resource "aws_autoscaling_group" "bar" { 
    name = "${aws_launch_configuration.as_conf.name}" 
    launch_configuration = "${aws_launch_configuration.as_conf.name}" 

    lifecycle { 
    create_before_destroy = true 
    } 
} 

(взятый из Terraform-х launch configuration docs)

Теперь, когда изменения конфигурации запуска, например, если либо пользовательские данные, либо AMI, которые используются, меняются, это заставит Terraform создать новую конфигурацию запуска, которая, в свою очередь, заставляет новую группу автомасштабирования из-за зависимости от имени.

Как Terraform использует конфигурацию жизненного цикла create_before_destroy, он создаст новую конфигурацию запуска и ASG, прежде чем уничтожить ее. В приведенной выше простой настройке ASG вернется как завершенная, как только один экземпляр будет считаться здоровым AWS.

К сожалению, это только показывает, когда экземпляр EC2 здоров, а не то, что он успешно выполняет задачи. Как упоминалось в комментариях к этому ответу, ECS не будет автообновлять задачи для новых экземпляров в кластере, и поэтому Terraform затем уничтожит экземпляры, которые запускают задачи ECS в старой ASG, прежде чем ECS сможет перенести их на новые экземпляры ASG, вызвав отключение.

Чтобы обойти это (а также позволить экземплярам сбой и заменяться в целом более удобным образом), вы можете использовать ASG lifecycle hooks для выполнения некоторых действий, когда экземпляр помечен для завершения, но до того, как он фактически завершен.

Там хороший AWS blog post о делает именно это и имеет некоторый [пример лямбда-кода], который реагирует на крючок, чтобы истощить экземпляры контейнеров, помеченных для прекращения до завершения жизненного цикла крюк, который затем позволит ГАС прекратить экземпляры , Высушив экземпляры контейнера, ECS автоматически перепланирует минимальное количество здоровых заданий на неиспользуемые экземпляры (в новой ASG).

Если ваши задачи ECS зарегистрированы на балансировщике нагрузки, задачи будут отменены регистрацией ECS из балансировочного устройства нагрузки после запуска нового набора задач, а затем задачи останутся на протяжении периода времени ожидания слива балансировочного устройства нагрузки ,

+0

Вы действительно пробовали этот подход? AFAIK, если вы попробуете это, это либо приведет к общему отключению всех ваших услуг ECS, либо полностью сработает. Это потому, что Terraform создаст новую ASG (благодаря параметру 'create_before_destroy'), но у ECS нет причин для развертывания чего-либо на нем. Поэтому новая ASG будет пуста, а старая будет либо убита (включая все ваши ECS-сервисы), либо, если вы попробуете трюк с проверкой работоспособности ELB, команда 'apply' будет терпеть неудачу, поскольку ничто не развертывается на новой ASG и, следовательно, ничего не регистрируется в ELB. –

+0

Я выбил несколько фиктивных POC в этих строках, но сейчас мы не используем Docker в производстве. Чтобы выполнить эту работу, вам нужно, чтобы скрипт userdata присоединился к кластеру ECS, а затем запустил задачу, используя что-то вроде 'aws ecs start-task -cluster $ cluster -task-definition cadvisor: 1 --container-экземпляры $ instance_arn --region $ region' (взято из https://aws.amazon.com/blogs/compute/running-an-amazon-ecs-task-on-every-instance/), но да, иначе ECS будет только переносить задачи на новые экземпляры, когда старые экземпляры уничтожены. – ydaetskcoR

+0

Я пробовал этот подход, и Евгений прав. Это приводит к полному отключению кластера ECS, поскольку ECS раньше не переходит на новую ПГС. Возможным обходным решением может быть установка некоторой переменной ENV в определении задачи ECS, содержащей имя ASG. Это заставит ECS выполнить текущие задачи НЕАКТИВНО и перейти на резервные серверы. Однако я не думаю, что все это произойдет в правильном порядке/требуемом количестве времени. – Maklaus