#amazon-web-services #amazon-cloudformation #amazon-ecs #aws-fargate
Вопрос:
Я провел весь день, пытаясь развернуть образ в Fargate, но постоянно сталкиваюсь со следующей ошибкой:
ResourceInitializationError: не удалось извлечь секреты или реестр аутентификация: ошибка команды извлечения: : сигнал: убит
Я использую следующий шаблон cloudformation (сокращенный):
Parameters:
VPC:
Type: AWS::EC2::VPC::Id
Description: VPC Id. VPC's private subnets must have a NAT Gateway to download container image.
PublicSubnets:
Description: Choose which public subnets the Load Balancer and ECS Service should be deployed to
Type: List<AWS::EC2::Subnet::Id>
IamCertificateArn:
Type: String
Description: The IAM Certificate Arn, which must exist in the same region
Image:
Type: String
Description: Docker image. You can use images in the Docker Hub registry or specify other repositories (repository-url/image:tag).
ContainerPort:
Type: Number
Description: Port on which the application listens within the docker container
Default: 80
LoadBalancerPort:
Type: Number
Default: 443
RDSSecurityGroupId:
Type: AWS::EC2::SecurityGroup::Id
Description: Security Group of the RDS Instance
HealthCheckPath:
Type: String
Description: The health check path starting with / e.g. /health
HostedZoneName:
Type: String
Description: Domain name for your website (example.com.). Note it must end in a .
HostedZoneID:
Type: String
Description: Hosted Zone Id
Resources:
TaskDefinition:
Type: AWS::ECS::TaskDefinition
DependsOn:
- LogGroup
- TaskExecutionRole
Properties:
Family: !Join ["", [!Ref "AWS::StackName", TaskDefinition]]
NetworkMode: awsvpc
RequiresCompatibilities:
- FARGATE
Cpu: 512
Memory: 1GB
ExecutionRoleArn: !Ref TaskExecutionRole
TaskRoleArn: !Ref TaskExecutionRole
ContainerDefinitions:
- Name: !Ref "AWS::StackName"
Image: !Ref Image
PortMappings:
- ContainerPort: !Ref ContainerPort
LogConfiguration:
LogDriver: awslogs
Options:
awslogs-region: !Ref AWS::Region
awslogs-group: !Ref LogGroup
awslogs-stream-prefix:
!Join ["", [!Ref "AWS::StackName", -ecs-app]]
Command: ["./app -f config.toml"]
Cluster:
Type: AWS::ECS::Cluster
Properties:
ClusterName: !Join ["", [!Ref "AWS::StackName", "-", "Cluster"]]
Service:
Type: AWS::ECS::Service
DependsOn:
- ListenerHTTPS
Properties:
ServiceName: !Join ["", [!Ref "AWS::StackName", "-", "Service"]]
Cluster: !Ref Cluster
TaskDefinition: !Ref TaskDefinition
DeploymentConfiguration:
MinimumHealthyPercent: 100
MaximumPercent: 200
DesiredCount: 1
HealthCheckGracePeriodSeconds: 30
LaunchType: FARGATE
NetworkConfiguration:
AwsvpcConfiguration:
AssignPublicIp: ENABLED
Subnets: !Ref PublicSubnets
SecurityGroups:
- !Ref ContainerSecurityGroup
LoadBalancers:
- ContainerName: !Ref AWS::StackName
ContainerPort: !Ref ContainerPort
TargetGroupArn: !Ref TargetGroup
# API Load Balancer
TargetGroup:
Type: AWS::ElasticLoadBalancingV2::TargetGroup
Properties:
HealthCheckIntervalSeconds: 30
HealthCheckPath: !Ref HealthCheckPath
HealthCheckTimeoutSeconds: 10
UnhealthyThresholdCount: 2
HealthyThresholdCount: 2
Name: !Join ["", [!Ref AWS::StackName, "-", "TrgtGrp"]]
Port: !Ref ContainerPort
Protocol: HTTP
TargetGroupAttributes:
- Key: deregistration_delay.timeout_seconds
Value: 60 # default is 300
TargetType: ip
VpcId: !Ref VPC
LoadBalancer:
Type: AWS::ElasticLoadBalancingV2::LoadBalancer
Properties:
Name: !Join ["", [!Ref AWS::StackName, "-", "ELB"]]
Scheme: internet-facing
SecurityGroups:
- !Ref LoadBalancerSecurityGroup
Subnets: !Ref PublicSubnets
ListenerHTTPS:
Type: AWS::ElasticLoadBalancingV2::Listener
Properties:
DefaultActions:
- TargetGroupArn: !Ref TargetGroup
Type: forward
LoadBalancerArn: !Ref LoadBalancer
Port: !Ref LoadBalancerPort
Protocol: HTTPS
Certificates:
- CertificateArn: !Ref IamCertificateArn
TaskExecutionRole:
Type: 'AWS::IAM::Role'
Properties:
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Principal:
Service:
- ec2.amazonaws.com
- ecs.amazonaws.com
- ecs-tasks.amazonaws.com
Action:
- 'sts:AssumeRole'
Policies:
- PolicyDocument: {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:GetObject"
],
"Resource": [
"arn:aws:s3:::config.toml"
]
}
]
}
PolicyName: !Join ["", [!Ref "AWS::StackName", "-", "DownloadConfigFromS3Policy"]]
- PolicyDocument: {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ecr:GetAuthorizationToken",
"ecr:BatchCheckLayerAvailability",
"cr:GetDownloadUrlForLayer",
"ecr:BatchGetImage"
],
"Resource": "*"
}
]
}
PolicyName: !Join ["", [!Ref "AWS::StackName", "-", "PullImagePolicy"]]
ManagedPolicyArns:
- arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy
- arn:aws:iam::aws:policy/service-role/AmazonEC2ContainerServiceforEC2Role
VPCEndpointECRAPI:
Type: AWS::EC2::VPCEndpoint
Properties:
VpcEndpointType: Interface
SecurityGroupIds:
- !Ref PrivateLinkSecurityGroup
ServiceName: !Join ["", ["com.amazonaws.", !Ref "AWS::Region", ".ecr.api"]]
SubnetIds: !Ref PublicSubnets
VpcId: !Ref VPC
VPCEndpointECRDKR:
Type: AWS::EC2::VPCEndpoint
Properties:
VpcEndpointType: Interface
SecurityGroupIds:
- !Ref PrivateLinkSecurityGroup
ServiceName: !Join ["", ["com.amazonaws.", !Ref "AWS::Region", ".ecr.dkr"]]
SubnetIds: !Ref PublicSubnets
VpcId: !Ref VPC
VPCEndpointLogs:
Type: AWS::EC2::VPCEndpoint
Properties:
VpcEndpointType: Interface
SecurityGroupIds:
- !Ref PrivateLinkSecurityGroup
ServiceName: !Join ["", ["com.amazonaws.", !Ref "AWS::Region", ".logs"]]
SubnetIds: !Ref PublicSubnets
VpcId: !Ref VPC
VPCEndpointS3:
Type: AWS::EC2::VPCEndpoint
Properties:
VpcEndpointType: Interface
SecurityGroupIds:
- !Ref PrivateLinkSecurityGroup
ServiceName: !Join ["", ["com.amazonaws.", !Ref "AWS::Region", ".s3"]]
SubnetIds: !Ref PublicSubnets
VpcId: !Ref VPC
VPCEndpointSSM:
Type: AWS::EC2::VPCEndpoint
Properties:
VpcEndpointType: Interface
SecurityGroupIds:
- !Ref PrivateLinkSecurityGroup
ServiceName: !Join ["", ["com.amazonaws.", !Ref "AWS::Region", ".ssm"]]
SubnetIds: !Ref PublicSubnets
VpcId: !Ref VPC
# Security Groups
LoadBalancerSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Load balancer security group
GroupName: !Join ["", [!Ref "AWS::StackName", "-", "LoadBalancerSecurityGroup"]]
Tags:
- Key: ProjectName
Value: !Ref "AWS::StackName"
VpcId: !Ref VPC
LoadBalancerInboundRuleHTTP:
Type: AWS::EC2::SecurityGroupIngress
Properties:
GroupId: !Ref LoadBalancerSecurityGroup
IpProtocol: tcp
FromPort: 80
ToPort: 80
CidrIp: 0.0.0.0/0
LoadBalancerOutboundRuleHTTP:
Type: AWS::EC2::SecurityGroupEgress
Properties:
GroupId: !Ref LoadBalancerSecurityGroup
IpProtocol: tcp
FromPort: 80
ToPort: 80
CidrIp: 0.0.0.0/0
LoadBalancerInboundRuleHTTPS:
Type: AWS::EC2::SecurityGroupIngress
Properties:
GroupId: !Ref LoadBalancerSecurityGroup
IpProtocol: tcp
FromPort: 443
ToPort: 443
CidrIp: 0.0.0.0/0
LoadBalancerOutboundRuleHTTPS:
Type: AWS::EC2::SecurityGroupEgress
Properties:
GroupId: !Ref LoadBalancerSecurityGroup
IpProtocol: tcp
FromPort: 443
ToPort: 443
CidrIp: 0.0.0.0/0
LoadBalancerInboundRuleContainer:
Type: AWS::EC2::SecurityGroupIngress
Properties:
GroupId: !Ref LoadBalancerSecurityGroup
IpProtocol: tcp
FromPort: !Ref ContainerPort
ToPort: !Ref ContainerPort
SourceSecurityGroupId: !GetAtt ContainerSecurityGroup.GroupId
LoadBalancerOutboundRuleContainer:
Type: AWS::EC2::SecurityGroupEgress
Properties:
GroupId: !Ref LoadBalancerSecurityGroup
IpProtocol: tcp
FromPort: !Ref ContainerPort
ToPort: !Ref ContainerPort
DestinationSecurityGroupId: !GetAtt ContainerSecurityGroup.GroupId
ContainerSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Accepts traffic from and to load balancer
GroupName: !Join ["", [!Ref "AWS::StackName", "-", "ContainerSecurityGroup"]]
Tags:
- Key: ProjectName
Value: !Ref "AWS::StackName"
VpcId: !Ref VPC
ContainerInboundRuleHTTP:
Type: AWS::EC2::SecurityGroupIngress
Properties:
GroupId: !Ref ContainerSecurityGroup
IpProtocol: tcp
FromPort: !Ref ContainerPort
ToPort: !Ref ContainerPort
SourceSecurityGroupId: !GetAtt LoadBalancerSecurityGroup.GroupId
ContainerOutboundRuleHTTP:
Type: AWS::EC2::SecurityGroupEgress
Properties:
GroupId: !Ref ContainerSecurityGroup
IpProtocol: tcp
FromPort: !Ref ContainerPort
ToPort: !Ref ContainerPort
DestinationSecurityGroupId: !GetAtt LoadBalancerSecurityGroup.GroupId
ContainerInboundRuleRDS:
Type: AWS::EC2::SecurityGroupIngress
Properties:
GroupId: !Ref ContainerSecurityGroup
IpProtocol: tcp
FromPort: 5432
ToPort: 5432
SourceSecurityGroupId: !Ref RDSSecurityGroupId
ContainerInboundRuleRDS:
Type: AWS::EC2::SecurityGroupEgress
Properties:
GroupId: !Ref ContainerSecurityGroup
IpProtocol: tcp
FromPort: 5432
ToPort: 5432
DestinationSecurityGroupId: !Ref RDSSecurityGroupId
PrivateLinkSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupName: PrivateLink-SecurityGroup
GroupDescription: PrivateLink-SecurityGroup
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 443
ToPort: 443
CidrIp: 0.0.0.0/0 #should be cidrip of vpc
VpcId: !Ref VPC
Я рассмотрел несколько вопросов в StackOverflow и на форумах aws. Я могу подтвердить:
- у VPC включен DNS
- Назначение общедоступных IP-адресов включено на Fargate
- Частные подсети не используются
- Хранилище ECR является частным
- Я не храню никаких секретов в секретном менеджере
Я перепробовал все виды политик TaskExecutionPolicies, предоставляющих полный доступ к ECS, но все равно получаю ту же ошибку.
Честно говоря, я не знаю, что еще попробовать. Был бы очень признателен за некоторую помощь в этом вопросе.
Комментарии:
1. Ваш код неполон.
TargetGroup
иListenerHTTPS
не определены. Так что трудно строить догадки.2. @Marcin: Спасибо за ваш комментарий. Я добавил их определения к вопросу
Ответ №1:
Ваша проблема связана с неправильным ContainerSecurityGroup
. Он разрешает только исходящие подключения к вашему ALB. Таким образом, он не может получить ваши изображения. Я бы добавил следующее правило:
ContainerOutboundAll:
Type: AWS::EC2::SecurityGroupEgress
Properties:
GroupId: !Ref ContainerSecurityGroup
IpProtocol: tcp
FromPort: 0
ToPort: 65535
CidrIp: 0.0.0.0/0
Это позволит использовать весь исходящий трафик, побуждая done к ECR. Вы можете дополнительно поиграть с ним, разрешив доступ только к конечным точкам интерфейса VPC, если хотите.
Пожалуйста, обратите внимание: ContainerOutboundAll
это должно устранить вашу текущую ошибку. Ваш шаблон длинный и сложный, и у него может быть больше проблем, которые пока не очевидны. Если да, то новый вопрос был бы лучше для этих вопросов (если таковые имеются).
Комментарии:
1. Спасибо! Это решило проблему. Да, есть и другие проблемы, но я разберусь с ними или задам вопрос. Очень ценю вашу помощь 🙂
2. @W. K. S Нет проблем. Рад, что вы смогли пройти мимо текущего выпуска.