서비스 계정을 사용하여 Google Cloud API에 워크로드 인증


이 페이지에서는 서비스 계정을 사용하여 가상 머신(VM) 인스턴스에서 실행되는 앱이 Google Cloud API에 인증하고 리소스에 대한 액세스를 승인하도록 하는 방법을 설명합니다.

인증에 서비스 계정을 사용하려면 먼저 VM이 서비스 계정을 사용하도록 구성되었는지 확인해야 합니다. 이렇게 하려면 다음 절차 중 하나를 수행해야 합니다.

시작하기 전에

  • 서비스 계정 개요를 검토합니다.
  • 아직 인증을 설정하지 않았다면 설정합니다. 인증은 Google Cloud 서비스 및 API에 액세스하기 위해 ID를 확인하는 프로세스입니다. 로컬 개발 환경에서 코드 또는 샘플을 실행하려면 다음과 같이 Compute Engine에 인증하면 됩니다.

    이 페이지의 Python 샘플을 로컬 개발 환경에서 사용하려면 gcloud CLI를 설치 및 초기화한 다음 사용자 인증 정보로 애플리케이션 기본 사용자 인증 정보를 설정하세요.

    1. Google Cloud CLI를 설치합니다.
    2. gcloud CLI를 초기화하려면 다음 명령어를 실행합니다.

      gcloud init
    3. Google 계정의 로컬 인증 사용자 인증 정보를 만듭니다.

      gcloud auth application-default login

    자세한 내용은 다음을 참조하세요: Set up authentication for a local development environment.

개요

서비스 계정을 사용하여 실행할 VM 인스턴스를 설정하면 VM 인스턴스에서 실행되는 애플리케이션이 다음 인증 방법 중 하나를 사용할 수 있습니다.

서비스 계정 사용자 인증 정보를 사용하여 애플리케이션 인증

서비스 계정으로 실행되도록 인스턴스를 설정한 후 서비스 계정 사용자 인증 정보를 사용하여 인스턴스에서 실행 중인 애플리케이션을 인증할 수 있습니다.

클라이언트 라이브러리로 애플리케이션 인증

클라이언트 라이브러리에서는 애플리케이션 기본 사용자 인증 정보를 사용하여 Google API로 인증하고 이 API에 요청을 보낼 수 있습니다. 애플리케이션에서는 애플리케이션 기본 사용자 인증 정보를 통해 자동으로 여러 소스에서 사용자 인증 정보를 가져올 수 있으므로 애플리케이션 코드를 변경하지 않고 로컬에서 애플리케이션을 테스트한 다음 Compute Engine 인스턴스에 배포할 수 있습니다.

애플리케이션 기본 사용자 인증 정보에 대한 자세한 내용은 애플리케이션 기본 사용자 인증 정보에 사용자 인증 정보 제공을 참조하세요.

이 예시에서는 Python 클라이언트 라이브러리를 사용하여 Cloud Storage API를 인증하고 프로젝트의 버킷을 나열하도록 요청합니다. 이 예시에서는 다음 절차를 사용합니다.

  1. Cloud Storage API에 필요한 사용자 인증 정보를 가져오고 build() 메서드와 사용자 인증 정보로 Cloud Storage 서비스를 초기화합니다.
  2. Cloud Storage의 버킷을 나열합니다.

Cloud Storage에서 버킷을 관리할 수 있는 액세스 권한이 있는 인스턴스에서 이 샘플을 실행할 수 있습니다.

import argparse
from typing import List

from google.cloud import storage

def create_client() -> storage.Client:
    """
    Construct a client object for the Storage API using the
    application default credentials.

    Returns:
        Storage API client object.
    """
    # Construct the service object for interacting with the Cloud Storage API -
    # the 'storage' service, at version 'v1'.
    # Authentication is provided by application default credentials.
    # When running locally, these are available after running
    # `gcloud auth application-default login`. When running on Compute
    # Engine, these are available from the environment.
    return storage.Client()

