CI 파이프라인의 회사 정책에 따라 앱 검증

조직에서 정책 컨트롤러를 사용하여 Google Kubernetes Engine(GKE) Enterprise 버전 클러스터 간의 정책을 관리하는 경우 지속적 통합(CI) 파이프라인에서 해당 배포 구성을 검증할 수 있습니다. 이 튜토리얼에서는 이 결과를 얻는 방법을 보여줍니다. 앱의 CI 파이프라인을 빌드하는 개발자이거나 여러 앱팀을 위한 CI 파이프라인 템플릿을 빌드하는 플랫폼 엔지니어라면 앱 검증이 유용합니다.

정책은 조직의 보안과 규정 준수에서 중요한 부분입니다. 정책 컨트롤러를 사용하면 조직이 모든 클러스터에 대해 이러한 정책을 중앙에서 선언적으로 관리할 수 있습니다. 개발자는 이러한 정책의 중앙 집중식 선언적 특성을 활용할 수 있습니다. 개발 워크플로에서 이러한 특성을 사용하여 가능한 한 빨리 이러한 정책에 대해 앱 유효성을 검사할 수 있습니다. 배포 중 대신에 CI 파이프라인의 정책 위반에 대해 알아보는 것은 두 가지 주요 이점이 있습니다. 이를 통해 개발 초기부터 보안 문제를 반영하고, 피드백 루프를 강화하고, 이러한 위반사항을 수정하는 데 필요한 시간과 비용을 줄일 수 있습니다.

이 튜토리얼에서는 Cloud Build를 CI 도구로 사용하고 데모용 정책이 포함된 샘플 GitHub 저장소를 사용합니다.

리소스

이 튜토리얼에서는 여러 Kubernetes 도구를 사용합니다. 이 섹션에서는 이러한 도구에는 무엇이 있는지, 서로 어떻게 상호작용하는지, 다른 도구로 바꿀 수 있는지 여부를 설명합니다.

이 튜토리얼에서 사용하는 도구는 다음과 같습니다.

  • 정책 컨트롤러: 오픈소스 프로젝트 개방형 정책 에이전트 - Gatekeeper를 기반으로 합니다. 정책 컨트롤러는 Kubernetes 클러스터에서 생성된 객체에 대한 정책을 적용합니다(예: 특정 옵션의 사용 방지 또는 특정 라벨 사용 적용). 이러한 정책을 제약조건이라고 합니다. 제약조건은 Kubernetes 커스텀 리소스로 정의됩니다. 정책 컨트롤러는 Google Kubernetes Engine(GKE) Enterprise 버전의 일부로 제공되지만 해당 구현에 정책 컨트롤러 대신 개방형 정책 에이전트 - Gatekeeper를 사용할 수 있습니다.

  • GitHub: 이 튜토리얼에서는 GitHub를 사용해서 Git 저장소를 호스팅합니다. 이러한 저장소는 샘플 앱을 위한 저장소와 정책 컨트롤러의 제약조건이 포함된 저장소입니다. 편의상 두 저장소는 단일 Git 저장소의 서로 다른 폴더 두 개입니다. 하지만 실제로는 서로 다른 저장소입니다. 모든 Git 솔루션을 사용할 수 있습니다.

  • Cloud Build: Cloud Build는 Google Cloud의 CI 솔루션입니다. 이 튜토리얼에서는 유효성 검사 테스트를 실행하는 데 사용합니다. 구현 세부정보는 CI 시스템 간에 다를 수 있지만 이 튜토리얼에 설명된 개념은 모든 컨테이너 기반 CI 시스템에서 사용될 수 있습니다.

  • Kustomize: Kustomize는 Kubernetes 구성에 사용되는 맞춤설정 도구입니다. '기본' 구성을 가져오고 맞춤설정을 적용하는 방식으로 작동합니다. Kubernetes 구성에 대해 DRY(반복 금지) 방식을 사용할 수 있습니다. Kustomize를 사용하면 기본 구성의 모든 환경에 공통적인 요소를 유지하고 환경별로 맞춤설정을 만들 수 있습니다. 이 튜토리얼에서는 앱 저장소의 Kustomize 구성을 유지하고 CI 파이프라인의 구성을 '빌드'(예: 맞춤설정 적용)합니다. 이 튜토리얼에서 설명하는 개념은 클러스터에 적용할 수 있는 Kubernetes 구성을 생성하는 모든 도구(예: helm template 명령어)와 함께 사용할 수 있습니다.

  • Kpt: Kpt는 Kubernetes 구성의 워크플로를 빌드하는 도구입니다. kpt를 사용하면 Kubernetes 구성 가져오기, 표시, 맞춤설정, 업데이트, 유효성 검사, 적용을 수행할 수 있습니다. Git 및 YAML 파일과 호환되므로 Kubernetes 생태계의 기존 도구 대부분과 호환됩니다. 이 튜토리얼에서는 CI 파이프라인에서 kpt를 사용하여 anthos-config-management-samples 저장소에서 제약조건을 가져오고 이러한 제약조건에 대해 Kubernetes 구성을 검증합니다.

