Cloud Service Mesh、Config Sync、Policy Controller を使用してアプリのセキュリティを強化する


このチュートリアルでは、クラスタとアプリのセキュリティ体制を改善する方法について説明します。ご自身が信頼性の高いサービス メッシュのモニタリングと管理に役立つ一連のツール Cloud Service Mesh を使用してオンライン ストア用のアプリを管理している組織のプラットフォーム管理者であると想定してください。メッシュとアプリを保護するのは、ご自身の責任です。

構成ミスを防止し、Cloud Service Mesh ポリシーを自動的に検証するには、Policy ControllerConfig Sync を使用します。Policy Controller を使用すると、クラスタに対して完全にプログラム可能なポリシーを適用できます。Policy Controller には、メッシュのセキュリティ脆弱性とベスト プラクティスのコンプライアンスを監査するために、Cloud Service Mesh のセキュリティ バンドルと併用できる制約テンプレートのデフォルト ライブラリが付属しています。Config Sync は、中央の Kubernetes 宣言型構成ファイルを使用してクラスタの状態を継続的に調整します。Policy Controller と Config Sync を併用すると、Cloud Service Mesh ポリシーの構成に制約を継続的に適用できます。

次の図は、Cloud Service Mesh、Policy Controller、Config Sync が連携して、このチュートリアルで使用する Ingress ゲートウェイOnline Boutique サンプルアプリを管理し保護する方法を示しています。

このチュートリアル用に作成するアーキテクチャを示す図

目標

  • Google Kubernetes Engine(GKE)クラスタを作成し、そのクラスタをフリートに登録する。
  • Policy Controller、Config Sync、Cloud Service Mesh をクラスタにインストールする。
  • 複数のリポジトリを同期するように Config Sync を構成する。
  • Config Sync を使用して、構成ファイル、アプリ、Istio リソースをデプロイするためのベスト プラクティスを適用する。
  • クラスタ構成ファイル、Online Boutique サンプルアプリ、Config Sync の Ingress ゲートウェイをデプロイする。
  • Policy Controller の Cloud Service Mesh ポリシー バンドルを利用して、次のセキュリティのベスト プラクティスを適用する。
    • メッシュ内のすべてのワークロードに自動サイドカー インジェクションがあることを確認する。
    • メッシュ内のすべてのトラフィックを暗号化する。
    • メッシュ内のすべてのワークロードについて、きめ細かなアクセス制御を保証する。

費用

このドキュメントでは、Google Cloud の次の課金対象のコンポーネントを使用します。

  • GKE.
  • GKE Enterprise. The billing for GKE Enterprise includes billing for the Cloud Service Mesh, Config Sync, and Policy Controller.

料金計算ツールを使うと、予想使用量に基づいて費用の見積もりを生成できます。 新しい Google Cloud ユーザーは無料トライアルをご利用いただける場合があります。

このドキュメントに記載されているタスクの完了後、作成したリソースを削除すると、それ以上の請求は発生しません。詳細については、クリーンアップをご覧ください。

始める前に

  1. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Go to project selector

  2. Make sure that billing is enabled for your Google Cloud project.

環境を準備する

このセクションでは、Cloud Service Mesh、Policy Controller、Config Sync をインストールできるよう環境を準備します。

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

    Activate Cloud Shell

  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
    

    Config Connector

    このチュートリアルでは、Config Connector リソースを扱います。これらのリソースを使用して、[gcloud] タブと同じタスクを完了できます。これらのリソースを利用するには、Config Connector をインストールし、環境に最適な方法でリソースを適用します。

    次の 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 分以上かかることがあります。

GKE クラスタの設定

このセクションでは、GKE クラスタを作成してフリートに登録します。フリートとは、複数のクラスタと他のリソースを論理的に編成するための Google Cloud のコンセプトで、フリートを使用することによって、マルチクラスタ機能の使用と管理、複数のシステム間での一貫したポリシーの適用が可能になります。

