将 IAP 与 Anthos Service Mesh 集成


本教程介绍如何将 Identity-Aware Proxy (IAP) 与 Anthos Service Mesh 集成。借助 IAP 与 Anthos Service Mesh 的集成,您可以基于 Google 的 BeyondCorp 原则安全地访问服务。IAP 会验证用户身份和请求的上下文,以确定是否应允许用户访问应用或资源。IAP 与 Anthos Service Mesh 的集成可为您提供以下优势:

  • 对在 Anthos Service Mesh 上运行的工作负载完成情境感知访问权限控制。您可以根据发出请求的特性(例如用户身份、IP 地址和设备类型)设置精细的访问权限政策。您可以根据请求网址的主机名和路径来结合您的访问权限政策与限制。

  • 在 Anthos Service Mesh 授权中启用对情境感知声明的支持。

  • 通过 Google Cloud 负载均衡器对应用的可扩缩、安全和可用性高的访问权限。高性能负载均衡提供分布式拒绝服务攻击 (DDoS) 的内置保护,并且支持全局任播 IP 寻址

目标

  • 进行设置:
    1. 设置您的 Google Cloud 项目以授予权限并启用 IAP 所需的 Google API。
    2. 预留一个外部静态 IP 地址,并配置域名以使用该 IP 地址(这是负载均衡器所需的)。
    3. 使用将 IAP 与 Anthos Service Mesh 集成所需的选项设置一个新的 Google Kubernetes Engine (GKE) 集群。
    4. 使用集成所需的选项安装 Anthos Service Mesh。
    5. 部署一个示例应用。
    6. 部署负载均衡器。
  • 启用 IAP。

  • 在服务网格上启用 RCToken 支持。

费用

在本文档中,您将使用 Google Cloud 的以下收费组件:

您可使用价格计算器根据您的预计使用情况来估算费用。 Google Cloud 新用户可能有资格申请免费试用

完成本文档中描述的任务后,您可以通过删除所创建的资源来避免继续计费。如需了解详情,请参阅清理

准备工作

要求

  • 您必须拥有 Anthos 试用许可或已订阅 Anthos。 如需了解详情,请参阅 Anthos 价格指南

  • 您的 GKE 集群必须满足以下要求:

    • 至少具有四个节点。
    • 最小机器类型是配备了四个 vCPU 的 e2-standard-4
    • 使用 GKE 的 发布版本而不是静态版本
  • 如需将服务端口纳入服务网格,必须为服务端口命名,并且名称必须包含以下语法的端口协议:name: protocol[-suffix],其中方括号表示必须以短划线开头的可选后缀。 如需了解详情,请参阅命名服务端口

  • 如果您是在专用集群上安装 Anthos Service Mesh,则必须添加防火墙规则来打开端口 9443,以使用自动 Sidecar 注入。如果您未添加防火墙规则并启用了自动 Sidecar 注入,则在部署工作负载时会收到错误。如需详细了解如何添加防火墙规则,请参阅针对特定用例添加防火墙规则

  • 如果您在组织中创建了服务边界,则可能需要将 Mesh CA 服务添加到边界。如需了解详情,请参阅将 Mesh CA 添加到服务边界

设置您的环境

如需在 Google Kubernetes Engine 上进行安装,您可以使用 Cloud Shell、Google Cloud 资源的浏览器内置命令行界面或您自己运行 Linux 或 macOS 的计算机,按照安装指南操作。

选项 A:使用 Cloud Shell

Cloud Shell 预配一个运行基于 Debian 的 Linux 操作系统的 g1-small Compute Engine 虚拟机 (VM)。使用 Cloud Shell 的优势如下:

  • Cloud Shell 包含您需要的 gcloudkubectlhelm 命令行工具。

  • 您的 Cloud Shell $HOME 目录具有 5GB 永久性存储空间。

  • 您可以选择文本编辑器

    • 代码编辑器,可通过点击 Cloud Shell 窗口顶部的 来访问。

    • Emac、Vim 或 Nano,可从 Cloud Shell 中的命令行访问。

如需使用 Cloud Shell,请执行以下操作:

  1. 前往 Google Cloud 控制台
  2. 选择您的 Google Cloud 项目。
  3. 点击 Google Cloud 控制台窗口顶部的激活 Cloud Shell 按钮。

    Google Cloud Platform 控制台

    一个 Cloud Shell 会话随即会在 Google Cloud 控制台底部的新框内打开,并显示命令行提示符。

    Cloud Shell 会话

  4. 更新组件:

    gcloud components update
    

    该命令会以如下所示的输出作为响应:

    ERROR: (gcloud.components.update)
    You cannot perform this action because the gcloud CLI component manager
    is disabled for this installation. You can run the following command
    to achieve the same result for this installation:
    
    sudo apt-get update && sudo apt-get --only-upgrade install ...
  5. 复制并粘贴长命令以更新组件。

  6. 安装 kubectl

    sudo apt-get install kubectl
    
  7. 安装 kpt

    sudo apt-get install google-cloud-sdk-kpt
    