파이프라인

이 튜토리얼에서 사용하는 CI 파이프라인은 다음 다이어그램에 나와 있습니다.

정책 컨트롤러용 CI 파이프라인

이 파이프라인은 Cloud Build에서 실행되며 명령어는 샘플 앱 저장소의 복사본이 포함된 디렉터리에서 실행됩니다. kustomize를 통해 최종 Kubernetes 구성을 생성하면 파이프라인이 시작됩니다. 그런 후 kpt를 사용하여 anthos-config-management-샘플 저장소에서 검증할 제약조건을 가져옵니다. 마지막으로 kpt를 사용하여 이러한 제약조건에 대해 Kubernetes 구성의 유효성을 검사합니다. 이 마지막 단계를 수행하려면 이 유효성 검사를 수행하는 gatekeeper라는 특정 구성 함수를 사용합니다. 이 튜토리얼에서는 CI 파이프라인을 수동으로 트리거하지만 실제로는 개발자가 Git 저장소에 git push를 실행한 후에 실행되도록 구성합니다.

목표

  • Cloud Build로 샘플 앱의 CI 파이프라인을 실행합니다.
  • 정책 위반으로 인해 파이프라인이 실패했는지 확인합니다.
  • 정책을 준수하도록 샘플 앱 저장소를 수정합니다.
  • CI 파이프라인을 성공적으로 다시 실행합니다.

비용

이 튜토리얼에서는 비용이 청구될 수 있는 다음과 같은 Google Cloud 구성요소를 사용합니다.

  • Cloud Build
  • Google Kubernetes Engine(GKE) Enterprise 버전

프로젝트 사용량을 기준으로 예상 비용을 산출하려면 가격 계산기를 사용하세요.

이 튜토리얼을 마친 후에 계속 비용이 청구되지 않도록 하려면 만든 리소스를 삭제하면 됩니다. 자세한 내용은 삭제 섹션을 참조하세요.

시작하기 전에

  1. Google Cloud 프로젝트를 선택하거나 만듭니다. Google Cloud Console에서 리소스 관리 페이지로 이동합니다.

    리소스 관리로 이동

  2. 프로젝트에 결제를 사용 설정합니다.

  3. 이 튜토리얼에 나열된 명령어를 실행하려면 Cloud Shell을 엽니다.

    Cloud Shell로 이동

  4. Cloud Shell에서 gcloud config get-value project를 실행합니다.

    명령어가 방금 선택한 프로젝트의 ID를 반환하지 않으면 Cloud Shell이 프로젝트를 사용하도록 구성합니다.

    gcloud config set project PROJECT_ID
    

    PROJECT_ID를 프로젝트 ID로 바꿉니다.

  5. Cloud Shell에서 필요한 Cloud Build API를 사용 설정합니다.

    gcloud services enable cloudbuild.googleapis.com
    

샘플 앱 구성 유효성 검사

이 섹션에서는 Google에서 제공하는 샘플 앱 저장소에 대해 Cloud Build로 CI 파이프라인을 실행합니다. 이 파이프라인은 anthos-config-management-samples 저장소에 제공된 제약조건에 대해 샘플 앱 저장소에 제공된 Kubernetes 구성을 검증합니다.