このセクションで作成するクラスタは、Cloud Service Mesh、Policy Controller、Config Sync をインストールするクラスタです。また、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}
    

    Config Connector

    次の ContainerCluster マニフェストと ContainerNodePool マニフェストを使用します。

    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. クラスタをフリートに登録します。

    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.
    

    Config Connector

    次の 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 ファイルを使用して、Config Sync はこのチュートリアルの各手順に必要なマニフェストをデプロイします。ファイルを繰り返し操作して git コマンドを繰り返し実行する必要はなく、1 つのファイルを更新するだけで済むので、クラスタ、メッシュ、アプリケーションを保護するコンセプトとフローに注力できます。

Config Sync の複数のリポジトリを同期する機能を利用するには、次のリソースを使用します。

  • root-sync には RootSync リポジトリとして、RepoSyncsConstraintsClusterRoleRoleBindings、および istio-system などの一部のシステム名前空間に含まれるリソースなど、クラスタにわたるすべての構成ファイルが含まれています。
  • ingress-gateway には、最初の RepoSync として、Ingress ゲートウェイをデプロイして、このチュートリアルを通じてそれを段階的に保護するために必要なすべてのリソースが含まれています。
  • online-boutique には、2 番目の RepoSync として、Online Boutique アプリをデプロイし、このチュートリアルを通じてこれらを段階的に保護するために必要なすべてのリソースが含まれています。

Policy Controller、Config Sync、マネージド Cloud Service Mesh をインストールする

クラスタを作成して登録したら、Config Sync、Policy Controller、Cloud Service Mesh をクラスタにインストールし、デフォルトの RootSync の構成ファイルから同期するようにクラスタを構成できます。

  1. Config Sync と Policy Controller を管理する ConfigManagement 演算子を有効にします。

    gcloud

    gcloud beta container fleet config-management enable
    

    Config Connector

    次の GKEHubFeature マニフェストを使用します。

    apiVersion: gkehub.cnrm.cloud.google.com/v1beta1
    kind: GKEHubFeature
    metadata:
      name: configmanagement
    spec:
      projectRef:
        external: PROJECT_ID
      location: global
      resourceID: configmanagement
    
  2. フリートで Cloud Service Mesh を有効にします。

    gcloud

    gcloud container fleet mesh enable
    

    Config Connector

    次の GKEHubFeature マニフェストを使用します。

    apiVersion: gkehub.cnrm.cloud.google.com/v1beta1
    kind: GKEHubFeature
    metadata:
      name: servicemesh
    spec:
      projectRef:
        external: PROJECT_ID
      location: global
      resourceID: servicemesh
    
  3. Cloud Service Mesh の自動管理を有効にして、マネージド Cloud Service Mesh の推奨構成を Google が適用できるようにします。

    gcloud

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

    Config Connector

    次の 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. Config Sync と Policy Controller を有効にします。

    gcloud

    次のマニフェストを acm-config.yaml として ~/asm-acm-tutorial-dir ディレクトリに保存します。

    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 apply spec フィールドをご覧ください。

    ファイルを適用します。

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

    Config Connector

    次の 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
    

    Policy Controller と Config Sync がクラスタにインストールされています。次に、Config Sync はデフォルトの RootSync のすべての構成ファイルをクラスタと同期し始めます。これらの構成ファイルにより、次の主要コンポーネントがインストールされ、構成されます。

    • Online Boutique アプリと Ingress ゲートウェイを構成する 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 Reconciler に追加の権限が必要であるため、これらの権限を付与する ClusterRole と 2 つの 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. Policy Controller と Config Sync が正常にインストールされていることを確認するには、ステータスを確認します。

    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 であるかを確認する必要があります。

Ingress ゲートウェイとサンプル アプリケーションをデプロイする

