從 Amazon S3 簡易遷移至 Cloud Storage

本頁說明如何從 Amazon Simple Storage Service (Amazon S3) 簡易遷移至 Cloud Storage。在簡易遷移模式下,您必須使用既有的工具和程式庫來產生經過驗證的 REST 要求,再將要求傳送到 Cloud Storage,這和您在使用 Amazon S3 時所採取的做法是一樣的。

如果您初次接觸 Cloud Storage,而且不會直接使用 API,請考慮使用 Google Cloud 主控台設定及管理移轉作業。Google Cloud 控制台提供 Cloud Storage 的圖形介面,讓您僅需使用瀏覽器即可完成許多儲存工作,包括從 Amazon S3 將資料遷移至 Cloud Storage。

如要讓 Cloud Storage 儲存 Amazon S3 資料的備份,建議使用事件導向移轉作業,這類作業會使用 Amazon S3 事件通知,自動讓 Cloud Storage 值區與 Amazon S3 來源保持同步。

在簡易遷移情境中,從 Amazon S3 遷移至 Cloud Storage

如要向 Cloud Storage 發出要求,請完成下列步驟:

  • 設定預設 Google Cloud 專案
  • 取得 HMAC (雜湊式訊息驗證碼) 金鑰
  • 依照以下方式變更現有的工具或程式庫:

    • 變更要求端點以使用 Cloud Storage XML API 要求端點
    • 將 Amazon Web Services (AWS) 存取金鑰和密鑰替換為相應的 Cloud Storage 存取 ID 和密鑰 (統稱為 Cloud Storage HMAC 金鑰)。
    • 請確認 x-amz- 標頭使用支援的 Cloud Storage 值。舉例來說,x-amz-storage-class 應使用其中一個可用的 Cloud Storage 儲存空間類別

      在簡易遷移情境中使用 Cloud Storage XML API 時,在 Authorization 標頭中指定 AWS 簽名識別碼會使 Cloud Storage 知道在您的要求中預期 x-amz-* 標頭和 Amazon S3 ACL XML 語法。Cloud Storage 會處理具有x-goog-*對等項目的 x-amz-* 標頭,例如標頭表格中列出的標頭,並處理 x-amz-decoded-content-length 標頭

完成這些變更後,您就可以開始使用現有工具和程式庫,將 HMAC 要求傳送至 Cloud Storage。

舉例來說,下列程式碼顯示了如何使用 Amazon S3 SDK 列出 Cloud Storage 值區:

Go

詳情請參閱 Cloud Storage Go API 參考說明文件

如要驗證 Cloud Storage,請設定應用程式預設憑證。 詳情請參閱「設定用戶端程式庫的驗證機制」。

import (
	"context"
	"fmt"
	"io"
	"time"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/credentials"
	"github.com/aws/aws-sdk-go/aws/session"
	"github.com/aws/aws-sdk-go/service/s3"
)

func listGCSBuckets(w io.Writer, googleAccessKeyID string, googleAccessKeySecret string) error {
	// googleAccessKeyID := "Your Google Access Key ID"
	// googleAccessKeySecret := "Your Google Access Key Secret"

	// Create a new client and do the following:
	// 1. Change the endpoint URL to use the Google Cloud Storage XML API endpoint.
	// 2. Use Cloud Storage HMAC Credentials.
	sess := session.Must(session.NewSession(&aws.Config{
		Region:      aws.String("auto"),
		Endpoint:    aws.String("https://storage.googleapis.com"),
		Credentials: credentials.NewStaticCredentials(googleAccessKeyID, googleAccessKeySecret, ""),
	}))

	client := s3.New(sess)
	ctx := context.Background()

	ctx, cancel := context.WithTimeout(ctx, time.Second*10)
	defer cancel()
	result, err := client.ListBucketsWithContext(ctx, &s3.ListBucketsInput{})
	if err != nil {
		return fmt.Errorf("ListBucketsWithContext: %w", err)
	}

	fmt.Fprintf(w, "Buckets:")
	for _, b := range result.Buckets {
		fmt.Fprintf(w, "%s\n", aws.StringValue(b.Name))
	}

	return nil
}

Java

詳情請參閱 Cloud Storage Java API 參考說明文件

如要驗證 Cloud Storage,請設定應用程式預設憑證。 詳情請參閱「設定用戶端程式庫的驗證機制」。

import com.amazonaws.auth.AWSStaticCredentialsProvider;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.client.builder.AwsClientBuilder;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import com.amazonaws.services.s3.model.Bucket;
import java.util.List;

