LabHub
배우기 러닝패스 코스

KCA — Kyverno認定アソシエイト

署名検証ポリシーと資格情報を立てる

LabHub 에서 이어서 보기

한국어 원문으로 표시합니다.

목표

cosign 서명과 attestation 을 검증하는 Kyverno 정책을 작성하고, Kyverno 와 파드가 각각 프라이빗 레지스트리에 접근하는 데 필요한 자격 증명 리소스를 실제 클러스터에 올립니다.

왜 중요한가

서명 검증 정책은 문법보다 운영 조건이 어렵습니다. 서명이 있는지, 그 서명을 조회할 수 있는지, 조회한 서명이 내가 신뢰하는 주체의 것인지가 각각 다른 실패 모드이고 증상은 모두 파드가 안 뜬다로 같습니다. 특히 attestors.count 를 빼먹으면 entries 전부가 통과해야 하므로 키를 추가한 순간 전부 막히고, mutateDigest 를 켜면 태그를 밀어 파드를 재생성하던 파이프라인이 조용히 무력화됩니다. 이 실습은 그 함정들을 매니페스트 위에서 미리 밟아 봅니다.

단계

  1. /root/kca-verify/ 디렉터리를 만들고 verify-keys.yaml 에 kind ClusterPolicy, metadata.name kca-verify-images, spec.rules[0].name verify-signature 를 쓰세요. verifyImages[0].imageReferences10.0.0.202/platform/* 를 넣고, attestors[0].entries[0].keys.publicKeysBEGIN PUBLIC KEY 로 시작하는 PEM 공개키를 넣으세요.
  2. 같은 attestors[0]count1 로 두고 entries 를 두 개로 만드세요. 두 번째 항목은 keyless 이며 urlhttps://fulcio.sigstore.dev, rekor.urlhttps://rekor.sigstore.dev, issuerhttps://token.actions.githubusercontent.com, subject 에는 .github/workflows/ 가 들어간 워크플로 경로를 쓰세요.
  3. 같은 verifyImages[0]required, verifyDigest, mutateDigest 를 모두 true 로 두고 skipImageReferences10.0.0.202/platform/legacy-* 를 넣으세요. 그리고 spec.webhookConfiguration.timeoutSeconds 를 20에서 30 사이 값으로 두되 deprecated 인 spec.webhookTimeoutSeconds 는 쓰지 마세요.
  4. /root/kca-verify/verify-attestations.yaml 에 kind ClusterPolicy 를 쓰고 verifyImages[0].attestations 에 두 항목을 넣으세요. 하나는 type https://slsa.dev/provenance/v1 이고 conditions[0].all[0].key 로 빌더 신원을 검사하며, 다른 하나는 type https://cyclonedx.org/bom/v1.4 이고 conditions[0].all[0].keylog4j-core 컴포넌트 버전을 검사합니다.
  5. /root/kca-verify/allowed-registries.yaml 에 kind ClusterPolicy, metadata.name kca-allowed-registries 를 쓰세요. spec.rules[0].validate.foreach[0].listrequest.object.spec.[initContainers, containers][] 이고 중괄호로 감싸지 마세요. deny.conditions.all[0].operatorAnyNotIn, value 목록에 10.0.0.202/platform/* 를 넣고 validate.failureActionEnforce 로 하세요.
  6. 클러스터에 네임스페이스 kca-verify 를 만들고 그 안에 Secret harbor-cred 를 실제로 만드세요. 타입은 kubernetes.io/dockerconfigjson 이고 서버는 10.0.0.202 입니다.
  7. 같은 네임스페이스에 ServiceAccount kca-deployer 를 만들어 imagePullSecretsharbor-cred 를 달고, Deployment kca-payments 를 실제로 만들어 serviceAccountNamekca-deployer 로 하고 컨테이너 이미지를 10.0.0.202/platform/payments@sha256: 뒤에 64자 16진수를 붙인 형태로 쓰세요.

참고

정적 키 기반 verifyImages

/root/kca-verify/ 디렉터리를 만들고 verify-keys.yaml 에 kind ClusterPolicy, metadata.name kca-verify-images, spec.rules[0].name verify-signature 를 쓰세요. verifyImages[0].imageReferences10.0.0.202/platform/* 를 넣고, attestors[0].entries[0].keys.publicKeysBEGIN PUBLIC KEY 로 시작하는 PEM 공개키를 넣으세요.

verifyImages 는 규칙 안의 배열이고 각 항목이 imageReferences 와 attestors 를 가집니다. 공개키는 PEM 문자열을 여러 줄로 넣습니다.

keyless 추가와 count 의 의미

같은 attestors[0]count1 로 두고 entries 를 두 개로 만드세요. 두 번째 항목은 keyless 이며 urlhttps://fulcio.sigstore.dev, rekor.urlhttps://rekor.sigstore.dev, issuerhttps://token.actions.githubusercontent.com, subject 에는 .github/workflows/ 가 들어간 워크플로 경로를 쓰세요.

entries 를 늘리기만 하면 모든 항목이 통과해야 합니다. 키 교체 기간을 무중단으로 넘기려면 몇 개가 통과하면 되는지를 명시해야 합니다.

다이제스트 고정과 예외, 그리고 타임아웃

같은 verifyImages[0]required, verifyDigest, mutateDigest 를 모두 true 로 두고 skipImageReferences10.0.0.202/platform/legacy-* 를 넣으세요. 그리고 spec.webhookConfiguration.timeoutSeconds 를 20에서 30 사이 값으로 두되 deprecated 인 spec.webhookTimeoutSeconds 는 쓰지 마세요.

세 불리언은 각각 검증 강제, 다이제스트 사용 강제, 태그를 다이제스트로 치환을 뜻합니다. 예외는 정책을 복제하지 말고 전용 필드에 적으세요. 레지스트리 왕복이 들어가는 정책은 웹훅 타임아웃 기본값으로 부족합니다.

provenance 와 SBOM 조건

/root/kca-verify/verify-attestations.yaml 에 kind ClusterPolicy 를 쓰고 verifyImages[0].attestations 에 두 항목을 넣으세요. 하나는 type https://slsa.dev/provenance/v1 이고 conditions[0].all[0].key 로 빌더 신원을 검사하며, 다른 하나는 type https://cyclonedx.org/bom/v1.4 이고 conditions[0].all[0].keylog4j-core 컴포넌트 버전을 검사합니다.

attestations 는 type 으로 어떤 진술인지 고르고 conditions 로 그 내용을 검사합니다. 서명만 보면 누가 빌드했는지는 검사하지 않은 것입니다.

허용 레지스트리 검사

/root/kca-verify/allowed-registries.yaml 에 kind ClusterPolicy, metadata.name kca-allowed-registries 를 쓰세요. spec.rules[0].validate.foreach[0].listrequest.object.spec.[initContainers, containers][] 이고 중괄호로 감싸지 마세요. deny.conditions.all[0].operatorAnyNotIn, value 목록에 10.0.0.202/platform/* 를 넣고 validate.failureActionEnforce 로 하세요.

foreach 의 list 는 중괄호로 감싸지 않습니다. 초기화 컨테이너까지 함께 순회해야 하며, 허용 목록 밖일 때 거부하는 연산자를 고르세요.

레지스트리 자격 증명 시크릿

클러스터에 네임스페이스 kca-verify 를 만들고 그 안에 Secret harbor-cred 를 실제로 만드세요. 타입은 kubernetes.io/dockerconfigjson 이고 서버는 10.0.0.202 입니다.

여기서부터 실제 클러스터입니다. 레지스트리 전용 시크릿 타입이 따로 있고, kubectl 에 그것을 만드는 하위 명령이 있습니다.

서비스어카운트와 다이제스트 고정 배포

같은 네임스페이스에 ServiceAccount kca-deployer 를 만들어 imagePullSecretsharbor-cred 를 달고, Deployment kca-payments 를 실제로 만들어 serviceAccountNamekca-deployer 로 하고 컨테이너 이미지를 10.0.0.202/platform/payments@sha256: 뒤에 64자 16진수를 붙인 형태로 쓰세요.

서비스어카운트에 imagePullSecrets 를 달면 그 계정으로 뜨는 파드가 물려받습니다. 이미지는 태그가 아니라 다이제스트로 고정된 형태여야 하고 sha256 은 64자입니다.