boto3 使用自定义 url 为 S3 上的有效存储桶名称提供 InvalidBucketName 错误

问题描述

我正在尝试为 S3 上的基本 get/put/delete/list 操作编写一个 python 脚本。我使用的是 cloudian S3 对象存储而不是 AWS。要设置 boto3 资源,我像这样设置端点和键 -

URL = 'http://ip:80'

s3_resource = boto3.resource ('s3',endpoint_url=URL,aws_access_key_id = ACCESS_KEY,aws_secret_access_key = SECRET_KEY,region_name='region1')

我手动创建了一些具有以下名称的测试存储桶,这些名称通过了有效的 S3 存储桶名称约束:

  • test-bucket-0
  • test-bucket-1
  • 样品桶
  • 测试桶

但是,当我尝试从 python 代码创建存储桶时,我反复收到以下错误 -

# >>> client.list_buckets()
# Traceback (most recent call last):
#   File "<stdin>",line 1,in <module>
#   File "/usr/local/lib/python3.8/site-packages/botocore/client.py",line 357,in _api_call
#     return self._make_api_call(operation_name,kwargs)
#   File "/usr/local/lib/python3.8/site-packages/botocore/client.py",line 676,in _make_api_call
#     raise error_class(parsed_response,operation_name)
# botocore.exceptions.ClientError: An error occurred (InvalidBucketName) when calling the ListBuckets operation: The specified bucket is not valid.

作为 boto3 的新手,我真的不确定 boto3 会期待什么。我尝试了各种组合来创建与 S3 服务的连接,例如使用 client 而不是 resource,但问题是一致的。

我尝试过的其他一些 S3 连接如下:

s3 = boto3.resource('s3',endpoint_url='http://10.43.235.193:80',aws_access_key_id = 'aaa',aws_secret_access_key = 'sss',config=Config(signature_version='s3v4'),region_name='region1')
conn = boto3.connect_s3(                                                                                                                                                       
    aws_access_key_id = 'aaa',host = '10.43.235.193',port = 80,is_secure = False,) 
from boto3.session import Session
session = Session(
    aws_access_key_id='aaa',aws_secret_access_key='sss',region_name='region1'
)

s3 = session.resource('s3')
client = session.client('s3',endpoint_url='http://10.43.235.193:80') # s3-region1.example.com
s3_client = boto3.client ('s3',endpoint_url=s3_endpoint,region_name='region1')

python 脚本在容器内运行,并且与运行 s3 容器的 pod 相同。因此,IP 可以从一个容器访问到另一个容器。我该如何解决这个问题?

解决方法

我的发现很奇怪。尽管 InvalidBucketName 出现错误是非常具有误导性的,我在 boto3 github 上发现了很多关于此的线程。但事实证明,大多数用户使用的是 AWS,而不是本地私有云 S3,因此并没有太大帮助。

对我来说,拥有 IP 前。创建 s3_client 时,10.50.32.5 作为配置中的 S3 端点不起作用。因此有这样的端点设置 -

s3_client = boto3.client ('s3',endpoint_url='http://10.50.32.5:80',aws_access_key_id = 'AAA',aws_secret_access_key = 'SSS',region_name='region1')

失败了。

我是如何解决这个问题的?

我在 /etc/hosts 中添加了一个 DNS 条目;即像这样的 IP 和 S3 端点 URL 的映射 -

10.50.32.5   s3-region1.example.com

然后像这样使用 boto 创建了一个 S3 客户端 -

s3_client = boto3.client ('s3',endpoint_url=s3_endpoint,aws_secret_access_key = 'BBB',region_name='region1')

它奏效了。