public class ListGcsBuckets {
  public static void listGcsBuckets(String googleAccessKeyId, String googleAccessKeySecret) {

    // String googleAccessKeyId = "your-google-access-key-id";
    // String googleAccessKeySecret = "your-google-access-key-secret";

    // Create a BasicAWSCredentials using Cloud Storage HMAC credentials.
    BasicAWSCredentials googleCreds =
        new BasicAWSCredentials(googleAccessKeyId, googleAccessKeySecret);

    // Create a new client and do the following:
    // 1. Change the endpoint URL to use the Google Cloud Storage XML API endpoint.
    // 2. Use Cloud Storage HMAC Credentials.
    AmazonS3 interopClient =
        AmazonS3ClientBuilder.standard()
            .withEndpointConfiguration(
                new AwsClientBuilder.EndpointConfiguration(
                    "https://storage.googleapis.com", "auto"))
            .withCredentials(new AWSStaticCredentialsProvider(googleCreds))
            .build();

    // Call GCS to list current buckets
    List<Bucket> buckets = interopClient.listBuckets();

    // Print bucket names
    System.out.println("Buckets:");
    for (Bucket bucket : buckets) {
      System.out.println(bucket.getName());
    }

    // Explicitly clean up client resources.
    interopClient.shutdown();
  }

Python

詳情請參閱 Cloud Storage Python API 參考說明文件

如要驗證 Cloud Storage,請設定應用程式預設憑證。 詳情請參閱「設定用戶端程式庫的驗證機制」。

import boto3  # type: ignore


def list_gcs_buckets(
    google_access_key_id: str, google_access_key_secret: str
) -> List[str]:
    """Lists all Cloud Storage buckets using AWS SDK for Python (boto3)
    Positional arguments:
        google_access_key_id: hash-based message authentication code (HMAC) access ID
        google_access_key_secret: HMAC access secret

    Returned value is a list of strings, one for each bucket name.

    To use this sample:
    1. Create a Cloud Storage HMAC key: https://cloud.google.com/storage/docs/authentication/managing-hmackeys#create
    2. Change endpoint_url to a Google Cloud Storage XML API endpoint.

    To learn more about HMAC: https://cloud.google.com/storage/docs/authentication/hmackeys#overview
    """
    client = boto3.client(
        "s3",
        region_name="auto",
        endpoint_url="https://storage.googleapis.com",
        aws_access_key_id=google_access_key_id,
        aws_secret_access_key=google_access_key_secret,
    )

    # Call GCS to list current buckets
    response = client.list_buckets()

    # Return list of bucket names
    results = []
    for bucket in response["Buckets"]:
        results.append(bucket["Name"])
        print(bucket["Name"])  # Can remove if not needed after development
    return results

設定預設專案

如要在簡易遷移情境中使用 Cloud Storage,建議您設定預設專案,Cloud Storage 會使用該專案執行特定作業,例如 GET 服務或 PUT 值區。如未設定預設專案,您必須在特定要求中指定專案標頭

如何設定預設專案:

  1. 在Google Cloud 控制台中開啟「Cloud Storage Settings」(Cloud Storage 設定) 頁面
  2. 選取 [Interoperability] (互通性) 分頁標籤。
  3. 按一下「具有互通存取權限的預設專案」部分中的「將 PROJECT-ID 設為預設專案」

    如果專案已經是預設專案,您會看到「PROJECT-ID is your default project for interoperable access」(PROJECT-ID 是供互通存取的預設專案)

這個專案現在即為預設專案。您隨時可以變更預設專案,只要選擇其他專案並按照這些步驟操作即可。

或者,指定專案標頭

除了設定預設專案之外,您也可以在需要指定專案的個別要求中使用 x-amz-project-id 標頭。

  • 使用 x-amz-project-id 的要求會使用標頭中指定的專案,即使有現有的預設專案也一樣。

在下列情況下,x-amz-project-id 標頭非常實用:

  • 您正在處理多個專案。
  • 您的要求是由與其他專案相關聯的服務帳戶提出,因為服務帳戶會將父項專案做為預設專案。

請注意,Amazon S3 沒有專案,因此視您使用的工具或用戶端程式庫而定,可能無法指定 x-amz-project-id 標頭。在這種情況下,您應設定預設專案

使用 HMAC 金鑰

如要在簡易遷移情境中使用 Cloud Storage XML API,請使用 Cloud Storage 雜湊架構訊息驗證代碼 (HMAC) 金鑰進行驗證。一般來說,您應建立與服務帳戶相關聯的 HMAC 金鑰,但也可以使用與使用者帳戶相關聯的金鑰。

在簡易遷移情境中進行驗證

使用 Authorization 標頭

如果您要在簡易遷移情境中進行需要驗證的操作,則必須包含 Authorization 要求標頭,就像對 Amazon S3 發出要求時一樣。Amazon S3 要求的 Authorization 標頭語法為:

Authorization: AWS4-HMAC-SHA256 Credential=AWS-ACCESS-KEY/CREDENTIAL_SCOPE, SignedHeaders=SIGNED_HEADERS, Signature=SIGNATURE

在簡易遷移情境中,您只需要將標頭變更為使用 Cloud Storage HMAC 存取 ID,並確保您附加的 Signature 是以 Cloud Storage HMAC 密鑰計算:

Authorization: ALGORITHM Credential=GOOG-ACCESS-ID/CREDENTIAL_SCOPE, SignedHeaders=SIGNED_HEADERS, Signature=SIGNATURE

Authorization 標頭的各個部分為:

