AWS Batch特权模式下boto/botocore连接超时问题排查求助
看起来你碰到了AWS Batch特权模式下,boto3/botocore无法获取容器角色凭证的连接超时问题,我来帮你梳理几个可能的排查方向——毕竟你已经确认了角色权限和安全组出站规则没问题,那问题大概率出在特权模式带来的网络或容器配置变化上:
首先先把你的报错信息整理出来,方便定位:
TimeoutError: timed out The above exception was the direct cause of the following exception: urllib3.exceptions.ConnectTimeoutError: (<botocore.awsrequest.AWSHTTPConnection object at 0x7f858aa9b700>, 'Connection to 169.254.170.2 timed out. (connect timeout=2)') botocore.exceptions.ConnectTimeoutError: Connect timeout on endpoint URL: "http://169.254.170.2/v2/credentials/f379b1f3-1673-43b3-9ae7-523b2534be77" botocore.exceptions.MetadataRetrievalError: Error retrieving metadata: Received error when attempting to retrieve container metadata: Connect timeout on endpoint URL: "http://169.254.170.2/v2/credentials/f379b1f3-1673-43b3-9ae7-523b2534be77" botocore.exceptions.CredentialRetrievalError: Error when retrieving credentials from container-role: Error retrieving metadata: Received error when attempting to retrieve container metadata: Connect timeout on endpoint URL: "http://169.254.170.2/v2/credentials/f379b1f3-1673-43b3-9ae7-523b2534be77"
核心背景说明
169.254.170.2是ECS(AWS Batch基于ECS构建)的任务元数据服务V2的地址,容器内的SDK会自动访问这个地址获取角色凭证,正常情况下这个地址在容器网络内是可访问的。
排查方向
网络模式冲突问题:
检查你的Batch作业定义里的网络模式,如果是host模式+特权模式,那肯定会出问题。因为host模式下容器共享主机的网络栈,而主机的元数据地址是169.254.169.254,169.254.170.2这个地址在主机网络里是不存在的,自然会超时。如果是这种情况,把网络模式改回默认的bridge即可。特权容器的网络命名空间/路由问题:
特权模式下容器可能会修改自身或主机的网络配置,你可以在作业里添加一个初始化步骤,执行以下命令测试连通性:ping 169.254.170.2 -c 3 curl http://169.254.170.2/v2/credentials/f379b1f3-1673-43b3-9ae7-523b2534be77 ip route看看能不能ping通目标地址,路由表里有没有169.254.0.0/16网段的路由(AWS链路本地地址段)。如果没有这条路由,可能是容器网络配置异常导致的。
特权容器修改主机iptables规则:
特权模式下容器拥有修改主机iptables的权限,如果你的作业里有操作iptables的脚本,可能无意中阻断了到169.254.170.2的流量。你可以登录到Batch计算节点(EC2实例),执行iptables -L -n查看主机的iptables规则,同时进入容器内部执行同样的命令,检查是否有阻断规则。计算节点的Docker配置异常:
有些自定义的Docker daemon配置会影响特权容器的网络访问,比如配置了--iptables=false或者修改了默认网桥的设置。你可以检查计算节点上的/etc/docker/daemon.json文件,看看有没有相关配置导致元数据服务访问失败。SELinux/AppArmor的限制:
虽然特权模式会绕过大部分安全限制,但部分系统的SELinux或AppArmor可能仍会限制容器对某些网络资源的访问。你可以临时关闭计算节点的SELinux(执行setenforce 0)测试一次作业,看看是否能解决问题,如果可以,再调整SELinux规则。
备注:内容来源于stack exchange,提问作者Vincent Claes

