이 튜토리얼에서는 Secret Manager에서 Google Kubernetes Engine(GKE) 클러스터에 사용되는 민감한 정보를 저장하고 GKE 및 Google Cloud 클라이언트 라이브러리용 워크로드 아이덴티티 제휴를 사용하여 포드의 데이터에 보다 안전하게 액세스하는 방법을 보여줍니다. 이 튜토리얼은 클러스터 내 스토리지 외부로 민감한 정보를 이동하려는 보안 관리자를 대상으로 합니다.
민감한 정보를 클러스터 스토리지 외부에 저장하면 공격이 발생하더라도 데이터에 대한 무단 액세스 위험을 줄일 수 있습니다. GKE용 워크로드 아이덴티티 제휴를 사용하여 데이터에 액세스하면 장기 실행 서비스 계정 키 관리와 관련된 위험을 방지하고 클러스터 내 RBAC 규칙 대신 Identity and Access Management(IAM)를 사용하여 보안 비밀에 대한 액세스를 제어할 수 있습니다. Secret Manager 또는 HashiCorp Vault와 같은 외부 보안 비밀 저장소 공급업체를 사용할 수 있습니다.
이 튜토리얼에서는 GKE Autopilot 클러스터를 사용합니다. GKE Standard를 사용하여 단계를 수행하려면 GKE용 워크로드 아이덴티티 제휴를 수동으로 사용 설정해야 합니다.
GKE용 워크로드 아이덴티티 제휴를 사용하면 정적 서비스 계정 키 파일과 같은 보안 수준이 낮은 접근 방식을 사용하지 않고도 GKE 워크로드에서 Google Cloud API에 액세스할 수 있습니다. 이 튜토리얼에서는 예시로 Secret Manager를 사용하지만 동일한 단계를 따라 다른 Google Cloud API에 액세스할 수 있습니다. 자세한 내용은 GKE용 워크로드 아이덴티티 제휴를 참조하세요.
목표
- Google Cloud Secret Manager에서 보안 비밀을 만듭니다.
- GKE Autopilot 클러스터, Kubernetes 네임스페이스, Kubernetes 서비스 계정을 만듭니다.
- 보안 비밀에 Kubernetes 서비스 계정에 대한 액세스 권한을 부여하는 IAM 허용 정책을 만듭니다.
- 테스트 애플리케이션을 사용하여 서비스 계정 액세스를 확인합니다.
- Secret Manager API를 사용하여 보안 비밀에 액세스하는 샘플 앱을 실행합니다.
비용
이 문서에서는 비용이 청구될 수 있는 다음과 같은 Google Cloud 구성요소를 사용합니다.
프로젝트 사용량을 기준으로 예상 비용을 산출하려면 가격 계산기를 사용하세요.
이 문서에 설명된 태스크를 완료했으면 만든 리소스를 삭제하여 청구가 계속되는 것을 방지할 수 있습니다. 자세한 내용은 삭제를 참조하세요.
시작하기 전에
- Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
- Install the Google Cloud CLI.
-
To initialize the gcloud CLI, run the following command:
gcloud init
-
Create or select a Google Cloud project.
-
Create a Google Cloud project:
gcloud projects create PROJECT_ID
Replace
PROJECT_ID
with a name for the Google Cloud project you are creating. -
Select the Google Cloud project that you created:
gcloud config set project PROJECT_ID
Replace
PROJECT_ID
with your Google Cloud project name.
-
-
Make sure that billing is enabled for your Google Cloud project.
-
Enable the Kubernetes Engine and Secret Manager APIs:
gcloud services enable container.googleapis.com
secretmanager.googleapis.com - Install the Google Cloud CLI.
-
To initialize the gcloud CLI, run the following command:
gcloud init
-
Create or select a Google Cloud project.
-
Create a Google Cloud project:
gcloud projects create PROJECT_ID
Replace
PROJECT_ID
with a name for the Google Cloud project you are creating. -
Select the Google Cloud project that you created:
gcloud config set project PROJECT_ID
Replace
PROJECT_ID
with your Google Cloud project name.
-
-
Make sure that billing is enabled for your Google Cloud project.
-
Enable the Kubernetes Engine and Secret Manager APIs:
gcloud services enable container.googleapis.com
secretmanager.googleapis.com -
Grant roles to your user account. Run the following command once for each of the following IAM roles:
roles/secretmanager.admin, roles/container.clusterAdmin
gcloud projects add-iam-policy-binding PROJECT_ID --member="user:USER_IDENTIFIER" --role=ROLE
- Replace
PROJECT_ID
with your project ID. -
Replace
USER_IDENTIFIER
with the identifier for your user account. For example,user:myemail@example.com
. - Replace
ROLE
with each individual role.
- Replace
환경 준비
이 튜토리얼의 샘플 파일이 포함된 GitHub 저장소를 클론합니다.
git clone https://github.com/GoogleCloudPlatform/kubernetes-engine-samples
cd ~/kubernetes-engine-samples/security/wi-secrets
Secret Manager에서 보안 비밀 만들기
다음 예시에서는 보안 비밀을 만들기 위해 사용할 데이터를 보여줍니다.
샘플 데이터를 저장하기 위해 보안 비밀을 만듭니다.
gcloud secrets create bq-readonly-key \ --data-file=manifests/bq-readonly-key \ --ttl=3600s
이 명령어는 다음을 수행합니다.
us-central1
Google Cloud 리전에서 샘플 키를 사용하여 새로운 Secret Manager 보안 비밀을 만듭니다.- 명령어를 실행한지 한 시간 후 만료되도록 보안 비밀을 설정합니다.
클러스터 및 Kubernetes 리소스 만들기
GKE 클러스터, Kubernetes 네임스페이스, Kubernetes 서비스 계정을 만듭니다. 보안 비밀에 대한 읽기 전용 액세스와 읽기-쓰기 액세스가 있는 2개의 네임스페이스를 만듭니다. 또한 각 네임스페이스에서 GKE용 워크로드 아이덴티티 제휴에 사용할 Kubernetes 서비스 계정을 만듭니다.
GKE Autopilot 클러스터를 만듭니다.
gcloud container clusters create-auto secret-cluster \ --region=us-central1
클러스터는 배포하는 데 약 5분 정도 걸릴 수 있습니다. Autopilot 클러스터에는 항상 GKE용 워크로드 아이덴티티 제휴가 사용 설정됩니다. 대신 GKE Standard 클러스터를 사용하려면 계속하기 전 GKE용 워크로드 아이덴티티 제휴를 수동으로 사용 설정해야 합니다.
readonly-ns
네임스페이스 및admin-ns
네임스페이스를 만듭니다.kubectl create namespace readonly-ns kubectl create namespace admin-ns
readonly-sa
Kubernetes 서비스 계정 및admin-sa
Kubernetes 서비스 계정을 만듭니다.kubectl create serviceaccount readonly-sa --namespace=readonly-ns kubectl create serviceaccount admin-sa --namespace=admin-ns
IAM 허용 정책 만들기
readonly-sa
서비스 계정에 보안 비밀에 대한 읽기 전용 액세스를 부여합니다.gcloud secrets add-iam-policy-binding bq-readonly-key \ --member=principal://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/PROJECT_ID.svc.id.goog/subject/ns/readonly-ns/sa/readonly-sa \ --role='roles/secretmanager.secretAccessor' \ --condition=None
다음을 바꿉니다.
PROJECT_NUMBER
: 숫자형 Google Cloud 프로젝트 번호PROJECT_ID
: Google Cloud 프로젝트 ID
admin-sa
서비스 계정에 보안 비밀에 대한 읽기-쓰기 액세스를 부여합니다.gcloud secrets add-iam-policy-binding bq-readonly-key \ --member=principal://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/PROJECT_ID.svc.id.goog/subject/ns/admin-ns/sa/admin-sa \ --role='roles/secretmanager.secretAccessor' \ --condition=None gcloud secrets add-iam-policy-binding bq-readonly-key \ --member=principal://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/PROJECT_ID.svc.id.goog/subject/ns/admin-ns/sa/admin-sa \ --role='roles/secretmanager.secretVersionAdder' \ --condition=None
보안 비밀 액세스 확인
각 네임스페이스에 테스트 포드를 배포하여 읽기 전용 및 읽기-쓰기 액세스를 확인합니다.
읽기 전용 포드 매니페스트를 검토합니다.
이 포드는
readonly-ns
네임스페이스에서readonly-sa
서비스 계정을 사용합니다.읽기-쓰기 포드 매니페스트를 검토합니다.
이 포드는
admin-ns
네임스페이스에서admin-sa
서비스 계정을 사용합니다.테스트 포드를 배포합니다.
kubectl apply -f manifests/admin-pod.yaml kubectl apply -f manifests/readonly-pod.yaml
포드 실행이 시작하는 데 몇 분 정도 걸릴 수 있습니다. 진행률을 모니터링하려면 다음 명령어를 실행합니다.
watch kubectl get pods -n readonly-ns
포드 상태가
RUNNING
으로 변경되면Ctrl+C
를 눌러 명령줄로 돌아갑니다.
읽기 전용 액세스 테스트
readonly-test
포드에서 셸을 엽니다.kubectl exec -it readonly-test --namespace=readonly-ns -- /bin/bash
보안 비밀을 읽어봅니다.
gcloud secrets versions access 1 --secret=bq-readonly-key
출력은
key=my-api-key
입니다.보안 비밀에 새 데이터를 기록해봅니다.
printf "my-second-api-key" | gcloud secrets versions add bq-readonly-key --data-file=-
출력은 다음과 비슷합니다.
ERROR: (gcloud.secrets.versions.add) PERMISSION_DENIED: Permission 'secretmanager.versions.add' denied for resource 'projects/PROJECT_ID/secrets/bq-readonly-key' (or it may not exist).
읽기 전용 서비스 계정을 사용하는 포드는 보안 비밀을 읽을 수만 있고 새 데이터를 쓸 수 없습니다.
포드를 종료합니다.
exit
읽기-쓰기 액세스 테스트
admin-test
포드에서 셸을 엽니다.kubectl exec -it admin-test --namespace=admin-ns -- /bin/bash
보안 비밀을 읽어봅니다.
gcloud secrets versions access 1 --secret=bq-readonly-key
출력은
key=my-api-key
입니다.보안 비밀에 새 데이터를 기록해봅니다.
printf "my-second-api-key" | gcloud secrets versions add bq-readonly-key --data-file=-
출력은 다음과 비슷합니다.
Created version [2] of the secret [bq-readonly-key].
새 보안 비밀 버전을 읽습니다.
gcloud secrets versions access 2 --secret=bq-readonly-key
출력은
my-second-api-key
입니다.포드를 종료합니다.
exit
포드는 사용자가 포드 매니페스트에서 사용된 Kubernetes 서비스 계정에 부여한 액세스 수준만 받습니다. admin-ns
네임스페이스에서 admin-sa
Kubernetes 계정을 사용하는 모든 포드는 새 버전의 보안 비밀을 작성할 수 있지만 readonly-sa
Kubernetes 서비스 계정을 사용하는 readonly-ns
네임스페이스의 포드는 보안 비밀을 읽을 수만 있습니다.
코드에서 보안 비밀 액세스
이 섹션에서는 다음과 같은 작업을 수행하게 됩니다.
클라이언트 라이브러리를 사용하여 Secret Manager에서 보안 비밀을 읽는 샘플 애플리케이션을 배포합니다.
애플리케이션이 보안 비밀에 액세스할 수 있는지 확인합니다.
가능한 한 모든 경우에 Secret Manager API를 사용하여 애플리케이션 코드에서 Secret Manager 보안 비밀에 액세스합니다.
샘플 애플리케이션 소스 코드를 검토합니다.
이 애플리케이션은 Secret Manager API를 호출하여 보안 비밀 읽기를 시도합니다.
샘플 애플리케이션 포드 매니페스트를 검토합니다.
이 매니페스트는 다음을 수행합니다.
readonly-ns
네임스페이스에서readonly-sa
서비스 계정을 사용하는 포드를 만듭니다.- Google 이미지 레지스트리에서 샘플 애플리케이션을 가져옵니다. 이 애플리케이션은 Google Cloud 클라이언트 라이브러리를 사용하여 Secret Manager API를 호출합니다. 저장소의
/main.go
에서 애플리케이션 코드를 볼 수 있습니다. - 사용할 샘플 애플리케이션의 환경 변수를 설정합니다.
샘플 애플리케이션에서 환경 변수를 바꿉니다.
sed -i "s/YOUR_PROJECT_ID/PROJECT_ID/g" "manifests/secret-app.yaml"
샘플 앱을 배포합니다.
kubectl apply -f manifests/secret-app.yaml
포드 작동을 시작하는 데 몇 분 정도 걸릴 수 있습니다. 포드에 클러스터에서 새 노드가 필요하면 GKE가 포드를 프로비저닝하는 동안
CrashLoopBackOff
유형 이벤트가 표시될 수 있습니다. 노드가 성공적으로 프로비저닝되면 충돌이 중지됩니다.보안 비밀 액세스를 확인합니다.
kubectl logs readonly-secret-test -n readonly-ns
출력은
my-second-api-key
입니다. 출력이 비어 있으면 포드가 아직 실행 중이 아닐 수 있습니다. 잠시 후 다시 시도해 보세요.
대체 방법
민감한 정보를 포드에 마운트해야 하는 경우 GKE용 Secret Manager 부가기능(미리보기)을 사용합니다. 이 부가기능은 GKE 클러스터에서 Kubernetes Secret Store CSI 드라이버의 Google Cloud Secret Manager 제공업체를 배포하고 관리합니다. 자세한 내용은 GKE에서 Secret Manager 부가기능 사용을 참조하세요.
보안 비밀을 마운트된 볼륨으로 제공할 때는 다음과 같은 위험이 있습니다.
- 마운트된 볼륨은 디렉터리 순회 공격에 취약합니다.
- 디버그 엔드포인트 열기와 같은 잘못된 구성으로 인해 환경 변수가 손상될 수 있습니다.
가능한 한 모든 경우에 Secret Manager API를 통해 보안 비밀에 프로그래매틱 방식으로 액세스하는 것이 좋습니다. 자세한 내용은 이 튜토리얼의 샘플 애플리케이션 도는 Secret Manager 클라이언트 라이브러리를 참조하세요.
삭제
이 튜토리얼에서 사용된 리소스 비용이 Google Cloud 계정에 청구되지 않도록 하려면 리소스가 포함된 프로젝트를 삭제하거나 프로젝트를 유지하고 개별 리소스를 삭제하세요.
개별 리소스 삭제
다음과 같이 클러스터를 삭제합니다.
gcloud container clusters delete secret-cluster \ --region=us-central1
선택사항: Secret Manager에서 보안 비밀을 삭제합니다.
gcloud secrets delete bq-readonly-key
이 단계를 수행하지 않으면 만들기 중
--ttl
플래그를 설정하여 보안 비밀이 자동으로 만료됩니다.
프로젝트 삭제
Delete a Google Cloud project:
gcloud projects delete PROJECT_ID
다음 단계
- GKE용 워크로드 아이덴티티 제휴 작동 방식에 대해 자세히 알아봅니다.
- Google Cloud에 대한 참조 아키텍처, 다이어그램, 권장사항을 살펴봅니다. Cloud 아키텍처 센터를 살펴보세요.