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

boto3 gives InvalidBucketName error for valid bucket names on S3 with custom url

我正在尝试为 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 存储桶名称约束的名称:

但是,当我尝试从 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',                                                                                                                                              
    aws_secret_access_key = 'sss',                                                                                                                                       
    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,
   aws_access_key_id = 'aaa',
   aws_secret_access_key = 'sss',
   region_name='region1')

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

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

对我来说,拥有IP ex。 10.50.32.5 在创建 s3_client 时作为配置中的 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_access_key_id = 'AAA',
   aws_secret_access_key = 'BBB',
   region_name='region1')

它奏效了。