选项 B:在本地使用命令行工具

在本地机器上,安装并初始化 gcloud CLI

如果您已安装 gcloud CLI,请执行以下操作:

  1. 使用 gcloud CLI 进行身份验证:

    gcloud auth login
    
  2. 更新组件:

    gcloud components update
    
  3. 安装 kubectl

    gcloud components install kubectl
    
  4. 安装 kpt

    gcloud components install kpt
    

设置项目

  1. 获取将在其中创建集群的项目的项目 ID:

    gcloud

    gcloud projects list

    控制台

    1. 在 Google Cloud 控制台中,转到信息中心页面

      转到“信息中心”页面

    2. 点击页面顶部的从以下列表中选择:下拉列表。在随即显示的从以下列表中选择:窗口中,选择您的项目。

      项目 ID 会显示在项目信息中心的项目信息卡片上。

  2. 为项目 ID 创建环境变量:
    export PROJECT_ID=YOUR_PROJECT_ID
    
  3. gcloud 命令行工具设置默认项目 ID:
    gcloud config set project ${PROJECT_ID}
  4. 为项目编号创建环境变量:
    export PROJECT_NUMBER=$(gcloud projects describe ${PROJECT_ID} --format="value(projectNumber)")

  5. 设置所需的 Identity and Access Management (IAM) 角色。如果您是 Project Owner,则拥有完成安装和向 Environ 注册集群所需的所有必要权限。如果您不是 Project Owner,则需要有人授予您以下特定 IAM 角色。在以下命令中,将 GCP_EMAIL_ADDRESS 更改为您用于登录 Google Cloud 的帐号。
    gcloud projects add-iam-policy-binding ${PROJECT_ID} \
         --member user:GCP_EMAIL_ADDRESS \
         --role=roles/editor \
         --role=roles/compute.admin \
         --role=roles/container.admin \
         --role=roles/resourcemanager.projectIamAdmin \
         --role=roles/iam.serviceAccountAdmin \
         --role=roles/iam.serviceAccountKeyAdmin \
         --role=roles/gkehub.admin

    如需详细了解如何授予 IAM 角色,请参阅授予、更改和撤消对资源的访问权限。如需了解这些角色,请参阅安装 Anthos Service Mesh 所需的权限

  6. 启用以下 API:
    gcloud services enable \
        container.googleapis.com \
        compute.googleapis.com \
        monitoring.googleapis.com \
        logging.googleapis.com \
        cloudtrace.googleapis.com \
        meshca.googleapis.com \
        meshtelemetry.googleapis.com \
        meshconfig.googleapis.com \
        iamcredentials.googleapis.com \
        anthos.googleapis.com \
        gkeconnect.googleapis.com \
        gkehub.googleapis.com \
        cloudresourcemanager.googleapis.com \
        iap.googleapis.com
    

    启用 API 可能需要 1 分钟或更长时间才能完成。启用这些 API 后,您将会看到如下所示的输出:

    Operation "operations/acf.601db672-88e6-4f98-8ceb-aa3b5725533c" finished
    successfully.
    

预留静态 IP 地址并配置 DNS

如需将 Identity-Aware Proxy 与 Anthos Service Mesh 集成,您必须设置 Google Cloud HTTP(S) 负载均衡器,它需要一个指向静态 IP 地址的域名。您可以预留一个静态外部 IP 地址,这样会将该地址无限期地分配给您的项目,直到您明确释放该地址。

  1. 预留静态外部 IP 地址:

    gcloud compute addresses create example-static-ip --global
    
  2. 获取静态 IP 地址:

    gcloud compute addresses describe example-static-ip --global
    
  3. 在您的域名注册商中,使用静态 IP 地址配置完全限定域名 (FQDN)。通常情况下,将 A 记录添加到 DNS 设置。为 FQDN 添加 A 记录的配置步骤和术语会因您的域名注册商而异。

  4. 在环境变量中设置域名:

    export DOMAIN_NAME=YOUR_DOMAIN_NAME

    DNS 设置可能需要 24 到 48 小时才能生效。您可以继续设置本教程中的所有内容,但在 DNS 设置生效之前无法测试设置。

设置新的 GKE 集群

本部分介绍使用 Anthos Service Mesh 所需的选项创建 GKE 集群的基础知识。如需了解详情,请参阅创建集群

