ConoHaのオブジェクトストレージを使ってみる

本記事は、[ConoHa Advent Calendar 2024](https://qiita.com/advent-calendar/2024/conoha) 15日目の記事です。

# はじめに

今年もやってきました、アドベントカレンダーの季節です。

去年からConoHaの使ってない機能とかを使う機会になってます。やったね。

ついでに、去年はChromeBookでしたが今年はWindows PCになりました。うれしい。

みんなもう美雲このはちゃんのかわいさはご存じだと思いますので省略します。記事が長くなっちゃう。

# やること
今年はオブジェクトストレージを使ってみます。

# オブジェクトストレージとは？
ConoHaさんのホームページから引用します。

> オブジェクトストレージは、大容量データを低コストで保存するのに最適なストレージです。容量無制限、データ転送料金無料で利用できるため、お客様は高品質なストレージを低価格でシンプルな価格体系で利用できます。
> 
> [オブジェクトストレージ｜レンタルサーバーならConoHa](https://www.conoha.jp/conoha/objectstorage/)

安価に大容量データを保存できるストレージってことですね

オブジェクトストレージといえば、AWSのS3とかが有名ですがS3はデータの転送料金が従量課金制となっています。(詳しくはAWSのホームページを見てください)

個人的には、転送料金が掛かっちゃうと毎月のコスト計算が大変になるので困ります。

転送料金無料なのはありがたい！



# 契約

早速契約します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/388444/49de22a1-1f4f-182f-f9b3-b771e222a137.png)

管理ページからオブジェクトストレージに行きます。

右のツールアイコンを押します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/388444/3f203c01-d41f-72f3-84cf-eebc130d4dba.png)

容量選択画面が出るので、ここでは一番最小の100GBを選びます。

料金安くてうれしいね。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/388444/e0605881-5269-2877-0278-a7a2a64a2470.png)

「0GB/100GB」となっていればOKです。

# 使ってみる
ConoHaさんは優しいので、利用ガイドを用意してくれています。

[オブジェクトストレージ](https://support.conoha.jp/vps/guide/objectstorage/)

**しかし！この利用ガイドは更新されていない**ようで、古いAPIの仕様が書かれてます。

(具体的には、Ver.2.0のものが書かれているようです。)

気をつけてください。(一敗)

最新のAPI仕様は別ページを見ましょう。

[ConoHa VPS 3.0 APIドキュメント](https://doc.conoha.jp/api-vps3/)

今回は`curl`をつかってオブジェクトストレージを使ってみます。

## API利用準備をする
オブジェクトストレージを使うには、ConoHaのAPIを利用します。

APIを利用するために必要な情報を取得します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/388444/dff9a7b0-b5d0-cc38-de8e-4637a568d46b.png)

管理画面のAPIに必要な情報があります。

APIユーザー欄にある「ユーザーID」と「パスワード」が必要です。

また、テナント情報欄にある「テナントID」も必要です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/388444/a66f3a4d-e7fd-731a-62c6-419091d5ce40.png)

そして、エンドポイントURLも入手しておきましょう。

一番上の「Identity Service」と「Object Storage Service」のURLを入手しておきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/388444/5f7da7bf-43e1-5e2a-a339-72ad32a05556.png)

## 認証トークンを生成する
リクエストは以下のようにします。

```shell
curl -v -s -XPOST \
-H "Accept: application/json" \
-d '{"auth": {"identity": {"methods": ["password"],"password":{"user":{"id": "APIユーザーID","password": "パスワード"}}},"scope": {"project":{"id": "テナントID"}}}}' \
~Identity Serviceのエンドポイント~/auth/tokens
```

POSTでやります。

ヘッダを`Accept: application/json`にします。

また、データをJSONにします。

`-d`で指定したものがJSONです。

リクエスト先は、エンドポイントでOKです。

ヘッダの`x-subject-token:`がトークンです。

トークンは毎回入力すると長くなるので、環境変数にぶち込んでおきましょう

ついでに、`Object Storage Service`のエンドポイントURLも環境変数に入れておきます。

```shell
token=~返ってきたトークン~
object_storage_service_endpoint=~Object Storage Serviceのエンドポイント~
```

## コンテナ一覧を取得する

それでは早速オブジェクトストレージにアクセスします。

リクエストは以下のようにします。

```shell
curl -s -XGET \
-H "Accept: application/json" \
-H "X-Auth-Token: $token" \
$object_storage_service_endpoint
```

