Из рубрик #error + #issue. Пренеприятная проблема была получена при попытке срочного разворота важного окружения. В процессе подъёма #autoscaling_group для #ecs_cluster с несколькими рабочими нодами и сервисами на них с важным моментом - docker image лежит не в ECR, а в #private_docker_hub, то на давно отрепетированном сценарии (правда лишь с одной нодой) вылезла страннейшая ошибка - вторая (!) нода не могла загрузить контейнер. Т.е. первая грузила и успешно работала, а вторая (такая же, этот же образ) - зависала на ошибке:
Не получив образ по таймауту срабатывал откат. Ошибка нерегулярная, т.к. с энной попытки получалось задеплоить и успешно работать. Либо поставить одну ноду - и тогда ни разу не было такой ошибки.
Гуглинг показал, что у такой же ошибки есть братья по разуму, где, судя по всему, такая ситуация возникала именно в связке докерхаб + новый #ecs_agent. И в данном случае он как раз был обновлён. потому наверняка это одна из причин.
После детального изучения выяснилось, что в результате, видимо, каких-то неадекватных лагов с отдачей второго образа, амазоновская команда для подключения в #autoscalig_group:
вылетала в ошибку и расположенный за ней код не исполнялся! И если, как в моём случае, именно после этой команды задавалась переменная
Изменения последовательности команд - решило проблему. При чём важно учесть, что есть и другие команды, которые обладают таким поведением, потому важный код помещаем в начало #UserData, а проблемные - в самый конец и с учётом важности:
STOPPED (CannotPullContainerError: API error (404): pull ac)
Не получив образ по таймауту срабатывал откат. Ошибка нерегулярная, т.к. с энной попытки получалось задеплоить и успешно работать. Либо поставить одну ноду - и тогда ни разу не было такой ошибки.
Гуглинг показал, что у такой же ошибки есть братья по разуму, где, судя по всему, такая ситуация возникала именно в связке докерхаб + новый #ecs_agent. И в данном случае он как раз был обновлён. потому наверняка это одна из причин.
После детального изучения выяснилось, что в результате, видимо, каких-то неадекватных лагов с отдачей второго образа, амазоновская команда для подключения в #autoscalig_group:
/opt/aws/bin/cfn-signal -e $? --stack ${AWS::StackName} --resource autoscalingGroup --region ${AWS::Region}вылетала в ошибку и расположенный за ней код не исполнялся! И если, как в моём случае, именно после этой команды задавалась переменная
ECS_ENGINE_AUTH_DATA для авторизации на докере, то, получается, она не попадала в ecs.config и агент после никак не мог получить доступ к приватному репозиторию.Изменения последовательности команд - решило проблему. При чём важно учесть, что есть и другие команды, которые обладают таким поведением, потому важный код помещаем в начало #UserData, а проблемные - в самый конец и с учётом важности:
/opt/aws/bin/cfn-signal -e $? --stack ${AWS::StackName} --resource autoscalingGroup --region ${AWS::Region}
stop ecs
start ecsGitHub
ECS Problem: cannot pull container from docker repository #422
Hi, guys. We have problem Service wont start with error: Status reason CannotPullContainerError: Error: image xxx/yyyy:latest not found We have private repository on hub.docker.com. I tried to pull container from my machine - everything ...
Башеписание в UserData
При использовании сложных баш-конструкций в CloudFormation UserData типа:
Строчка
Для правильного написания таких вещей, переменные нужно экранировать восклицательным знаком, как указано в документации:
To write a dollar sign and curly braces (${}) literally, add an exclamation point (!) after the open curly brace, such as ${!Literal}. AWS CloudFormation resolves this text as ${Literal}.
То есть правильное написание проблемной строки должно быть таким:
Однако в общем случае стоит избегать подобных сложностей в UserData, а ещё лучше, для конкретного этого примера, использовать встроенную переменную ${AWS::Region}.
#CloudFormation #UserData
При использовании сложных баш-конструкций в CloudFormation UserData типа:
UserData:
Fn::Base64: !Sub |
#!/bin/bash -xe
CurZone=$(curl http://instance-data/latest/meta-data/placement/availability-zone)
CurRegion=${CurZone:0:${#CurZone} - 1}
Строчка
CurRegion=${CurZone:0:${#CurZone} - 1} даст #error:Template error: variable names in Fn::Sub syntax must contain only alphanumeric characters, underscores, periods, and colons.Для правильного написания таких вещей, переменные нужно экранировать восклицательным знаком, как указано в документации:
To write a dollar sign and curly braces (${}) literally, add an exclamation point (!) after the open curly brace, such as ${!Literal}. AWS CloudFormation resolves this text as ${Literal}.
То есть правильное написание проблемной строки должно быть таким:
CurRegion=${!CurZone:0:${!#CurZone} - 1}Однако в общем случае стоит избегать подобных сложностей в UserData, а ещё лучше, для конкретного этого примера, использовать встроенную переменную ${AWS::Region}.
#CloudFormation #UserData
Amazon
Fn::Sub - AWS CloudFormation
Use the AWS CloudFormation Fn::Sub function to substitute variables in an input string with values that you specify.