このセクションでは、Online Boutique サンプル アプリケーションIngress ゲートウェイをデプロイして、上り(内向き)トラフィックを管理します。

  1. Online Boutique のサンプル アプリケーションと Ingress ゲートウェイをデプロイします。

    次のコマンドは、sed を使用して acm-config.yaml マニフェストを更新し、Ingress ゲートウェイとサンプルアプリのデプロイに必要なリソースを Config Sync がデプロイするようにします。

    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 と 2 つの RepoSyncs の Config Sync ステータスを表示します。

    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 を再度実行します。

    1 つのリポジトリの情報のみを表示するには、--sync-name フラグと --sync-namespace フラグを使用します。マネージド リソースの詳細を表示するには、--managed-resources フラグを追加します。詳細については、複数のクラスタの Config Sync のステータスを表示するをご覧ください。

  3. Ingress ゲートウェイのパブリック IP アドレスがプロビジョニングされるまで待ちます。

    until kubectl -n asm-ingress get svc asm-ingressgateway -o jsonpath='{.status.loadBalancer}' | grep "ingress"; do : ; done
    
  4. Ingress ゲートウェイのパブリック 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}
    

ポリシーを適用してメッシュを保護する

次のセクションでは、Policy Controller を活用し、制約を作成して Cloud Service Mesh ポリシー バンドルのポリシーを適用します。

サイドカー プロキシのインジェクションを適用する

このセクションでは、ポリシーを適用して、メッシュ内のすべてのワークロードで自動サイドカー インジェクションが有効になっていることを確認します。

  1. サイドカー プロキシ インジェクションを適用するには、制約を適用します。

    次のコマンドでは、sed を使用して acm-config.yaml マニフェストを更新し、Config Sync が関連リソースのデプロイを開始するようにします。

    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 の Config Sync ステータスを表示します。

    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
    

    Policy Controller がこれらの制約を評価するまでに数分かかる場合があります。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 には 0 TOTAL-VIOLATIONS があります。

  4. これらの Constraints を有効にするには、labelannotation のどちらも指定せずにクラスタに 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 マニフェストを更新し、Config Sync が関連リソースのデプロイを開始するようにします。

    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
    

    上記のコマンドは次のリソースをデプロイします。

    • メッシュレベルの mTLS PeerAuthenticationistio-system 名前空間に適用する 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
    • すべての PeerAuthenticationsSTRICT 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 の Config Sync ステータスを表示します。

    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. PeerAuthenticationistio-system にデプロイして、問題を修正します。メッシュ内のすべてのサービスが平文トラフィックを受け入れるのを防ぐには、mTLS モードを STRICT に設定してメッシュ全体の PeerAuthentication ポリシーを設定します。ポリシーをデプロイすると、コントロール プレーンが TLS 証明書を自動的にプロビジョニングし、ワークロードの相互認証を可能にします。

    次のコマンドでは、sed を使用して acm-config.yaml マニフェストを更新し、Config Sync が関連リソースのデプロイを開始するようにします。

    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 Namespace に次の STRICT mTLS PeerAuthentication をデプロイします。これにより、メッシュ全体に mTLS STRICT が適用されます。

    apiVersion: security.istio.io/v1beta1
    kind: PeerAuthentication
    metadata:
      name: default
    spec:
      mtls:
        mode: STRICT
  5. RootSync の Config Sync ステータスを表示します。

    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
    

    Policy Controller がこれらの 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 マニフェストを更新し、Config Sync が関連リソースのデプロイを開始するようにします。

    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
    

    上記のコマンドは次のリソースをデプロイします。

    • メッシュレベルのデフォルトの deny AuthorizationPolicyistio-system 名前空間で適用する 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 名前空間内の 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 の Config Sync ステータスを表示します。

    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. AuthorizationPolicyistio-system Namespace にデプロイして、問題を修正します。

    次のコマンドでは、sed を使用して acm-config.yaml マニフェストを更新し、Config Sync が関連リソースのデプロイを開始するようにします。

    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 Namespace に次の deny-all AuthorizationPolicy をデプロイします。

    apiVersion: security.istio.io/v1beta1
    kind: AuthorizationPolicy
    metadata:
      name: deny-all
    spec:
      {}
  5. RootSync の Config Sync ステータスを表示します。

    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
    

    Policy Controller がこれらの 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}
    

    エラー RBAC: access denied が表示されます。これは、デフォルトの deny AuthorizationPolicy がメッシュ全体に適用されていることを示します。

  8. この問題を修正するには、asm-ingressonlineboutique の Namespace に、よりきめ細かな AuthorizationPolicies をデプロイします。

    次のコマンドでは、sed を使用して acm-config.yaml マニフェストを更新し、Config Sync が関連リソースのデプロイを開始するようにします。

    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 名前空間内のアプリごとの AuthorizationPolicycartservice アプリの例を次に示します。

      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"
    • AuthorizationPoliciesprincipal と評価されるアプリごとに一意の ID を指定するための asm-ingress 名前空間と onlineboutique 名前空間のアプリごとの ServiceAccountcartservice アプリの例を次に示します。

      apiVersion: v1
      kind: ServiceAccount
      metadata:
        name: cartservice
  9. RootSync と 2 つの RepoSyncs の Config Sync ステータスを表示します。

    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 を再度実行します。

    1 つのリポジトリの情報のみを表示するには、--sync-name フラグと --sync-namespace フラグを使用します。マネージド リソースの詳細を表示するには、--managed-resources フラグを追加します。詳細については、複数のクラスタの Config Sync のステータスを表示するをご覧ください。

  10. ブラウザから Online Boutique アプリに再度アクセスします。

    echo http://${EXTERNAL_IP}
    

    数分待ってから、ウェブサイトが期待どおりに動作することを再度確認します。