如需设置新集群,请执行以下操作:

  1. 为新集群选择区域或地区机器类型和 GKE 发布版本。Anthos Service Mesh 所需的最小机器类型为 e2-standard-4。您可以使用任何发布版本选项。

    • 如果您要创建单区域集群,请运行以下命令来获取可用 GCP 区域的列表:

      gcloud compute zones list
      
    • 如果您要创建地区级集群,请运行以下命令来获取可用地区的列表:

      gcloud compute regions list
      
    • 如需获取机器类型列表,请执行以下操作:

      gcloud compute machine-types list | more
      
  2. 创建以下环境变量:

    • 设置集群名称:

      export CLUSTER_NAME=YOUR_CLUSTER_NAME

      集群名称只能包含小写字母、数字和“-”,必须以字母开头,以字母数字结尾,并且不能超过 40 个字符。

    • CLUSTER_LOCATION 设置为您的集群区域或集群地区:

      export CLUSTER_LOCATION=YOUR_ZONE_OR_REGION
    • 设置工作负载池:

      export WORKLOAD_POOL=${PROJECT_ID}.svc.id.goog
    • 设置网格 ID:

      export MESH_ID="proj-${PROJECT_NUMBER}"
    • 设置发布版本。将 YOUR_CHANNEL 替换为以下某个值:regularstablerapid

      export CHANNEL=YOUR_CHANNEL

      如需了解每个发布版本,请参阅您可以获得哪些发布版本

  3. 为 Google Cloud CLI 设置默认可用区或区域。

    • 对于单区域集群,请设置默认区域:

      gcloud config set compute/zone ${CLUSTER_LOCATION}
    • 对于地区级集群,请设置默认地区:

      gcloud config set compute/region ${CLUSTER_LOCATION}

    提示:为了让您以后更轻松地设置 shell 环境,您可以将每个环境变量的 export 语句复制并粘贴到启动新 shell 时将对其执行 source 的简单 shell 脚本。您还可以添加 gcloud 命令,以将默认值设置为脚本。或者,您可以使用 gcloud init 创建并激活命名的 gcloud 配置。

  4. 使用 Anthos Service Mesh 所需的选项创建集群。以下命令会创建一个集群,其中包含 4 个机器类型为 e2-standard-4 的节点,该机器类型具有 4 个 vCPU。这是 Anthos Service Mesh 所需的最小机器类型和节点数。您可以指定其他机器类型,前提是该机器类型至少有 4 个 vCPU,并且您可以根据系统要求增加节点数。

    gcloud beta container clusters create ${CLUSTER_NAME} \
        --machine-type=e2-standard-4 \
        --num-nodes=4 \
        --workload-pool=${WORKLOAD_POOL} \
        --enable-stackdriver-kubernetes \
        --subnetwork=default \
        --labels=mesh_id=${MESH_ID} \
        --release-channel=${CHANNEL}

    clusters create 命令包含:

    • workload-pool=${WORKLOAD_POOL}:启用 Workload Identity,这是从 GKE 应用安全访问 Google Cloud 服务的推荐方法。

    • enable-stackdriver-kubernetes:启用 GKE 上的 Cloud Monitoring 和 Cloud Logging

    • subnetwork=default:创建默认子网

    • labels mesh_id=${MESH_ID}:在集群上设置 mesh_id 标签,该标签对于在 Google Cloud 控制台中的 Anthos Service Mesh 页面上显示指标必不可少。

    • release-channel ${CHANNEL}:在指定的发布版本中注册集群。

准备安装 Anthos Service Mesh

在继续操作之前,请验证 ASM 网格数据平面服务帐号是否为项目成员:

gcloud projects get-iam-policy ${PROJECT_ID} | grep -B 1 'roles/meshdataplane.serviceAgent'

