파일 시스템에서 Cloud Storage로 전송

이 페이지에서는 파일 시스템(온프레미스 또는 클라우드 내)과 Cloud Storage 간에 전송 작업을 만드는 방법을 보여줍니다.

파일 시스템에서 Cloud Storage로 전송은 에이전트 기반 전송입니다. 즉, 파일 시스템에 액세스할 수 있는 머신에 소프트웨어 에이전트를 설치하여 전송을 조정합니다.

권한 구성

전송을 만들기 전에 다음 항목에 대한 권한을 구성해야 합니다.

전송을 만드는 데 사용되는 사용자 계정. 이 계정은 Google Cloud 콘솔에 로그인된 계정이거나 `gcloud` CLI에 인증할 때 지정된 계정입니다. 사용자 계정은 일반 사용자 계정이나 사용자 관리형 서비스 계정일 수 있습니다.
Google 관리 서비스 계정은 서비스 에이전트라고도 하며 Storage Transfer Service에서 사용됩니다. 이 계정은 일반적으로 project-PROJECT_NUMBER@storage-transfer-service.iam.gserviceaccount.com 형식을 사용하는 이메일 주소로 식별됩니다.
전송 에이전트에 Google Cloud 권한을 제공하는 전송 에이전트 계정. 전송 에이전트 계정은 설치하는 사용자의 사용자 인증 정보나 사용자 관리형 서비스 계정의 사용자 인증 정보를 사용하여 인증합니다.

자세한 내용은 에이전트 기반 전송 권한을 참조하세요.

에이전트 풀에 에이전트 설치

에이전트 기반 전송은 소프트웨어 에이전트를 사용하여 전송을 조정합니다. 이러한 에이전트는 전송에 관련된 파일 시스템에 대한 액세스 권한이 있는 머신에 설치되어야 합니다.

에이전트 풀 이름이나 에이전트 ID 프리픽스에 개인 식별 정보(PII) 또는 보안 데이터와 같은 민감한 정보를 포함하지 마세요. 리소스 이름은 다른 Google Cloud 리소스 이름으로 전파될 수 있으며 프로젝트 외부의 Google 내부 시스템에 노출될 수 있습니다.
  1. 에이전트 풀을 만듭니다. 이 작업의 사용자 계정 사용자 계정 기호을 사용합니다.
  2. 에이전트 풀에 에이전트를 설치합니다. 이 작업의 전송 에이전트 계정 을 사용합니다.

소스 에이전트 풀에서 에이전트 3개를 시작하는 것이 좋습니다. 전송이 진행되면 전송 속도를 모니터링합니다. 전송이 진행되는 동안 풀에 에이전트를 더 추가할 수 있습니다.

에이전트당 VM 1개로, VM마다 최소 CPU 4개와 8GiB RAM이 있는 것이 좋습니다.

전송 옵션

파일 시스템에서 Cloud Storage로 전송할 때 다음과 같은 Storage Transfer Service 기능을 사용할 수 있습니다.

매니페스트를 사용하여 특정 파일 전송
작업할 Storage Transfer Service 파일의 목록을 전달할 수 있습니다. 자세한 내용은 매니페스트를 사용하여 특정 파일 또는 객체 전송을 참조하세요.
스토리지 클래스 지정
대상 버킷의 데이터에 사용할 Cloud Storage 스토리지 클래스를 지정할 수 있습니다. REST 세부정보는 StorageClass 옵션을 참조하거나 Google Cloud CLI에서 --custom-storage-class 플래그를 사용하세요.

대상 버킷에 자동 클래스가 사용 설정되면 스토리지 클래스 설정이 무시됩니다. 자동 클래스를 사용 설정하면 처음에는 버킷으로 전송된 객체가 Standard Storage로 설정됩니다.

메타데이터 보존

파일 시스템에서 파일을 전송할 때 Storage Transfer Service는 선택적으로 특정 속성을 커스텀 메타데이터로 보존할 수 있습니다. 나중에 이러한 파일을 파일 시스템에 다시 작성하면 Storage Transfer Service는 보존된 메타데이터를 다시 POSIX 속성으로 변환할 수 있습니다.

보존할 수 있는 메타데이터와 전송을 구성하는 방법에 대한 자세한 내용은 메타데이터 보존POSIX 파일 시스템 전송 섹션을 참조하세요.

