이 튜토리얼에서는 증명이 필요한 Binary Authorization 정책을 구성하고 테스트하는 방법을 보여줍니다. 이 정책 유형은 이미지 배포를 허용하기 전 컨테이너 이미지에 서명된 증명이 포함되었는지 확인하여 컨테이너 기반 소프트웨어 공급망을 보호합니다.
Binary Authorization은 배포 시에 증명자를 사용하여 증명에서 디지털 서명을 확인합니다. 증명자는 일반적으로 지속적 통합(CI) 파이프라인의 일부로 서명자에 의해 생성됩니다.
이 튜토리얼에서 GKE 클러스터, 증명, 증명자는 모두 단일 프로젝트에 위치합니다. 단일 프로젝트 구성은 주로 서비스를 테스트하거나 실험하는 데 유용합니다. 실제 예시를 더 보려면 다중 프로젝트 구성을 참조하세요.
아래의 단계는 명령줄에서 수행하는 작업을 설명합니다. Google Cloud Console을 사용하여 이러한 단계를 수행하려면 Google Cloud Console 사용 시작하기를 참조하세요.
목표
이 튜토리얼에서는 다음을 수행하는 방법을 알아봅니다.
- Binary Authorization이 사용 설정된 Google Kubernetes Engine(GKE) 클러스터 만들기
- Binary Authorization 시행자가 증명의 서명을 확인하는 데 사용하는 증명자 만들기
- 증명이 필요한 정책 구성
- 암호화 키 쌍을 만들어 증명을 서명한 후 나중에 확인
- 컨테이너 이미지 다이제스트에 서명하여 서명 만들기
- 서명을 사용하여 증명 만들기
- GKE에 컨테이너 이미지를 배포하여 정책 테스트
비용
이 문서에서는 비용이 청구될 수 있는 다음과 같은 Google Cloud 구성요소를 사용합니다.
- Artifact Registry or Container Registry
- Binary Authorization
- GKE
- Optional: Cloud Key Management Service
프로젝트 사용량을 기준으로 예상 비용을 산출하려면 가격 계산기를 사용하세요.
시작하기 전에
- 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.
-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
-
Make sure that billing is enabled for your Google Cloud project.
- Install the Google Cloud CLI.
-
To initialize the gcloud CLI, run the following command:
gcloud init
-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
-
Make sure that billing is enabled for your Google Cloud project.
- Install the Google Cloud CLI.
-
To initialize the gcloud CLI, run the following command:
gcloud init
- GKE와의 상호작용을 위해
kubectl
을 설치합니다.
Binary Authorization 사용 설정
기본 프로젝트 설정
첫 번째 단계는 gcloud
명령어에서 사용되는 기본 Google Cloud 프로젝트를 설정하는 것입니다.
PROJECT_ID=PROJECT_ID gcloud config set project ${PROJECT_ID}
여기서 PROJECT_ID는 프로젝트 이름입니다.
필요한 API 사용 설정
API 사용 설정 대상:
Container Registry
gcloud --project=${PROJECT_ID} \ services enable\ container.googleapis.com\ containerregistry.googleapis.com\ binaryauthorization.googleapis.com
Artifact Registry
gcloud --project=${PROJECT_ID} \ services enable\ container.googleapis.com\ artifactregistry.googleapis.com\ binaryauthorization.googleapis.com
Binary Authorization이 사용 설정된 클러스터 만들기
클러스터 만들기
Binary Authorization이 사용 설정된 GKE 클러스터를 만듭니다. 배포된 컨테이너 이미지를 실행할 클러스터입니다. 클러스터를 만들 때 --binauthz-evaluation-mode=PROJECT_SINGLETON_POLICY_ENFORCE
플래그를 gcloud container clusters create
명령어에 전달합니다.
클러스터를 만들려면 다음 단계를 따르세요.
gcloud container clusters create \ --binauthz-evaluation-mode=PROJECT_SINGLETON_POLICY_ENFORCE \ --zone us-central1-a \ test-cluster
여기에서 GKE 영역 us-central1-a
에 test-cluster
라는 클러스터를 만듭니다.
kubectl
구성
kubectl
설치를 위해 로컬 kubeconfig
파일도 업데이트해야 합니다. 이 파일은 GKE에서 클러스터에 액세스하는 데 필요한 사용자 인증 정보와 엔드포인트 정보를 제공합니다.
로컬 kubeconfig
파일을 업데이트하려면 다음을 실행하세요.
gcloud container clusters get-credentials \ --zone us-central1-a \ test-cluster
기본 정책 보기
Binary Authorization의 정책은 컨테이너 이미지의 배포를 제어하는 규칙 집합입니다. 정책은 프로젝트당 하나만 사용할 수 있습니다. 기본적으로 정책은 모든 컨테이너 이미지를 배포하도록 구성됩니다.
Binary Authorization을 사용하면 YAML 형식으로 정책 파일을 내보내고 가져올 수 있습니다. 이 형식에는 서비스에 저장된 정책의 구조가 반영됩니다. gcloud
명령어를 사용하여 정책을 구성할 때 이 파일을 수정합니다.
기본 정책을 보려면 정책 YAML 파일을 내보내세요.
gcloud container binauthz policy export
기본적으로 파일에 포함되는 내용은 다음과 같습니다.
defaultAdmissionRule: enforcementMode: ENFORCED_BLOCK_AND_AUDIT_LOG evaluationMode: ALWAYS_ALLOW globalPolicyEvaluationMode: ENABLE name: projects/PROJECT_ID/policy
기본 규칙은 정책의 defaultAdmissionRule
노드에 정의되어 있습니다. evaluationMode
는 정책이 모든 이미지 배포 시도를 허용하도록 지정합니다. 이 튜토리얼에서는 증명을 요구하도록 기본 규칙을 업데이트합니다.
globalPolicyEvaluationMode
는 Google에서 관리하는 시스템 이미지를 Binary Authorization 시행에서 제외합니다.
허용 목록에 예외 이미지를 추가하려면 정책 파일에 다음을 추가합니다.
admissionWhitelistPatterns: - namePattern: EXEMPT_IMAGE_PATH
EXEMPT_IMAGE_PATH
를 제외할 am 이미지의 경로로 바꿉니다. 추가 이미지를 제외하려면 - namePattern
항목을 추가합니다. admissionWhitelistPatterns
에 대해 자세히 알아보세요.
정책 구조에 대한 자세한 내용은 정책 YAML 참조를 확인하세요.
증명자 만들기
증명자는 배포 시 Binary Authorization 시행자가 GKE에서 서명된 컨테이너 이미지를 배포하도록 허용할지 여부를 결정하는 확인 권한입니다. 증명자는 공개 키를 포함하며 일반적으로 소프트웨어 공급망 보안을 담당하는 조직 내 직원이 관리합니다.
증명자를 만들려면 다음을 수행해야 합니다.
- Artifact Analysis에서 메모를 만들어 승인 프로세스에 사용된 신뢰할 수 있는 메타데이터 저장
- Binary Authorization에서 증명자를 만들고 생성한 메모를 연결합니다.
이 튜토리얼에서는 test-attestor
라는 증명자 하나와 test-attestor-note
라는 컨테이너 분석 메모를 사용합니다. 실제 시나리오에서는 제한 없이 증명자를 사용할 수 있으며, 각 증명자는 컨테이너 이미지의 승인 프로세스에 참여하는 당사자를 나타냅니다.
Artifact Analysis 메모 만들기
증명자 및 Artifact Analysis 메모의 이름을 저장할 변수를 설정합니다.
ATTESTOR_NAME=test-attestor NOTE_ID=test-attestor-note
다음과 같이 바꿉니다.
- test-attestor: 선택한 증명자 이름입니다.
- attestor-note: 선택한 증명자 메모 이름입니다.
/tmp/note_payload.json
에 컨테이너 분석 메모를 설명하는 JSON 파일을 만듭니다.cat > /tmp/note_payload.json << EOM { "name": "projects/${PROJECT_ID}/notes/${NOTE_ID}", "attestation": { "hint": { "human_readable_name": "Attestor Note" } } } EOM
Artifact Analysis REST API에 HTTP 요청을 보내 메모를 만듭니다.
curl -X POST \ -H "Content-Type: application/json" \ -H "Authorization: Bearer $(gcloud auth print-access-token)" \ --data-binary @/tmp/note_payload.json \ "https://containeranalysis.googleapis.com/v1/projects/${PROJECT_ID}/notes/?noteId=${NOTE_ID}"
메모가 생성되었는지 확인합니다.
curl \ -H "Authorization: Bearer $(gcloud auth print-access-token)" \ "https://containeranalysis.googleapis.com/v1/projects/${PROJECT_ID}/notes/${NOTE_ID}"
증명자 만들기
이제 증명자를 만들 수 있습니다.
Binary Authorization에서 증명자를 만듭니다.
gcloud container binauthz attestors create ${ATTESTOR_NAME} \ --attestation-authority-note=${NOTE_ID} \ --attestation-authority-note-project=${PROJECT_ID}
증명자가 생성되었는지 확인합니다.
gcloud container binauthz attestors list
생성된 증명자는 연결된 키 쌍이 없이는 사용할 수 없습니다. 키 쌍은 이 가이드의 뒷부분에서 만듭니다.
키 쌍 생성
Binary Authorization은 암호화 키를 사용하여 서명자의 ID를 안전하게 확인합니다. 이렇게 하면 승인된 컨테이너 이미지만 배포할 수 있습니다. 키 쌍은 비공개 키와 공개 키로 구성됩니다. 서명자는 비공개 키를 사용하여 컨테이너 이미지 다이제스트를 서명합니다. 그러면 증명에 저장되는 서명이 생성됩니다. 공개 키는 증명자에 저장됩니다. 배포 시 Binary Authorization 시행자는 증명자의 공개 키를 사용하여 컨테이너의 배포를 허용하기 전에 증명의 서명을 확인합니다.
이 튜토리얼에서는 암호화 키에 공개 키 인프라 (X.509) (PKIX) 형식을 사용합니다. 이 튜토리얼에서는 PKIX 키 쌍을 생성하는 데 권장되는 타원 곡선 디지털 서명 알고리즘 (ECDSA)을 사용합니다. 이미지 서명에 RSA 또는 PGP 키를 사용할 수도 있습니다.
서명 알고리즘에 대한 자세한 내용은 키 용도 및 알고리즘을 참고하세요.
Cloud Key Management Service(Cloud KMS)에서 생성하여 저장된 키는 PKIX와 호환되는 형식입니다. PKIX 키 및 Cloud KMS 사용에 대한 자세한 내용은 gcloud CLI를 사용하여 증명자 만들기를 참조하세요.
PKIX(Cloud KMS)
Cloud KMS에서 키 쌍을 만들려면 다음 안내를 따르세요.
키 쌍을 만드는 데 필요한 환경 변수를 설정합니다.
KMS_KEY_PROJECT_ID=${PROJECT_ID} KMS_KEYRING_NAME=my-binauthz-keyring KMS_KEY_NAME=my-binauthz-kms-key-name KMS_KEY_LOCATION=global KMS_KEY_PURPOSE=asymmetric-signing KMS_KEY_ALGORITHM=ec-sign-p256-sha256 KMS_PROTECTION_LEVEL=software KMS_KEY_VERSION=1
키링을 만들려면 다음 명령어를 실행합니다.
gcloud kms keyrings create ${KMS_KEYRING_NAME} \ --location ${KMS_KEY_LOCATION}
키를 만들려면 다음 명령어를 실행합니다.
gcloud kms keys create ${KMS_KEY_NAME} \ --location ${KMS_KEY_LOCATION} \ --keyring ${KMS_KEYRING_NAME} \ --purpose ${KMS_KEY_PURPOSE} \ --default-algorithm ${KMS_KEY_ALGORITHM} \ --protection-level ${KMS_PROTECTION_LEVEL}
공개 키를 증명자에 추가하려면 다음 명령어를 실행합니다.
gcloud --project="${PROJECT_ID}" \ container binauthz attestors public-keys add \ --attestor="${ATTESTOR_NAME}" \ --keyversion-project="${KMS_KEY_PROJECT_ID}" \ --keyversion-location="${KMS_KEY_LOCATION}" \ --keyversion-keyring="${KMS_KEYRING_NAME}" \ --keyversion-key="${KMS_KEY_NAME}" \ --keyversion="${KMS_KEY_VERSION}"
다음과 같이 증명자로부터 공개 키 ID를 가져옵니다.
gcloud container binauthz attestors describe <var>ATTESTOR_NAME</var>
명령어를 사용하면 언제든지 공개 키 ID를 볼 수 있습니다.공개 키 ID를 환경 변수에 저장하려면 다음 명령어를 입력하세요.
PUBLIC_KEY_ID=$(gcloud container binauthz attestors describe ${ATTESTOR_NAME} \ --format='value(userOwnedGrafeasNote.publicKeys[0].id)' --project ${PROJECT_ID})
PKIX(로컬 키)
PKIX 키 쌍을 생성하려면 다음 단계를 따르세요.
비공개 키를 만듭니다.
PRIVATE_KEY_FILE="/tmp/ec_private.pem" openssl ecparam -genkey -name prime256v1 -noout -out ${PRIVATE_KEY_FILE}
비공개 키에서 공개 키를 추출합니다.
PUBLIC_KEY_FILE="/tmp/ec_public.pem" openssl ec -in ${PRIVATE_KEY_FILE} -pubout -out ${PUBLIC_KEY_FILE}
공개 키를 증명자에 추가합니다.
이제 Binary Authorization에서 ID 확인에 사용할 수 있도록 내보낸 공개 키를 증명자에 추가합니다.
gcloud --project="${PROJECT_ID}" \ beta container binauthz attestors public-keys add \ --attestor="${ATTESTOR_NAME}" \ --pkix-public-key-file=${PUBLIC_KEY_FILE} \ --pkix-public-key-algorithm=ecdsa-p256-sha256
공개 키 ID를 저장합니다.
공개 키 ID를 저장하려면 위의
public-keys add
결과에서 복사하면 됩니다. 증명자의 공개 키 ID를 증명자에 추가한 후 보려면gcloud container binauthz attestors describe ${ATTESTOR_NAME}
를 사용하세요.PUBLIC_KEY_ID=$(gcloud container binauthz attestors describe ${ATTESTOR_NAME} \ --format='value(userOwnedGrafeasNote.publicKeys[0].id)')
정책 구성
이제 정책을 구성할 수 있습니다. 이 단계에서는 정책 YAML 파일을 로컬 시스템으로 내보내고 위에서 정의한 증명자의 증명을 요구하도록 기본 규칙을 수정합니다.
정책을 구성하려면 다음 단계를 따르세요.
Google이 관리하는 시스템 이미지를 허용하고,
evaluationMode
를REQUIRE_ATTESTATION
으로 설정하고, 생성된 증명자를 참조하는requireAttestationsBy
라는 노드를 추가하는 새로운 정책 파일을 만듭니다.cat > /tmp/policy.yaml << EOM globalPolicyEvaluationMode: ENABLE defaultAdmissionRule: evaluationMode: REQUIRE_ATTESTATION enforcementMode: ENFORCED_BLOCK_AND_AUDIT_LOG requireAttestationsBy: - projects/${PROJECT_ID}/attestors/${ATTESTOR_NAME} name: projects/${PROJECT_ID}/policy EOM
정책 YAML 파일을 Binary Authorization으로 가져옵니다.
gcloud container binauthz policy import /tmp/policy.yaml
정책 구성에 대한 자세한 내용은 gcloud CLI를 사용하여 정책 구성을 참조하세요.
정책 테스트
클러스터에 샘플 컨테이너 이미지 배포를 시도하여 위에서 구성한 정책을 테스트할 수 있습니다. 필요한 증명이 적용되지 않은 경우 정책에서 배포를 차단합니다.
이 튜토리얼에서는 Container Registry 및 Artifact Registry의 샘플 이미지를 사용할 수 있습니다. Container Registry의 이미지는 gcr.io/google-samples/hello-app:1.0
경로에 있습니다. Artifact Registry의 이미지는 us-docker.pkg.dev/google-samples/containers/gke/hello-app:1.0
경로에 있습니다.
두 경로 모두 'Hello, World!' 샘플 애플리케이션이 포함된 Google에서 생성된 공개 이미지를 포함합니다.
먼저 이미지를 배포해 봅니다.
kubectl run hello-server --image gcr.io/google-samples/hello-app:1.0 --port 8080
이제 Binary Authorization에서 배포를 차단했는지 확인합니다.
kubectl get pods
이 명령어는 이미지가 배포되지 않았음을 나타내는 다음 메시지를 출력합니다.
No resources found.
배포에 대한 세부정보를 확인할 수 있습니다.
kubectl get event --template \ '{{range.items}}{{"\033[0;36m"}}{{.reason}}:{{"\033[0m"}}\{{.message}}{{"\n"}}{{end}}'
다음과 비슷한 응답이 표시됩니다.
FailedCreate: Error creating: pods POD_NAME is forbidden: admission webhook "imagepolicywebhook.image-policy.k8s.io" denied the request: Image IMAGE_NAME denied by Binary Authorization default admission rule. Image IMAGE_NAME denied by attestor ATTESTOR_NAME: No attestations found
이 출력에서 각 항목의 의미는 다음과 같습니다.
- POD_NAME: 포드의 이름입니다.
- IMAGE_NAME: 이미지의 이름입니다.
- ATTESTOR_NAME: 증명자의 이름입니다.
다음 단계를 진행하려면 배포를 삭제해야 합니다.
kubectl delete deployment hello-server
증명 만들기
증명은 서명자가 만든 디지털 문서로, GKE에서 연결된 컨테이너 이미지를 배포할 수 있는지 여부를 인증합니다. 증명을 만드는 프로세스는 '이미지 서명'이라고도 합니다. 서명자는 사람이거나 컨테이너 이미지를 빌드할 때 실행되는 자동화된 프로세스일 수 있습니다. 서명은 키 쌍의 비공개 키를 사용하여 생성됩니다. 배포 시 Binary Authorization 시행자는 증명의 공개 키를 사용하여 증명의 서명을 확인합니다.
이 튜토리얼에서 증명에는 단순히 이미지 배포를 승인했음이 표시됩니다.
증명을 만들려면 다음 단계를 따르세요.
이미지의 레지스트리 경로와 다이제스트를 저장할 변수를 설정합니다.
Container Registry
IMAGE_PATH="gcr.io/google-samples/hello-app" IMAGE_DIGEST="sha256:c62ead5b8c15c231f9e786250b07909daf6c266d0fcddd93fea882eb722c3be4" IMAGE_TO_ATTEST=${IMAGE_PATH}@${IMAGE_DIGEST}
Artifact Registry
IMAGE_PATH="us-docker.pkg.dev/google-samples/containers/gke/hello-app" IMAGE_DIGEST="sha256:37e5287945774f27b418ce567cd77f4bbc9ef44a1bcd1a2312369f31f9cce567" IMAGE_TO_ATTEST=${IMAGE_PATH}@${IMAGE_DIGEST}
증명을 만들려면 다음을 수행합니다.
PKIX Cloud KMS
Cloud KMS 키를 사용하여 증명을 만들려면 다음 명령어를 실행합니다.
gcloud beta container binauthz attestations sign-and-create \ --project="${PROJECT_ID}" \ --artifact-url="${IMAGE_TO_ATTEST}" \ --attestor="${ATTESTOR_NAME}" \ --attestor-project="${PROJECT_ID}" \ --keyversion-project="${KMS_KEY_PROJECT_ID}" \ --keyversion-location="${KMS_KEY_LOCATION}" \ --keyversion-keyring="${KMS_KEYRING_NAME}" \ --keyversion-key="${KMS_KEY_NAME}" \ --keyversion="${KMS_KEY_VERSION}"
PKIX(로컬 키)
로컬 키를 사용하여 증명을 만들려면 다음 단계를 따르세요.
증명 페이로드를 생성합니다.
gcloud container binauthz create-signature-payload \ --artifact-url=${IMAGE_TO_ATTEST} > /tmp/generated_payload.json
페이로드 JSON 파일에 포함되는 내용은 다음과 같습니다.
{ "critical": { "identity": { "docker-reference": "gcr.io/google-samples/hello-app" }, "image": { "docker-manifest-digest": "sha256:c62ead5b8c15c231f9e786250b07909daf6c266d0fcddd93fea 882eb722c3be4" }, "type": "Google cloud binauthz container signature" } }
PKIX 비공개 키로 페이로드에 서명하고 서명 파일을 생성하려면 다음 명령어를 실행합니다.
openssl dgst -sha256 -sign ${PRIVATE_KEY_FILE} /tmp/generated_payload.json > /tmp/ec_signature
서명 파일은 이 가이드의 앞부분에서 만든 페이로드 JSON 파일의 서명된 버전입니다.
증명을 만들고 검증합니다.
gcloud container binauthz attestations create \ --project="${PROJECT_ID}" \ --artifact-url="${IMAGE_TO_ATTEST}" \ --attestor="projects/${PROJECT_ID}/attestors/${ATTESTOR_NAME}" \ --signature-file=/tmp/ec_signature \ --public-key-id="${PUBLIC_KEY_ID}" \ --validate
PUBLIC_KEY_ID
를 위의 PKIX 키 쌍 생성에서 찾은 공개 키 ID로 바꿉니다.validate
플래그는 정책에 구성된 증명자로 증명을 확인할 수 있는지 검사합니다.
증명이 생성되었는지 확인합니다.
gcloud container binauthz attestations list \ --attestor=$ATTESTOR_NAME --attestor-project=$PROJECT_ID
증명 만들기에 대한 자세한 내용은 증명 만들기를 참조하세요.
정책 다시 테스트
다시 샘플 컨테이너 이미지를 클러스터에 배포하여 정책을 테스트합니다.
Binary Authorization에서 다이제스트를 사용하여 증명을 조회하므로 이번에는 1.0
또는 latest
와 같은 태그가 아닌 다이제스트를 사용하여 이미지를 배포해야 합니다. 여기에서는 필요한 증명이 적용되었으므로 Binary Authorization을 통해 이미지를 배포할 수 있습니다.
이미지를 배포하려면 다음 단계를 따르세요.
kubectl run hello-server --image ${IMAGE_TO_ATTEST} --port 8080
이미지가 배포되었는지 확인하려면 다음을 실행하세요.
kubectl get pods
위 명령어가 반환하는 메시지는 다음과 같으며, 배포가 성공했음을 나타냅니다.
NAME READY STATUS RESTARTS AGE hello-server-579859fb5b-h2k8s 1/1 Running 0 1m
삭제
이 튜토리얼에서 사용된 리소스 비용이 Google Cloud 계정에 청구되지 않도록 하려면 리소스가 포함된 프로젝트를 삭제하거나 프로젝트를 유지하고 개별 리소스를 삭제하세요.
GKE에서 만든 클러스터를 삭제합니다.
gcloud container clusters delete \ --zone=us-central1-a \ test-cluster
다음 단계
- Binary Authorization 자세히 알아보기
- Binary Authorization에서 사용되는 주요 개념 알아보기
built-by-cloud-build
증명자를 사용하여 Cloud Build에서 빌드한 이미지만 배포 (미리보기)합니다.- 테스트 실행 모드를 사용 설정하여 시행 중지
- breakglass를 사용하여 시행 우회