如果上一个命令没有输出任何内容,请返回设置凭据和权限部分,然后运行 curl 命令。

    Linux

  1. 将 Anthos Service Mesh 安装文件下载到当前工作目录中:
    curl -LO https://storage.googleapis.com/gke-release/asm/istio-1.4.10-asm.18-linux.tar.gz
  2. 下载签名文件并使用 openssl 验证签名:
    curl -LO https://storage.googleapis.com/gke-release/asm/istio-1.4.10-asm.18-linux.tar.gz.1.sig
    openssl dgst -verify - -signature istio-1.4.10-asm.18-linux.tar.gz.1.sig istio-1.4.10-asm.18-linux.tar.gz <<'EOF'
    -----BEGIN PUBLIC KEY-----
    MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEWZrGCUaJJr1H8a36sG4UUoXvlXvZ
    wQfk16sxprI2gOJ2vFFggdq3ixF2h4qNBt0kI7ciDhgpwS8t+/960IsIgw==
    -----END PUBLIC KEY-----
    EOF

    预期输出为 Verified OK

  3. Mac OS

  4. 将 Anthos Service Mesh 安装文件下载到当前工作目录中:
    curl -LO https://storage.googleapis.com/gke-release/asm/istio-1.4.10-asm.18-osx.tar.gz
  5. 下载签名文件并使用 openssl 验证签名:
    curl -LO https://storage.googleapis.com/gke-release/asm/istio-1.4.10-asm.18-osx.tar.gz.1.sig
    openssl dgst -sha256 -verify /dev/stdin -signature istio-1.4.10-asm.18-osx.tar.gz.1.sig istio-1.4.10-asm.18-osx.tar.gz <<'EOF'
    -----BEGIN PUBLIC KEY-----
    MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEWZrGCUaJJr1H8a36sG4UUoXvlXvZ
    wQfk16sxprI2gOJ2vFFggdq3ixF2h4qNBt0kI7ciDhgpwS8t+/960IsIgw==
    -----END PUBLIC KEY-----
    EOF

    预期输出为 Verified OK

  6. Windows

  7. 将 Anthos Service Mesh 安装文件下载到当前工作目录中:
    curl -LO https://storage.googleapis.com/gke-release/asm/istio-1.4.10-asm.18-win.zip
  8. 下载签名文件并使用 openssl 验证签名:
    curl -LO https://storage.googleapis.com/gke-release/asm/istio-1.4.10-asm.18-win.zip.1.sig
    openssl dgst -verify - -signature istio-1.4.10-asm.18-win.zip.1.sig istio-1.4.10-asm.18-win.zip <<'EOF'
    -----BEGIN PUBLIC KEY-----
    MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEWZrGCUaJJr1H8a36sG4UUoXvlXvZ
    wQfk16sxprI2gOJ2vFFggdq3ixF2h4qNBt0kI7ciDhgpwS8t+/960IsIgw==
    -----END PUBLIC KEY-----
    EOF

    预期输出为 Verified OK

  9. 将文件内容提取到文件系统上的任意位置。例如,如需将内容提取到当前工作目录,请运行以下命令:
    tar xzf istio-1.4.10-asm.18-linux.tar.gz

    该命令会在当前工作目录中创建一个名为 istio-1.4.10-asm.18 的安装目录,其中包含:

    • samples 中的示例应用
    • bin 目录中的以下工具:
      • istioctl:您使用 istioctl 来安装 Anthos Service Mesh。
      • asmctl:安装 Anthos Service Mesh 后,您可以使用 asmctl 来帮助验证安全配置。(目前 Anthos clusters on VMware 不支持 asmctl。)

  10. 确保您位于 Anthos Service Mesh 安装的根目录。
    cd istio-1.4.10-asm.18
  11. 为方便起见,请将 /bin 目录中的工具添加到 PATH:
    export PATH=$PWD/bin:$PATH

安装 Anthos Service Mesh

安装 Anthos Service Mesh 并设置将 Anthos Service Mesh 与 IAP 集成所需的选项。

PERMISSIVE mTLS

istioctl manifest apply --set profile=asm \
  --set values.gateways.istio-ingressgateway.type=NodePort \
  --set values.global.trustDomain=${WORKLOAD_POOL} \
  --set values.global.sds.token.aud=${WORKLOAD_POOL} \
  --set values.nodeagent.env.GKE_CLUSTER_URL=https://container.googleapis.com/v1/projects/${PROJECT_ID}/locations/${CLUSTER_LOCATION}/clusters/${CLUSTER_NAME} \
  --set values.global.meshID=${MESH_ID} \
  --set values.global.proxy.env.GCP_METADATA="${PROJECT_ID}|${PROJECT_NUMBER}|${CLUSTER_NAME}|${CLUSTER_LOCATION}"

STRICT mTLS

istioctl manifest apply --set profile=asm \
  --set values.gateways.istio-ingressgateway.type=NodePort \
  --set values.global.trustDomain=${WORKLOAD_POOL} \
  --set values.global.sds.token.aud=${WORKLOAD_POOL} \
  --set values.nodeagent.env.GKE_CLUSTER_URL=https://container.googleapis.com/v1/projects/${PROJECT_ID}/locations/${CLUSTER_LOCATION}/clusters/${CLUSTER_NAME} \
  --set values.global.meshID=${MESH_ID} \
  --set values.global.proxy.env.GCP_METADATA="${PROJECT_ID}|${PROJECT_NUMBER}|${CLUSTER_NAME}|${CLUSTER_LOCATION}" \
  --set values.global.mtls.enabled=true

您为 istio-ingressgateway 指定 NodePort,它会配置 {[mesh_name]} 以打开服务网格上的特定端口。这样,您就可以设置负载均衡器,以将发送到您的域名的流量路由到此端口。其他选项会启用 Anthos Service Mesh 证书授权机构 (Mesh CA)。

检查控制层面组件

检查 istio-system 中的控制层面 Pod 是否已启动:

kubectl get pod -n istio-system