앱 구성의 유효성을 검사하려면 다음 안내를 따르세요.

  1. Cloud Shell에서 샘플 앱 저장소를 클론합니다.

    git clone https://github.com/GoogleCloudPlatform/anthos-config-management-samples.git
    
  2. Cloud Build로 CI 파이프라인을 실행합니다. 빌드 로그가 Cloud Shell에 직접 표시됩니다.

    cd anthos-config-management-samples/ci-app/app-repo
    gcloud builds submit .
    

    실행하는 파이프라인은 다음 파일에 정의되어 있습니다.

    steps:
    - id: 'Prepare config'
      # This step builds the final manifests for the app
      # using kustomize and the configuration files
      # available in the repository.
      name: 'gcr.io/google.com/cloudsdktool/cloud-sdk'
      entrypoint: '/bin/sh'
      args: ['-c', 'mkdir hydrated-manifests && kubectl kustomize config/prod > hydrated-manifests/prod.yaml']
    - id: 'Download policies'
      # This step fetches the policies from the Anthos Config Management repository
      # and consolidates every resource in a single file.
      name: 'gcr.io/kpt-dev/kpt'
      entrypoint: '/bin/sh'
      args: ['-c', 'kpt pkg get https://github.com/GoogleCloudPlatform/anthos-config-management-samples.git/ci-app/acm-repo/cluster@main constraints
                      && kpt fn source constraints/ hydrated-manifests/ > hydrated-manifests/kpt-manifests.yaml']
    - id: 'Validate against policies'
      # This step validates that all resources comply with all policies.
      name: 'gcr.io/kpt-fn/gatekeeper:v0.2'
      args: ['--input', 'hydrated-manifests/kpt-manifests.yaml']

    정책 컨트롤러에서 제약조건은 제약조건 템플릿의 인스턴스화에 해당합니다. 제약조건 템플릿은 제약조건을 구현하는 데 사용되는 실제 Rego 코드를 포함합니다. gcr.io/kpt-fn/gatekeeper 함수를 사용하려면 제약조건 템플릿과 제약조건 정의가 모두 필요합니다. 샘플 정책 저장소에는 모두 포함되어 있지만 실제로는 다른 위치에 저장될 수 있습니다. 필요에 따라 kpt pkg get 명령어를 사용하여 제약조건 템플릿과 제약조건을 모두 다운로드하세요.

    이 튜토리얼에서는 Cloud Build와 함께 gcr.io/kpt-fn/gatekeeper를 사용하여 리소스를 검증하지만 다른 두 가지 대안을 사용할 수 있습니다.

    kpt fn eval hydrated-manifests/kpt-manifests.yaml --image gcr.io/kpt-fn/gatekeeper:v0.2
    
    gator test -f hydrated-manifests/kpt-manifests.yaml
    
  3. 몇 분 후에 파이프라인이 실패하여 다음 오류가 표시되는지 확인합니다.

    [...]
    Step #2 - "Validate against policies": [error] apps/v1/Deployment/nginx-deployment : Deployment objects should have an 'owner' label indicating who created them.
    Step #2 - "Validate against policies": violatedConstraint: deployment-must-have-owner
    Finished Step #2 - "Validate against policies"
    2022/05/11 18:55:18 Step Step #2 - "Validate against policies" finished
    2022/05/11 18:55:19 status changed to "ERROR"
    ERROR
    ERROR: build step 2 "gcr.io/kpt-fn/gatekeeper:v0.2" failed: exit status 1
    2022/05/11 18:55:20 Build finished with ERROR status
    

    구성에서 위반한 제약조건은 다음 파일에 정의되어 있습니다. 이는 K8sRequiredLabels라는 Kubernetes 커스텀 리소스입니다.

    apiVersion: constraints.gatekeeper.sh/v1beta1
    kind: K8sRequiredLabels
    metadata:
      name: deployment-must-have-owner
    spec:
      match:
        kinds:
          - apiGroups: ["apps"]
            kinds: ["Deployment"]
      parameters:
        labels:
          - key: "owner"
        message: "Deployment objects should have an 'owner' label indicating who created them."

    이 제약조건에 해당하는 제약조건 템플릿은 GitHub의 requiredlabels.yaml을 참조하세요.

  4. 전체 Kubernetes 구성을 직접 빌드하고 실제로 owner 라벨이 없는지 확인합니다. 구성을 빌드하려면 다음을 실행합니다.

    kubectl kustomize config/prod
    

회사 정책을 준수하도록 앱 수정

이 섹션에서는 Kustomize를 사용하여 정책 위반을 수정합니다.

  1. Cloud Shell에서 commonLabels 섹션을 기본 Kustomization 파일에 추가합니다.

    cat <<EOF >> config/base/kustomization.yaml
    commonLabels:
      owner: myself
    EOF
    
  2. 전체 Kubernetes 구성을 빌드하고 현재 owner 라벨이 있는지 확인합니다.

    kubectl kustomize config/prod
    
  3. Cloud Build로 CI 파이프라인을 다시 실행합니다.

    gcloud builds submit .
    

    이제 파이프라인이 다음과 같이 출력됩니다.

    [...]
    Step #2 - "Validate against policies": [RUNNING] "gcr.io/kpt-fn/gatekeeper:v0"
    Step #2 - "Validate against policies": [PASS] "gcr.io/kpt-fn/gatekeeper:v0"
    [...]
    

삭제

  1. Google Cloud 콘솔에서 리소스 관리 페이지로 이동합니다.

    리소스 관리로 이동

  2. 프로젝트 목록에서 삭제할 프로젝트를 선택하고 삭제를 클릭합니다.
  3. 대화상자에서 프로젝트 ID를 입력한 후 종료를 클릭하여 프로젝트를 삭제합니다.

다음 단계