1. 소개
개요
Cloud Run 함수는 개발자가 서버 또는 런타임 환경을 관리할 필요 없이 HTTPS를 사용하여 트리거하거나 CloudEvents에 응답할 수 있는 단일 목적의 독립형 함수를 만들 수 있는 경량형 컴퓨팅 솔루션입니다. 블로그 게시물에서 Cloud Run 함수에 대해 자세히 알아보세요.
Cloud Run 함수 호출을 제어하는 방법에는 크게 두 가지가 있습니다. ID를 기반으로 액세스 보호와 네트워크 기반 액세스 제어를 사용하여 액세스 보호입니다. 이 Codelab에서는 첫 번째 접근 방식에 중점을 두고 함수를 호출하기 위해 ID를 기반으로 액세스를 보호하는 세 가지 시나리오를 안내합니다.
- gcloud ID 토큰을 사용하여 로컬 개발 및 테스트 목적으로 함수 호출
- 로컬에서 개발 및 테스트할 때 서비스 계정을 가장하여 프로덕션과 동일한 사용자 인증 정보를 사용합니다.
- Google 클라이언트 라이브러리를 사용하여 Google Cloud API에 대한 인증을 처리합니다(예: 서비스가 함수를 호출해야 하는 경우).
학습할 내용
- Cloud Run 함수에서 인증을 구성하고 인증이 올바르게 구성되었는지 확인하는 방법
- gcloud ID의 토큰을 제공하여 로컬 개발 환경에서 인증된 함수 호출
- 서비스 계정을 만들고 함수를 호출할 수 있는 적절한 역할을 부여하는 방법
- 함수를 호출하는 데 적절한 역할이 있는 로컬 개발 환경에서 서비스를 명의 도용하는 방법
2. 설정 및 요구사항
기본 요건
- Cloud Console에 로그인되어 있습니다.
- 이전에 HTTP 트리거 Cloud Run 함수를 배포했습니다. 빠른 시작 예시를 참고하세요.
- (선택사항) 세 번째 시나리오의 경우 이 Codelab에서는 Node.js 및 npm을 예로 사용하지만 Google 인증 클라이언트 라이브러리에서 지원하는 모든 런타임을 사용할 수 있습니다.
Cloud Shell 활성화
- Cloud Console에서 Cloud Shell 활성화
를 클릭합니다.
Cloud Shell을 처음 시작하는 경우 Cloud Shell에 대한 설명이 포함된 중간 화면이 표시됩니다. 중간 화면이 표시되면 계속을 클릭합니다.
Cloud Shell을 프로비저닝하고 연결하는 데 몇 분 정도만 걸립니다.
이 가상 머신에는 필요한 모든 개발 도구가 로드되어 있습니다. 영구적인 5GB 홈 디렉터리를 제공하고 Google Cloud에서 실행되므로 네트워크 성능과 인증이 크게 개선됩니다. 이 Codelab에서 대부분의 작업은 브라우저만으로도 수행할 수 있습니다.
Cloud Shell에 연결되면 인증이 완료되었고 프로젝트가 자신의 프로젝트 ID로 설정된 것을 확인할 수 있습니다.
- Cloud Shell에서 다음 명령어를 실행하여 인증되었는지 확인합니다.
gcloud auth list
명령어 결과
Credentialed Accounts ACTIVE ACCOUNT * <my_account>@<my_domain.com> To set the active account, run: $ gcloud config set account `ACCOUNT`
- Cloud Shell에서 다음 명령어를 실행하여 gcloud 명령어가 프로젝트를 알고 있는지 확인합니다.
gcloud config list project
명령어 결과
[core] project = <PROJECT_ID>
또는 다음 명령어로 설정할 수 있습니다.
gcloud config set project <PROJECT_ID>
명령어 결과
Updated property [core/project].
3. 인증된 Cloud Run 함수 만들기 및 테스트
인증을 요구한다는 것은 함수를 호출하는 주체에 Cloud Run 호출자 역할이 있어야 함을 의미합니다. 그렇지 않으면 함수에서 403 Forbidden 오류를 반환합니다. 이 Codelab에서는 주체에 적절한 호출자 역할을 부여하는 방법을 보여줍니다.
간소화된 gcloud 명령어를 위한 로컬 환경 변수 설정
먼저 이 Codelab에서 사용되는 gcloud
명령어의 가독성을 개선하기 위해 몇 가지 환경 변수를 만듭니다.
REGION=us-central1 PROJECT_ID=$(gcloud config get-value project)
함수의 소스 코드 만들기
이 Codelab에서는 Node.js를 사용하지만 Google 인증 클라이언트 라이브러리에서 지원하는 모든 런타임을 사용할 수 있습니다.
먼저 디렉터리를 만들고 해당 디렉터리로 이동합니다.
mkdir auth-function-codelab && cd $_
그런 다음 package.json 파일을 만듭니다.
touch package.json echo '{ "dependencies": { "@google-cloud/functions-framework": "^3.0.0" } } ' > package.json
다음으로 index.js 소스 파일을 만듭니다.
touch index.js echo 'const functions = require("@google-cloud/functions-framework"); functions.http("helloWorld", (req, res) => { res.send(`Hello ${req.query.name || req.body.name || "World"}!`); });' > index.js
인증된 함수 만들기
다음은 nodejs20 런타임용 인증 함수를 만드는 단계입니다. 하지만 Google Auth 클라이언트 라이브러리에서 지원하는 모든 런타임을 사용할 수 있습니다.
FUNCTION_NAME=authenticated-function-codelab ENTRY_POINT=helloWorld
Cloud Run 함수를 Cloud Run에 직접 배포하려면 다음 명령어를 실행합니다.
gcloud beta run deploy $FUNCTION_NAME \ --source . \ --function helloWorld \ --region $REGION \ --no-allow-unauthenticated
그런 다음 함수 URL을 환경 변수로 저장하여 나중에 사용할 수 있습니다.
FUNCTION_URL="$(gcloud run services describe $FUNCTION_NAME --region $REGION --format 'value(status.url)')"
Cloud Functions 2세대로 배포하려면 다음 명령어를 사용합니다.
gcloud functions deploy nodejs-http-function \ --gen2 \ --runtime=nodejs20 \ --region=$REGION \ --source=. \ --entry-point=helloWorld \ --trigger-http \ --no-allow-unauthenticated
그런 다음 함수 URL을 환경 변수로 저장하여 나중에 사용할 수 있습니다.
FUNCTION_URL="$(gcloud functions describe $FUNCTION_NAME --gen2 --region us-central1 --format='get(serviceConfig.uri)')"
익명 호출자로 호출을 시도하여 함수에 인증이 필요한지 확인
인증 없이 함수를 호출하여 예상되는 403 오류가 발생하는지 확인합니다.
명령줄에서 다음 curl
명령어를 실행합니다.
curl -i $FUNCTION_URL
다음과 같은 결과가 표시됩니다.
<html><head> <meta http-equiv="content-type" content="text/html;charset=utf-8"> <title>403 Forbidden</title> </head> <body text=#000000 bgcolor=#ffffff> <h1>Error: Forbidden</h1> <h2>Your client does not have permission to get URL <code>/</code> from this server.</h2> <h2></h2> </body></html>
이제 인증을 제공하여 함수를 호출할 수 있는 세 가지 시나리오를 살펴볼 준비가 되었습니다.
4. 시나리오 1: gcloud ID 토큰 사용
개발자는 로컬에서 함수를 개발하는 동안 함수를 테스트할 수 있는 방법을 원합니다. 이 섹션에서는 빠른 테스트를 실행하여 함수가 자체 ID를 사용하여 올바르게 인증되는지 확인합니다.
다음 명령어를 실행하여 gcloud
로 인증되었는지 확인합니다.
gcloud auth list
활성 ID 옆에 별표가 표시됩니다(예:
Credentialed Accounts ACTIVE ACCOUNT * <my_account>@<my_domain.com> To set the active account, run: $ gcloud config set account `ACCOUNT`
문서에서 gcloud init 설정 및 gcloud auth login에 관해 자세히 알아보세요.
그런 다음 함수를 호출하고 ID 토큰을 전달합니다.
curl $FUNCTION_URL -H "Authorization: bearer $(gcloud auth print-identity-token)"
이제 결과가 표시됩니다.
Hello World!
문제 해결
403 Forbidden 오류가 발생하면 ID에 Cloud Run 호출자 역할이 있는지 확인합니다. IAM 콘솔을 사용하여 주 구성원에게 부여된 역할을 확인할 수 있습니다.
자체 ID 토큰을 사용하면 개발 중에 함수를 빠르게 테스트할 수 있지만 인증된 함수의 호출자에게는 적절한 역할이 필요합니다. 그러지 않으면 호출자에게 403 Forbidden 오류가 발생합니다.
함수를 호출하는 역할이 있는 ID 및 서비스 계정의 수를 제한하여 최소 권한의 원칙을 따르는 것이 좋습니다. 다음 시나리오에서는 새 서비스 계정을 만들고 함수를 호출하는 데 적절한 역할을 부여하는 방법을 알아봅니다.
5. 시나리오 2: 서비스 계정 가장
이 시나리오에서는 로컬에서 개발하고 테스트할 때 함수를 호출하기 위해 서비스 계정을 가장 (즉, 권한을 가정)합니다. 서비스 계정을 가장하여 프로덕션과 동일한 사용자 인증 정보로 함수를 테스트할 수 있습니다.
이렇게 하면 역할을 확인할 뿐만 아니라 로컬 테스트 목적으로 다른 ID에 Cloud Functions 호출자 역할을 부여하지 않아도 되므로 최소 권한의 원칙을 준수할 수 있습니다.
이 Codelab에서는 이 Codelab에서 만든 함수를 호출하는 역할만 있는 새 서비스 계정을 만듭니다.
새 서비스 계정 만들기
먼저 gcloud 명령어에 사용되는 서비스 계정을 나타내는 환경 변수를 몇 개 더 만듭니다.
SERVICE_ACCOUNT_NAME="invoke-functions-codelab" SERVICE_ACCOUNT_ADDRESS=$SERVICE_ACCOUNT_NAME@$PROJECT_ID.iam.gserviceaccount.com
다음으로 서비스 계정을 만듭니다.
gcloud iam service-accounts create $SERVICE_ACCOUNT_NAME \ --display-name="Cloud Run function Authentication codelab"
서비스 계정에 Cloud Run 호출자 역할을 부여합니다.
gcloud run services add-iam-policy-binding $FUNCTION_NAME \ --region=us-central1 \ --member serviceAccount:$SERVICE_ACCOUNT_ADDRESS \ --role='roles/run.invoker'
서비스 계정을 가장하여 함수 호출
이를 위해 새롭게 생성된 서비스 계정의 ID 토큰을 가져와서 가장합니다.
명의 도용에 필요한 역할 추가
서비스 계정을 가장하려면 서비스 계정에 대한 ID 토큰을 생성할 수 있는 서비스 계정 토큰 생성자 (roles/iam.serviceAccountTokenCreator) 역할이 사용자 계정에 있어야 합니다.
다음 명령어를 실행하여 활성 사용자 계정에 이 역할을 부여할 수 있습니다.
ACCOUNT_EMAIL=$(gcloud auth list --filter=status:ACTIVE --format="value(account)") gcloud iam service-accounts add-iam-policy-binding $SERVICE_ACCOUNT_ADDRESS \ --member user:$ACCOUNT_EMAIL \ --role='roles/iam.serviceAccountTokenCreator'
서비스 계정의 ID 토큰 사용
권한이 전파될 때까지 몇 분 정도 기다립니다. 이제 서비스 계정의 ID 토큰을 전달하여 함수를 호출할 수 있습니다.
curl $FUNCTION_URL -H "Authorization: bearer $(gcloud auth print-identity-token --impersonate-service-account $SERVICE_ACCOUNT_ADDRESS)"
다음과 같은 내용이 표시됩니다.
WARNING: This command is using service account impersonation. All API calls will be executed as [invoke-functions-codelab@<project-id>.iam.gserviceaccount.com]. Hello World!
6. 시나리오 3: Google 클라이언트 라이브러리 사용
이 Codelab의 마지막 부분에서는 로컬에서 소규모 서비스를 실행하여 서비스 계정의 ID 토큰을 생성한 다음 Google 인증 클라이언트 라이브러리 및 애플리케이션 기본 사용자 인증 정보 (ADC)를 사용하여 프로그래매틱 방식으로 함수를 호출합니다. Google 클라이언트 라이브러리에 대한 자세한 내용은 문서의 클라이언트 라이브러리 설명 섹션을 참조하세요.
ADC를 사용하는 것은 다른 Google Cloud 리소스 (예: Cloud Storage, Vision API 등)와 상호작용하는 동안 로컬 (예: 노트북, Cloud Shell 등)에서 함수를 작성하고 테스트하려는 경우에 특히 중요합니다. 이 예시에서는 서비스에서 인증이 필요한 다른 함수를 호출하는 방법을 보여줍니다. ADC 및 로컬 개발에 관한 자세한 내용은 로컬에서 Cloud Functions를 개발 및 테스트하는 방법 | Google Cloud 블로그 블로그 게시물을 참고하세요.
gcloud 명령어를 실행하여 서비스 계정 명의 도용
ADC는 애플리케이션 환경을 기반으로 사용자 인증 정보를 자동으로 찾아서 Google Cloud API에 인증하는 데 사용합니다. –impersonate-service-account 플래그를 사용하면 Google Cloud API에 대한 인증에 서비스 계정의 ID를 사용하여 서비스 계정을 가장할 수 있습니다.
서비스 계정을 명의 도용하려면 다음 명령어를 실행하면 됩니다.
gcloud auth application-default login --impersonate-service-account=$SERVICE_ACCOUNT_ADDRESS
이제 ID 대신 해당 서비스 계정으로 gcloud 명령어를 실행합니다.
인증된 함수를 호출하는 서비스를 만들고 실행
각 런타임에는 설치할 수 있는 자체 Google Auth 클라이언트 라이브러리가 있습니다. 이 Codelab에서는 Node.js 앱을 로컬에서 만들고 실행하는 방법을 안내합니다.
Node.js의 경우 다음 단계를 따르세요.
- 새 디렉터리 만들기
mkdir local-dev && cd $_
- 새 Node.js 앱 만들기
npm init -y
- Google 인증 클라이언트 라이브러리 설치
npm install google-auth-library
index.js
파일 만들기- Cloud Run 함수의 URL을 가져옵니다. 이 URL은 다음 단계에서 코드에 추가합니다.
echo $FUNCTION_URL
- index.js에 다음 코드를 추가합니다. targetAudience 변수를 Cloud Run 함수 URL로 변경해야 합니다.
index.js
// Cloud Functions uses your function's url as the `targetAudience` value
const targetAudience = '<YOUR-CLOUD-RUN-FUNCTION-URL>';
// For Cloud Functions, endpoint(`url`) and `targetAudience` should be equal
const url = targetAudience;
const { GoogleAuth } = require('google-auth-library');
const auth = new GoogleAuth();
async function request() {
console.info(`request ${url} with target audience ${targetAudience}`);
// this call retrieves the ID token for the impersonated service account
const client = await auth.getIdTokenClient(targetAudience);
const res = await client.request({ url });
console.info(res.data);
}
request().catch(err => {
console.error(err.message);
process.exitCode = 1;
});
- 앱 실행
node index.js
결과로 'Hello World!'가 표시됩니다.
문제 해결
리소스에서 'iam.serviceAccounts.getOpenIdToken' 권한이 거부되었다는 오류가 표시되거나 권한이 존재하지 않는 경우 서비스 계정 토큰 생성자 역할이 적용될 때까지 몇 분 정도 기다려 주세요.
이 환경에서 ID 토큰을 가져올 수 없음 오류가 발생하고 GCE를 사용하거나 GOOGLE_APPLICATION_CREDENTIALS 환경 변수를 서비스 계정 사용자 인증 정보 JSON 파일로 설정했다면 명령어를 실행하지 않았을 수 있습니다.
gcloud auth application-default login --impersonate-service-account=$SERVICE_ACCOUNT_ADDRESS
7. 축하합니다.
축하합니다. Codelab을 완료했습니다.
Cloud Run 함수 보안에 관한 문서를 검토하는 것이 좋습니다.
로컬 개발자 환경에서 Cloud Run 함수를 개발하고 테스트하는 방법을 알아보려면 Cloud Run 함수로 로컬 개발에 관한 블로그 게시물도 참고하세요.
학습한 내용
- Cloud Run 함수에서 인증을 구성하고 인증이 올바르게 구성되었는지 확인하는 방법
- gcloud ID의 토큰을 제공하여 로컬 개발 환경에서 인증된 함수 호출
- 서비스 계정을 만들고 함수를 호출할 수 있는 적절한 역할을 부여하는 방법
- 함수 호출에 적절한 역할이 있는 로컬 개발 환경에서 서비스를 가장하는 방법
8. 삭제
의도치 않은 요금이 청구되지 않도록 하려면(예: 이 Cloud 함수가 무료 등급의 월별 Cloud Run 함수 호출 할당량보다 더 자주 실수로 호출됨) Cloud 함수를 삭제하거나 2단계에서 만든 프로젝트를 삭제하면 됩니다.
서비스 계정 가장을 중지하려면 ID를 사용하여 다시 로그인하면 됩니다.
gcloud auth application-default login
Cloud Run 함수를 삭제하려면 https://console.cloud.google.com/functions/에서 Cloud Run 함수 Cloud 콘솔로 이동합니다. 2단계에서 만든 프로젝트가 현재 선택된 프로젝트인지 확인합니다.
앞서 배포한 my-authenticated-function을 선택합니다. 삭제를 누릅니다.
전체 프로젝트를 삭제하려면 https://console.cloud.google.com/cloud-resource-manager로 이동하여 2단계에서 만든 프로젝트를 선택하고 삭제를 선택합니다. 프로젝트를 삭제하면 Cloud SDK에서 프로젝트를 변경해야 합니다. gcloud projects list
를 실행하면 사용 가능한 모든 프로젝트의 목록을 볼 수 있습니다.