從 Amazon S3 簡易遷移至 Cloud Storage

本頁面說明如何完成從 Amazon Simple Storage Service (Amazon S3) 到 Cloud Storage 的簡易遷移作業。在簡單的遷移作業中,您可以使用現有工具和程式庫,產生向 Amazon S3 發出的已驗證 REST 要求,然後改為向 Cloud Storage 發出已驗證要求。

如果您是 Cloud Storage 新手,且不會直接使用 API,建議使用 Google Cloud 控制台設定及管理移轉作業。Google Cloud 控制台提供 Cloud Storage 的圖形介面,讓您只要使用瀏覽器,就能完成許多儲存工作,包括將資料從 Amazon S3 遷移至 Cloud Storage。

如要讓 Cloud Storage 儲存 Amazon S3 資料的備份,建議使用事件導向移轉作業,這類作業會使用 Amazon S3 事件通知,自動讓 Cloud Storage bucket 與 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 簽章 ID,可讓 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 bucket:

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 bucket。如未設定預設專案,則必須在特定要求中指定專案標頭。

如何設定預設專案:

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

    如果該專案已是預設專案,您會看到「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 要求標頭,就像對 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 的 bucket、套用預先定義的 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 權限時,不需要同時指定 WRITE 和 READ 權限。

在以下情境中,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 做為簽章 ID,但會搭配您的 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 標記。

後續步驟