本文介绍了s3fs:如何使用 IMDS v2 在代理后面的 AWS EC2 实例上挂载 S3 存储桶的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们在将 AWS S3 存储桶(使用 s3fs v1.90)挂载到 AWS EC2 实例时遇到了一些问题:

  • 正在运行 Ubuntu 18.04
  • 需要 IMDS v2 会话令牌
  • 在代理后面

curl 库返回的 HTTP 响应代码是417 - 预期失败"(更多详细信息见下文).我在 www 上发现了一些提示,417 错误可能与我们的代理配置有关,请参阅:
HTTP POST 返回错误:417期望失败".
https://knowledge.ni.com/KnowledgeArticleDetails?id=kA00Z0000019LuWSAU

这让我相信我们的 NO_PROXY 配置没有被 s3fs 接收,但我真的不确定......

无论如何,这就是我们为了挂载存储桶所做的尝试:

sudo s3fs SOME_BUCKET ./mnt-s3/-o iam_role=SOME_ROLE,url=https://s3.eu-central-1.amazonaws.com,endpoint=eu-central-1,allow_other,uid=1000,gid=1000,mp_umask=007,use_cache=/tmp/s3foldercache,dbglevel=debug -f

这是输出:

2021-09-08T12:36:27.681Z [INF] curl.cpp:CheckIAMCredentialUpdate(1826):IAM 访问令牌刷新...2021-09-08T12:36:27.681Z [INF] curl.cpp:GetIAMCredentials(3068): [IAM 角色=SOME_ROLE]2021-09-08T12:36:27.681Z [DBG] curl_handlerpool.cpp:GetHandler(81):从池中获取处理程序:rest = 312021-09-08T12:36:27.681Z [DBG] curl.cpp:RequestPerform(2509):连接到 URL http://169.254.169.254/latest/api/token2021-09-08T12:36:27.682Z [ERR] curl.cpp:RequestPerform(2622):HTTP 响应代码 417,返回 EIO.正文:<?xml version="1.0";编码=iso-8859-1"?<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml";xml:lang="en"lang="en"><头><title>417 - 期望失败</title><身体><h1>417 - 期望失败</h1></html>2021-09-08T12:36:27.682Z [ERR] curl.cpp:GetIAMCredentials(3105):AWS IMDSv2 令牌检索失败:-52021-09-08T12:36:27.682Z [DBG] curl.cpp:RequestPerform(2509):连接到 URL http://169.254.169.254/latest/meta-data/iam/security-credentials/SOME_ROLE2021-09-08T12:36:27.684Z [ERR] curl.cpp:RequestPerform(2622):HTTP 响应代码 401,返回 EIO.正文:<?xml version="1.0";编码=iso-8859-1"?<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml";xml:lang="en"lang="en"><头><title>401 - 未经授权</title><身体><h1>401 - 未授权</h1></html>2021-09-08T12:36:27.684Z [ERR] curl.cpp:CheckIAMCredentialUpdate(1830):IAM 访问令牌刷新失败2021-09-08T12:36:27.684Z [DBG] curl_handlerpool.cpp:ReturnHandler(103):将处理程序返回到池2021-09-08T12:36:27.684Z [INF] curl_handlerpool.cpp:ReturnHandler(110):池满:销毁最旧的处理程序2021-09-08T12:36:27.685Z [CRT] s3fs.cpp:s3fs_check_service(3520):无法检查 IAM 角色名称 (SOME_ROLE).2021-09-08T12:36:27.685Z [ERR] s3fs.cpp:s3fs_exit_fuseloop(3372):由于错误而退出 FUSE 事件循环

但是,当直接运行 curl 时,我们确实会收到一个有效的 IMDS v2 令牌:

$ curl -v -X PUT -H "X-aws-ec2-metadata-token-ttl-seconds: 21600";http://169.254.169.254/latest/api/token* 尝试 169.254.169.254...* TCP_NODELAY 设置* 连接到 169.254.169.254 (169.254.169.254) 端口 80 (#0)>PUT/latest/api/token HTTP/1.1>主持人:169.254.169.254>用户代理:curl/7.58.0>接受: */*>X-aws-ec2-metadata-token-ttl-seconds:21600>* HTTP 1.0,假设在正文之后关闭<HTTP/1.0 200 正常<内容长度:56<内容类型:文本/纯文本<日期:2021 年 9 月 8 日,星期三 13:14:02 GMT<X-Aws-Ec2-Metadata-Token-Ttl-Seconds:21600<连接:关闭<服务器:EC2ws<* 关闭连接 0SOME_TOKEN

最后,这是我们的代理配置(由环境变量定义):

$ echo $HTTP_PROXY<SOME_HOST>:<SOME_PORT>$ echo $NO_PROXY169.254.169.254,*.eu-central-1.amazonaws.com

所以,我最好的猜测是 s3fs 可能会忽略 NO_PROXY 变​​量,在向本地 IP 169.254.169.254 询问新令牌时尝试使用我们的代理.

解决方案

