이 튜토리얼에서는 증명이 필요한 Binary Authorization 정책을 구성하고 테스트하는 방법을 보여줍니다. 이 정책 유형은 이미지 배포를 허용하기 전 컨테이너 이미지에 서명된 증명이 포함되었는지 확인하여 컨테이너 기반 소프트웨어 공급망을 보호합니다.
Binary Authorization은 배포 시에 증명자를 사용하여 증명에서 디지털 서명을 확인합니다. 증명자는 일반적으로 지속적 통합(CI) 파이프라인의 일부로 서명자에 의해 생성됩니다.
이 튜토리얼에서 GKE 클러스터, 증명, 증명자는 모두 단일 프로젝트에 위치합니다. 단일 프로젝트 구성은 주로 서비스를 테스트하거나 실험하는 데 유용합니다. 실제 예시를 더 보려면 다중 프로젝트 구성을 참조하세요.
아래의 단계는 명령줄에서 수행하는 작업을 설명합니다. Google Cloud Console을 사용하여 이러한 단계를 수행하려면 Google Cloud Console 사용 시작하기를 참조하세요.
목표
이 튜토리얼에서는 다음을 수행하는 방법을 알아봅니다.
- Binary Authorization이 사용 설정된 Google Kubernetes Engine(GKE) 클러스터 만들기
- Binary Authorization 시행자가 증명의 서명을 확인하는 데 사용하는 증명자 만들기
- 증명이 필요한 정책 구성
- 암호화 키 쌍을 만들어 증명을 서명한 후 나중에 확인
- 컨테이너 이미지 다이제스트에 서명하여 서명 만들기
- 서명을 사용하여 증명 만들기
- GKE에 컨테이너 이미지를 배포하여 정책 테스트
비용
이 가이드에서는 비용이 청구될 수 있는 다음과 같은 Google Cloud 구성요소를 사용합니다.
프로젝트 사용량을 기준으로 예상 비용을 산출하려면 가격 계산기를 사용하세요.
시작하기 전에
- Google Cloud 계정에 로그인합니다. Google Cloud를 처음 사용하는 경우 계정을 만들고 Google 제품의 실제 성능을 평가해 보세요. 신규 고객에게는 워크로드를 실행, 테스트, 배포하는 데 사용할 수 있는 $300의 무료 크레딧이 제공됩니다.
-
Google Cloud Console의 프로젝트 선택기 페이지에서 Google Cloud 프로젝트를 선택하거나 만듭니다.
-
Cloud 프로젝트에 결제가 사용 설정되어 있는지 확인합니다. 프로젝트에 결제가 사용 설정되어 있는지 확인하는 방법을 알아보세요.
- Google Cloud CLI를 설치합니다.
-
gcloud CLI를 초기화하려면 다음 명령어를 실행합니다.
gcloud init
-
Google Cloud Console의 프로젝트 선택기 페이지에서 Google Cloud 프로젝트를 선택하거나 만듭니다.
-
Cloud 프로젝트에 결제가 사용 설정되어 있는지 확인합니다. 프로젝트에 결제가 사용 설정되어 있는지 확인하는 방법을 알아보세요.
- Google Cloud CLI를 설치합니다.
-
gcloud CLI를 초기화하려면 다음 명령어를 실행합니다.
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
기본적으로 파일에 포함되는 내용은 다음과 같습니다.
admissionWhitelistPatterns: - namePattern: gcr.io/google_containers/* - namePattern: gcr.io/google-containers/* - namePattern: k8s.gcr.io/** - namePattern: gke.gcr.io/** - namePattern: gcr.io/stackdriver-agents/* globalPolicyEvaluationMode: ENABLE defaultAdmissionRule: evaluationMode: ALWAYS_ALLOW enforcementMode: ENFORCED_BLOCK_AND_AUDIT_LOG name: projects/${PROJECT_ID}/policy
여기에서 기본 규칙은 정책의 defaultAdmissionRule
노드에 정의되어 있습니다.
evaluationMode
는 정책이 모든 이미지 배포 시도를 허용하도록 지정합니다. 이 튜토리얼에서는 증명을 요구하도록 기본 규칙을 업데이트합니다.
정책 구조에 대한 자세한 내용은 정책 YAML 참조를 확인하세요.
증명자 만들기
증명자는 배포 시 Binary Authorization 시행자가 GKE에서 서명된 컨테이너 이미지를 배포하도록 허용할지 여부를 결정하는 확인 권한입니다. 증명자는 공개 키를 포함하며 일반적으로 소프트웨어 공급망 보안을 담당하는 조직 내 직원이 관리합니다.
증명자를 만들려면 다음을 수행해야 합니다.
이 튜토리얼에서는 test-attestor
라는 증명자 하나와 test-attestor-note
라는 컨테이너 분석 메모를 사용합니다. 실제 시나리오에서는 제한 없이 증명자를 사용할 수 있으며, 각 증명자는 컨테이너 이미지의 승인 프로세스에 참여하는 당사자를 나타냅니다.
컨테이너 분석 메모 만들기
증명자 및 컨테이너 분석 메모의 이름을 저장할 변수를 설정합니다.
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
Container 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
생성된 증명자는 연결된 PKIX 키 쌍이 없이는 사용할 수 없습니다. PKIX 키 쌍은 아래에서 만듭니다.
키 쌍 생성
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 키 쌍을 생성하려면 다음 단계를 따르세요.
비공개 키를 만듭니다.
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}
ECDSA 공개 키를 증명자에 추가합니다.
이제 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}
증명 페이로드를 생성합니다.
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를 사용하여 시행 우회