---
title: S3 协议接口
weight: 3
menu:
   main:
      parent: "编程接口"
summary: Ozone 支持 Amazon 的 Simple Storage Service (S3) 协议，事实上，你不需要对基于 S3 客户端和 S3 SDK 的应用做任何修改就可以在 Ozone 上使用。
---

<!---
  Licensed to the Apache Software Foundation (ASF) under one or more
  contributor license agreements.  See the NOTICE file distributed with
  this work for additional information regarding copyright ownership.
  The ASF licenses this file to You under the Apache License, Version 2.0
  (the "License"); you may not use this file except in compliance with
  the License.  You may obtain a copy of the License at

      http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
-->


Ozone 提供了兼容 S3 的 REST 接口，你可以使用任何兼容 S3 的工具来操作 Ozone 的对象存储数据。

S3 桶存放在 `/s3v` 卷下。

## 起步

S3 网关是提供兼容 S3 的 API 的独立组件，它应当和普通的 Ozone 组件分别启动。

你可以使用发行包启动一个基于 docker 的集群，其中会包括 S3 网关。

进入 `compose/ozone` 目录，启动服务：

```bash
docker-compose up -d --scale datanode=3
```

你可以通过 `http://localhost:9878` 访问 S3 网关。

## URL 规范

Ozone S3 网关既支持虚拟主机风格的 URL 作为桶地址（形如：http://bucketname.host:9878），也支持多级路径风格的 URL 作为桶地址（形如 http://host:9878/bucketname）。

默认使用多级路径风格，如果要使用虚拟主机风格的 URL，在 `ozone-site.xml` 中设置你的主域名：

```xml
<property>
   <name>ozone.s3g.domain.name</name>
   <value>s3g.internal</value>
</property>
```

## 已实现的 REST 端点

S3 网关服务的操作：

端点    | 状态      |
------------|-------------|
GET 服务 | 已实现 |

桶操作：

端点                            | 状态      | 备注
------------------------------------|-------------|---------------
GET 桶（列举对象）第二版  | 已实现 |
HEAD 桶                         | 已实现 |
DELETE 桶                       | 已实现 |
PUT 桶 (创建桶)          | 已实现 |
Delete 多个对象 (POST)      | 已实现 |

对象操作：

端点                            | 状态          | 备注 
------------------------------------|-----------------|---------------
PUT 对象                          | 已实现     |
GET 对象                          | 已实现     |
分块上传                    | 已实现     | 但不包括当前分块上传的进度
DELETE 对象                       | 已实现     |
HEAD 对象                         | 已实现      |


## 安全

如果不启用安全机制，你可以*使用***任何** AWS_ACCESS_KEY_ID 和 AWS_SECRET_ACCESS_KEY 来访问 Ozone 的 S3 服务。

在启用了安全机制的情况下，你可以通过 `ozone s3 getsecret` 命令获取 key 和 secret（需要进行 Kerberos 认证）。

```bash
kinit -kt /etc/security/keytabs/testuser.keytab testuser/scm@EXAMPLE.COM
ozone s3 getsecret
awsAccessKey=testuser/scm@EXAMPLE.COM
awsSecret=c261b6ecabf7d37d5f9ded654b1c724adac9bd9f13e247a235e567e8296d2999
```

注意：自 Ozone 1.4.0 起，使用 `getsecret` 生成的密钥**仅会显示一次**。若密钥丢失，用户必须先 `revokesecret`，再用 `getsecret` 生成新的密钥。

现在你可以使用 key 和 secret 来访问 S3 endpoint：

```bash
export AWS_ACCESS_KEY_ID=testuser/scm@EXAMPLE.COM
export AWS_SECRET_ACCESS_KEY=c261b6ecabf7d37d5f9ded654b1c724adac9bd9f13e247a235e567e8296d2999
aws s3api --endpoint http://localhost:9878 create-bucket --bucket bucket1
```

## 公开任何卷

Ozone 与 S3 相比，Ozone 在命名空间层次结构中多了一个元素：卷。默认情况下，可以使用 S3 接口访问 `/s3v` 卷的所有存储桶，但仅有 `/s3v` 卷的（Ozone）存储桶被公开。

为了使 S3 接口上的任何其他桶可用，可以创建一个“符号链接”的桶:

```bash
ozone sh volume create /s3v
ozone sh volume create /vol1

ozone sh bucket create /vol1/bucket1
ozone sh bucket link /vol1/bucket1 /s3v/common-bucket
```

本例通过 S3 接口将 `/vol1/bucket1` Ozone 桶公开为 S3 兼容的 `common-bucket`。

(注:桶链接功能的实现细节可在[设计文档]({{< ref path="design/volume-management.md" lang="en">}})中找到)

## 客户端

### AWS 命令行接口 

通过指定自定义的 --endpoint 选项，`aws` 命令行接口可以在 Ozone S3 上使用。

```bash
aws s3api --endpoint http://localhost:9878 create-bucket --bucket buckettest
```

或者

```bash
aws s3 ls --endpoint http://localhost:9878 s3://buckettest
```

