调用ssm.ap-southeast-2.amazonaws.com
时,似乎ECS API挂起。以下是挂起的调试结果
2020-06-11 22:47:10,831 - MainThread - urllib3.connectionpool - DEBUG - Starting new HTTPS connection (2): ssm.ap-southeast-2.amazonaws.com:443
在EC2实例上可以正常工作。仅在ECS任务容器内部不起作用,并且连接超时。
这可能是什么原因?
最佳答案
嗯...我认为您的容器是IMDSv2的受害者。请允许我解释。
实例元数据是有关您的实例的数据,可用于配置或管理正在运行的实例。实例元数据分为几类,例如,主机名,事件和安全组。您可以通过调用以下URL查询实例元数据:
http://169.254.169.254/latest/meta-data/
2019年11月19日,实例元数据服务的v2发布了。 EC2实例元数据服务版本2(IMDSv2)引入的功能之一是“针对开放层3防火墙和NAT保护” 1,它在包含 secret token 的低级IP数据包上将TTL(或跳数限制2)设置为1,因此数据包只能跨一台主机。 TTL为1表示实例无法将数据包转发到在ECS容器实例上运行的Docker容器,因为这将被视为另一跳。
从1:
更改的结果是,以Bridge或AWSVPC模式在ECS实例上运行的Docker容器不再能够查询元数据终结点。以下请求将超时:
$ curl -X PUT -H "x-aws-ec2-metadata-token-ttl-seconds: 120" "http://169.254.169.254/latest/api/token"
如果使用AWS CLI,则它具有IMDSv1的后备机制,但经过很长的延迟(5秒)后才变得相当不可用。
来自:https://github.com/aws/aws-sdk-js/issues/3024#issuecomment-589135606:
选项1(谨慎使用)
通过为--http-put-response-hop-limit标志指定值,可以在容器实例上使用'modify-instance-metadata-options'3 AWS CLI调用将TTL更改为更高的值。
在EC2实例上运行时,以下AWS CLI命令将值修改为“2”:
$ aws ec2 modify-instance-metadata-options --instance-id $(curl 169.254.169.254/latest/meta-data/instance-id) --http-put-response-hop-limit 2 --http-endpoint enabled
...之后,从Docker容器成功执行针对 token 端点的curl命令。
可以从Autoscaling生命周期挂钩中调用Lambda函数,以使用ModifyInstanceMetadataOptions api调用在任何启动实例上配置值“2”。另一个选择是将此命令放置在EC2实例的UserData中,以便每个实例都可以使用更新的跳数限制对其进行“自我配置”。请注意,在这种情况下,实例配置文件应具有与“ec2:ModifyInstanceMetadataOptions”权限相关联的策略,此调用才能成功。
选项2(推荐)
对于ECS,不认为从容器访问实例凭证是最佳实践,而是建议设置任务角色并使用AWS_CONTAINER_CREDENTIALS_RELATIVE_URI环境变量从ECS代理中检索容器特定的凭证,例如,使用“curl 169.254.170.2 $ AWS_CONTAINER_CREDENTIALS_RELATIVE_URI“命令,AWS CLI的最新版本默认使用此命令。
您可以在4上阅读有关任务角色凭证的更多信息。任务元数据的类似端点也可以使用5。
可以在这里找到更多讨论:
关于amazon-web-services - 调用ssm API端点时ECS容器挂起,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/62324816/