네트워크 대역폭 관리
Storage Transfer Service는 기본적으로 파일 시스템에서 파일을 전송하는 데 사용할 수 있는 대역폭을 최대한 많이 사용합니다. 전송이 다른 네트워크 트래픽에 영향을 주지 않도록 대역폭 한도를 설정할 수 있습니다. 대역폭 한도는 에이전트 풀 수준에서 적용됩니다.

자세한 내용은 네트워크 대역폭 관리를 참조하세요.

대역폭 한도를 설정하거나 변경하려면 사용자 계정에 스토리지 전송 관리자(roles/storagetransfer.admin) 역할이 필요합니다.

로깅
Storage Transfer Service는 Storage Transfer Service용 Cloud Logging(권장) 및 에이전트 기반 전송 로그를 지원합니다.

전송 만들기

전송 작업 이름에 개인 식별 정보(PII) 또는 보안 데이터와 같은 민감한 정보를 포함하지 마세요. 리소스 이름은 다른 Google Cloud 리소스 이름으로 전파될 수 있으며 프로젝트 외부의 Google 내부 시스템에 노출될 수 있습니다.

Storage Transfer Service는 전송을 만드는 데 사용되는 인터페이스를 여러 개 제공합니다.

Google Cloud 콘솔

  1. Google Cloud 콘솔의 Storage Transfer Service 페이지로 이동합니다.

    Storage Transfer Service로 이동

  2. 전송 작업 만들기를 클릭합니다. 전송 작업 만들기 페이지가 표시됩니다.

  3. POSIX 파일 시스템을 소스로 선택합니다.

  4. Cloud Storage를 대상 유형으로 선택하고 다음 단계를 클릭합니다.

  5. 기존 에이전트 풀을 선택하거나 에이전트 풀 만들기를 선택하고 안내에 따라 새 풀을 만듭니다.

  6. 파일 시스템 디렉터리의 정규화된 경로를 지정합니다.

  7. 다음 단계를 클릭합니다.

  8. 버킷 또는 폴더 필드에 대상 버킷과 폴더 이름(선택사항)을 입력하거나 찾아보기를 클릭하여 현재 프로젝트의 기존 목록에서 버킷을 선택합니다. 새 버킷을 만들려면 버킷 아이콘 새 버킷 만들기를 클릭합니다.

  9. 다음 단계를 클릭합니다.

  10. 예약 옵션을 선택합니다.

  11. 다음 단계를 클릭합니다.

  12. 전송 작업의 설정을 선택합니다.

    • 설명 필드에 전송 설명을 입력합니다. 작업을 구분할 수 있도록 의미 있고 고유한 설명을 입력하는 것이 좋습니다.

    • 메타데이터 옵션에서 기본 옵션을 사용하거나 값을 하나 이상 업데이트합니다. 자세한 내용은 메타데이터 보존을 참조하세요.

    • 덮어쓸 시점에서 다음 중 하나를 선택합니다.

      • 사용 안 함: Storage Transfer Service는 대상에 있는 파일과 이름이 같은 소스에서 파일 전송을 건너뜁니다.

      • 다른 경우: 이름이 같은 소스 파일에 다른 Etag 또는 체크섬 값이 있는 경우 대상 파일을 덮어씁니다.

      • 항상: 소스 파일 이름이 같으면 동일하더라도 항상 대상 파일을 덮어씁니다.

    • 삭제 시점에서 다음 중 하나를 선택합니다.

      • 삭제 안함: 소스 또는 대상 위치에서 파일을 삭제하지 않습니다.

      • 전송 후 소스에서 파일 삭제: 파일이 대상으로 전송된 후 소스에서 파일을 삭제합니다.

      • 소스에도 없는 경우 대상 위치에서 파일 삭제: 대상 Cloud Storage 버킷의 파일이 소스에도 없는 경우 Cloud Storage 버킷에서 파일을 삭제합니다.

        이 옵션을 사용하면 대상 Cloud Storage 버킷이 소스와 정확하게 일치합니다.

    • Cloud Storage에서 로깅 사용 설정 또는 Cloud Logging에서 로깅 사용 설정 여부를 선택합니다. 자세한 내용은 파일 시스템 전송 로그Storage Transfer Service용 Cloud Logging을 참조하세요.

  13. 전송 작업을 만들려면 만들기를 클릭합니다.

gcloud

gcloud 명령어를 사용하기 전에 Google Cloud CLI를 설치합니다.