レスポンスが`[]`となっていればOKです。

## コンテナを作る
早速コンテナを作ってみましょう

リクエストは以下のようにします。

```shell
curl -v -XPUT \
-H "Accept: application/json" \
-H "X-Auth-Token: $token" \
$object_storage_service_endpoint/~コンテナ名~
```

`HTTP/1.1 202 Accepted`となっていれば成功です。

先ほどのコンテナ一覧取得を使うと以下のようにレスポンスが返ってきました。

```json
[{"name":"test_container","count":0,"bytes":0}]
```

ちゃんと作られてますね。やったぜ。

## オブジェクトをアップロードする
それでは、オブジェクトをアップロードします。

つまり、ファイルをアップロードします。

テキストファイルをアップロードしてみます。

リクエストは以下のようにします。

```shell
curl -v -s -XPUT \
-H "Accept: application/json" \
-H "X-Auth-Token: $token" \
$object_storage_service_endpoint/~コンテナ名~/~ファイル名~ -d @./~アップロードするファイル~
```

`HTTP/1.1 201 Created`となっていればOKです。

これで、オブジェクトをアップロードできました。やったね。

先ほどのコンテナ一覧取得を使うと以下のようにレスポンスが返ってきました。

```json
[{"name":"test_container","count":1,"bytes":36}]
```

ちゃんとオブジェクトが作られてるっぽいですね。

## オブジェクトをダウンロード
では、先ほどアップロードしたオブジェクトをダウンロードしてみます。

リクエストは以下のようにします。

```shell
curl -XGET \
-H "Accept: application/json" \
-H "X-Auth-Token: $token" \
-H "Content-Type: ~コンテンツタイプ~" \
$object_storage_service_endpoint/~コンテナ名~/~オブジェクト名~ -O
```

ダウンロードしたファイルを確認してみます。

```shell
$ cat text_file.txt
このはちゃん清楚かわいい
```

大丈夫そうです。

## コンテナをWebで公開
では、このコンテナをWebで公開してみます。

なお、オブジェクト単位で公開は無理です。コンテナ単位となります。ご注意を。

リクエストは以下のようにします。

```shell
curl -v -XPOST \
-H "Accept: application/json" \
-H "X-Auth-Token: $token" \
-H "X-Container-Read: .r:*" \
$object_storage_service_endpoint/~コンテナ名~
```

`HTTP/1.1 204 No Content`となっていればOKです。

これでコンテナごとWebに公開しました。

それでは、アクセスしてみます。

```shell
curl $object_storage_service_endpoint/test_container/text_file.txt
```

レスポンス:

```Shell
このはちゃん清楚かわいい
```

ちゃんと見れてますね！

## 公開したコンテナを非公開にする
ちゃんと非公開にしておきましょう。

リクエストは以下のようにします。

```shell
curl -v -XPOST \
-H "Accept: application/json" \
-H "X-Auth-Token: $token" \
-H "X-Container-Read;" \
$object_storage_service_endpoint/~コンテナ名~
```

`HTTP/1.1 204 No Content`となっていればOKです。

## オブジェクトを削除
それでは、オブジェクトを削除してみます。

リクエストは以下のようにします。

```shell
curl -v -s -X DELETE \
-H "Accept: application/json" \
-H "X-Auth-Token: $token" \
$object_storage_service_endpoint/~コンテナ名~/~ファイル名~
```

`HTTP/1.1 204 No Content`となっていればOKです。

コンテナ一覧取得を使うと以下のようにレスポンスが返ってきました。

```json
[{"name":"test_container","count":0,"bytes":0}]
```

ちゃんと消えてるみたいです。

(ちなみにワイルドカードは使えません。)

## コンテナを削除
オブジェクトの次はコンテナの削除です。

リクエストは以下のようにします。

```shell
curl -v -s -X DELETE \
-H "Accept: application/json" \
-H "X-Auth-Token: $token" \
$object_storage_service_endpoint/~コンテナ名~
```

`HTTP/1.1 204 No Content`となっていればOKです。

コンテナ一覧取得を使うと以下のようにレスポンスが返ってきました。

```json
[]
```

ちゃんと消えてますね！

(ちなみに、オブジェクトが入っている場合はコンテナを削除できません。)

## 容量の大きい(5GB以上)動画をアップロードしてみる
上で紹介したAPIでは、5GB以上のファイルはアップロードできません。