预期会看到类似如下所示的输出:

NAME                                      READY   STATUS      RESTARTS   AGE
istio-galley-5c65896ff7-m2pls             2/2     Running     0          18m
istio-ingressgateway-587cd459f-q6hqt      2/2     Running     0          18m
istio-nodeagent-74w69                     1/1     Running     0          18m
istio-nodeagent-7524w                     1/1     Running     0          18m
istio-nodeagent-7652w                     1/1     Running     0          18m
istio-nodeagent-7948w                     1/1     Running     0          18m
istio-pilot-9db77b99f-7wfb6               2/2     Running     0          18m
istio-sidecar-injector-69c4d9f875-dt8rn   1/1     Running     0          18m
promsd-55f464d964-lqs7w                   2/2     Running     0          18m

您应该会看到集群中每个节点的 istio-nodeagent 实例。Mesh CA 取代了 Citadel OSS Istio 组件,用于创建节点代理来为服务网格中运行的工作负载颁发 mTLS 证书。

部署示例应用

启用 IAP 之前,您需要在 GKE 集群上运行的应用,以便验证所有请求是否都具有身份。本指南使用 Bookinfo 示例来演示如何设置 HTTP(S) 负载均衡器并启用 IAP。

启动应用服务

  1. 将目录更改为 Anthos Service Mesh 安装的根目录。

  2. default 命名空间添加标签以使用自动 Sidecar 注入

    kubectl label namespace default istio-injection=enabled
    
  3. 部署应用:

    kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml
    
  4. 确认所有 bookinfo 服务都正在运行:

    kubectl get services
    

    预期输出如下所示:

    NAME                       CLUSTER-IP   EXTERNAL-IP   PORT(S)              AGE
    details                    10.0.0.31            9080/TCP             6m
    kubernetes                 10.0.0.1             443/TCP              7d
    productpage                10.0.0.120           9080/TCP             6m
    ratings                    10.0.0.15            9080/TCP             6m
    reviews                    10.0.0.170           9080/TCP             6m
  5. 确认所有 pod 都正在运行:

    kubectl get pods
    

    预期输出如下所示:

    NAME                                        READY     STATUS    RESTARTS   AGE
    details-v1-1520924117-48z17                 2/2       Running   0          6m
    productpage-v1-560495357-jk1lz              2/2       Running   0          6m
    ratings-v1-734492171-rnr5l                  2/2       Running   0          6m
    reviews-v1-874083890-f0qf0                  2/2       Running   0          6m
    reviews-v2-1343845940-b34q5                 2/2       Running   0          6m
    reviews-v3-1813607990-8ch52                 2/2       Running   0          6m
  6. 确认 Bookinfo 应用正在运行:

    kubectl exec -it $(kubectl get pod -l app=ratings -o jsonpath='{.items[0].metadata.name}') -c ratings -- curl productpage:9080/productpage | grep -o "<title>.*</title>"
    

    预期输出:

    <title>Simple Bookstore App</title>
  7. 为应用定义 Ingress 网关和虚拟服务:

    kubectl apply -f samples/bookinfo/networking/bookinfo-gateway.yaml
    
  8. 确认网关已创建:

    kubectl get gateway
    

    预期输出如下所示:

    NAME                AGE
    bookinfo-gateway    32s

外部请求

Bookinfo 的网关资源(在 samples/bookinfo/networking/bookinfo-gateway.yaml 中定义)使用预配置的 istio-ingressgateway。如前文所述,当您部署 Anthos Service Mesh 时,您为 istio-ingressgateway 指定了 NodePort,这会在服务网格上打开特定端口。 在您设置负载均衡器之前,您将无法在 GKE 集群之外(例如通过浏览器)访问 Bookinfo 应用。虽然集群中的节点具有外部 IP 地址,但来自集群外部的请求会被 Google Cloud 防火墙规则阻止。启用 IAP 后,将应用公开到公共互联网的正确方法是使用负载均衡器。请勿使用会绕过 IAP 的防火墙规则公开节点地址。

如需将请求路由到 Bookinfo,请在您的 Google Cloud 项目中设置 HTTP(S) 负载均衡器。由于负载均衡器在您的项目中,因此它位于防火墙内,可以访问集群中的节点。使用静态 IP 地址和您的域名配置负载均衡器后,您可以向域名发送请求,负载均衡器会将请求转发到集群中的节点。

部署负载均衡器

