Docker Hub에 대한 원격 저장소 인증 구성

이 문서에서는 Artifact Registry 원격 저장소의 Docker Hub 업스트림 저장소에 대한 인증을 구성하는 방법을 설명합니다.

공개 이미지만 사용하는 경우에도 인증을 하면 다운로드 비율 제한이 증가하므로 Docker Hub에 인증하는 것이 좋습니다. Docker Hub 다운로드 비율 제한에 대한 자세한 내용은 Docker Hub 비율 제한을 참조하세요. 원격 저장소를 사용하면 Docker Hub 사용자 이름과 보안 비밀로 저장된 개인 액세스 토큰을 추가하여 Docker Hub에 인증할 수 있습니다.

이 문서에서는 Artifact Registry Docker 원격 저장소Docker Hub 계정을 이미 만들었다고 가정합니다.

원격 저장소에 대한 자세한 내용은 원격 저장소 개요를 참조하세요.

필요한 역할

원격 저장소에 대한 Docker Hub 인증을 구성하는 데 필요한 권한을 얻으려면 관리자에게 프로젝트에 대한 다음 IAM 역할을 부여해 달라고 요청하세요.

역할 부여에 대한 자세한 내용은 액세스 관리를 참조하세요.

커스텀 역할이나 다른 사전 정의된 역할을 통해 필요한 권한을 얻을 수도 있습니다.

Docker Hub 개인 액세스 토큰 만들기

  1. Docker Hub에 로그인합니다.
  2. 읽기 전용 권한이 있는 개인 액세스 토큰을 만듭니다.
  3. 액세스 토큰을 복사합니다.

  4. 로컬 또는 Cloud Shell의 텍스트 파일에 액세스 토큰을 저장합니다.

보안 비밀 버전에 개인 액세스 토큰 저장

  1. Secret Manager에서 보안 비밀을 만듭니다.
  2. Docker Hub 개인 액세스 토큰을 보안 비밀 버전으로 저장합니다.

Artifact Registry 서비스 계정에 보안 비밀에 대한 액세스 권한 부여

Artifact Registry 서비스 에이전트는 Google Cloud 서비스와 상호작용할 때 Artifact Registry를 대신하여 동작하는 Google 관리형 서비스 계정입니다. 서비스 에이전트가 Secret Manager에 저장된 보안 비밀을 사용하도록 하려면 서비스 에이전트에게 비밀 버전을 볼 수 있는 권한을 부여해야 합니다.

서비스 에이전트 식별자는 다음과 같습니다.

service-PROJECT-NUMBER@gcp-sa-artifactregistry.iam.gserviceaccount.com

PROJECT-NUMBER는 Artifact Registry가 실행 중인 Google Cloud 프로젝트의 프로젝트 번호입니다.

Artifact Registry 서비스 에이전트에 Secret Manager 보안 비밀 접근자 역할을 부여하려면 다음 안내를 따르세요.

콘솔

  1. Google Cloud 콘솔에서 Secret Manager 페이지로 이동합니다.

    보안 비밀 관리자 페이지로 이동

  2. Secret Manager 페이지에서 보안 비밀 이름 옆에 있는 체크박스를 클릭합니다.

  3. 아직 열려 있지 않으면 정보 패널 표시를 클릭하여 패널을 엽니다.

  4. 정보 패널에서 주 구성원 추가를 클릭합니다.

  5. 새 주 구성원 텍스트 영역에 추가할 구성원의 이메일 주소를 입력합니다.

  6. 역할 선택 드롭다운에서 Secret Manager를 선택한 후 Secret Manager 보안 비밀 접근자를 선택합니다.

gcloud

$ gcloud secrets add-iam-policy-binding secret-id \
    --member="member" \
    --role="roles/secretmanager.secretAccessor"

여기서 member는 사용자, 그룹 또는 서비스 계정과 같은 IAM 구성원입니다.

C#

Artifact Registry에 인증하려면 애플리케이션 기본 사용자 인증 정보를 설정합니다. 자세한 내용은 로컬 개발 환경의 인증 설정을 참조하세요.


