附註:
- 此教學課程需要存取 Oracle Cloud。若要註冊免費帳戶,請參閱開始使用 Oracle Cloud Infrastructure Free Tier 。
- 它使用 Oracle Cloud Infrastructure 憑證、租用戶及區間的範例值。完成實驗室時,請將這些值取代為您雲端環境特有的值。
搭配 OpenStack Swift API 使用 Oracle Cloud Infrastructure Object Storage Service
簡介
Oracle Cloud Infrastructure (OCI) Object Storage 是一種資料儲存架構,可作為物件管理及組織數位資訊,每個物件都包含資料、描述資料及唯一 ID。與傳統檔案或區塊儲存不同,OCI Object Storage 不依賴階層式結構,因此能夠有效率且可擴展地處理大量非結構化資料。物件儲存在平面位址空間中,可簡化資料擷取,並實現無縫擴展性。此解決方案適用於多媒體內容和備份等各種資料類型,因其彈性、持久性及易於存取,使它成為雲端環境、封存儲存及分散式系統的強大選擇。使用者可透過 HTTP 協定使用 REST 介面與物件儲存服務互動。
OCI 物件儲存服務是雲端儲存解決方案,Oracle 可處理管理複雜性,確保可靠且符合成本效益的資料持久性。此平台的靈活性可讓您以無縫接軌的方式進行擴展,完全不影響效能或服務可靠性。
OCI 物件儲存透過 Amazon S3 相容 API 與 OpenStack Swift API 和 Amazon Simple Storage Service (Amazon S3) 相容。這可讓客戶繼續使用現有的工具 (例如 SDK 從屬端),將對其應用程式進行變更的需求降到最低。如需詳細資訊,請參閱 Amazon S3 Compatibility API 。本教學課程將著重於 OCI OpenStack Swift 相容的 API 使用量。
開始討論 OpenStack Swift API 之前,我們需要釐清 OCI 物件儲存中使用的部分建構。
-
命名空間主要用於為儲存桶和物件提供 OCI 區域層級的帳戶層級隔離。建立 Oracle Cloud Infrastructure 租用戶帳戶後,系統會指定一個唯一且不可變的 OCI 物件儲存命名空間名稱。這些命名空間會延伸至租用戶內的所有區間,且在所有區域都保持不變。
-
儲存桶是儲存物件的邏輯容器。儲存桶是區域層次的資源。
-
物件:任何類型的資料 (不論內容類型為何) 都會儲存為物件。一個物件是由物件本身與物件的描述資料所組成。每個物件都儲存在儲存桶中。
-
區間是用來組織雲端資源的邏輯建構。OCI 物件儲存的儲存桶只能存在於一個區間中。每個區間都會套用控制物件儲存資源存取的 Oracle Cloud Infrastructure Identity and Access Management (OCI IAM) 原則。
OpenStack Swift 定義三個建構:「帳戶」、「容器」和「物件」。
-
帳戶代表階層的最上層,而且與專案或租用戶同義。
-
容器是用來作為物件的命名空間。
我們現在可以識別 OCI 物件儲存與 OpenStack Swift API 之間的等效資源。
- OCI 物件儲存命名空間等同於 Swift 帳戶。
- OCI Object Storage bucket 等同於 Swift 容器。
- OCI 物件儲存物件等同於 Swift 物件。
目標
- 說明將 OCI 物件儲存服務與 OpenStack Swift 相容 API 搭配使用的各種方式。
必要條件
-
產生 OCI 認證權杖: OCI Swift API 的使用需要使用 OCI 認證權杖進行認證。如需詳細資訊,請參閱建立認證權杖。
-
建立原則以授予使用者使用 OCI 物件儲存服務的存取權。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 相容 API 或 OCI Swift API 建立的儲存設定,會建立在 Oracle Cloud Infrastructure 租用戶的根隔間中。您可以為 OCI Amazon S3 相容 API 或 OCI Swift API 指定其他區間,以建立儲存桶。如需詳細資訊,請參閱編輯租用戶的 Amazon S3 相容性 API 和 Swift API 區間指定項目。
OCI Swift API 支援三種驗證要求的方法。
方法 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 認證的權杖型驗證
您必須呼叫該區域的 OCI Swift API 授權端點,並在要求中包含 X-Storage-User
和 X-Storage-Pass
標頭。如果認證要求成功,您將會收到含有可用於要求授權之 X-Storage-Token
標頭的回應,以及帳戶之 OCI Swift API 端點的 X-Storage-Url
標頭。
X-Storage-User
標頭的格式為 <tenancy-namespace>:<username>
。
例如,如果 tenancy-namespace
為 axaxnpcrorw5
,且使用者名稱與「方法 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)
-
列出帳戶中的儲存桶,只會列出來自所選 OCI Swift API 區間的儲存桶。
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 認證的權杖型驗證
為了說明 OCI Swift API v2 授權程序,我們將使用官方 OpenStack Swift API Python 套裝軟體 python-swiftclient 4.5.0 ,以及 v2 認證 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
F95070-01
March 2024