您可以使用 Ingress 资源创建使用自动配置的 SSL 证书的 HTTP(S) 负载均衡器。系统会为您的网域预配、续订和管理 Google 管理的 SSL 证书

  1. 创建 ManagedCertificate 资源。此资源会指定 SSL 证书的网域。spec.domains 列表只能包含一个网域。不支持通配符网域。

    cat <<EOF | kubectl apply -f -
    apiVersion: networking.gke.io/v1beta1
    kind: ManagedCertificate
    metadata:
      name: example-certificate
    spec:
      domains:
        - ${DOMAIN_NAME}
    EOF
  2. 通过定义 Ingress 资源来创建负载均衡器。

    • networking.gke.io/managed-certificates 注释设置为您在上一步中创建的证书的名称 example-certificate

    • kubernetes.io/ingress.global-static-ip-name 注释设置为您预留的静态 IP 地址的名称 example-static-ip

    • serviceName 设置为 istio-ingressgateway,后者会在 Bookinfo 示例的 Gateway 资源中使用。

    cat <<EOF | kubectl create -f -
    apiVersion: extensions/v1beta1
    kind: Ingress
    metadata:
      name: example-ingress
      namespace: istio-system
      annotations:
        kubernetes.io/ingress.global-static-ip-name: example-static-ip
        networking.gke.io/managed-certificates: example-certificate
    spec:
      backend:
        serviceName: istio-ingressgateway
        servicePort: 80
    EOF
  3. 在 Google Cloud 控制台中,前往 Kubernetes Engine > Service 和 Ingress 页面。

    前往“Service 和 Ingress”页面

    您应该会在状态列中看到“正在创建 Ingress”(Creating ingress) 消息。等待 GKE 完全预配 Ingress,然后再继续。每隔几分钟刷新一次页面以获取 Ingress 的最新状态。预配 Ingress 后,您可能会看到“正常”状态,或者错误“所有后端服务均处于运行状况并不佳的状态”。GKE 预配的其中一项资源是默认健康检查。如果您看到错误消息,这表示已预配 Ingress,并且已运行默认健康检查。当您看到“正常”状态或错误时,请继续下一部分,为负载均衡器配置健康检查。

为负载均衡器配置健康检查。

如需配置健康检查,您需要获取 Ingress 创建的默认健康检查的 ID,然后更新健康检查,以使用 istio-ingress 的健康检查路径和端口。

  1. 获取用于应用默认凭据的新用户凭据:

      gcloud auth application-default login

  2. 获取 Ingress 创建的默认健康检查的 ID:

    1. 设置以下环境变量:

      • 后端服务:桥接给定 Service NodePort 上的各个实例组。

        BACKEND_SERVICE=$(gcloud compute url-maps list | grep example-ingress | awk '{print $2}' | cut -d'/' -f 2)

      • 健康检查:这是部署 Ingress 时自动创建的默认健康检查。

        HC=$(gcloud compute backend-services describe ${BACKEND_SERVICE} --global | grep healthChecks | cut -d'/' -f 10 | tail -n 1)

      • 健康检查入站流量端口:这是 istio-ingress 的健康检查端口。

        export HC_INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="status-port")].nodePort}')

      • 健康检查入站流量路径:这是 istio-ingress 的健康检查路径。

        export HC_INGRESS_PATH=$(kubectl -n istio-system get deployments istio-ingressgateway -o jsonpath='{.spec.template.spec.containers[?(@.name=="istio-proxy")].readinessProbe.httpGet.path}')

      • 健康检查 API:这是调用来配置健康检查的 API。
        export HC_API=https://compute.googleapis.com/compute/v1/projects/${PROJECT_ID}/global/healthChecks/${HC}

    2. 通过调用 healthChecks API 获取默认健康检查并存入 JSON 文件:

      curl --request GET  --header "Authorization: Bearer $(gcloud auth application-default print-access-token)" ${HC_API} > health_check.json
  3. 更新健康检查以使用 istio-ingress 的健康检查路径和端口:

    1. 按如下所示的方式更新 health_check.json 文件:

      • httpHealthCheck.port 设置为 ${HC_INGRESS_PORT} 的值。
      • httpHealthCheck.requestPath 设置为 ${HC_INGRESS_PATH} 的值。
      • 添加以下特性并将其设置为空字符串:httpHealthCheck.portSpecification=""

      最简单的方法是使用预安装在 Cloud Shell 上的 jq

      jq ".httpHealthCheck.port=${HC_INGRESS_PORT} | .httpHealthCheck.requestPath=\"${HC_INGRESS_PATH}\" | .httpHealthCheck.portSpecification=\"\"" health_check.json > updated_health_check.json

      如果您对生成的 updated_health_check.json 文件运行 cat,则会如下所示:

      {
      "id": "5062913090021441698",
      "creationTimestamp": "2019-11-12T10:47:41.934-08:00",
      "name": "${HC}",
      "description": "Default kubernetes L7 Loadbalancing health check.",
      "checkIntervalSec": 60,
      "timeoutSec": 60,
      "unhealthyThreshold": 10,
      "healthyThreshold": 1,
      "type": "HTTP",
      "httpHealthCheck": {
        "port": 32394,
        "requestPath": "/healthz/ready",
        "proxyHeader": "NONE",
        "portSpecification": ""
      },
      "selfLink": "https://www.googleapis.com/compute/v1/projects/${PROJECT_ID}/global/healthChecks/${HC}",
      "kind": "compute#healthCheck"
      }
      

      如果您手动修改 JSON 文件,而不是使用 jq 命令,请将该文件保存为 updated_health_check.json,以使它与下一个命令中的文件名匹配。

    2. 更新健康检查:

      curl --request PATCH --header "Authorization: Bearer $(gcloud auth application-default print-access-token)" --header "Content-Type: application/json" --data @updated_health_check.json ${HC_API}

    GKE 更新健康检查需要几分钟时间。在 Google Cloud 控制台中,大约每分钟刷新一次 Kubernetes Engine > Service 和 Ingress 页面,直到 Ingress 的状态更改为“正常”。

  4. 测试负载平衡器。将浏览器指向:

    http://YOUR_DOMAIN_NAME/productpage

    其中,YOUR_DOMAIN_NAME 是您使用外部静态 IP 地址配置的域名。

    您应该会看到 Bookinfo 应用的 productpage。如果您多次刷新该页面,您应该会看到不同版本的评论,以轮询方式呈现:红色星标、黑色星标、无星标。

    您还应测试对 Bookinfo 的 https 访问权限。