using Google.Cloud.SecretManager.V1;
using Google.Cloud.Iam.V1;

public class IamGrantAccessSample
{
    public Policy IamGrantAccess(
      string projectId = "my-project", string secretId = "my-secret",
      string member = "user:foo@example.com")
    {
        // Create the client.
        SecretManagerServiceClient client = SecretManagerServiceClient.Create();

        // Build the resource name.
        SecretName secretName = new SecretName(projectId, secretId);

        // Get current policy.
        Policy policy = client.GetIamPolicy(new GetIamPolicyRequest
        {
            ResourceAsResourceName = secretName,
        });

        // Add the user to the list of bindings.
        policy.AddRoleMember("roles/secretmanager.secretAccessor", member);

        // Save the updated policy.
        policy = client.SetIamPolicy(new SetIamPolicyRequest
        {
            ResourceAsResourceName = secretName,
            Policy = policy,
        });
        return policy;
    }
}

Go

Artifact Registry에 인증하려면 애플리케이션 기본 사용자 인증 정보를 설정합니다. 자세한 내용은 로컬 개발 환경의 인증 설정을 참조하세요.

import (
	"context"
	"fmt"
	"io"

	secretmanager "cloud.google.com/go/secretmanager/apiv1"
)

// iamGrantAccess grants the given member access to the secret.
func iamGrantAccess(w io.Writer, name, member string) error {
	// name := "projects/my-project/secrets/my-secret"
	// member := "user:foo@example.com"

	// Create the client.
	ctx := context.Background()
	client, err := secretmanager.NewClient(ctx)
	if err != nil {
		return fmt.Errorf("failed to create secretmanager client: %w", err)
	}
	defer client.Close()

	// Get the current IAM policy.
	handle := client.IAM(name)
	policy, err := handle.Policy(ctx)
	if err != nil {
		return fmt.Errorf("failed to get policy: %w", err)
	}

	// Grant the member access permissions.
	policy.Add(member, "roles/secretmanager.secretAccessor")
	if err = handle.SetPolicy(ctx, policy); err != nil {
		return fmt.Errorf("failed to save policy: %w", err)
	}

	fmt.Fprintf(w, "Updated IAM policy for %s\n", name)
	return nil
}

Java

Artifact Registry에 인증하려면 애플리케이션 기본 사용자 인증 정보를 설정합니다. 자세한 내용은 로컬 개발 환경의 인증 설정을 참조하세요.

import com.google.cloud.secretmanager.v1.SecretManagerServiceClient;
import com.google.cloud.secretmanager.v1.SecretName;
import com.google.iam.v1.Binding;
import com.google.iam.v1.GetIamPolicyRequest;
import com.google.iam.v1.Policy;
import com.google.iam.v1.SetIamPolicyRequest;
import java.io.IOException;

public class IamGrantAccess {

  public static void iamGrantAccess() throws IOException {
    // TODO(developer): Replace these variables before running the sample.
    String projectId = "your-project-id";
    String secretId = "your-secret-id";
    String member = "user:foo@example.com";
    iamGrantAccess(projectId, secretId, member);
  }

  // Grant a member access to a particular secret.
  public static void iamGrantAccess(String projectId, String secretId, String member)
      throws IOException {
    // 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.
    try (SecretManagerServiceClient client = SecretManagerServiceClient.create()) {
      // Build the name from the version.
      SecretName secretName = SecretName.of(projectId, secretId);

      // Request the current IAM policy.
      Policy currentPolicy =
          client.getIamPolicy(
              GetIamPolicyRequest.newBuilder().setResource(secretName.toString()).build());

      // Build the new binding.
      Binding binding =
          Binding.newBuilder()
              .setRole("roles/secretmanager.secretAccessor")
              .addMembers(member)
              .build();

      // Create a new IAM policy from the current policy, adding the binding.
      Policy newPolicy = Policy.newBuilder().mergeFrom(currentPolicy).addBindings(binding).build();

      // Save the updated IAM policy.
      client.setIamPolicy(
          SetIamPolicyRequest.newBuilder()
              .setResource(secretName.toString())
              .setPolicy(newPolicy)
              .build());

      System.out.printf("Updated IAM policy for %s\n", secretId);
    }
  }
}