def list_buckets(client: storage.Client, project_id: str) -> List[storage.Bucket]:
    """
    Retrieve bucket list of a project using provided client object.

    Args:
        client: Storage API client object.
        project_id: name of the project to list buckets from.

    Returns:
        List of Buckets found in the project.
    """
    buckets = client.list_buckets()
    return list(buckets)

def main(project_id: str) -> None:
    client = create_client()
    buckets = list_buckets(client, project_id)
    print(buckets)

if __name__ == "__main__":
    parser = argparse.ArgumentParser(
        description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter
    )
    parser.add_argument("project_id", help="Your Google Cloud Project ID.")

    args = parser.parse_args()

    main(args.project_id)

액세스 토큰으로 직접 애플리케이션 인증

대부분의 애플리케이션에서는 사용자 인증 정보를 찾아 토큰을 관리하는 애플리케이션 기본 사용자 인증 정보를 사용하여 인증할 수 있습니다. 하지만 애플리케이션에서 OAuth2 액세스 토큰의 제공을 요구하는 경우 Compute Engine을 통해 메타데이터 서버에서 애플리케이션에서 사용할 액세스 토큰을 가져올 수 있습니다.

애플리케이션을 인증하도록 이러한 액세스 토큰을 가져오고 사용하는 몇 가지 옵션이 있습니다. 예를 들어 curl을 사용하여 간단한 요청을 만들거나 Python과 같은 프로그래밍 언어를 사용하여 유연성을 높일 수 있습니다.

cURL

curl을 사용하여 액세스 토큰을 요청하고 API에 요청을 보내려면 다음 안내를 따르세요.

  1. 애플리케이션이 실행되는 인스턴스에서 다음 명령어를 실행하여 메타데이터 서버에 액세스 토큰을 쿼리합니다.

    $ curl "http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token" \
    -H "Metadata-Flavor: Google"

    요청을 실행하면 다음과 비슷한 응답이 반환됩니다.

    {
          "access_token":"ya29.AHES6ZRN3-HlhAPya30GnW_bHSb_QtAS08i85nHq39HE3C2LTrCARA",
          "expires_in":3599,
          "token_type":"Bearer"
     }

    API 요청의 경우 전체 응답이 아닌 access_token 값을 포함해야 합니다. jq 명령줄 JSON 프로세서가 설치되었으면 다음 명령어를 사용하여 응답에서 액세스 토큰 값을 추출할 수 있습니다.

    $ ACCESS_TOKEN=`curl \
    "http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token" \
    -H "Metadata-Flavor: Google" | jq -r '.access_token'`
    
  2. 응답에서 access_token 속성 값을 복사하고 이 값을 사용하여 API에 요청을 보냅니다. 예를 들어 다음 요청은 특정 영역의 프로젝트에 있는 인스턴스를 목록으로 출력합니다.

    $ curl https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/zones/ZONE/instances \
    -H "Authorization":"Bearer ACCESS_TOKEN"
    

    다음을 바꿉니다.

    • PROJECT_ID: 요청의 프로젝트 ID입니다.
    • ZONE: VM을 나열할 영역입니다.
    • ACCESS_TOKEN: 이전 단계에서 가져온 액세스 토큰 값입니다.

    요청에 설정할 수 있는 매개변수에 대한 자세한 내용은 시스템 매개변수 문서를 참조하세요.

Python

다음 예시에서는 Python 애플리케이션에서 Cloud Storage API에 액세스할 수 있는 토큰을 요청하는 방법을 보여줍니다. 이 예시에서는 다음 절차를 따릅니다.

  1. 메타데이터 서버에서 액세스 토큰을 요청합니다.
  2. 서버 응답에서 액세스 토큰을 추출합니다.
  3. 액세스 토큰을 사용하여 Cloud Storage에 요청합니다.
  4. 요청이 성공하면 스크립트가 응답을 출력합니다.

import argparse

import requests