启用 IAP

以下步骤介绍了如何启用 IAP。

  1. 使用 list 命令检查您是否已有品牌。每个项目只能有一个品牌。

    gcloud iap oauth-brands list

    以下是 gcloud 响应示例(如果存在品牌):

    name: projects/[PROJECT_NUMBER]/brands/[BRAND_ID]
    applicationTitle: [APPLICATION_TITLE]
    supportEmail: [SUPPORT_EMAIL]
    orgInternalOnly: true
    
  2. 如果不存在品牌,请使用 create 命令:

    gcloud iap oauth-brands create --application_title=APPLICATION_TITLE --support_email=SUPPORT_EMAIL

    调用 API 时上述字段为必填字段:

    • supportEmail:OAuth 同意屏幕上显示的支持电子邮件。该电子邮件地址可以是用户的地址,也可以是 Google 群组别名。虽然服务帐号也有一个电子邮件地址,但它们不是实际有效的电子邮件地址,在创建品牌时不能使用。但是,服务帐号可以是 Google 群组的所有者。创建新的 Google 群组或配置现有群组,然后将所需的服务帐号设置为该群组的所有者。

    • applicationTitle:OAuth 同意屏幕上显示的应用名称。

    响应包含以下字段:

    name: projects/[PROJECT_NUMBER]/brands/[BRAND_ID]
    applicationTitle: [APPLICATION_TITLE]
    supportEmail: [SUPPORT_EMAIL]
    orgInternalOnly: true
    

创建 IAP OAuth 客户端

  1. 使用 create 命令可以创建客户端。使用上一步中的品牌 name

    gcloud iap oauth-clients create projects/PROJECT_NUMBER/brands/BRAND-ID --display_name=NAME

    响应包含以下字段:

    name: projects/[PROJECT_NUMBER]/brands/[BRAND_NAME]/identityAwareProxyClients/[CLIENT_ID]
    secret: [CLIENT_SECRET]
    displayName: [NAME]
    

为您的服务启用 IAP

使用以下命令可以为您的服务启用 IAP。将 CLIENT_IDCLIENT_SECRET 分别替换为您之前创建的客户端中的 OAuth 客户端 ID 和客户端密钥。

gcloud beta iap web enable \
    --oauth2-client-id=CLIENT_ID \
    --oauth2-client-secret=CLIENT_SECRET \
    --resource-type=backend-services \
    --service=${BACKEND_SERVICE}

配置 IAP 访问权限列表

向 IAP 的访问权限政策添加用户:

gcloud beta iap web add-iam-policy-binding \
    --member=user:EMAIL_ADDRESS \
    --role=roles/iap.httpsResourceAccessor \
    --resource-type=backend-services \
    --service=$BACKEND_SERVICE

其中 EMAIL_ADDRESS 是用户的完整电子邮件地址,例如 alice@example.com

在服务网格上启用 RCToken 支持

默认情况下,IAP 会生成一个 JSON Web 令牌 (JWT),其作用范围仅限于 OAuth 客户端。对于 Anthos Service Mesh,您可以配置 IAP 以生成 RequestContextToken (RCToken),这是一种 JWT,但可配置受众群体。通过 RCToken,您可以将 JWT 的受众群体配置为任意字符串,该字符串可在 Anthos Service Mesh 政策中使用以实现精细授权。