https://github.com/s3fs-fuse/s3fs-fuse/pull/1766

We are having some trouble to mount an AWS S3 bucket (using s3fs v1.90) into an AWS EC2 instance which:

  • is running Ubuntu 18.04
  • requires IMDS v2 session tokens
  • is behind a proxy

The HTTP response code returned by the curl lib is "417 - Expectation Failed" (more details below). I found some hints on the www that the 417 error might relate to our proxy config, see:
HTTP POST Returns Error: 417 "Expectation Failed."
https://knowledge.ni.com/KnowledgeArticleDetails?id=kA00Z0000019LuWSAU

This makes me believe that our NO_PROXY config is not being picked up by s3fs, but I'm really not sure...

Anyway, this is what we've tried to do in order to mount the bucket:

sudo s3fs SOME_BUCKET ./mnt-s3/ -o iam_role=SOME_ROLE,url=https://s3.eu-central-1.amazonaws.com,endpoint=eu-central-1,allow_other,uid=1000,gid=1000,mp_umask=007,use_cache=/tmp/s3foldercache,dbglevel=debug -f

This is the output:


2021-09-08T12:36:27.681Z [INF] curl.cpp:CheckIAMCredentialUpdate(1826): IAM Access Token refreshing...
2021-09-08T12:36:27.681Z [INF]       curl.cpp:GetIAMCredentials(3068): [IAM role=SOME_ROLE]
2021-09-08T12:36:27.681Z [DBG] curl_handlerpool.cpp:GetHandler(81): Get handler from pool: rest = 31
2021-09-08T12:36:27.681Z [DBG] curl.cpp:RequestPerform(2509): connecting to URL http://169.254.169.254/latest/api/token
2021-09-08T12:36:27.682Z [ERR] curl.cpp:RequestPerform(2622): HTTP response code 417, returning EIO. Body Text: <?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
         "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
 <head>
  <title>417 - Expectation Failed</title>
 </head>
 <body>
  <h1>417 - Expectation Failed</h1>
 </body>
</html>
2021-09-08T12:36:27.682Z [ERR] curl.cpp:GetIAMCredentials(3105): AWS IMDSv2 token retrieval failed: -5
2021-09-08T12:36:27.682Z [DBG] curl.cpp:RequestPerform(2509): connecting to URL http://169.254.169.254/latest/meta-data/iam/security-credentials/SOME_ROLE
2021-09-08T12:36:27.684Z [ERR] curl.cpp:RequestPerform(2622): HTTP response code 401, returning EIO. Body Text: <?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
 <head>
  <title>401 - Unauthorized</title>
 </head>
 <body>
  <h1>401 - Unauthorized</h1>
 </body>
</html>
2021-09-08T12:36:27.684Z [ERR] curl.cpp:CheckIAMCredentialUpdate(1830): IAM Access Token refresh failed
2021-09-08T12:36:27.684Z [DBG] curl_handlerpool.cpp:ReturnHandler(103): Return handler to pool
2021-09-08T12:36:27.684Z [INF] curl_handlerpool.cpp:ReturnHandler(110): Pool full: destroy the oldest handler
2021-09-08T12:36:27.685Z [CRT] s3fs.cpp:s3fs_check_service(3520): Failed to check IAM role name(SOME_ROLE).
2021-09-08T12:36:27.685Z [ERR] s3fs.cpp:s3fs_exit_fuseloop(3372): Exiting FUSE event loop due to errors

When running curl directly, though, we do receive a valid IMDS v2 token:

$ curl -v -X PUT -H "X-aws-ec2-metadata-token-ttl-seconds: 21600" http://169.254.169.254/latest/api/token

*   Trying 169.254.169.254...
* TCP_NODELAY set
* Connected to 169.254.169.254 (169.254.169.254) port 80 (#0)
> PUT /latest/api/token HTTP/1.1
> Host: 169.254.169.254
> User-Agent: curl/7.58.0
> Accept: */*
> X-aws-ec2-metadata-token-ttl-seconds: 21600
>
* HTTP 1.0, assume close after body
< HTTP/1.0 200 OK
< Content-Length: 56
< Content-Type: text/plain
< Date: Wed, 08 Sep 2021 13:14:02 GMT
< X-Aws-Ec2-Metadata-Token-Ttl-Seconds: 21600
< Connection: close
< Server: EC2ws
<
* Closing connection 0
SOME_TOKEN

Finally, this is our proxy config (defined by environment variables):

$ echo $HTTP_PROXY
<SOME_HOST>:<SOME_PORT>

$ echo $NO_PROXY
169.254.169.254,*.eu-central-1.amazonaws.com

So, my best guess is that s3fs might be ignoring the NO_PROXY variable, trying to use our proxy when asking local IP 169.254.169.254 for a new token.

解决方案

A fix for this is being worked on in https://github.com/s3fs-fuse/s3fs-fuse/pull/1766

这篇关于s3fs:如何使用 IMDS v2 在代理后面的 AWS EC2 实例上挂载 S3 存储桶的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-15 03:28