繁体   English   中英

使用 Boto3 S3 资源时 S3 Ninja 端点抛出无法连接错误

[英]S3 Ninja endpoint throws could not connect error when using Boto3 S3 resource

我正在尝试在 Python 中将S3 Ninjaboto3一起使用,但尽管 docker 容器正在运行,但我无法将 S3 客户端配置为使用 S3 Ninja。

尝试使用boto3.session.Session().client().get_object()获取对象时,我的尝试导致以下错误。

s3 = S3()
content = s3.get('mybucket', 'myobject')

botocore.exceptions.EndpointConnectionError:无法连接到端点 URL:“http://localhost:9444/mybucket/myobject.json”

使用curl http://localhost:9444/mybucket/myfile.json按预期返回文件,因此 S3 Ninja 似乎正在工作。 但是,S3 客户端由于某种原因找不到它。

我已经为端点 URL 尝试了以下两个值。

  • http://localhost:9444
  • http://localhost:9444/s3
class S3:

    client: boto3.client

    def __init__(self) -> None:
        local = os.environ.get('LOCAL')
        if local == 'true':
            self.client = boto3.session.Session().client(
                service_name='s3',
                aws_access_key_id='my_access_key',
                aws_secret_access_key='my_secret_key',
                endpoint_url='http://localhost:9444',
                config=botocore.client.Config(
                    s3={
                        'addressing_style': 'path'
                    }
                )
            )
        else:
            self.client = boto3.client('s3')

    def get(self, bucket_name: str, key: str) -> str:
        response = self.client.get_object(
            Bucket=bucket_name,
            Key=key)
        return response['Body'].read().decode('utf-8')

有什么问题?

这是一个令人沮丧的问题,一段时间后我发现这是由于我使用了 Lambda 函数造成的。

我的问题中的代码是 Lambda 函数的一部分。 函数和 API 使用sam local start-api在本地运行,任何调用实际上都在 docker 容器中运行。 所以这个问题是 Lambda 容器无法与本地主机上的 S3 Ninja 对话,因为它没有在本地主机上运行。

这里的简单修复是针对默认 docker 网络(网桥)的 IP, 172.17.0.1 ,而不是 localhost。

class S3:

    client: boto3.client

    def __init__(self) -> None:

        local = Environment.local == 'true'

        if local:
            logger.info('Using S3 Ninja to emulate the S3 API.')
            self.client = boto3.client(
                service_name='s3',
                aws_access_key_id='AKIAIOSFODNN7EXAMPLE',
                aws_secret_access_key='wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY',
                endpoint_url='http://172.17.0.1:9444/s3/'
            )
        else:
            self.client = boto3.client('s3')

也可以在单独的 docker 网络上运行 S3 Ninja,然后在同一网络上启动本地 API。 我不确定为什么需要这样做,但认为值得一提。

docker network create lambda-local
docker network inspect lambda-local # Record the gateway IP address.
docker run --name s3ninja --network lambda-local -d -p 9444:9000 scireum/s3-ninja:latest
sam local start-api --docker-network lambda-local
# Make sure to use the gateway IP address discovered using 'docker network inspect'.
endpoint_url='http://172.20.0.1:9444/s3/'

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM