使用 Cloud Service Mesh、Config Sync 和 Policy Controller 增强应用的安全性


本教程介绍如何改进集群和应用的安全状况。假设您是平台管理员,您的组织正在使用 Cloud Service Mesh 管理其网店的应用,Cloud Service Mesh 是一套工具,可帮助您监控和管理可靠的服务网格。您需要负责确保网格和应用的安全。

您可以使用 Policy ControllerConfig Sync 防止配置错误并自动验证 Cloud Service Mesh 政策。Policy Controller 支持为您的集群强制执行完全可编程的政策。Policy Controller 还附带一个默认的限制条件模板库,您可以将该库与 Cloud Service Mesh 安全包结合使用,以审核网格安全漏洞的合规性并了解是否符合最佳实践。Config Sync 使用一组集中式 Kubernetes 声明式配置文件来持续协调集群的状态。通过搭配使用 Policy Controller 和 Config Sync,您可以持续对 Cloud Service Mesh 政策配置实施限制条件

下图简要展示了在本教程中 Cloud Service Mesh、Policy Controller 和 Config Sync 如何协同工作,以管理和保护您在本教程中使用的入站流量网关Online Boutique 示例应用

展示您为本教程创建的架构的示意图

目标

  • 创建 Google Kubernetes Engine (GKE) 集群并向舰队注册集群。
  • 在集群上安装 Policy Controller、Config Sync 和 Cloud Service Mesh。
  • 将 Config Sync 配置为同步多个代码库
  • 应用使用 Config Sync 部署配置、应用和 Istio 资源的最佳实践。
  • 使用 Config Sync 部署集群配置、Online Boutique 示例应用和入站流量网关。
  • 利用 Policy Controller 的 Cloud Service Mesh 政策包来强制执行以下安全方面的最佳实践:
    • 确保网格中的所有工作负载都具有自动 Sidecar 注入。
    • 加密网格中的所有流量。
    • 保证网格中的所有工作负载都具有精细的访问权限控制。

费用

在本文档中,您将使用 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. Verify 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
    

    此操作可能需要超过一分钟才能完成。

  6. 设置 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

      使用以下 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 环境变量的值。

      此操作可能需要五分钟以上才能完成。

    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 命令。

    如需利用 Config Sync 的同步多个代码库功能,请使用以下资源:

    • root-sync 作为 RootSync 代码库,包含集群中的所有配置(包括 RepoSyncsConstraintsClusterRoleRoleBindings)以及某些系统命名空间(如 istio-system)中包含的资源。
    • ingress-gateway 作为第一个 RepoSync,包含在本教程中部署入站流量网关并逐步确保其安全所需的所有资源。
    • online-boutique 作为第二个 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 自动管理功能,以便让 Google 应用推荐的托管式 Cloud Service Mesh 配置:

      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

      将以下清单另存为 ~/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 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 应用和入站流量网关的 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
      • 由于 RepoSync 协调器需要其他权限才能创建 Istio 资源,因此系统还会向您的集群应用 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. 如需确保 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
      

      如果您在 StatusPolicy_Controller 行中看到 PENDINGNOT_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: ERROR 而不是 state.code: OK,请等待几分钟,然后再次运行 gcloud container fleet mesh describe。 在继续学习本教程之前,您需要确保 servicemesh.controlPlaneManagement.details.code 字段具有 REVISION_READY 值。

    部署入站流量网关和示例应用

    在本部分中,您将部署 Online Boutique 示例应用入站流量网关以管理入站流量。

    1. 部署 Online Boutique 示例应用和入站网关。

      以下命令使用 sed 更新 acm-config.yaml 清单,以使 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 和两个 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: RECONCILING 而不是 status: SYNCED,请等待几分钟,然后再次运行 gcloud alpha anthos config sync repo describe

      如需仅查看一个代码库的信息,您可以使用 --sync-name--sync-namespace 标志。如需详细查看代管式资源,请添加 --managed-resources 标志。如需了解详情,请参阅跨多个集群查看 Config Sync 状态

    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}
      

    实施政策以保护您的网格

    在接下来的部分中,您将利用 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
      

      上述命令会部署以下资源:

      • K8sRequiredLabels Constraint,要求网格中的任何 Namespace 均包含特定的 Cloud Service Mesh 边车代理注入标签

        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
      • AsmSidecarInjection Constraint,用于禁止网格中的任何 Pod 绕过 Istio 代理边车注入:

        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: RECONCILING 而不是 status: SYNCED,请等待几分钟,然后再次运行 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 的工作方式,请尝试在集群中创建一个不包含 labelannotationNamespace

      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
      

      上述命令会部署以下资源:

      • AsmPeerAuthnMeshStrictMtls Constraint,用于在 istio-system 命名空间中强制执行网格级 mTLS PeerAuthentication

        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"
      • DestinationRuleTLSEnabled Constraint,用于禁止为 Istio DestinationRules 中的所有主机和主机子集停用 TLS:

        apiVersion: constraints.gatekeeper.sh/v1beta1
        kind: DestinationRuleTLSEnabled
        metadata:
          name: destination-rule-tls-enabled
        spec:
          enforcementAction: deny
          match:
            kinds:
            - apiGroups:
              - networking.istio.io
              kinds:
              - DestinationRule
      • AsmPeerAuthnStrictMtls Constraint,用于强制所有 PeerAuthentications 无法覆盖 STRICT mTLS:

        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: RECONCILING 而不是 status: SYNCED,请等待几分钟,然后再次运行 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-system 中部署 PeerAuthentication 来解决此问题。如需阻止网格中的所有服务接受明文流量,请设置 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 命名空间中部署以下 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: RECONCILING 而不是 status: SYNCED,请等待几分钟,然后再次运行 gcloud alpha anthos config sync repo describe

    6. 验证 Constraints 是否已创建:

      kubectl get constraints
      

      请注意,可能需要几分钟时间使 Policy Controller 评估这些 Constraints。等待并再次运行此 kubectl get constraints 命令,直到您在每行的 TOTAL-VIOLATIONS 列下获取值。

      输出类似于以下内容:

      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
      

      上述命令会部署以下资源:

      • AsmAuthzPolicyDefaultDeny Constraint,用于在 istio-system 命名空间中强制执行网格级默认拒绝 AuthorizationPolicy

        apiVersion: constraints.gatekeeper.sh/v1beta1
        kind: AsmAuthzPolicyDefaultDeny
        metadata:
          name: default-deny-authorization-policies
        spec:
          enforcementAction: deny
          parameters:
            rootNamespace: istio-system
            strictnessLevel: High
      • AsmAuthzPolicyEnforceSourcePrincipals Constraint,强制要求任何 AuthorizationPolicies 均定义精细的来源主体(“*”除外)。只有 asm-ingress 命名空间中的入站流量网关是此规则的例外情况,以便接收来自最终用户的流量并将流量重定向到 Online Boutique 的 frontend 应用。

        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: RECONCILING 而不是 status: SYNCED,请等待几分钟,然后再次运行 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 清单,以使 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 命名空间中部署以下全部拒绝 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: RECONCILING 而不是 status: SYNCED,请等待几分钟,然后再次运行 gcloud alpha anthos config sync repo describe

    6. 验证 Constraints 是否已创建:

      kubectl get constraints
      

      请注意,可能需要几分钟时间使 Policy Controller 评估这些 Constraints。等待并再次运行此 kubectl get constraints 命令,直到您在每行的 TOTAL-VIOLATIONS 列下获取值。

      输出类似于以下内容:

      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,该错误确认默认拒绝 AuthorizationPolicy 会应用于整个网格。

    8. 通过在 asm-ingressonlineboutique 命名空间中部署更精细的 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 命名空间中每个应用的 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"
      • asm-ingressonlineboutique 命名空间中每个应用的 ServiceAccount,以便在 AuthorizationPolicies 中将每个应用的唯一身份评估为 principal。下面是 cartservice 应用的示例:

        apiVersion: v1
        kind: ServiceAccount
        metadata:
          name: cartservice
    9. 查看 RootSync 和两个 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: RECONCILING 而不是 status: SYNCED,请等待几分钟,然后再次运行 gcloud alpha anthos config sync repo describe

      如需仅查看一个代码库的信息,您可以使用 --sync-name--sync-namespace 标志。此外,如需详细查看代管式资源,您可以添加 --managed-resources 标志。如需了解详情,请参阅跨多个集群查看 Config Sync 状态

    10. 再次通过浏览器访问 Online Boutique 应用:

      echo http://${EXTERNAL_IP}
      

      如果等待几分钟,您现在应该会看到网站再次按预期成功运行。

    查看 GKE Enterprise 安全功能的状态

    您可以在 Google Cloud 控制台中查看 GKE Enterprise 安全功能(包括身份验证和授权政策)的状态。

    1. 在 Google Cloud 控制台中,前往 GKE Enterprise Security 页面。

      前往 GKE Enterprise 安全

      政策摘要显示应用安全的状态,包括服务访问权限控制 (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。此命令可能需要五分钟以上才能完成。

    输出类似于以下内容:

    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
    

后续步骤