METADATA_URL = "http://metadata.google.internal/computeMetadata/v1/"
METADATA_HEADERS = {"Metadata-Flavor": "Google"}
SERVICE_ACCOUNT = "default"

def get_access_token() -> str:
    """
    Retrieves access token from the metadata server.

    Returns:
        The access token.
    """
    url = f"{METADATA_URL}instance/service-accounts/{SERVICE_ACCOUNT}/token"

    # Request an access token from the metadata server.
    r = requests.get(url, headers=METADATA_HEADERS)
    r.raise_for_status()

    # Extract the access token from the response.
    access_token = r.json()["access_token"]

    return access_token

def list_buckets(project_id: str, access_token: str) -> dict:
    """
    Calls Storage API to retrieve a list of buckets.

    Args:
        project_id: name of the project to list buckets from.
        access_token: access token to authenticate with.

    Returns:
        Response from the API.
    """
    url = "https://www.googleapis.com/storage/v1/b"
    params = {"project": project_id}
    headers = {"Authorization": f"Bearer {access_token}"}

    r = requests.get(url, params=params, headers=headers)
    r.raise_for_status()

    return r.json()

def main(project_id: str) -> None:
    """
    Retrieves access token from metadata server and uses it to list
    buckets in a project.

    Args:
        project_id: name of the project to list buckets from.
    """
    access_token = get_access_token()
    buckets = list_buckets(project_id, access_token)
    print(buckets)

if __name__ == "__main__":
    parser = argparse.ArgumentParser(
        description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter
    )
    parser.add_argument("project_id", help="Your Google Cloud project ID.")

    args = parser.parse_args()

    main(args.project_id)

액세스 토큰은 짧은 기간이 지나면 만료됩니다. 메타데이터 서버에서는 액세스 토큰이 만료되기 전 남은 시간이 5분이 될 때까지 액세스 토큰을 캐시합니다. 토큰을 캐시할 수 없는 경우 초당 쿼리 수가 50개 이상인 요청에 비율 제한이 적용될 수 있습니다. API 호출이 성공하려면 애플리케이션에 유효한 액세스 토큰이 있어야 합니다.

서비스 계정을 사용하여 인스턴스에서 도구 인증

일부 애플리케이션에서는 대부분의 Compute Engine 이미지에 기본적으로 포함된 gcloudgsutil 도구의 명령어를 사용할 수 있습니다. 이러한 도구는 인스턴스의 서비스 계정과 서비스 계정에 부여된 관련 권한을 자동으로 인식합니다. 특히 서비스 계정에 올바른 역할을 부여했다면 gcloud auth login을 사용하지 않고도 인스턴스에서 gcloudgsutil 도구를 사용할 수 있습니다.

서비스 계정은 자동으로 인식되며 인스턴스에 포함된 gcloud 도구와 gsutil 도구에만 인식이 적용됩니다. 새 도구를 만들거나 커스텀 도구를 추가한 경우 클라이언트 라이브러리를 사용하거나 애플리케이션에서 직접 액세스 토큰을 사용하여 애플리케이션을 승인해야 합니다.

자동 서비스 계정 인식을 활용하려면 서비스 계정에 적절한 IAM 역할을 부여하고 서비스 계정을 인스턴스에 연결합니다. 예를 들어 서비스 계정에 roles/storage.objectAdmin 역할을 부여하면 gsutil 도구는 자동으로 Cloud Storage 객체를 관리하고 액세스할 수 있습니다.

마찬가지로 서비스 계정에 roles/compute.instanceAdmin.v1을 사용 설정하면 gcloud compute 도구는 자동으로 인스턴스를 관리할 수 있습니다.

다음 단계

직접 사용해 보기

Google Cloud를 처음 사용하는 경우 계정을 만들어 실제 시나리오에서 Compute Engine의 성능을 평가할 수 있습니다. 신규 고객에게는 워크로드를 실행, 테스트, 배포할 수 있는 무료 크레딧 $300가 제공됩니다.

Compute Engine 무료로 사용해 보기