  • ALGORITHM:您使用的簽名演算法及版本。使用 AWS4-HMAC-SHA256 表示您使用 HMAC V4 簽名,並打算傳送 x-amz-* 標頭。您也可以使用 GOOG4-HMAC-SHA256,這表示您使用 HMAC V4 簽名,並打算傳送 x-goog-* 標頭;或是使用 GOOG4-RSA-SHA256,這表示您使用 RSA V4 簽名,並打算傳送 x-goog-* 標頭。

  • GOOG-ACCESS-ID:存取 ID,可識別提出和簽署要求的實體。在簡易遷移中,請將您用來存取 Amazon S3 的 Amazon Web Service (AWS) 存取金鑰 ID 換成 Cloud Storage HMAC 存取 ID。您的 Cloud Storage HMAC 存取 ID 開頭為 GOOG

  • CREDENTIAL_SCOPE:憑證範圍,如簽章中所定義。在簡易遷移中,如果您使用 AWS4-HMAC-SHA256 作為 ALGORITHM 值,就不必變更憑證範圍。

  • SIGNED_HEADERS:簽署此要求時必須納入的標頭名稱清單 (以分號分隔)。所有標頭應採用小寫,並依據字元代碼排序。

    以下是 Amazon S3 類型的簽署標頭字串範例:

    content-type;host;x-amz-date

    在簡易遷移中,您不必對已簽署標頭字串進行任何變更。

  • SIGNATURE:允許驗證要求的簽章。在簡易遷移中,將 AWS 存取金鑰資訊換成對應的 Cloud Storage HMAC 金鑰資訊。

驗證要求範例

下列範例會將名為 /europe/france/paris.jpg 的物件上傳至名為 my-travel-maps 的值區,套用預先定義的 ACL public-read,以及為審核者定義自訂中繼資料標頭。以下是向 Amazon S3 值區提出的要求:

PUT europe/france/paris.jpg HTTP/1.1
Host: my-travel-maps.s3.amazonaws.com
Date: Mon, 11 Mar 2019 23:46:19 GMT
Content-Length: 888814
Content-Type: image/jpg
x-amz-acl: public-read
x-amz-date:20190311T192918Z
x-amz-meta-reviewer: joe,jane
Authorization: AWS4-HMAC-SHA256 Credential=AWS-ACCESS-KEY/20190311/us-east-1/s3/aws4_request, SignedHeaders=content-length;content-type;host;x-amz-acl;x-amz-date;x-amz-meta-reviewer, Signature=SIGNATURE

以下是向 Cloud Storage 值區提出的要求:

PUT europe/france/paris.jpg HTTP/1.1
Host: my-travel-maps.storage.googleapis.com
Date: Mon, 11 Mar 2019 23:46:19 GMT
Content-Length: 888814
Content-Type: image/jpg
x-amz-acl: public-read
x-amz-date:20190311T192918Z
x-amz-meta-reviewer: joe,jane
Authorization: AWS4-HMAC-SHA256 Credential=GOOG-ACCESS-ID/20190311/us-east-1/s3/aws4_request, SignedHeaders=content-length;content-type;host;x-amz-acl;x-amz-date;x-amz-meta-reviewer, Signature=SIGNATURE

這是為此要求建立的對應標準化要求:

PUT
/europe/france/paris.jpg

content-length:888814
content-type:image/jpg
host:my-travel-maps.storage.googleapis.com
x-amz-acl:public-read
x-amz-date:20190311T192918Z
x-amz-meta-reviewer:joe,jane

content-length,content-type,host,x-amz-acl,x-amz-date,x-amz-meta-reviewer
82e3da8b3f35989512e8d428add7eca73ab0e5f36586e66fbad8e1051343cbd2

這是為此要求建立的對應欲簽署字串:

AWS4-HMAC-SHA256
20190311T192918Z
20190311/us-east-1/s3/aws4_request
73918a5ff373d7a03e406fbf9ea35675396b06fca2af76c27a5c451fa783ef65

此要求並未提供 Content-MD5 標頭,因此訊息第二行會顯示空字串。

簡易遷移情境中的存取權控管

Cloud Storage 必須接受 Amazon S3 產生的 ACL,才能支援簡易遷移。在簡易遷移情境中,您將會使用 AWS 當做簽名識別碼,讓 Cloud Storage 瞭解將會收到採用 Amazon S3 ACL XML 語法的 ACL 語法。您應確保使用的 Amazon S3 ACL 會對應至 Cloud Storage ACL 模型。舉例來說,如果您的工具和程式庫使用 Amazon S3 的 ACL 語法授予值區的 WRITE 權限,那麼這些工具和程式庫也必須授予值區的 READ 權限 (因為 Cloud Storage 採用同心圓權限)。當您使用 Cloud Storage 語法授予 WRITE 權限時,不需要同時指定 WRITEREAD 權限。

在以下情境中,Cloud Storage 支援 Amazon S3 ACL 語法:

