EC2实例UserData脚本未执行,无法从ECR拉取Docker镜像
问题诊断与解决方案
核心问题分析
EC2实例UserData脚本未正常执行,cloud-init日志报ECR登录400错误及no basic auth credentials,根源通常是IAM权限不足、ECR登录命令格式错误或环境依赖缺失。
排查与修复步骤
1. 确认IAM角色权限
EC2实例必须关联具备ECR访问权限的IAM角色,至少包含以下权限:
ecr:GetAuthorizationTokenecr:BatchCheckLayerAvailabilityecr:GetDownloadUrlForLayerecr:BatchGetImage
最简方案是直接附加AWS托管策略AmazonEC2ContainerRegistryReadOnly到实例角色。
2. 修正UserData中的ECR登录命令
错误的登录命令会导致400响应,正确格式需指定区域并使用get-login-password(替代已废弃的get-login):
aws ecr get-login-password --region <你的区域> | docker login --username AWS --password-stdin <AWS账号ID>.dkr.ecr.<你的区域>.amazonaws.com
3. 确保环境依赖完整
- 确认实例预装AWS CLI:Amazon Linux 2/2023默认预装,Ubuntu/RHEL需手动安装(可在UserData中添加安装命令)
- 确保Docker服务已启动:在脚本开头加入
systemctl start docker && systemctl enable docker
修正后的Terraform示例配置
# 创建EC2访问ECR的IAM角色 resource "aws_iam_role" "ec2_ecr_access_role" { name = "ec2-ecr-access-role" assume_role_policy = jsonencode({ Version = "2012-10-17" Statement = [ { Action = "sts:AssumeRole" Effect = "Allow" Principal = { Service = "ec2.amazonaws.com" } } ] }) } # 附加ECR只读权限策略 resource "aws_iam_role_policy_attachment" "ecr_readonly_attach" { role = aws_iam_role.ec2_ecr_access_role.name policy_arn = "arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly" } # 创建实例配置文件 resource "aws_iam_instance_profile" "ec2_ecr_profile" { name = "ec2-ecr-profile" role = aws_iam_role.ec2_ecr_access_role.name } # 配置EC2启动模板(含正确的UserData) resource "aws_launch_template" "ec2_with_ecr" { name_prefix = "ec2-ecr-template" image_id = "ami-0c55b159cbfafe1f0" # 替换为对应区域的Amazon Linux 2 AMI instance_type = "t2.micro" iam_instance_profile { name = aws_iam_instance_profile.ec2_ecr_profile.name } # 编码后的UserData脚本 user_data = base64encode(<<-EOF #!/bin/bash # 启动并启用Docker服务 systemctl start docker systemctl enable docker # 配置ECR参数 AWS_REGION="us-east-1" ACCOUNT_ID="123456789012" REPO_NAME="your-image-repo" IMAGE_TAG="latest" # ECR登录 aws ecr get-login-password --region \${AWS_REGION} | docker login --username AWS --password-stdin \${ACCOUNT_ID}.dkr.ecr.\${AWS_REGION}.amazonaws.com # 拉取并运行镜像 docker pull \${ACCOUNT_ID}.dkr.ecr.\${AWS_REGION}.amazonaws.com/\${REPO_NAME}:\${IMAGE_TAG} docker run -d --name app-container \${ACCOUNT_ID}.dkr.ecr.\${AWS_REGION}.amazonaws.com/\${REPO_NAME}:\${IMAGE_TAG} EOF ) }
验证修复效果
部署完成后,登录EC2实例执行以下命令确认:
- 查看cloud-init执行日志:
cat /var/log/cloud-init-output.log - 检查Docker状态:
systemctl status docker - 验证ECR登录状态:
docker info | grep -A5 "Registry" - 查看容器运行状态:
docker ps
内容的提问来源于stack exchange,提问作者user15915737
相关产品推荐
相关产品推荐