如需配置 RCToken,请执行以下操作:

  1. 为您的项目编号创建环境变量。这是在创建项目时自动生成并分配给项目的编号。(这与项目 ID 不同。)

    export PROJECT_NUMBER=YOUR_PROJECT_NUMBER
  2. 为 RCToken 受众群体创建环境变量。这可以是您所需的任何字符串。

    export RCTOKEN_AUD="your-rctoken-aud"
    
  3. 提取现有 IAP 设置

    gcloud beta iap settings get --format json \
    --project=${PROJECT_NUMBER} --resource-type=compute \
    --service=${BACKEND_SERVICE} > iapSettings.json
    
  4. 使用 RCToken 受众群体更新 IapSettings

    cat iapSettings.json | jq --arg RCTOKEN_AUD_STR $RCTOKEN_AUD \
    '. + {applicationSettings: {csmSettings: {rctokenAud: $RCTOKEN_AUD_STR}}}' \
    > updatedIapSettings.json
    
    gcloud beta iap settings set updatedIapSettings.json --format json \
    --project=${PROJECT_NUMBER} --resource-type=compute --service=${BACKEND_SERVICE}
    
  5. 在 Istio 入站流量网关上启用 RCToken 身份验证。

    cat <<EOF | kubectl apply -f -
    apiVersion: "authentication.istio.io/v1alpha1"
    kind: "Policy"
    metadata:
      name: "ingressgateway"
      namespace: istio-system
    spec:
      targets:
      - name: "istio-ingressgateway"
      origins:
      - jwt:
          issuer: "https://cloud.google.com/iap"
          jwksUri: "https://www.gstatic.com/iap/verify/public_key-jwk"
          audiences:
          - "$RCTOKEN_AUD"
          jwt_headers:
          - "ingress-authorization"
          trigger_rules:
          - excluded_paths:
            - exact: /healthz/ready
      principalBinding: USE_ORIGIN
    EOF
  6. 确保向 Bookinfo productpage 发出的请求仍成功:

    http://DOMAIN_NAME/productpage

如需测试政策,请执行以下操作:

  1. 创建 IapSettings 请求对象,但将 rctokenAud 设置为不同的字符串:

    echo $(cat <<EOF
    {
       "name": "projects/${PROJECT_NUMBER}/iap_web/compute/services/${BACKEND_SERVICE}",
       "applicationSettings": {
         "csmSettings": {
           "rctokenAud": "some-other-arbitrary-string"
         }
       }
     }
    EOF
    ) > request.txt
  2. 调用 IapSettings API 来设置 RCtoken 受众群体。

    curl --request PATCH --header "Authorization: Bearer $(gcloud beta auth application-default print-access-token)" ${IAP_SETTINGS_API}
  3. 向 Bookinfo productpage 发出请求,请求应会失败:

    http://DOMAIN_NAME/productpage

启用 Pod 安全政策

通过启用 pod 安全政策,您可以确保遭到入侵的命名空间(istio-system 除外)不会影响共用相同节点的其他命名空间的安全性。可与 Mesh CA 一起使用的 PodSecurityPolicy 资源文件随 Anthos Service Mesh 一起提供。您可以根据需要修改这些文件。在以下示例中,您首先应用 pod 安全政策,然后为 GKE 集群启用 pod 安全政策

  1. 针对集群中的所有服务帐号应用默认 Pod 安全政策。

    kubectl apply -f "samples/security/psp/all-pods-psp.yaml"
    
  2. 应用 pod 安全政策来保护 Secret Discovery Service (SDS)

    kubectl apply -f "samples/security/psp/citadel-agent-psp.yaml"
    

    这可为 Citadel 代理(也称为节点代理)提供在主机虚拟机上创建 UDS 路径 /var/run/sds 的权限。

  3. 运行以下命令以启用 pod 安全政策:

    gcloud beta container clusters update ${CLUSTER_NAME} \
        --enable-pod-security-policy
    

    启用 pod 安全政策可能需要几分钟时间。在此过程中,现有工作负载将无法连接到 Kubernetes 主实例。等待 Kubernetes 主实例再次启动。您可以在 Google Cloud Console 的 Kubernetes 集群页面上查看集群状态。

    如需了解详情,请参阅使用 pod 安全政策

清理

完成本教程后,移除以下资源以防止您的帐号产生不必要的费用:

  1. 删除代管式证书:

    kubectl delete managedcertificates example-certificate
  2. 删除 Ingress 以释放负载均衡资源:

    kubectl -n istio-system delete ingress example-ingress

  3. 删除静态 IP 地址:

    gcloud compute addresses delete example-static-ip --global

    如果您这样做,请务必从您的域名注册商中删除 IP 地址。

  4. 删除集群,以删除组成集群的资源,例如计算实例、磁盘和网络资源:

    gcloud container clusters delete ${CLUSTER_NAME}