そのため、DLOもしくはSLOを使用します。

ドキュメントによると、SLOはDLOに比べて完全性、信頼性が向上するらしいです。

(よくわかんない)

ドキュメントを見ると、何やらファイルを分割してアップロードして...と普通にオブジェクトをアップロードするのと比べて少々面倒なようです。

今回は、SLOの方を使ってみたいと思います。

~~頑張って探した~~5GB以上の動画ファイルをアップロードしてみようと思います。

公式ドキュメント([ラージオブジェクトアップロード（SLO）](https://doc.conoha.jp/api-vps3/object-upload_slo-v3/))に従ってやってみます。

今回は次のファイルをアップロードします。

ファイル名: `Minecraft_Rec_01.mp4`

まずは、ファイルを1GBごとに分割します。

```shell
split -b 1G Minecraft_Rec_01_mp4 segment_Minecraft_Rec_01_mp4_
```

セグメントファイルができました。

```shell
$ ls
Minecraft_Rec_01.mp4             segment_Minecraft_Rec_01_mp4_ab  segment_Minecraft_Rec_01_mp4_ad  segment_Minecraft_Rec_01_mp4_af
segment_Minecraft_Rec_01_mp4_aa  segment_Minecraft_Rec_01_mp4_ac  segment_Minecraft_Rec_01_mp4_ae
```

次に、コンテナを作ります。

```shell
curl -i -X PUT \
-H "Accept: application/json" \
-H "X-Auth-Token: $token" \
$object_storage_service_endpoint/Movies
```

次に、セグメントファイルというファイル専用のコンテナを作ります。

```shell
curl -i -X PUT \
-H "Accept: application/json" \
-H "X-Auth-Token: $token" \
$object_storage_service_endpoint/Movies_segments
```

このセグメントファイルをアップロードします。

```shell
curl -i -X PUT -H "X-Auth-Token: $token" $object_storage_service_endpoint/Movies_segments/segment_Minecraft_Rec_01_mp4_aa -T segment_Minecraft_Rec_01_mp4_aa
curl -i -X PUT -H "X-Auth-Token: $token" $object_storage_service_endpoint/Movies_segments/segment_Minecraft_Rec_01_mp4_ab -T segment_Minecraft_Rec_01_mp4_ab
curl -i -X PUT -H "X-Auth-Token: $token" $object_storage_service_endpoint/Movies_segments/segment_Minecraft_Rec_01_mp4_ac -T segment_Minecraft_Rec_01_mp4_ac
curl -i -X PUT -H "X-Auth-Token: $token" $object_storage_service_endpoint/Movies_segments/segment_Minecraft_Rec_01_mp4_ad -T segment_Minecraft_Rec_01_mp4_ad
curl -i -X PUT -H "X-Auth-Token: $token" $object_storage_service_endpoint/Movies_segments/segment_Minecraft_Rec_01_mp4_ae -T segment_Minecraft_Rec_01_mp4_ae
curl -i -X PUT -H "X-Auth-Token: $token" $object_storage_service_endpoint/Movies_segments/segment_Minecraft_Rec_01_mp4_af -T segment_Minecraft_Rec_01_mp4_af
```

このセグメントファイルは大体1つ1GBぐらいなのでちょっと時間がかかります。

(`&`使うとかシェルスクリプトにするなどすることをお勧めします。)

次に、MD5ハッシュを確認します。

```shell
md5sum segment_Minecraft_Rec_01_mp4_a*
```

```shell
$ md5sum segment_Minecraft_Rec_01_mp4_a*
e14aa0586ab60d8fb25d7cc3c6386db7  segment_Minecraft_Rec_01_mp4_aa
dd66a8de8864ff0376323d46b096a1d5  segment_Minecraft_Rec_01_mp4_ab
2f180136f5a134237ad4384e64f8bfce  segment_Minecraft_Rec_01_mp4_ac
82994d560638a3b3bdd6fa3eb9feb63c  segment_Minecraft_Rec_01_mp4_ad
bc3bf40b860a6e0cc57692ebab700591  segment_Minecraft_Rec_01_mp4_ae
8ecbb3648528fbcc728bbfe811a21298  segment_Minecraft_Rec_01_mp4_af
```

ファイルサイズも確認します。

```shell
ls -l
```

```shell
$ ls -l
total 11871696
-rwxrwxrwx 1 mendoitarou mendoitarou 6078304474 Sep  8 11:56 Minecraft_Rec_01.mp4
-rwxrwxrwx 1 mendoitarou mendoitarou 1048576000 Nov 22 22:18 segment_Minecraft_Rec_01_mp4_aa
-rwxrwxrwx 1 mendoitarou mendoitarou 1048576000 Nov 22 22:18 segment_Minecraft_Rec_01_mp4_ab
-rwxrwxrwx 1 mendoitarou mendoitarou 1048576000 Nov 22 22:19 segment_Minecraft_Rec_01_mp4_ac
-rwxrwxrwx 1 mendoitarou mendoitarou 1048576000 Nov 22 22:19 segment_Minecraft_Rec_01_mp4_ad
-rwxrwxrwx 1 mendoitarou mendoitarou 1048576000 Nov 22 22:19 segment_Minecraft_Rec_01_mp4_ae
-rwxrwxrwx 1 mendoitarou mendoitarou  835424474 Nov 22 22:19 segment_Minecraft_Rec_01_mp4_af
```

MD5ハッシュとファイルサイズから`manifest`ファイルを作成します。

ここでは、動画ファイル(mp4)をアップロードしているので`Content-Type`に`video/mp4`を指定しています。

```shell
curl -i -X PUT \
-H "Accept: application/json" \
-H "X-Auth-Token: $token" \
-H "Content-Type: video/mp4" \
-d '[{"path" : "Movies_segments/segment_Minecraft_Rec_01_mp4_aa", "etag": "e14aa0586ab60d8fb25d7cc3c6386db7", "size_bytes": 1048576000},
{"path" : "Movies_segments/segment_Minecraft_Rec_01_mp4_ab", "etag": "dd66a8de8864ff0376323d46b096a1d5", "size_bytes": 1048576000},
{"path" : "Movies_segments/segment_Minecraft_Rec_01_mp4_ac", "etag": "2f180136f5a134237ad4384e64f8bfce", "size_bytes": 1048576000},
{"path" : "Movies_segments/segment_Minecraft_Rec_01_mp4_ad", "etag": "82994d560638a3b3bdd6fa3eb9feb63c", "size_bytes": 1048576000},
{"path" : "Movies_segments/segment_Minecraft_Rec_01_mp4_ae", "etag": "bc3bf40b860a6e0cc57692ebab700591", "size_bytes": 1048576000},
{"path" : "Movies_segments/segment_Minecraft_Rec_01_mp4_af", "etag": "8ecbb3648528fbcc728bbfe811a21298", "size_bytes": 835424474}]' \
$object_storage_service_endpoint/Movies/Minecraft_Rec_01.mp4?multipart-manifest=put
```

これで、アップロード完了です。

(DLOの方はMD5ハッシュ値を検証しないようなので、信頼性が落ちるということだと思われます。)

コンテナ一覧取得を使うと以下のようにレスポンスが返ってきました。

```json
[{"name":"Movies","count":1,"bytes":786},{"name":"Movies_segments","count":6,"bytes":6078304474}]
```

ちゃんとアップロードできてそうです。

Webに公開して、ブラウザで確認してみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/388444/837eb151-dd9b-e49e-5891-8c0b4eda795a.png)

ちゃんとできました！

**ここで注意点。**

このようにして公開したファイルをWebで公開する際には`Movies`(`manifest`ファイル)と`Movies_segments`(セグメントファイル)を入れてある**2つのコンテナを公開する必要**があります。

`Movies`だけ公開してもダメです。皆さんも気を付けましょう。(1敗)

# オブジェクトストレージの解約
解約は最初の契約の手順で、容量を0GBにすることで解約可能です。

注意点ですが、オブジェクトストレージを解約するときは**オブジェクトとコンテナをすべて削除しておく必要**があります。

残ってると削除に失敗します。(一敗)

# おわりに
オブジェクトストレージ、めっちゃ楽しい。

オブジェクトストレージは大体、写真とか動画とかを置いておくところとして使われることが多いらしいです。

拡張が簡単、容量に対して安価など、多くのメリットがあります。

お金があれば、即契約したいですね。

お金があれば.....!!!(お金貯めて契約予定です。)

皆さんも、一度使ってみてはいかがでしょうか！

詳細は、ConoHaさんのホームページに丸投げしておきます()

[オブジェクトストレージ｜レンタルサーバーならConoHa](https://www.conoha.jp/conoha/objectstorage/)

それでは、皆さん！よいConoHaライフを！