Cloud Service Mesh, 구성 동기화, 정책 컨트롤러로 앱 보안 강화

이 튜토리얼에서는 클러스터 및 앱의 보안 상태를 개선하는 방법을 보여줍니다. 사용자가 안정적인 서비스 메시를 모니터링하고 관리하는 데 도움이 되는 도구 모음인 Cloud Service Mesh를 사용하여 조직에서 온라인 상점의 앱을 관리하는 플랫폼 관리자라고 가정해 봅시다. 즉, 메시와 앱의 안전을 책임져야 하는 위치입니다.

정책 컨트롤러구성 동기화를 사용하여 잘못된 구성을 방지하고 Cloud Service Mesh 정책을 자동으로 검증할 수 있습니다. 정책 컨트롤러를 사용 설정하면 클러스터에 완전히 프로그래밍 가능한 정책을 적용할 수 있습니다. 또한 정책 컨트롤러에는 Cloud Service Mesh 보안 번들과 함께 사용할 수 있는 제약조건 템플릿의 기본 라이브러리가 제공되어 메시 보안 취약점 및 권장사항의 규정 준수를 감사합니다. 구성 동기화는 Kubernetes 선언적 구성 파일의 중앙 집합으로 등록된 클러스터 상태를 지속적으로 조정합니다. 정책 컨트롤러와 구성 동기화를 함께 사용하면 Cloud Service Mesh 정책 구성에 제약조건을 지속적으로 적용할 수 있습니다.

다음은 이 튜토리얼에서 Cloud Service Mesh, 정책 컨트롤러, 구성 동기화가 함께 작동하여 어떻게 이 튜토리얼에서 사용되는 인그레스 게이트웨이Online Boutique 샘플 앱을 관리하고 보호하는지를 개괄적으로 보여주는 다이어그램입니다.

이 튜토리얼에서 만드는 아키텍처를 보여주는 다이어그램

개발 환경 준비

