ノート:
- このチュートリアルでは、Oracle Cloudへのアクセスが必要です。無料アカウントにサインアップするには、Oracle Cloud Infrastructure Free Tierの開始を参照してください。
- Oracle Cloud Infrastructureの資格証明、テナンシおよびコンパートメントに例の値を使用します。演習を終える際は、これらの値をクラウド環境に固有の値に置き換えてください。
Use Oracle Cloud Infrastructure Object Storage Service with OpenStack Swift API
イントロダクション
Oracle Cloud Infrastructure (OCI) Object Storageは、デジタル情報をオブジェクトとして管理および編成するデータ・ストレージ・アーキテクチャであり、それぞれがデータ、メタデータおよび一意の識別子で構成されます。従来のファイルまたはブロック・ストレージとは異なり、OCI Object Storageは階層構造に依存せず、膨大な量の非構造化データを効率的かつスケーラブルに処理できます。オブジェクトはフラットなアドレス空間に格納されるため、データの取得が簡素化され、シームレスなスケーラビリティが可能になります。このソリューションは、マルチメディアのコンテンツやバックアップなどの多様なデータ型に最適であり、柔軟性、耐久性、アクセスのしやすさにより、クラウド環境、アーカイブ・ストレージ、分散システムに対して堅牢な選択肢となります。ユーザーは、HTTPプロトコルを介してRESTインタフェースを使用してオブジェクト・ストレージ・サービスと対話します。
OCI Object Storageサービスは、Oracleが管理の複雑さを処理し、信頼性とコスト効率の高いデータ耐久性を保証するクラウドベースのストレージ・ソリューションです。プラットフォームの弾力性により、パフォーマンスやサービスの信頼性を損なうことなく、シームレスに拡張できるため、段階的に開始できます。
OCI Object Storageは、Amazon S3 Compatibility APIを通じて、OpenStack Swift APIおよびAmazon Simple Storage Service (Amazon S3)とのAPI互換性を提供します。これにより、お客様は既存のツール(SDKクライアントなど)を引き続き使用できるため、アプリケーションに変更を加える必要が最小限に抑えられます。詳細は、Amazon S3 Compatibility APIを参照してください。このチュートリアルでは、OCI OpenStack Swift互換APIの消費に焦点を当てます。
OpenStack Swift APIについて説明する前に、OCI Object Storageで使用される構成の一部を明確にする必要があります。
-
ネームスペースは、バケットとオブジェクトの両方のOCIリージョン・レベルでアカウント・レベルの分離を実現するために使用されます。Oracle Cloud Infrastructureテナント・アカウントを作成すると、一意で変更できないOCI Object Storageネームスペース名が割り当てられます。これらのネームスペースは、テナンシ内のすべてのコンパートメントにわたって拡張され、すべてのリージョンで同じままになります。
-
バケットは、オブジェクトを格納するための論理コンテナです。バケットはリージョン・レベルのリソースです。
-
オブジェクト:コンテンツ・タイプに関係なく、あらゆるタイプのデータがオブジェクトとして格納されます。オブジェクトは、オブジェクト自体と、そのオブジェクトに関するメタデータで構成されます。各オブジェクトはバケットに格納されます。
-
コンパートメントは、クラウド・リソースの編成に使用される論理構成です。OCIオブジェクト・ストレージ・バケットが存在できるのは1つのコンパートメントのみです。オブジェクト・ストレージ・リソースへのアクセスを制御するOracle Cloud Infrastructure Identity and Access Management (OCI IAM)ポリシーは、コンパートメントごとに適用されます。
OpenStack Swiftでは、アカウント、コンテナおよびオブジェクトの3つの構成を定義します。
-
「アカウント」は階層の最上位レベルを表し、プロジェクトまたはテナントと同義です。
-
containerは、objectsの名前空間として使用されます。
OCI Object StorageとOpenStack Swift APIの間で同等のリソースを識別できるようになりました。
- OCIオブジェクト・ストレージのネームスペースは、Swiftアカウントと同じです。
- OCIオブジェクト・ストレージのバケットは、Swiftのコンテナと同じです。
- OCI Object Storageのオブジェクトは、Swiftのオブジェクトと同等です。
目的
- OCI Object StorageサービスをOpenStack Swift互換APIとともに使用する様々な方法を説明します。
前提条件
-
OCI認証トークンの生成: OCI Swift APIの消費には、OCI認証トークンを使用した認証が必要です。詳細は、「認証トークンの作成」を参照してください。
-
OCI Object Storageサービスを使用するアクセス権をユーザーに付与するポリシーを作成します。Oracle Cloud Infrastructure Identity and Access Management (OCI IAM)ポリシーは、コンパートメント内のオブジェクト・ファミリ・リソースを管理するためのユーザー・アクセスを許可します。OCIリソースはコンパートメントに編成され、リソースへのアクセスはコンパートメントに定義されたポリシーによって管理されます。このチュートリアルでは、次のポリシーを作成する必要があります。
allow group <group-name> to manage object-family in tenancy
.
OCI Swift APIの使用
OCI Swift APIのリージョン・エンドポイントでは、一貫性のあるURL形式https://swiftobjectstorage.<region-identifier>.oraclecloud.com
が使用されます。たとえば、米国東部リージョン(US-ashburn-1)のネイティブOCI Swift APIエンドポイントは、https://swiftobjectstorage.US-ashburn-1.oraclecloud.com
です。
リージョン・レベルでのテナント・レベルの分離を考慮すると、OCI Swift APIエンドポイントはhttps://swiftobjectstorage.<region-identifier>.oraclecloud.com/<tenancy-namespace>
になります。ここで、<tenancy-namespace>
は、リポジトリを作成するテナンシの自動生成されたオブジェクト・ストレージ・ネームスペース文字列です。詳細は、テナンシ情報ページを参照してください。
OCI Swift APIには、コンパートメントの概念がありません。デフォルトでは、OCI Amazon S3 Compatibility APIまたはOCI Swift APIを使用して作成されたバケットは、Oracle Cloud Infrastructureテナンシのルート・コンパートメントに作成されます。OCI Amazon S3 Compatibility APIまたはOCI Swift APIに異なるコンパートメントを指定して、バケットを作成できます。詳細は、テナンシのAmazon S3 Compatibility APIおよびSwift APIコンパートメント指定の編集を参照してください。
OCI Swift APIは、リクエストを認証するための3つのアプローチをサポートしています。
アプローチ1: 基本認証ヘッダーの使用
ユーザー名の形式は<username>
です。たとえば、john.doe@acme.com
です。テナントがOracle Identity Cloud Serviceとフェデレートされている場合は、oracleidentitycloudservice/<username>
の書式を使用します。
パスワードは、ユーザーに対して生成された認証トークンです。たとえば、my-auth-token
です。詳細は、認証トークンの取得を参照してください。
OCI Swift APIへの各リクエストには、次のヘッダーを含める必要があります。
- 認可:
Basic <base64(username:password)>
。
たとえば、ユーザー名がoracleidentitycloudservice/john.doe@acme.com
で、パスワードがmy-auth-token
の場合、ヘッダーは次のようになります。
- 認可:
Basic b3JhY2xlaWRlbnRpdHljbG91ZHNlcnZpY2Uvam9obi5kb2VAYWNtZS5jb206b ktYXV0aC10b2tlbg==
。
公式ドキュメントに記載されているAPIコールの一部を使用します(OpenStack Swift APIを参照)。
例:
-
次の必須の環境変数を初期化します。
user='<username>' password='<password>' region='<oci-region>' tenancy_namespace='<tenancy-namespace>' bucket_name='tutorial-bucket' object_name='sample.txt'
-
アカウント内のバケットをリストします。選択したOCI Swift APIコンパートメントのバケットのみがリストされます。
curl -sS -D /dev/stderr "https://swiftobjectstorage.${region}.oraclecloud.com/v1/${tenancy_namespace}" -u "${user}:${password}" | jq
-
バケットの作成
curl -sS -i "https://swiftobjectstorage.${region}.oraclecloud.com/v1/${tenancy_namespace}/${bucket_name}" -X PUT -u "${user}:${password}"
-
ファイルをバケットにアップロードします。
echo 'sample file' > ${object_name} curl -s -i "https://swiftobjectstorage.${region}.oraclecloud.com/v1/${tenancy_namespace}/${bucket_name}/${object_name}" -X PUT --data-binary "@${object_name}" -u "${user}:${password}"
-
バケット・コンテンツを一覧表示します。
curl -sS -D /dev/stderr "https://swiftobjectstorage.${region}.oraclecloud.com/v1/${tenancy_namespace}/${bucket_name}" -u "${user}:${password}" | jq
-
バケットからファイルをフェッチします。
curl -s -D /dev/stderr "https://swiftobjectstorage.${region}.oraclecloud.com/v1/${tenancy_namespace}/${bucket_name}/${object_name}" -u "${user}:${password}" -o downloaded_file.txt cat downloaded_file.txt
-
バケットからファイルを削除します。
curl -sS -i "https://swiftobjectstorage.${region}.oraclecloud.com/v1/${tenancy_namespace}/${bucket_name}/${object_name}" -X DELETE -u "${user}:${password}"
-
バケットを削除します。
curl -s -i "https://swiftobjectstorage.${region}.oraclecloud.com/v1/${tenancy_namespace}/${bucket_name}" -X DELETE -u "${user}:${password}"
アプローチ2: v1認証を使用したトークン・ベース認証
You will have to call the OCI Swift API authorization endpoint for the region and include the X-Storage-User
and X-Storage-Pass
headers in the request. If the authentication request is successful, you will receive a response with X-Storage-Token
header that can be used for request authorization, and X-Storage-Url
header with the OCI Swift API endpoint for the account.
X-Storage-User
ヘッダーの形式は<tenancy-namespace>:<username>
です。
たとえば、tenancy-namespace
がaxaxnpcrorw5
で、ユーザー名がApproach 1と同じ場合、ヘッダーの値はaxaxnpcrorw5:oracleidentitycloudservice/john.doe@acme.com
です。
X-Storage-Pass
は、生成された認証トークンです。
例:
-
次の必須の環境変数を初期化します。
user='<username>' password='<password>' region='<oci-region>' tenancy_namespace='<tenancy-namespace>' bucket_name='tutorial-bucket' object_name='sample.txt'
-
トークンを生成します。
curl -sS -D swift_headers.txt https://swiftobjectstorage.eu-frankfurt-1.oraclecloud.com/auth/v1.0 -H "X-Storage-User: ${tenancy_namespace}:${user}" -H "X-Storage-Pass: ${password}" X_Auth_Token=$(cat swift_headers.txt | grep X-Auth-Token | cut -d":" -f 2)
-
List buckets in the account, only buckets from the selected OCI Swift API compartments will be listed.
curl -s -D /dev/stderr "https://swiftobjectstorage.${region}.oraclecloud.com/v1/${tenancy_namespace}" -H "X-Auth-Token: ${X_Auth_Token}" | jq
-
バケットの作成
curl -s -i "https://swiftobjectstorage.${region}.oraclecloud.com/v1/${tenancy_namespace}/${bucket_name}" -X PUT -H "X-Auth-Token: ${X_Auth_Token}"
-
ファイルをバケットにアップロードします。
echo 'sample file' > ${object_name} curl -s -i "https://swiftobjectstorage.${region}.oraclecloud.com/v1/${tenancy_namespace}/${bucket_name}/${object_name}" -X PUT --data-binary "@${object_name}" -H "X-Auth-Token: ${X_Auth_Token}"
-
バケット・コンテンツを一覧表示します。
curl -s -D /dev/stderr "https://swiftobjectstorage.${region}.oraclecloud.com/v1/${tenancy_namespace}/${bucket_name}" -H "X-Auth-Token: ${X_Auth_Token}" | jq
-
バケットからファイルをフェッチします。
curl -s -D /dev/stderr "https://swiftobjectstorage.${region}.oraclecloud.com/v1/${tenancy_namespace}/${bucket_name}/${object_name}" -H "X-Auth-Token: ${X_Auth_Token}" -o downloaded_file.txt cat downloaded_file.txt
-
バケットからファイルを削除します。
curl -s -i "https://swiftobjectstorage.${region}.oraclecloud.com/v1/${tenancy_namespace}/${bucket_name}/${object_name}" -X DELETE -H "X-Auth-Token: ${X_Auth_Token}"
-
バケットを削除します。
curl -s -i "https://swiftobjectstorage.${region}.oraclecloud.com/v1/${tenancy_namespace}/${bucket_name}" -X DELETE -H "X-Auth-Token: ${X_Auth_Token}"
アプローチ3: v2認証を使用したトークン・ベース認証
To illustrate the OCI Swift API v2 authorization procedure, we will use the official OpenStack Swift API Python package python-swiftclient 4.5.0, and the required dependencies for the v2 auth python-keystoneclient 5.4.0.
例:
-
次のコマンドを実行して、
3.6
より上のPythonバージョンにアクセスできることを確認します。詳細は、Pythonのダウンロードを参照してください。python3 --version
-
必要なPythonモジュールをインストールします。
python3 -m pip install python-swiftclient python-keystoneclient click
-
次のコードを使用して、OCI Swift API v2と対話できます。実行する前に、次のコードの
<user>
、<password>
、<region>
および<tenancy-namespace>
のプレースホルダを必ず置き換えてください。import click import os from swiftclient.client import Connection from swiftclient.exceptions import ClientException user='<username>' password='<password>' region='<oci-region>' tenancy_namespace='<tenancy-namespace>' bucket_name='tutorial-bucket' object_name='sample.txt' _authurl = f'https://swiftobjectstorage.{region}.oraclecloud.com/auth/v2.0/' _auth_version = '2' _user = f'{user}' _key = f'{password}' _tenant_name = f'{tenancy_namespace}' conn = Connection( authurl=_authurl, user=_user, key=_key, tenant_name=_tenant_name, auth_version=_auth_version ) @click.group(invoke_without_command=True) @click.pass_context def main(ctx): available_commands = { "a": ("List buckets in the account", get_account), "b": ("Create a new bucket", put_container), "c": ("Upload an object to the bucket", put_object), "d": ("List objects in the bucket", get_container), "e": ("Download object from the bucket", get_object), "f": ("Delete object from the bucket", delete_object), "g": ("Delete bucket from the account", delete_container) } while True: click.echo("Available actions") for index, command in available_commands.items(): click.echo(f"{index} - {command[0]}") action = click.prompt("Please select an option from the list") if action in available_commands.keys(): ctx.invoke(available_commands[action][1]) print("###"*10) @main.command() def get_account(conn=conn): print("Listing buckets in the account.") try: resp_headers = conn.get_account() for entry in resp_headers[1]: print(entry["name"]) except ClientException as e: print(f"Failed to get the buckets in the tenancy. Error: {e}") raise else: print(f"Successfuly listed bucket in the '{_tenant_name}' account.") @main.command() def put_container(conn=conn, bucket_name=bucket_name): print(f"Creating a new bucket named {bucket_name}.") try: resp_headers = conn.put_container(container=bucket_name) except ClientException as e: print(f"Failed to create the new bucket named {bucket_name} in the tenancy. Error: {e}") raise else: print(f"The '{bucket_name}' was successfuly created.") @main.command() def put_object(conn=conn, bucket_name=bucket_name, object_name=object_name): print(f"Uploading a new file, '{object_name}' to the new bucket '{bucket_name}'.") try: if not os.path.isfile(object_name): with open(object_name, "w") as f: f.write("sample file") with open(object_name) as f: resp_headers = conn.put_object(container=bucket_name, obj=object_name, contents=object_name) except ClientException as e: print(f"Failed to create a new object named '{object_name}' in the bucket '{bucket_name}'. Error: {e}") raise else: print(f"The '{object_name}' file was successfuly uploaded to '{bucket_name}' bucket.") @main.command() def get_container(conn=conn, bucket_name=bucket_name): print(f"List {bucket_name} bucket contents.") try: resp_headers = conn.get_container(container=bucket_name) for entry in resp_headers[1]: print(entry["name"]) except ClientException as e: print(f"Failed to list objects in the bucket {bucket_name}. Error: {e}") raise else: print(f"The '{bucket_name}' content was successfuly listed.") @main.command() def get_object(conn=conn, bucket_name=bucket_name, object_name=object_name, dest_file="downloaded_file.txt"): print(f"Fetch {object_name} object from the bucket {bucket_name}.") try: resp_headers = conn.get_object(container=bucket_name, obj=object_name) with open(dest_file, "wb") as f: f.write(resp_headers[1]) except ClientException as e: print(f"Failed to download {object_name} from {bucket_name} to local file named '{dest_file}'. Error: {e}") raise else: print(f"The '{object_name}' object was saved locally to '{dest_file}'.") @main.command() def delete_object(conn=conn, bucket_name=bucket_name, object_name=object_name): print(f"Deleting {object_name} object from the bucket {bucket_name}.") try: resp_headers = conn.delete_object(container=bucket_name, obj=object_name) except ClientException as e: print(f"Failed to delete {object_name} from {bucket_name}. Error: {e}") raise else: print(f"The '{object_name}' object was deleted.") @main.command() def delete_container(conn=conn, bucket_name=bucket_name): print(f"Deleting the bucket {bucket_name}.") try: resp_headers = conn.delete_container(container=bucket_name) except ClientException as e: print(f"Failed to delete {object_name} from {bucket_name}. Error: {e}") raise else: print(f"The '{bucket_name}' bucket was deleted.") if __name__ == "__main__": main()
関連リンク
承認
- 著者 - Andrei Ilas (プリンシパル・クラウド・アーキテクト)
その他の学習リソース
docs.oracle.com/learnの他のラボをご覧いただくか、Oracle Learning YouTubeチャネルで無料のラーニング・コンテンツにアクセスしてください。また、education.oracle.com/learning-explorerにアクセスして、Oracle Learning Explorerになります。
製品ドキュメントは、Oracle Help Centerを参照してください。
Use Oracle Cloud Infrastructure Object Storage Service with OpenStack Swift API
F95066-01
March 2024