새 전송 작업을 만들려면 gcloud transfer jobs create 명령어를 사용합니다. 일정 또는 --do-not-run이 지정되지 않은 한, 새 작업을 만들면 지정된 전송이 시작됩니다.

gcloud transfer jobs create \
  posix:///SOURCE \
  gs://DESTINATION/ \
  --source-agent-pool=SOURCE_POOL_NAME

각 항목의 의미는 다음과 같습니다.

  • SOURCE는 파일 시스템 루트의 절대 경로입니다. posix:// 프리픽스가 추가되므로 최종 값에 슬래시 3개가 포함됩니다. 예를 들면 posix:///tmp/data/입니다.

  • DESTINATION은 Cloud Storage 버킷 이름이며, 필요한 경우 폴더 경로 다음에 후행 슬래시가 옵니다. 예를 들면 gs://example-bucket/data/입니다.

  • --source-agent-pool은 이 전송에 사용할 소스 에이전트 풀을 지정합니다.

추가로 선택할 수 있는 옵션은 다음과 같습니다.

  • --do-not-run은 명령어를 제출할 때 Storage Transfer Service가 작업을 실행하지 못하도록 방지합니다. 작업을 실행하려면 업데이트하여 일정을 추가하거나 jobs run을 사용하여 수동으로 시작합니다.

  • --manifest-file은 소스에서 전송할 파일 목록이 포함된 Cloud Storage의 CSV 파일 경로를 지정합니다. 매니페스트 파일 형식 지정은 매니페스트를 사용하여 특정 파일 또는 객체 전송을 참조하세요.

  • 작업 정보: --name--description을 지정할 수 있습니다.

  • 일정: --schedule-starts, --schedule-repeats-every, --schedule-repeats-until, --do-not-run을 지정합니다.

  • 전송 옵션: 대상 파일(--overwrite-when=different 또는always)을 덮어쓸지 여부와 전송 중 또는 전송 후에 특정 파일을 삭제할지 여부(--delete-from=destination-if-unique 또는source-after-transfer)를 지정하고, 보존할 메타데이터 값(--preserve-metadata)을 지정하며, 필요한 경우 전송된 객체에 스토리지 클래스를 선택적으로 설정할 수 있습니다(--custom-storage-class).

모든 옵션을 보려면 gcloud transfer jobs create --help를 실행하거나 gcloud 참고 문서를 참조하세요. 에이전트 기반 전송에 모든 옵션이 지원되지는 않습니다. 지원되지 않는 옵션의 도움말 텍스트에는 이 효과에 대한 메모가 있습니다.

REST

다음 예시에서는 REST API를 통해 Storage Transfer Service를 사용하는 방법을 보여줍니다.

Storage Transfer Service API를 사용하여 전송 작업을 구성하거나 편집할 때 시간은 UTC여야 합니다. 전송 작업 일정을 지정하는 방법에 대한 자세한 내용은 일정을 참조하세요.

파일을 POSIX 파일 시스템에서 Cloud Storage 버킷으로 이동하려면 posixDataSource와 함께 transferJobs.create를 사용합니다.

POST https://storagetransfer.googleapis.com/v1/transferJobs
{
 "name":"transferJobs/sample_transfer",
 "description": "My First Transfer",
 "status": "ENABLED",
 "projectId": "my_transfer_project_id",
 "schedule": {
     "scheduleStartDate": {
         "year": 2022,
         "month": 5,
         "day": 2
     },
     "startTimeOfDay": {
         "hours": 22,
         "minutes": 30,
         "seconds": 0,
         "nanos": 0
     }
     "scheduleEndDate": {
         "year": 2022,
         "month": 12,
         "day": 31
     },
     "repeatInterval": {
         "259200s"
     },
 },
 "transferSpec": {
     "posixDataSource": {
          "rootDirectory": "/bar/",
     },
     "sourceAgentPoolName": "my_example_pool",
     "gcsDataSink": {
          "bucketName": "destination_bucket"
          "path": "foo/bar/"
     },
  }
}

schedule 필드는 선택사항입니다. 이 필드가 포함되지 않은 경우 전송 작업은 transferJobs.run 요청으로 시작해야 합니다.

작업을 만든 후 전송 상태를 확인하려면 transferJobs.get을 사용합니다.

GET https://storagetransfer.googleapis.com/v1/transferJobs/sample_transfer?project_id=my_transfer_project_id