Node.js

Artifact Registry에 인증하려면 애플리케이션 기본 사용자 인증 정보를 설정합니다. 자세한 내용은 로컬 개발 환경의 인증 설정을 참조하세요.

/**
 * TODO(developer): Uncomment these variables before running the sample.
 */
// const name = 'projects/my-project/secrets/my-secret';
// const member = 'user:you@example.com';
//
// NOTE: Each member must be prefixed with its type. See the IAM documentation
// for more information: https://cloud.google.com/iam/docs/overview.

// Imports the Secret Manager library
const {SecretManagerServiceClient} = require('@google-cloud/secret-manager');

// Instantiates a client
const client = new SecretManagerServiceClient();

async function grantAccess() {
  // Get the current IAM policy.
  const [policy] = await client.getIamPolicy({
    resource: name,
  });

  // Add the user with accessor permissions to the bindings list.
  policy.bindings.push({
    role: 'roles/secretmanager.secretAccessor',
    members: [member],
  });

  // Save the updated IAM policy.
  await client.setIamPolicy({
    resource: name,
    policy: policy,
  });

  console.log(`Updated IAM policy for ${name}`);
}

grantAccess();

PHP

Artifact Registry에 인증하려면 애플리케이션 기본 사용자 인증 정보를 설정합니다. 자세한 내용은 로컬 개발 환경의 인증 설정을 참조하세요.

// Import the Secret Manager client library.
use Google\Cloud\SecretManager\V1\Client\SecretManagerServiceClient;

// Import the Secret Manager IAM library.
use Google\Cloud\Iam\V1\Binding;
use Google\Cloud\Iam\V1\GetIamPolicyRequest;
use Google\Cloud\Iam\V1\SetIamPolicyRequest;

/**
 * @param string $projectId Your Google Cloud Project ID (e.g. 'my-project')
 * @param string $secretId  Your secret ID (e.g. 'my-secret')
 * @param string $member Your member (e.g. 'user:foo@example.com')
 */
function iam_grant_access(string $projectId, string $secretId, string $member): void
{
    // Create the Secret Manager client.
    $client = new SecretManagerServiceClient();

    // Build the resource name of the secret.
    $name = $client->secretName($projectId, $secretId);

    // Get the current IAM policy.
    $policy = $client->getIamPolicy((new GetIamPolicyRequest)->setResource($name));

    // Update the bindings to include the new member.
    $bindings = $policy->getBindings();
    $bindings[] = new Binding([
        'members' => [$member],
        'role' => 'roles/secretmanager.secretAccessor',
    ]);
    $policy->setBindings($bindings);

    // Build the request.
    $request = (new SetIamPolicyRequest)
        ->setResource($name)
        ->setPolicy($policy);

    // Save the updated policy to the server.
    $client->setIamPolicy($request);

    // Print out a success message.
    printf('Updated IAM policy for %s', $secretId);
}

Python

Artifact Registry에 인증하려면 애플리케이션 기본 사용자 인증 정보를 설정합니다. 자세한 내용은 로컬 개발 환경의 인증 설정을 참조하세요.

def iam_grant_access(
    project_id: str, secret_id: str, member: str
) -> iam_policy_pb2.SetIamPolicyRequest:
    """
    Grant the given member access to a secret.
    """

    # Import the Secret Manager client library.
    from google.cloud import secretmanager

    # Create the Secret Manager client.
    client = secretmanager.SecretManagerServiceClient()

    # Build the resource name of the secret.
    name = client.secret_path(project_id, secret_id)

    # Get the current IAM policy.
    policy = client.get_iam_policy(request={"resource": name})

    # Add the given member with access permissions.
    policy.bindings.add(role="roles/secretmanager.secretAccessor", members=[member])

    # Update the IAM Policy.
    new_policy = client.set_iam_policy(request={"resource": name, "policy": policy})

    # Print data about the secret.
    print(f"Updated IAM policy on {secret_id}")