이 섹션에서는 Cloud Service Mesh, 정책 컨트롤러, 구성 동기화를 설치할 수 있도록 환경을 준비합니다.

  1. In the Google Cloud console, activate Cloud Shell.

    Activate Cloud Shell

    At the bottom of the Google Cloud console, a Cloud Shell session starts and displays a command-line prompt. Cloud Shell is a shell environment with the Google Cloud CLI already installed and with values already set for your current project. It can take a few seconds for the session to initialize.

  2. Google Cloud CLI를 최신 버전으로 업그레이드합니다.

    gcloud components update
    
  3. 이 튜토리얼에서 만드는 파일을 저장하려면 디렉터리를 만듭니다.

    mkdir ~/asm-acm-tutorial-dir
    
  4. 이 튜토리얼의 나머지 부분을 간소화하려면 다음 환경 변수를 만듭니다.

    PROJECT_ID=PROJECT_ID
    gcloud config set project $PROJECT_ID
    CLUSTER=asm-acm-tutorial
    CLUSTER_ZONE=us-east4-a
    MEMBERSHIP=asm-acm-tutorial
    PROJECT_NUMBER=$(gcloud projects describe ${PROJECT_ID} --format='get(projectNumber)')
    

    PROJECT_ID를 이 튜토리얼에 사용할 프로젝트 ID로 바꿉니다.

    Cloud Shell을 승인하라는 메시지가 표시되면 승인을 클릭하여 작업을 완료합니다.

  5. 이 튜토리얼에 필요한 API를 사용 설정합니다.

    gcloud

    gcloud services enable \
        mesh.googleapis.com \
        anthos.googleapis.com
    

    구성 커넥터

    이 튜토리얼에는 구성 커넥터 리소스가 포함되어 있습니다. 이러한 리소스를 사용하여 gcloud 탭에서 완료하는 작업을 완료할 수 있습니다. 이러한 리소스를 활용하려면 구성 커넥터를 설치하고 환경에 가장 적합한 방식으로 리소스를 적용합니다.

    다음 Services 매니페스트를 사용합니다.

    apiVersion: serviceusage.cnrm.cloud.google.com/v1beta1
    kind: Service
    metadata:
      annotations:
        cnrm.cloud.google.com/deletion-policy: "abandon"
        cnrm.cloud.google.com/disable-dependent-services: "false"
      name: mesh.googleapis.com
    spec:
      resourceID: mesh.googleapis.com
      projectRef:
        external: PROJECT_ID
    ---
    apiVersion: serviceusage.cnrm.cloud.google.com/v1beta1
    kind: Service
    metadata:
      annotations:
        cnrm.cloud.google.com/deletion-policy: "abandon"
        cnrm.cloud.google.com/disable-dependent-services: "false"
      name: anthos.googleapis.com
    spec:
      resourceID: anthos.googleapis.com
      projectRef:
        external: PROJECT_ID
    

    이 작업을 완료하는 데 1분 이상 걸릴 수 있습니다.

  6. GKE 클러스터 설정

    이 섹션에서는 GKE 클러스터를 만든 다음 Fleet에 등록합니다. Fleet는 클러스터와 기타 리소스를 논리적으로 구성하기 위한Google Cloud 개념으로, 이를 사용하면 멀티 클러스터 기능을 사용 및 관리하고 시스템 전체에 일관된 정책을 적용할 수 있습니다.

    이 섹션에서 만드는 클러스터는 Cloud Service Mesh, 정책 컨트롤러, 구성 동기화를 설치하는 클러스터입니다. 또한 Online Boutique 샘플 앱을 배포하는 클러스터입니다.

    클러스터를 설정하려면 다음 단계를 완료하세요.

    1. GKE 클러스터를 만듭니다.

      gcloud

      gcloud container clusters create ${CLUSTER} \
          --zone ${CLUSTER_ZONE} \
          --machine-type=e2-standard-4 \
          --num-nodes 4 \
          --workload-pool ${PROJECT_ID}.svc.id.goog \
          --labels mesh_id=proj-${PROJECT_NUMBER}
      

      구성 커넥터

      다음 ContainerClusterContainerNodePool 매니페스트를 사용합니다.

      apiVersion: container.cnrm.cloud.google.com/v1beta1
      kind: ContainerNodePool
      metadata:
        annotations:
          cnrm.cloud.google.com/project-id: PROJECT_ID
        name: asm-acm-tutorial
      spec:
        clusterRef:
          name: asm-acm-tutorial
        location: us-east4-a
        nodeConfig:
          machineType: e2-standard-4
        nodeCount: 4
      ---
      apiVersion: container.cnrm.cloud.google.com/v1beta1
      kind: ContainerCluster
      metadata:
        annotations:
          cnrm.cloud.google.com/project-id: PROJECT_ID
          cnrm.cloud.google.com/remove-default-node-pool: "true"
        labels:
          mesh_id: proj-PROJECT_NUMBER
        name: asm-acm-tutorial
      spec:
        location: us-east4-a
        initialNodeCount: 1
        workloadIdentityConfig:
          workloadPool: PROJECT_ID.svc.id.goog
      

      PROJECT_NUMBER를 앞에서 검색한 PROJECT_NUMBER 환경 변수의 값으로 바꿉니다.

      이 작업을 완료하는 데 5분 이상 걸릴 수 있습니다.

    2. GKE 클러스터가 성공적으로 생성되도록 하려면 상태를 설명합니다.

      gcloud container clusters list \
          --zone ${CLUSTER_ZONE} \
          --project ${PROJECT_ID}
      

      출력은 다음과 비슷합니다.

      NAME                LOCATION      MASTER_VERSION   MASTER_IP      MACHINE_TYPE   NODE_VERSION     NUM_NODES  STATUS
      asm-acm-tutorial    us-east4-a    1.23.12-gke.100  35.186.179.30  e2-standard-4  1.23.12-gke.100  3          RUNNING
      
    3. GKE 클러스터에 연결합니다.

      gcloud container clusters get-credentials ${CLUSTER} \
          --zone ${CLUSTER_ZONE} \
          --project ${PROJECT_ID}
      
    4. Fleet에 클러스터를 등록합니다.

      gcloud

      gcloud container fleet memberships register ${MEMBERSHIP} \
          --project ${PROJECT_ID} \
          --gke-cluster ${CLUSTER_ZONE}/${CLUSTER} \
          --enable-workload-identity
      

      출력은 다음과 비슷합니다.

      kubeconfig entry generated for asm-acm-tutorial.
      Waiting for membership to be created...done.
      Created a new membership [projects/PROJECT_ID/locations/global/memberships/asm-acm-tutorial] for the cluster [asm-acm-tutorial]
      Generating the Connect Agent manifest...
      Deploying the Connect Agent on cluster [asm-acm-tutorial] in namespace [gke-connect]...
      Deployed the Connect Agent on cluster [asm-acm-tutorial] in namespace [gke-connect].
      Finished registering the cluster [asm-acm-tutorial] with the Fleet.
      

      구성 커넥터

      다음 GKEHubMembership 매니페스트를 사용합니다.

      apiVersion: gkehub.cnrm.cloud.google.com/v1beta1
      kind: GKEHubMembership
      metadata:
        annotations:
          cnrm.cloud.google.com/project-id: PROJECT_ID
        name: asm-acm-tutorial
      spec:
        location: global
        authority:
          issuer: https://container.googleapis.com/v1/projects/PROJECT_ID/locations/us-east4-a/clusters/asm-acm-tutorial
        endpoint:
          gkeCluster:
            resourceRef:
              name: asm-acm-tutorial
      
    5. GKE 클러스터를 성공적으로 등록하려면 상태를 설명합니다.

      gcloud container fleet memberships list
      

      출력은 다음과 비슷합니다.

      NAME              EXTERNAL_ID                           LOCATION
      asm-acm-tutorial  0e12258c-8831-4d81-b5c0-5e7099a468cc  global
      

    저장소 살펴보기

    다음 설치 섹션에서 매니페스트 acm-config.yaml 파일을 적용합니다. 이 매니페스트는 클러스터가 샘플 저장소의 asm-acm-tutorial 폴더에서 동기화되도록 구성합니다. 이 폴더에는 튜토리얼의 나머지 부분을 완료하는 데 필요한 모든 구성 파일이 있습니다.

    이 튜토리얼을 간소화하려면 sed 명령어를 사용하여 acm-config.yaml을 업데이트합니다. 구성 동기화는 acm-config.yaml 파일을 사용하여 이 튜토리얼의 각 단계에 필요한 매니페스트를 배포합니다. 파일 하나를 업데이트하면 파일을 반복적으로 조작하고 git 명령어를 반복적으로 실행하지 않고도 클러스터, 메시, 애플리케이션 보안의 개념과 흐름에 집중할 수 있습니다.

    구성 동기화의 여러 저장소 동기화 기능을 활용하려면 다음 리소스를 사용합니다.

    • RootSync 저장소로 사용되는 root-sync에는 RepoSyncs, Constraints, ClusterRole, RoleBindingsistio-system과 같은 일부 시스템 네임스페이스에 포함된 리소스를 포함하여 클러스터의 모든 구성이 포함됩니다.
    • ingress-gateway는 첫 번째 RepoSync로서 인그레스 게이트웨이를 배포하고 이 튜토리얼 전체에서 점진적으로 보호하는 데 필요한 모든 리소스를 포함합니다.
    • 두 번째 RepoSynconline-boutique에는 Online Boutique 앱을 배포하고 이 튜토리얼 전체에서 점진적으로 보호하는 데 필요한 모든 리소스가 포함되어 있습니다.

    정책 컨트롤러, 구성 동기화, 관리형 Cloud Service Mesh 설치

    클러스터를 만들고 등록했으므로 이제 클러스터에 구성 동기화, 정책 컨트롤러, Cloud Service Mesh를 설치하고 기본 RootSync의 구성에서 동기화하도록 클러스터를 구성합니다.

    1. 구성 동기화와 정책 컨트롤러를 관리하는 ConfigManagement 연산자를 사용 설정합니다.

      gcloud

      gcloud beta container fleet config-management enable
      

      구성 커넥터

      다음 GKEHubFeature 매니페스트를 사용합니다.

      apiVersion: gkehub.cnrm.cloud.google.com/v1beta1
      kind: GKEHubFeature
      metadata:
        name: configmanagement
      spec:
        projectRef:
          external: PROJECT_ID
        location: global
        resourceID: configmanagement
      
    2. Fleet에서 Cloud Service Mesh를 사용 설정합니다.

      gcloud

      gcloud container fleet mesh enable
      

      구성 커넥터

      다음 GKEHubFeature 매니페스트를 사용합니다.

      apiVersion: gkehub.cnrm.cloud.google.com/v1beta1
      kind: GKEHubFeature
      metadata:
        name: servicemesh
      spec:
        projectRef:
          external: PROJECT_ID
        location: global
        resourceID: servicemesh
      
    3. Google에서 관리형 Cloud Service Mesh의 권장 구성을 적용할 수 있도록 Cloud Service Mesh 자동 관리를 사용 설정합니다.

      gcloud

      gcloud container fleet mesh update \
          --management automatic \
          --memberships ${MEMBERSHIP}
      

      구성 커넥터

      다음 GKEHubFeatureMembership 매니페스트를 사용합니다.

      apiVersion: gkehub.cnrm.cloud.google.com/v1beta1
      kind: GKEHubFeatureMembership
      metadata:
        name: servicemesh-membership
      spec:
        projectRef:
          external: PROJECT_ID
        location: global
        membershipRef:
          name: asm-acm-tutorial
        featureRef:
          name: servicemesh
        mesh:
          management: MANAGEMENT_AUTOMATIC
      
    4. 구성 동기화 및 정책 컨트롤러를 사용 설정합니다.

      gcloud

      다음 매니페스트를 ~/asm-acm-tutorial-dir 디렉터리에 acm-config.yaml로 저장합니다.

      applySpecVersion: 1
      spec:
        configSync:
          enabled: true
          policyDir: asm-acm-tutorial/root-sync/init
          secretType: none
          sourceFormat: unstructured
          syncRepo: https://github.com/GoogleCloudPlatform/anthos-config-management-samples
          syncBranch: main
        policyController:
          enabled: true
          referentialRulesEnabled: true
          templateLibraryInstalled: true
      

      Google Cloud CLI 구성 필드에 대한 자세한 내용은 gcloud 적용 사양 필드를 참조하세요.

      파일을 적용합니다.

      gcloud beta container fleet config-management apply \
          --membership ${MEMBERSHIP} \
          --config ~/asm-acm-tutorial-dir/acm-config.yaml
      

      구성 커넥터

      다음 GKEHubFeatureMembership 매니페스트를 사용합니다.

      apiVersion: gkehub.cnrm.cloud.google.com/v1beta1
      kind: GKEHubFeatureMembership
      metadata:
        name: configmanagement-membership
      spec:
        projectRef:
          external: PROJECT_ID
        location: global
        membershipRef:
          name: asm-acm-tutorial
        featureRef:
          name: configmanagement
        configmanagement:
          configSync:
            sourceFormat: unstructured
            git:
              policyDir: asm-acm-tutorial/root-sync/init
              secretType: none
              syncBranch: main
              syncRepo: https://github.com/GoogleCloudPlatform/anthos-config-management-samples
          policyController:
            enabled: true
            referentialRulesEnabled: true
            templateLibraryInstalled: true
      

      정책 컨트롤러 및 구성 동기화가 클러스터에 설치됩니다. 그런 다음 구성 동기화가 기본 RootSync의 모든 구성을 클러스터에 동기화하기 시작합니다. 이러한 구성은 다음 주요 구성요소를 설치하고 구성합니다.

      • Online Boutique 앱과 인그레스 게이트웨이를 구성하는 RepoSync 객체는 다음과 같이 동기화됩니다.

        apiVersion: configsync.gke.io/v1beta1
        kind: RepoSync
        metadata:
          name: repo-sync
        spec:
          override:
            enableShellInRendering: true
          sourceFormat: unstructured
          git:
            repo: https://github.com/GoogleCloudPlatform/anthos-config-management-samples
            revision: HEAD
            branch: main
            dir: asm-acm-tutorial/online-boutique/init
            auth: none
        apiVersion: configsync.gke.io/v1beta1
        kind: RepoSync
        metadata:
          name: repo-sync
        spec:
          override:
            enableShellInRendering: true
          sourceFormat: unstructured
          git:
            repo: https://github.com/GoogleCloudPlatform/anthos-config-management-samples
            revision: HEAD
            branch: main
            dir: asm-acm-tutorial/ingress-gateway/init
            auth: none
      • Istio 리소스를 만들려면 RepoSync 조정자에 추가 권한이 필요하므로 이러한 권한을 부여하는 ClusterRole 및 두 개의 RoleBinding 객체도 클러스터에 적용됩니다.

        apiVersion: rbac.authorization.k8s.io/v1
        kind: ClusterRole
        metadata:
          labels:
            rbac.authorization.k8s.io/aggregate-to-edit: "true"
          name: custom:aggregate-to-edit:istio
        rules:
        - apiGroups:
          - "networking.istio.io"
          - "security.istio.io"
          resources:
          - "virtualservices"
          - "authorizationpolicies"
          - "gateways"
          verbs:
          - "*"
        apiVersion: rbac.authorization.k8s.io/v1
        kind: RoleBinding
        metadata:
          name: repo-sync
        subjects:
        - kind: ServiceAccount
          name: ns-reconciler-onlineboutique
          namespace: config-management-system
        roleRef:
          kind: ClusterRole
          name: edit
          apiGroup: rbac.authorization.k8s.io
        apiVersion: rbac.authorization.k8s.io/v1
        kind: RoleBinding
        metadata:
          name: repo-sync
        subjects:
        - kind: ServiceAccount
          name: ns-reconciler-asm-ingress
          namespace: config-management-system
        roleRef:
          kind: ClusterRole
          name: edit
          apiGroup: rbac.authorization.k8s.io
    5. 정책 컨트롤러와 구성 동기화가 성공적으로 설치되었는지 확인하려면 상태를 확인합니다.

      gcloud beta container fleet config-management status
      

      출력은 다음과 비슷합니다.

      Name: asm-acm-tutorial
      Status: SYNCED
      Last_Synced_Token: 4b3384d
      Sync_Branch: main
      Last_Synced_Time: 2022-05-04T21:32:58Z
      Policy_Controller: INSTALLED
      

      Status 또는 Policy_Controller 행에 PENDING 또는 NOT_INSTALLED가 표시되면 몇 분 정도 기다린 후 gcloud beta container fleet config-management status을 다시 실행합니다.

    6. Cloud Service Mesh를 성공적으로 설치하려면 상태를 설명합니다.

      gcloud container fleet mesh describe
      

      출력은 다음과 비슷합니다.

      createTime: '2022-09-13T23:12:56.477042921Z'
      membershipSpecs:
        projects/PROJECT_NUMBER/locations/global/memberships/asm-acm-tutorial:
          mesh:
            management: MANAGEMENT_AUTOMATIC
      membershipStates:
        projects/PROJECT_NUMBER/locations/global/memberships/asm-acm-tutorial:
          servicemesh:
            controlPlaneManagement:
              details:
              - code: REVISION_READY
                details: 'Ready: asm-managed'
              state: ACTIVE
            dataPlaneManagement:
              details:
              - code: OK
                details: Service is running.
              state: ACTIVE
          state:
            code: OK
            description: |-
              Revision(s) ready for use: asm-managed.
              All Canonical Services have been reconciled successfully.
            updateTime: '2022-09-14T00:19:10.571552206Z'
      name: projects/PROJECT_ID/locations/global/features/servicemesh
      resourceState:
        state: ACTIVE
      spec: {}
      state:
        state: {}
      updateTime: '2022-09-14T00:19:14.135113118Z'
      

      state.code: OK 대신 state.code: ERROR이 표시되면 몇 분 기다렸다가 다시 gcloud container fleet mesh describe를 실행합니다. 튜토리얼을 진행하기 전에 servicemesh.controlPlaneManagement.details.code 필드에 REVISION_READY 값이 있는지 확인해야 합니다.

    인그레스 게이트웨이 및 샘플 애플리케이션 배포

    이 섹션에서는 Online Boutique 샘플 애플리케이션인그레스 게이트웨이를 배포하여 인그레스 트래픽을 관리합니다.

    1. Online Boutique 샘플 애플리케이션과 인그레스 게이트웨이를 배포합니다.

      다음 명령어는 sed를 통해 acm-config.yaml 매니페스트를 업데이트하여 인그레스 게이트웨이와 샘플 앱을 배포하는 데 필요한 리소스를 배포하는 구성 동기화를 가져옵니다.

      sed -i "s,root-sync/init,root-sync/deployments,g" ~/asm-acm-tutorial-dir/acm-config.yaml
      gcloud beta container fleet config-management apply \
          --membership ${MEMBERSHIP} \
          --config ~/asm-acm-tutorial-dir/acm-config.yaml
      

      이 단계를 완료하는 데 몇 분 정도 걸릴 수 있습니다.

    2. RootSync 및 두 개의 RepoSyncs에 대한 구성 동기화 상태를 확인합니다.

      gcloud alpha anthos config sync repo describe
      

      출력은 다음과 비슷합니다.

      getting 3 RepoSync and RootSync from projects/PROJECT_ID/locations/global/memberships/asm-acm-tutorial
      [
        {
          "clusters": [
            "projects/PROJECT_ID/locations/global/memberships/asm-acm-tutorial"
          ],
          "commit": "95a30c052566357afb9db3d7f6153d9c0f219c03",
          "errors": [],
          "source": "https://github.com/GoogleCloudPlatform/anthos-config-management-samples//asm-acm-tutorial/root-sync/deployments@main",
          "status": "SYNCED"
        },
        {
          "clusters": [
            "projects/PROJECT_ID/locations/global/memberships/asm-acm-tutorial"
          ],
          "commit": "95a30c052566357afb9db3d7f6153d9c0f219c03",
          "errors": [],
          "source": "https://github.com/GoogleCloudPlatform/anthos-config-management-samples//asm-acm-tutorial/ingress-gateway/deployments@main",
          "status": "SYNCED"
        },
        {
          "clusters": [
            "projects/PROJECT_ID/locations/global/memberships/asm-acm-tutorial"
          ],
          "commit": "95a30c052566357afb9db3d7f6153d9c0f219c03",
          "errors": [],
          "source": "https://github.com/GoogleCloudPlatform/anthos-config-management-samples//asm-acm-tutorial/online-boutique/deployments@main",
          "status": "SYNCED"
        }
      ]
      

      status: SYNCED 대신 status: RECONCILING이 표시되면 몇 분 기다렸다가 다시 gcloud alpha anthos config sync repo describe를 실행합니다.

      하나의 저장소 정보만 보려면 --sync-name--sync-namespace 플래그를 사용할 수 있습니다. 관리형 리소스를 자세히 보려면 --managed-resources 플래그를 추가합니다. 자세한 내용은 여러 클러스터에서 구성 동기화 상태 보기를 참조하세요.

    3. 인그레스 게이트웨이의 공개 IP 주소가 프로비저닝될 때까지 기다립니다.

      until kubectl -n asm-ingress get svc asm-ingressgateway -o jsonpath='{.status.loadBalancer}' | grep "ingress"; do : ; done
      
    4. 인그레스 게이트웨이의 공개 IP 주소를 가져옵니다.

      EXTERNAL_IP=$(kubectl get svc asm-ingressgateway -n asm-ingress -o jsonpath="{.status.loadBalancer.ingress[*].ip}")
      
    5. 브라우저에서 IP 주소에 방문하여 Online Boutique 앱이 성공적으로 배포되었는지 확인합니다.

      echo http://${EXTERNAL_IP}
      

    메시를 보호하기 위한 정책 시행

    다음 섹션에서는 정책 컨트롤러를 활용하여 제약조건을 만들어Cloud Service Mesh 정책 번들의 정책을 적용합니다.

    사이드카 프록시 삽입 적용

    이 섹션에서는 메시의 모든 워크로드에 자동 사이드카 삽입이 사용 설정되도록 하는 정책을 적용합니다.

    1. 사이드카 프록시 삽입을 시행하려면 제약조건을 적용하세요.

      다음 명령어는 sed를 사용하여 acm-config.yaml 매니페스트를 업데이트해 관련 리소스를 배포하는 구성 동기화를 가져옵니다.

      sed -i "s,root-sync/deployments,root-sync/enforce-sidecar-injection,g" ~/asm-acm-tutorial-dir/acm-config.yaml
      gcloud beta container fleet config-management apply \
          --membership ${MEMBERSHIP} \
          --config ~/asm-acm-tutorial-dir/acm-config.yaml
      

      위의 명령어는 다음 리소스를 배포합니다.

      • 메시의 모든 Namespace에 특정 Cloud Service Mesh 사이드카 프록시 삽입 라벨을 포함해야 하는 K8sRequiredLabels Constraint:

        apiVersion: constraints.gatekeeper.sh/v1beta1
        kind: K8sRequiredLabels
        metadata:
          name: namespace-sidecar-injection-label
        spec:
          enforcementAction: deny
          match:
            kinds:
            - apiGroups:
              - ""
              kinds:
              - Namespace
            excludedNamespaces:
            - config-management-monitoring
            - config-management-system
            - default
            - gatekeeper-system
            - gke-connect
            - istio-system
            - kube-node-lease
            - kube-public
            - kube-system
            - resource-group-system
          parameters:
            labels:
            - allowedRegex: enabled
              key: istio-injection
      • 메시의 모든 Pod가 Istio 프록시 사이드카 삽입을 우회하지 못하도록 하는 AsmSidecarInjection Constraint:

        apiVersion: constraints.gatekeeper.sh/v1beta1
        kind: AsmSidecarInjection
        metadata:
          name: pod-sidecar-injection-annotation
        spec:
          enforcementAction: deny
          match:
            kinds:
            - apiGroups:
              - ""
              kinds:
              - Pod
            excludedNamespaces:
            - kube-system
          parameters:
            strictnessLevel: High
    2. RootSync의 구성 동기화 상태를 확인합니다.

      gcloud alpha anthos config sync repo describe \
          --sync-name root-sync \
          --sync-namespace config-management-system
      

      출력은 다음과 비슷합니다.

      getting 1 RepoSync and RootSync from projects/PROJECT_ID/locations/global/memberships/asm-acm-tutorial
      [
        {
          "clusters": [
            "projects/PROJECT_ID/locations/global/memberships/asm-acm-tutorial"
          ],
          "commit": "7d15d49af13c44aa531a4565b2277ddcf8b81884",
          "errors": [],
          "source": "https://github.com/GoogleCloudPlatform/anthos-config-management-samples//asm-acm-tutorial/root-sync/enforce-sidecar-injection@main",
          "status": "SYNCED"
        }
      ]
      

      status: SYNCED 대신 status: RECONCILING이 표시되면 몇 분 기다렸다가 다시 gcloud alpha anthos config sync repo describe를 실행합니다.

    3. Constraints가 생성되었는지 확인합니다.

      kubectl get constraints
      

      정책 컨트롤러가 이러한 제약조건을 평가하는 데 몇 분 정도 걸릴 수 있습니다. TOTAL-VIOLATIONS 열에 값이 표시되지 않으면 기다렸다가 kubectl get constraints를 다시 실행합니다.

      출력은 다음과 비슷합니다.

      NAME                                                                                       ENFORCEMENT-ACTION   TOTAL-VIOLATIONS
      podsidecarinjectionannotation.constraints.gatekeeper.sh/pod-sidecar-injection-annotation   deny                 0
      
      NAME                                                                            ENFORCEMENT-ACTION   TOTAL-VIOLATIONS
      k8srequiredlabels.constraints.gatekeeper.sh/namespace-sidecar-injection-label   deny                 0
      

      NamespacesPods를 올바르게 설정했으므로 이러한 Constraints에 대한 0TOTAL-VIOLATIONS입니다.

    4. 작동 중인 이러한 Constraints를 보려면 label이나 annotation이 없는 클러스터에 Namespace를 생성해 보십시오.

      kubectl create namespace test
      

      출력은 다음 오류와 유사합니다.

      Error from server (Forbidden): admission webhook "validation.gatekeeper.sh" denied the request: [namespace-sidecar-injection-label] you must provide labels: {"istio-injection"}
      

    트래픽 암호화 적용

    이 섹션에서는 메시의 모든 트래픽이 암호화되도록 정책을 적용합니다.

    1. 트래픽 암호화를 시행하려면 제약조건을 적용하세요.

      다음 명령어는 sed를 사용하여 acm-config.yaml 매니페스트를 업데이트해 관련 리소스를 배포하는 구성 동기화를 가져옵니다.

      sed -i "s,root-sync/enforce-sidecar-injection,root-sync/enforce-strict-mtls,g" ~/asm-acm-tutorial-dir/acm-config.yaml
      gcloud beta container fleet config-management apply \
          --membership ${MEMBERSHIP} \
          --config ~/asm-acm-tutorial-dir/acm-config.yaml
      

      위의 명령어는 다음 리소스를 배포합니다.

      • istio-system 네임스페이스에 메시 수준 mTLS PeerAuthentication을 적용하는 AsmPeerAuthnMeshStrictMtls Constraint:

        apiVersion: constraints.gatekeeper.sh/v1beta1
        kind: AsmPeerAuthnMeshStrictMtls
        metadata:
          name: mesh-level-strict-mtls
        spec:
          enforcementAction: deny
          parameters:
            rootNamespace: istio-system
            strictnessLevel: High
      • gatekeeper-system 네임스페이스의 참조 제약조건 Config. 이 참조 제약조건을 사용하면 AsmPeerAuthnMeshStrictMtls Constraint이 해당 정의에서 다른 객체를 참조할 수 있습니다(예: istio-system Namespace에서 모든 PeerAuthentication 검색).

        apiVersion: config.gatekeeper.sh/v1alpha1
        kind: Config
        metadata:
          name: config
        spec:
          sync:
            syncOnly:
              - group: ""
                version: "v1"
                kind: "Namespace"
              - group: "security.istio.io"
                version: "v1beta1"
                kind: "PeerAuthentication"
              - group: "security.istio.io"
                version: "v1beta1"
                kind: "AuthorizationPolicy"
      • Istio DestinationRules의 모든 호스트 및 호스트 하위 집합에 대해 TLS 사용 중지를 금지하는 DestinationRuleTLSEnabled Constraint:

        apiVersion: constraints.gatekeeper.sh/v1beta1
        kind: DestinationRuleTLSEnabled
        metadata:
          name: destination-rule-tls-enabled
        spec:
          enforcementAction: deny
          match:
            kinds:
            - apiGroups:
              - networking.istio.io
              kinds:
              - DestinationRule
      • 모든 PeerAuthentications에서 STRICT mTLS를 덮어쓸 수 없게 하는 AsmPeerAuthnStrictMtls Constraint:

        apiVersion: constraints.gatekeeper.sh/v1beta1
        kind: AsmPeerAuthnStrictMtls
        metadata:
          name: peerauthentication-strict-mtls
        spec:
          enforcementAction: deny
          match:
            kinds:
            - apiGroups:
              - security.istio.io
              kinds:
              - PeerAuthentication
          parameters:
            strictnessLevel: High
    2. RootSync의 구성 동기화 상태를 확인합니다.

      gcloud alpha anthos config sync repo describe \
          --sync-name root-sync \
          --sync-namespace config-management-system
      

      출력은 다음과 비슷합니다.

      getting 1 RepoSync and RootSync from projects/PROJECT_ID/locations/global/memberships/asm-acm-tutorial
      [
        {
          "clusters": [
            "projects/PROJECT_ID/locations/global/memberships/asm-acm-tutorial"
          ],
          "commit": "7d15d49af13c44aa531a4565b2277ddcf8b81884",
          "errors": [],
          "source": "https://github.com/GoogleCloudPlatform/anthos-config-management-samples//asm-acm-tutorial/root-sync/enforce-strict-mtls@main",
          "status": "SYNCED"
        }
      ]
      

      status: SYNCED 대신 status: RECONCILING이 표시되면 몇 분 기다렸다가 다시 gcloud alpha anthos config sync repo describe를 실행합니다.

    3. 다음 명령어를 실행하여 PeerAuthentication 위반에 대한 자세한 정보를 가져옵니다.

      kubectl get asmpeerauthnmeshstrictmtls.constraints.gatekeeper.sh/mesh-level-strict-mtls -ojsonpath='{.status.violations}'  | jq
      

      출력은 다음과 비슷합니다.

      [
        {
          "enforcementAction": "deny",
          "group": "constraints.gatekeeper.sh",
          "kind": "AsmPeerAuthnMeshStrictMtls",
          "message": "Root namespace <istio-system> does not have a strict mTLS PeerAuthentication",
          "name": "mesh-level-strict-mtls",
          "version": "v1beta1"
        }
      ]
      
    4. istio-systemPeerAuthentication을 배포하여 문제를 해결합니다. 메시의 모든 서비스에서 일반 텍스트 트래픽을 허용하지 않게 하려면 mTLS 모드를 STRICT로 설정하여 메시 전체 PeerAuthentication 정책을 설정합니다. 정책을 배포하면 워크로드가 서로 인증할 수 있도록 컨트롤 플레인에서 TLS 인증서를 자동으로 프로비저닝합니다.

      다음 명령어는 sed를 사용하여 acm-config.yaml 매니페스트를 업데이트해 관련 리소스를 배포하는 구성 동기화를 가져옵니다.

      sed -i "s,root-sync/enforce-strict-mtls,root-sync/fix-strict-mtls,g" ~/asm-acm-tutorial-dir/acm-config.yaml
      gcloud beta container fleet config-management apply \
          --membership ${MEMBERSHIP} \
          --config ~/asm-acm-tutorial-dir/acm-config.yaml
      

      위의 명령어는 istio-system 네임스페이스에 다음 STRICT mTLS PeerAuthentication을 배포합니다. 이렇게 하면 전체 메시에 mTLS STRICT가 적용됩니다.

      apiVersion: security.istio.io/v1beta1
      kind: PeerAuthentication
      metadata:
        name: default
      spec:
        mtls:
          mode: STRICT
    5. RootSync의 구성 동기화 상태를 확인합니다.

      gcloud alpha anthos config sync repo describe \
          --sync-name root-sync \
          --sync-namespace config-management-system
      

      출력은 다음과 비슷합니다.

      getting 1 RepoSync and RootSync from projects/PROJECT_ID/locations/global/memberships/asm-acm-tutorial
      [
        {
          "clusters": [
            "projects/PROJECT_ID/locations/global/memberships/asm-acm-tutorial"
          ],
          "commit": "7d15d49af13c44aa531a4565b2277ddcf8b81884",
          "errors": [],
          "source": "https://github.com/GoogleCloudPlatform/anthos-config-management-samples//asm-acm-tutorial/root-sync/fix-strict-mtls@main",
          "status": "SYNCED"
        }
      ]
      

      status: SYNCED 대신 status: RECONCILING이 표시되면 몇 분 기다렸다가 다시 gcloud alpha anthos config sync repo describe를 실행합니다.

    6. Constraints가 생성되었는지 확인합니다.

      kubectl get constraints
      

      정책 컨트롤러에서 이러한 Constraints를 평가하는 데 몇 분이 걸릴 수 있습니다. 각 행의 TOTAL-VIOLATIONS 열 아래에 값이 표시될 때까지 기다렸다가 이 kubectl get constraints 명령어를 다시 실행합니다.

      출력은 다음과 비슷합니다.

      NAME                                                                            ENFORCEMENT-ACTION   TOTAL-VIOLATIONS
      k8srequiredlabels.constraints.gatekeeper.sh/namespace-sidecar-injection-label   deny                 0
      NAME                                                                          ENFORCEMENT-ACTION   TOTAL-VIOLATIONS
      asmpeerauthnmeshstrictmtls.constraints.gatekeeper.sh/mesh-level-strict-mtls   deny                 0
      NAME                                                                               ENFORCEMENT-ACTION   TOTAL-VIOLATIONS
      destinationruletlsenabled.constraints.gatekeeper.sh/destination-rule-tls-enabled   deny                 0
      NAME                                                                              ENFORCEMENT-ACTION   TOTAL-VIOLATIONS
      asmpeerauthnstrictmtls.constraints.gatekeeper.sh/peerauthentication-strict-mtls   deny                 0
      NAME                                                                             ENFORCEMENT-ACTION   TOTAL-VIOLATIONS
      asmsidecarinjection.constraints.gatekeeper.sh/pod-sidecar-injection-annotation   deny                 0
      

    세밀한 액세스 제어 적용

    이 섹션에서는 메시의 모든 워크로드에 세분화된 액세스 제어가 포함되도록 정책을 적용합니다.

    1. 세분화된 액세스 제어를 적용하려면 제약조건을 적용하세요.

      다음 명령어는 sed를 사용하여 acm-config.yaml 매니페스트를 업데이트해 관련 리소스를 배포하는 구성 동기화를 가져옵니다.

      sed -i "s,root-sync/fix-strict-mtls,root-sync/enforce-authorization-policies,g" ~/asm-acm-tutorial-dir/acm-config.yaml
      gcloud beta container fleet config-management apply \
          --membership ${MEMBERSHIP} \
          --config ~/asm-acm-tutorial-dir/acm-config.yaml
      

      위의 명령어는 다음 리소스를 배포합니다.

      • istio-system 네임스페이스에 메시 수준 기본 거부 AuthorizationPolicy를 적용하는 AsmAuthzPolicyDefaultDeny Constraint:

        apiVersion: constraints.gatekeeper.sh/v1beta1
        kind: AsmAuthzPolicyDefaultDeny
        metadata:
          name: default-deny-authorization-policies
        spec:
          enforcementAction: deny
          parameters:
            rootNamespace: istio-system
            strictnessLevel: High
      • 모든 AuthorizationPolicies가 세분화된 소스 주 구성원('*' 이외)을 정의하도록 시행하는 AsmAuthzPolicyEnforceSourcePrincipals Constraint. 최종 사용자로부터 트래픽을 수신하고 Online Boutique의 frontend 앱으로 트래픽을 리디렉션하려면 asm-ingress 네임스페이스의 인그레스 게이트웨이만 이 규칙의 예외로 둡니다.

        apiVersion: constraints.gatekeeper.sh/v1beta1
        kind: AsmAuthzPolicyEnforceSourcePrincipals
        metadata:
          name: authz-source-principals-not-all
        spec:
          enforcementAction: deny
          match:
            kinds:
            - apiGroups:
              - security.istio.io
              kinds:
              - AuthorizationPolicy
            excludedNamespaces:
              - asm-ingress
    2. RootSync의 구성 동기화 상태를 확인합니다.

      gcloud alpha anthos config sync repo describe \
          --sync-name root-sync \
          --sync-namespace config-management-system
      

      출력은 다음과 비슷합니다.

      getting 1 RepoSync and RootSync from projects/PROJECT_ID/locations/global/memberships/asm-acm-tutorial
      [
        {
          "clusters": [
            "projects/PROJECT_ID/locations/global/memberships/asm-acm-tutorial"
          ],
          "commit": "7d15d49af13c44aa531a4565b2277ddcf8b81884",
          "errors": [],
          "source": "https://github.com/GoogleCloudPlatform/anthos-config-management-samples//asm-acm-tutorial/root-sync/enforce-authorization-policies@main",
          "status": "SYNCED"
        }
      ]
      

      status: SYNCED 대신 status: RECONCILING이 표시되면 몇 분 기다렸다가 다시 gcloud alpha anthos config sync repo describe를 실행합니다.

    3. 다음 명령어를 실행하여 관련된 위반에 대한 자세한 정보를 가져옵니다.

      kubectl get asmauthzpolicydefaultdeny.constraints.gatekeeper.sh/default-deny-authorization-policies -ojsonpath='{.status.violations}'  | jq
      

      출력은 다음과 비슷합니다.

      [
        {
          "enforcementAction": "deny",
          "group": "constraints.gatekeeper.sh",
          "kind": "AsmAuthzPolicyDefaultDeny",
          "message": "Root namespace <istio-system> does not have a default deny AuthorizationPolicy",
          "name": "default-deny-authorization-policies",
          "version": "v1beta1"
        }
      ]
      
    4. istio-system 네임스페이스에 AuthorizationPolicy를 배포하여 문제를 해결합니다.

      다음 명령어는 sed를 사용하여 acm-config.yaml 매니페스트를 업데이트해 관련 리소스를 배포하는 구성 동기화를 가져옵니다.

      sed -i "s,root-sync/enforce-authorization-policies,root-sync/fix-default-deny-authorization-policy,g" ~/asm-acm-tutorial-dir/acm-config.yaml
      gcloud beta container fleet config-management apply \
          --membership ${MEMBERSHIP} \
          --config ~/asm-acm-tutorial-dir/acm-config.yaml
      

      위의 명령어는 istio-system 네임스페이스에 다음과 같은 모두 거부 AuthorizationPolicy를 배포합니다.

      apiVersion: security.istio.io/v1beta1
      kind: AuthorizationPolicy
      metadata:
        name: deny-all
      spec:
        {}
    5. RootSync의 구성 동기화 상태를 확인합니다.

      gcloud alpha anthos config sync repo describe \
          --sync-name root-sync \
          --sync-namespace config-management-system
      

      출력은 다음과 비슷합니다.

      getting 1 RepoSync and RootSync from projects/PROJECT_ID/locations/global/memberships/asm-acm-tutorial
      [
        {
          "clusters": [
            "projects/PROJECT_ID/locations/global/memberships/asm-acm-tutorial"
          ],
          "commit": "7d15d49af13c44aa531a4565b2277ddcf8b81884",
          "errors": [],
          "source": "https://github.com/GoogleCloudPlatform/anthos-config-management-samples//asm-acm-tutorial/root-sync/fix-default-deny-authorization-policy@main",
          "status": "SYNCED"
        }
      ]
      

      status: SYNCED 대신 status: RECONCILING이 표시되면 몇 분 기다렸다가 다시 gcloud alpha anthos config sync repo describe를 실행합니다.

    6. Constraints가 생성되었는지 확인합니다.

      kubectl get constraints
      

      정책 컨트롤러에서 이러한 Constraints를 평가하는 데 몇 분이 걸릴 수 있습니다. 각 행의 TOTAL-VIOLATIONS 열 아래에 값이 표시될 때까지 기다렸다가 이 kubectl get constraints 명령어를 다시 실행합니다.

      출력은 다음과 비슷합니다.

      NAME                                                                             ENFORCEMENT-ACTION   TOTAL-VIOLATIONS
      asmsidecarinjection.constraints.gatekeeper.sh/pod-sidecar-injection-annotation   deny                 0
      NAME                                                                            ENFORCEMENT-ACTION   TOTAL-VIOLATIONS
      k8srequiredlabels.constraints.gatekeeper.sh/namespace-sidecar-injection-label   deny                 0
      NAME                                                                                      ENFORCEMENT-ACTION   TOTAL-VIOLATIONS
      asmauthzpolicydefaultdeny.constraints.gatekeeper.sh/default-deny-authorization-policies   deny                 0
      NAME                                                                          ENFORCEMENT-ACTION   TOTAL-VIOLATIONS
      asmpeerauthnmeshstrictmtls.constraints.gatekeeper.sh/mesh-level-strict-mtls   deny                 0
      NAME                                                                               ENFORCEMENT-ACTION   TOTAL-VIOLATIONS
      destinationruletlsenabled.constraints.gatekeeper.sh/destination-rule-tls-enabled   deny                 0
      NAME                                                                              ENFORCEMENT-ACTION   TOTAL-VIOLATIONS
      asmpeerauthnstrictmtls.constraints.gatekeeper.sh/peerauthentication-strict-mtls   deny                 0
      NAME                                                                                              ENFORCEMENT-ACTION   TOTAL-VIOLATIONS
      asmauthzpolicyenforcesourceprincipals.constraints.gatekeeper.sh/authz-source-principals-not-all   deny                 0
      
    7. 브라우저에서 Online Boutique 앱으로 이동합니다.

      echo http://${EXTERNAL_IP}
      

      기본 거부 AuthorizationPolicy가 전체 메시에 적용될지 확인하는 RBAC: access denied 오류가 표시됩니다.

    8. asm-ingressonlineboutique 네임스페이스에 더 세분화된 AuthorizationPolicies를 배포하여 이 문제를 해결합니다.

      다음 명령어는 sed를 사용하여 acm-config.yaml 매니페스트를 업데이트해 관련 리소스를 배포하는 구성 동기화를 가져옵니다.

      sed -i "s,root-sync/fix-default-deny-authorization-policy,root-sync/deploy-authorization-policies,g" ~/asm-acm-tutorial-dir/acm-config.yaml
      gcloud beta container fleet config-management apply \
          --membership ${MEMBERSHIP} \
          --config ~/asm-acm-tutorial-dir/acm-config.yaml
      

      위의 명령어는 다음 리소스를 배포합니다.

      • asm-ingress 네임스페이스의 AuthorizationPolicy:

        apiVersion: security.istio.io/v1beta1
        kind: AuthorizationPolicy
        metadata:
          name: asm-ingressgateway
        spec:
          selector:
            matchLabels:
              asm: ingressgateway
          rules:
          - to:
            - operation:
                ports:
                - "8080"
      • onlineboutique 네임스페이스의 앱별 AuthorizationPolicy입니다. cartservice 앱의 예시는 다음과 같습니다.

        apiVersion: security.istio.io/v1beta1
        kind: AuthorizationPolicy
        metadata:
          name: cartservice
        spec:
          selector:
            matchLabels:
              app: cartservice
          rules:
          - from:
            - source:
                principals:
                - cluster.local/ns/onlineboutique/sa/frontend
                - cluster.local/ns/onlineboutique/sa/checkoutservice
            to:
            - operation:
                paths:
                - /hipstershop.CartService/AddItem
                - /hipstershop.CartService/GetCart
                - /hipstershop.CartService/EmptyCart
                methods:
                - POST
                ports:
                - "7070"
      • AuthorizationPolicies에서 principal과 같이 앱별로 평가되는 고유 ID를 갖도록 asm-ingressonlineboutique 네임스페이스의 앱당 ServiceAccount. 다음은 cartservice 앱의 예시입니다.

        apiVersion: v1
        kind: ServiceAccount
        metadata:
          name: cartservice
    9. RootSync 및 두 개의 RepoSyncs에 대한 구성 동기화 상태를 확인합니다.

      gcloud alpha anthos config sync repo describe
      

      출력은 다음과 비슷합니다.

      getting 3 RepoSync and RootSync from projects/PROJECT_ID/locations/global/memberships/asm-acm-tutorial
      [
        {
          "clusters": [
            "projects/PROJECT_ID/locations/global/memberships/asm-acm-tutorial"
          ],
          "commit": "7d15d49af13c44aa531a4565b2277ddcf8b81884",
          "errors": [],
          "source": "https://github.com/GoogleCloudPlatform/anthos-config-management-samples//asm-acm-tutorial/root-sync/deploy-authorization-policies@main",
          "status": "SYNCED"
        },
        {
          "clusters": [
            "projects/PROJECT_ID/locations/global/memberships/asm-acm-tutorial"
          ],
          "commit": "7d15d49af13c44aa531a4565b2277ddcf8b81884",
          "errors": [],
          "source": "https://github.com/GoogleCloudPlatform/anthos-config-management-samples//asm-acm-tutorial/ingress-gateway/authorization-policies@main",
          "status": "SYNCED"
        },
        {
          "clusters": [
            "projects/PROJECT_ID/locations/global/memberships/asm-acm-tutorial"
          ],
          "commit": "7d15d49af13c44aa531a4565b2277ddcf8b81884",
          "errors": [],
          "source": "https://github.com/GoogleCloudPlatform/anthos-config-management-samples//asm-acm-tutorial/online-boutique/authorization-policies@main",
          "status": "SYNCED"
        }
      ]
      

      status: SYNCED 대신 status: RECONCILING이 표시되면 몇 분 기다렸다가 다시 gcloud alpha anthos config sync repo describe를 실행합니다.

      하나의 저장소 정보만 보려면 --sync-name--sync-namespace 플래그를 사용할 수 있습니다. 관리형 리소스를 자세히 보려면 --managed-resources 플래그를 추가하면 됩니다. 자세한 내용은 여러 클러스터에서 구성 동기화 상태 보기를 참조하세요.

    10. 브라우저에서 다시 Online Boutique 앱으로 이동합니다.

      echo http://${EXTERNAL_IP}
      

      몇 분 기다리면 웹사이트가 정상적으로 다시 작동합니다.

    GKE Enterprise 보안 기능 상태 보기

    Google Cloud 콘솔에서 인증 정책과 승인 정책을 포함한 GKE Enterprise 보안 기능의 상태를 볼 수 있습니다.

    1. Google Cloud 콘솔에서 GKE Enterprise 보안 페이지로 이동합니다.

      GKE Enterprise 보안으로 이동

      정책 요약에는 서비스 액세스 제어(AuthorizationPolicies) 및 mTLS를 포함한 애플리케이션 보안 상태가 표시됩니다.

    2. 정책 감사를 클릭하여 클러스터 및 두 네임스페이스(asm-ingressonlineboutique)의 워크로드 정책 상태를 확인합니다.

      서비스 액세스 제어mTLS 상태 카드는 개략적인 개요를 제공합니다.

      서비스 액세스 제어 및 mTLS 상태의 개략적인 개요

      워크로드 목록에는 각 워크로드의 서비스 액세스 제어 및 mTLS 상태가 표시됩니다.

      각 워크로드와 서비스 액세스 제어, mTLS 상태의 세부정보 목록

    이제 정책 컨트롤러 및 구성 동기화로 클러스터와 메시를 보호했습니다.