클라이언트 라이브러리

다음 샘플에서는 Go, 자바, Node.js, Python을 사용하여 프로그래매틱 방식으로 Storage Transfer Service를 사용하는 방법을 보여줍니다.

전송 작업을 프로그래매틱 방식으로 구성하거나 편집할 때 시간은 UTC여야 합니다. 전송 작업 일정을 지정하는 방법에 대한 자세한 내용은 일정을 참조하세요.

Storage Transfer Service 클라이언트 라이브러리에 대한 자세한 내용은 Storage Transfer Service 클라이언트 라이브러리 시작하기를 참조하세요.

파일을 POSIX 파일 시스템에서 Cloud Storage 버킷으로 이동하려면 다음 안내를 따르세요.

Go


import (
	"context"
	"fmt"
	"io"

	storagetransfer "cloud.google.com/go/storagetransfer/apiv1"
	"cloud.google.com/go/storagetransfer/apiv1/storagetransferpb"
)

func transferFromPosix(w io.Writer, projectID string, sourceAgentPoolName string, rootDirectory string, gcsSinkBucket string) (*storagetransferpb.TransferJob, error) {
	// Your project id
	// projectId := "myproject-id"

	// The agent pool associated with the POSIX data source. If not provided, defaults to the default agent
	// sourceAgentPoolName := "projects/my-project/agentPools/transfer_service_default"

	// The root directory path on the source filesystem
	// rootDirectory := "/directory/to/transfer/source"

	// The ID of the GCS bucket to transfer data to
	// gcsSinkBucket := "my-sink-bucket"

	ctx := context.Background()
	client, err := storagetransfer.NewClient(ctx)
	if err != nil {
		return nil, fmt.Errorf("storagetransfer.NewClient: %w", err)
	}
	defer client.Close()

	req := &storagetransferpb.CreateTransferJobRequest{
		TransferJob: &storagetransferpb.TransferJob{
			ProjectId: projectID,
			TransferSpec: &storagetransferpb.TransferSpec{
				SourceAgentPoolName: sourceAgentPoolName,
				DataSource: &storagetransferpb.TransferSpec_PosixDataSource{
					PosixDataSource: &storagetransferpb.PosixFilesystem{RootDirectory: rootDirectory},
				},
				DataSink: &storagetransferpb.TransferSpec_GcsDataSink{
					GcsDataSink: &storagetransferpb.GcsData{BucketName: gcsSinkBucket},
				},
			},
			Status: storagetransferpb.TransferJob_ENABLED,
		},
	}

	resp, err := client.CreateTransferJob(ctx, req)
	if err != nil {
		return nil, fmt.Errorf("failed to create transfer job: %w", err)
	}
	if _, err = client.RunTransferJob(ctx, &storagetransferpb.RunTransferJobRequest{
		ProjectId: projectID,
		JobName:   resp.Name,
	}); err != nil {
		return nil, fmt.Errorf("failed to run transfer job: %w", err)
	}
	fmt.Fprintf(w, "Created and ran transfer job from %v to %v with name %v", rootDirectory, gcsSinkBucket, resp.Name)
	return resp, nil
}

자바

import com.google.storagetransfer.v1.proto.StorageTransferServiceClient;
import com.google.storagetransfer.v1.proto.TransferProto;
import com.google.storagetransfer.v1.proto.TransferTypes.GcsData;
import com.google.storagetransfer.v1.proto.TransferTypes.PosixFilesystem;
import com.google.storagetransfer.v1.proto.TransferTypes.TransferJob;
import com.google.storagetransfer.v1.proto.TransferTypes.TransferSpec;
import java.io.IOException;

public class TransferFromPosix {

  public static void main(String[] args) throws IOException {
    // TODO(developer): Replace these variables before running the sample.

    // Your project id
    String projectId = "my-project-id";

    // The agent pool associated with the POSIX data source. If not provided, defaults to the
    // default agent
    String sourceAgentPoolName = "projects/my-project-id/agentPools/transfer_service_default";

    // The root directory path on the source filesystem
    String rootDirectory = "/directory/to/transfer/source";

    // The ID of the GCS bucket to transfer data to
    String gcsSinkBucket = "my-sink-bucket";

    transferFromPosix(projectId, sourceAgentPoolName, rootDirectory, gcsSinkBucket);
  }