Ruby

Artifact Registry에 인증하려면 애플리케이션 기본 사용자 인증 정보를 설정합니다. 자세한 내용은 로컬 개발 환경의 인증 설정을 참조하세요.

# project_id = "YOUR-GOOGLE-CLOUD-PROJECT"  # (e.g. "my-project")
# secret_id  = "YOUR-SECRET-ID"             # (e.g. "my-secret")
# member     = "USER-OR-ACCOUNT"            # (e.g. "user:foo@example.com")

# Require the Secret Manager client library.
require "google/cloud/secret_manager"

# Create a Secret Manager client.
client = Google::Cloud::SecretManager.secret_manager_service

# Build the resource name of the secret.
name = client.secret_path project: project_id, secret: secret_id

# Get the current IAM policy.
policy = client.get_iam_policy resource: name

# Add new member to current bindings
policy.bindings << Google::Iam::V1::Binding.new(
  members: [member],
  role:    "roles/secretmanager.secretAccessor"
)

# Update IAM policy
new_policy = client.set_iam_policy resource: name, policy: policy

# Print a success message.
puts "Updated IAM policy for #{secret_id}"

API

참고: 다른 예시와 달리 이는 전체 IAM 정책을 대체합니다.

$ curl "https://secretmanager.googleapis.com/v1/projects/project-id/secrets/secret-id:setIamPolicy" \
    --request "POST" \
    --header "authorization: Bearer $(gcloud auth print-access-token)" \
    --header "content-type: application/json" \
    --data "{\"policy\": {\"bindings\": [{\"members\": [\"member\"], \"role\": \"roles/secretmanager.secretAccessor\"}]}}"

보안 비밀에 대한 액세스 권한을 부여하거나 취소하는 방법에 대한 자세한 내용은 보안 비밀에 대한 액세스 관리를 참조하세요.

원격 저장소에 Docker Hub 사용자 인증 정보 추가

Docker Hub 사용자 인증 정보로 원격 저장소를 업데이트하려면 다음 안내를 따르세요.

콘솔

  1. Google Cloud 콘솔에서 저장소 페이지를 엽니다.

    저장소 페이지 열기

  2. 저장소 목록에서 저장소를 선택하고 저장소 수정을 클릭합니다.

  3. 원격 저장소 인증 모드 섹션에서 Docker Hub 사용자 이름 및 Docker Hub 액세스 토큰이 포함된 보안 비밀 버전을 업데이트하거나 추가합니다.

gcloud CLI

Docker Hub 사용자 인증 정보로 원격 저장소를 업데이트하려면 다음 명령어를 실행합니다.

gcloud artifacts repositories update REPOSITORY \
    --project=PROJECT_ID \
    --location=LOCATION \
    --remote-username=USERNAME \
    --remote-password-secret-version=projects/SECRET_PROJECT_ID/secrets/SECRET_ID/versions/SECRET_VERSION

다음을 바꿉니다.

  • REPOSITORY를 Artifact Registry 원격 저장소의 이름으로 바꿉니다.
  • PROJECT_ID를 Google Cloud 프로젝트 ID로 바꿉니다.
  • LOCATION을 저장소의 리전 또는 멀티 리전 위치로 바꿉니다. 기본값을 설정하는 경우 이 플래그를 생략할 수 있습니다. 지원되는 저장소 위치 목록을 보려면 gcloud artifacts locations list 명령어를 실행합니다.
  • USERNAME을 Docker Hub 사용자 이름으로 바꿉니다.
  • SECRET_PROJECT_ID를 보안 비밀을 만든 Google Cloud 프로젝트의 프로젝트 ID로 바꿉니다.
  • SECRET_ID를 보안 비밀에 지정한 이름으로 바꿉니다.
  • SECRET_VERSION을 Docker Hub 액세스 토큰을 저장한 보안 비밀 버전으로 바꿉니다.

사용자 인증 정보는 원격 저장소에서 다음에 업스트림 소스에서 아티팩트에 대한 요청을 보낼 때 사용됩니다.

다음 단계