  • 向 Cloud Storage 提出擷取 ACL 的要求時 (例如,GET 物件或 GET 值區要求) 時,Cloud Storage 會傳回 Amazon S3 ACL 語法。
  • 向 Cloud Storage 提出套用 ACL 的要求時 (例如,PUT 物件或 PUT 值區要求) 時,Cloud Storage 預期會收到 Amazon S3 ACL 語法。

簡易遷移情境中的 Authorization 標頭會使用 AWS 做為簽名識別碼,但是會搭配您的 Cloud Storage HMAC 存取 ID。

Authorization: AWS4-HMAC-SHA256 Credential=GOOG-ACCESS-ID/CREDENTIAL_SCOPE, SignedHeaders=SIGNED_HEADERS, Signature=SIGNATURE

下列範例說明向 Cloud Storage 提出之傳回物件 ACL 的 GET 要求。

GET europe/france/paris.jpg?acl HTTP/1.1
Host: my-travel-maps.storage.googleapis.com
Date: Thu, 21 Feb 2019 23:50:10 GMT
Content-Type: application/xml
X-Amz-Date: 20190221T235010Z
Authorization: AWS4-HMAC-SHA256 Credential=GOOGMC5PDPA5JLZYQMHQHRAX/20190221/region/s3/aws4_request, SignedHeaders=host;x-amz-date, Signature=29088b1d6dfeb2549f6ff67bc3744abb7e45475f0ad60400485805415bbfc534

要求的回應包括使用 Amazon S3 ACL 語法的 ACL。

<?xml version='1.0' encoding='UTF-8'?>
<AccessControlPolicy>
    <Owner>
        <ID>00b4903a972faa8bcce9382686e9129676f1cd6e5def1f5663affc2ba4652490
        </ID>
        <DisplayName>OwnerName</DisplayName>
    </Owner>
    <AccessControlList>
        <Grant>
            <Grantee xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
                xsi:type='CanonicalUser'>
                <ID>00b4903a972faa8bcce9382686e9129676f1cd6e5def1f5663affc2ba4652490</ID>
                <DisplayName>UserName</DisplayName>
            </Grantee>
            <Permission>FULL_CONTROL</Permission>
        </Grant>
    </AccessControlList>
</AccessControlPolicy>

下列範例說明向 Cloud Storage 提出之設定物件 ACL 的 PUT 要求。範例說明採用 Amazon S3 ACL 語法的要求主體。

PUT europe/france/paris.jpg?acl HTTP/1.1
Host: my-travel-maps.storage.googleapis.com
Date: Thu, 21 Feb 2019 23:50:10 GMT
Content-Type: application/xml
Content-Length: 337
X-Amz-Date: 20190221T235010Z
Authorization: AWS4-HMAC-SHA256 Credential=GOOGMC5PDPA5JLZYQMHQHRAX/20190221/region/s3/aws4_request, SignedHeaders=host;x-amz-date, Signature=29088b1d6dfeb2549f6ff67bc3744abb7e45475f0ad60400485805415bbfc534

<?xml version='1.0' encoding='utf-8'?>
<AccessControlPolicy>
  <AccessControlList>
    <Grant>
      <Grantee xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="AmazonCustomerByEmail">
        <EmailAddress>jeffersonloveshiking@gmail.com</EmailAddress>
      </Grantee>
      <Permission>FULL_CONTROL</Permission>
    </Grant>
  </AccessControlList>
</AccessControlPolicy>

最後,在簡易遷移情境中,您也可以在 Authorization 標頭中使用 GOOG1 簽名識別碼。在這種情況下,您必須使用 Cloud Storage ACL 語法,並確保所有 x-amz-* 標頭都變更為 x-goog-*。雖然上述做法可行,但我們還是建議您選擇完整遷移,以充分利用 Cloud Storage 的所有優勢。

XML API 與 Amazon S3 的相容性支援

如要參與 XML API 互通性討論,可在 Stack Overflow 上使用 google-cloud-storage 標記。

後續步驟