  public static void transferFromPosix(
      String projectId, String sourceAgentPoolName, String rootDirectory, String gcsSinkBucket)
      throws IOException {
    TransferJob transferJob =
        TransferJob.newBuilder()
            .setProjectId(projectId)
            .setTransferSpec(
                TransferSpec.newBuilder()
                    .setSourceAgentPoolName(sourceAgentPoolName)
                    .setPosixDataSource(
                        PosixFilesystem.newBuilder().setRootDirectory(rootDirectory).build())
                    .setGcsDataSink(GcsData.newBuilder().setBucketName(gcsSinkBucket).build()))
            .setStatus(TransferJob.Status.ENABLED)
            .build();

    // Initialize client that will be used to send requests. This client only needs to be created
    // once, and can be reused for multiple requests. After completing all of your requests, call
    // the "close" method on the client to safely clean up any remaining background resources,
    // or use "try-with-close" statement to do this automatically.
    try (StorageTransferServiceClient storageTransfer = StorageTransferServiceClient.create()) {

      // Create the transfer job
      TransferJob response =
          storageTransfer.createTransferJob(
              TransferProto.CreateTransferJobRequest.newBuilder()
                  .setTransferJob(transferJob)
                  .build());

      System.out.println(
          "Created a transfer job from "
              + rootDirectory
              + " to "
              + gcsSinkBucket
              + " with "
              + "name "
              + response.getName());
    }
  }
}

Node.js


// Imports the Google Cloud client library
const {
  StorageTransferServiceClient,
} = require('@google-cloud/storage-transfer');

/**
 * TODO(developer): Uncomment the following lines before running the sample.
 */
// Your project id
// const projectId = 'my-project'

// The agent pool associated with the POSIX data source. Defaults to the default agent
// const sourceAgentPoolName = 'projects/my-project/agentPools/transfer_service_default'

// The root directory path on the source filesystem
// const rootDirectory = '/directory/to/transfer/source'

// The ID of the GCS bucket to transfer data to
// const gcsSinkBucket = 'my-sink-bucket'

// Creates a client
const client = new StorageTransferServiceClient();

/**
 * Creates a request to transfer from the local file system to the sink bucket
 */
async function transferDirectory() {
  const createRequest = {
    transferJob: {
      projectId,
      transferSpec: {
        sourceAgentPoolName,
        posixDataSource: {
          rootDirectory,
        },
        gcsDataSink: {bucketName: gcsSinkBucket},
      },
      status: 'ENABLED',
    },
  };

  // Runs the request and creates the job
  const [transferJob] = await client.createTransferJob(createRequest);

  const runRequest = {
    jobName: transferJob.name,
    projectId: projectId,
  };

  await client.runTransferJob(runRequest);

  console.log(
    `Created and ran a transfer job from '${rootDirectory}' to '${gcsSinkBucket}' with name ${transferJob.name}`
  );
}

transferDirectory();

Python

from google.cloud import storage_transfer


def transfer_from_posix_to_gcs(
    project_id: str,
    description: str,
    source_agent_pool_name: str,
    root_directory: str,
    sink_bucket: str,
):
    """Create a transfer from a POSIX file system to a GCS bucket."""

    client = storage_transfer.StorageTransferServiceClient()

    # The ID of the Google Cloud Platform Project that owns the job
    # project_id = 'my-project-id'

    # A useful description for your transfer job
    # description = 'My transfer job'

    # The agent pool associated with the POSIX data source.
    # Defaults to 'projects/{project_id}/agentPools/transfer_service_default'
    # source_agent_pool_name = 'projects/my-project/agentPools/my-agent'

    # The root directory path on the source filesystem
    # root_directory = '/directory/to/transfer/source'

    # Google Cloud Storage sink bucket name
    # sink_bucket = 'my-gcs-sink-bucket'

    transfer_job_request = storage_transfer.CreateTransferJobRequest(
        {
            "transfer_job": {
                "project_id": project_id,
                "description": description,
                "status": storage_transfer.TransferJob.Status.ENABLED,
                "transfer_spec": {
                    "source_agent_pool_name": source_agent_pool_name,
                    "posix_data_source": {
                        "root_directory": root_directory,
                    },
                    "gcs_data_sink": {"bucket_name": sink_bucket},
                },
            }
        }
    )

    result = client.create_transfer_job(transfer_job_request)
    print(f"Created transferJob: {result.name}")