주:
- 이 사용지침서에서는 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는 디지털 정보를 객체로 관리하고 구성하는 데이터 스토리지 아키텍처로, 각각 데이터, 메타데이터 및 고유 식별자로 구성됩니다. 기존 파일 또는 블록 스토리지와 달리 OCI Object Storage는 계층 구조에 의존하지 않으므로 방대한 양의 비정형 데이터를 효율적이고 확장 가능한 방식으로 처리할 수 있습니다. 객체는 플랫 주소 공간에 저장되므로 데이터 검색을 단순화하고 원활한 확장이 가능합니다. 이 솔루션은 멀티미디어 컨텐츠 및 백업과 같은 다양한 데이터 유형에 이상적이므로 유연성, 내구성 및 액세스 용이성으로 인해 클라우드 환경, 아카이브 스토리지 및 분산 시스템을 위한 강력한 선택입니다. 사용자는 HTTP 프로토콜을 통해 REST 인터페이스를 사용하여 오브젝트 스토리지 서비스와 상호 작용합니다.
OCI Object Storage 서비스는 Oracle이 관리의 복잡성을 처리하여 신뢰할 수 있고 비용 효율적인 데이터 내구성을 보장하는 클라우드 기반 스토리지 솔루션입니다. 플랫폼 탄력성을 통해 성능 또는 서비스 안정성을 저하시키지 않고도 원활하게 확장할 수 있는 기능으로 점진적으로 시작할 수 있습니다.
OCI Object Storage는 Amazon S3 호환성 API를 통해 OpenStack Swift API 및 Amazon Simple Storage Service(Amazon S3)와의 API 호환성을 제공합니다. 이를 통해 고객은 기존 도구(예: SDK 클라이언트)를 계속 사용하여 애플리케이션을 변경할 필요성을 최소화할 수 있습니다. 자세한 내용은 Amazon S3 호환성 API를 참조하십시오. 이 사용지침서에서는 OCI OpenStack Swift 호환 API 사용을 중점적으로 다룹니다.
OpenStack Swift API에 대해 논의하기 전에 OCI Object Storage에서 사용되는 몇 가지 구성을 명확히 해야 합니다.
-
네임스페이스는 버킷과 객체 모두에 대해 OCI 리전 레벨에서 계정 수준 격리를 제공하기 위해 사용됩니다. Oracle Cloud Infrastructure 테넌트 계정을 생성하면 변경할 수 없는 고유 OCI Object Storage 네임스페이스 이름이 지정됩니다. 이러한 네임스페이스는 테넌시 내의 모든 구획에 걸쳐 확장되며 모든 지역에서 동일하게 유지됩니다.
-
버켓은 객체 저장을 위한 논리적 컨테이너입니다. 버킷은 지역 레벨 리소스입니다.
-
객체: 콘텐츠 유형에 관계없이 모든 데이터 유형이 객체로 저장됩니다. 객체는 객체 자체와 객체에 대한 메타데이터로 구성됩니다. 각 객체는 버킷에 저장됩니다.
-
구획은 클라우드 리소스를 구성하는 데 사용되는 논리적 구성입니다. OCI Object Storage 버킷은 하나의 구획에만 존재할 수 있습니다. 오브젝트 스토리지 리소스에 대한 액세스를 제어하는 OCI IAM(Oracle Cloud Infrastructure Identity and Access Management) 정책은 구획별로 적용됩니다.
OpenStack Swift는 계정, 컨테이너 및 객체의 세 가지 구성을 정의합니다.
-
계정은 계층의 최상위 레벨을 나타내며 프로젝트 또는 테넌트와 동의어입니다.
-
컨테이너는 객체에 대한 이름 공간으로 사용됩니다.
이제 OCI Object Storage와 OpenStack Swift API 간에 동등한 리소스를 식별할 수 있습니다.
- OCI Object Storage 이름 공간은 Swift 계정과 동일합니다.
- OCI Object Storage bucket은 Swift 컨테이너와 동일합니다.
- OCI Object Storage object는 Swift object와 동일합니다.
목표
- OpenStack Swift 호환 API와 함께 OCI Object Storage 서비스를 사용하는 다양한 방법을 보여줍니다.
필요 조건
-
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 지역 엔드포인트는 https://swiftobjectstorage.<region-identifier>.oraclecloud.com
의 일관된 URL 형식을 사용합니다. 예를 들어, 미국 동부 지역(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
. 자세한 내용은 Getting an Auth Token을 참조하십시오.
OCI Swift API에 대한 각 요청에는 다음 헤더가 포함되어야 합니다.
- 권한 부여:
Basic <base64(username:password)>
.
예를 들어, username이 oracleidentitycloudservice/john.doe@acme.com
이고 password가 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
-
Create a bucket.
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
이고 사용자 이름이 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)
-
계정의 버킷을 나열합니다. 선택한 OCI Swift API 구획의 버킷만 나열됩니다.
curl -s -D /dev/stderr "https://swiftobjectstorage.${region}.oraclecloud.com/v1/${tenancy_namespace}" -H "X-Auth-Token: ${X_Auth_Token}" | jq
-
Create a bucket.
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 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
F95067-01
March 2024