GKE Enterprise のセキュリティ機能のステータスを表示する

認証や認可ポリシーなどの GKE Enterprise セキュリティ機能のステータスは、Google Cloud コンソールで確認できます。

  1. Google Cloud コンソールで、[GKE Enterprise Security] ページに移動します。

    [GKE Enterprise Security]に移動

    [ポリシーの概要] には、サービスのアクセス制御(AuthorizationPolicies)や mTLS などのアプリケーション セキュリティのステータスが表示されます。

  2. [ポリシーの監査] をクリックして、クラスタと両方の名前空間(asm-ingressonlineboutique)のワークロード ポリシーのステータスを表示します。

    サービスのアクセス制御カードと mTLS ステータス カードには、概要が記載されています。

    サービス アクセス制御と mTLS ステータスの概要

    [ワークロード] リストに、各ワークロードのサービスのアクセス制御と mTLS ステータスが表示されます。

    各ワークロードとそのサービスのアクセス制御、mTLS ステータスの詳細なリスト

これで、Policy Controller と Config Sync を使用してクラスタとメッシュを保護できました。

クリーンアップ

このチュートリアルで使用したリソースについて、Google Cloud アカウントに課金されないようにするには、リソースを含むプロジェクトを削除するか、プロジェクトを維持して個々のリソースを削除します。

プロジェクトを削除する

    Delete a Google Cloud project:

    gcloud projects delete PROJECT_ID

リソースを個別に削除する

個々のリソースを削除するには:

  1. クラスタをフリートから登録解除します。

    gcloud

    gcloud container fleet memberships unregister ${CLUSTER} \
        --project=${PROJECT_ID} \
        --gke-cluster=${CLUSTER_ZONE}/${CLUSTER}
    

    出力は次のようになります。

    kubeconfig entry generated for asm-acm-tutorial.
    Waiting for membership to be deleted...done.
    Deleting membership CR in the cluster...done.
    Deleting namespace [gke-connect] in the cluster...done.
    

    Config Connector

    kubectl delete -f ~/asm-acm-tutorial-dir/fleet-membership.yaml
    
  2. クラスタを削除します。

    gcloud

    gcloud container clusters delete ${CLUSTER} \
        --zone ${CLUSTER_ZONE}
    

    プロンプトが表示されたら、y キーを押します。このコマンドが完了するまでに 5 分ほどかかります。

    出力は次のようになります。

    Deleting cluster asm-acm-tutorial...done.
    Deleted [https://container.googleapis.com/v1/projects/PROJECT_ID/zones/us-east4-a/clusters/asm-acm-tutorial].
    

    Config Connector

    kubectl delete -f ~/asm-acm-tutorial-dir/container-cluster.yaml
    
  3. 作成したファイルを削除します。

    rm -r ~/asm-acm-tutorial-dir
    

次のステップ