将 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,则必须添加防火墙规则来打开端口 15017,以使用自动 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

  1. 使用 Google Cloud 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 集群

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

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

    • 如需获取可用 GCP 区域的列表,请执行以下操作:

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

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

    • 设置集群名称:

      export CLUSTER_NAME=YOUR_CLUSTER_NAME

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

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

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

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

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

    gcloud beta container clusters create ${CLUSTER_NAME} \
        --project=${PROJECT_ID} \
        --zone=${CLUSTER_LOCATION} \
        --machine-type=n1-standard-4 \
        --num-nodes=4 \
        --workload-pool=${WORKLOAD_POOL} \
        --enable-stackdriver-kubernetes \
        --subnetwork=default \
        --labels mesh_id=${MESH_ID} \
        --addons=HttpLoadBalancing \
        --release-channel=regular
    

    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 信息中心显示指标必不可少。

    • HttpLoadBalancing 插件为该集群启用 HTTP (L7) 负载平衡控制器。

    • release-channel regular:在 regular 发布版本中注册集群,虽然您也可以选择 stable(如果您需要更高的稳定性)或 rapid(如果您想试用新的(不支持)GKE 功能)。

设置凭据和权限

  1. 初始化您的项目,以便准备好安装。除此之外,此命令还将创建一个服务帐号,让 Istio 组件(例如 Sidecar 代理)可安全地访问您项目的数据和资源:
    curl --request POST \
      --header "Authorization: Bearer $(gcloud auth print-access-token)" \
      --data '' \
      https://meshconfig.googleapis.com/v1alpha1/projects/${PROJECT_ID}:initialize

    该命令会以空花括号作为响应:{}

    如果您日后在此集群上安装新版本的 Anthos Service Mesh,则无需重新运行命令,但再次运行该命令不会影响安装。

  2. 获取用于与集群交互的身份验证凭据
    gcloud container clusters get-credentials ${CLUSTER_NAME}
  3. 向当前用户授予集群管理员权限。您需要这些权限,以便为 Anthos Service Mesh 创建必要的基于角色的访问权限控制 (RBAC) 规则:
    kubectl create clusterrolebinding cluster-admin-binding \
      --clusterrole=cluster-admin \
      --user="$(gcloud config get-value core/account)"

    如果看到 "cluster-admin-binding" already exists 错误,您可以放心地忽略该错误并继续采用现有集群管理员绑定。

注册您的集群

您必须向项目的队列注册集群,才能获取对 Google Cloud 控制台中的统一界面的访问权限。队列提供一种统一方法来查看和管理集群及其工作负载,包括 Google Cloud 之外的集群。

创建 Google Cloud 服务帐号和密钥文件

必须提供包含服务帐号凭据的 JSON 文件才能注册集群。为遵循最小权限原则,我们建议您为注册的每个集群创建不同的服务帐号。

如需创建服务帐号和密钥文件,请执行以下操作:

  1. 为服务帐号选择一个名称并为其创建环境变量:

    export SERVICE_ACCOUNT_NAME=SERVICE_ACCOUNT_NAME
    
  2. 创建服务帐号:

    gcloud iam service-accounts create ${SERVICE_ACCOUNT_NAME}
  3. 列出项目的所有服务帐号以确认服务帐号已创建:

    gcloud iam service-accounts list
  4. 将 gkehub.connect IAM 角色绑定到服务帐号:

    gcloud projects add-iam-policy-binding ${PROJECT_ID} \
       --member="serviceAccount:${SERVICE_ACCOUNT_NAME}@${PROJECT_ID}.iam.gserviceaccount.com" \
       --role="roles/gkehub.connect"
  5. 为您要保存 JSON 文件的本地文件路径创建环境变量。我们建议您使用服务帐号名称和项目 ID 命名文件,例如:/tmp/creds/${SERVICE_ACCOUNT_NAME}-${PROJECT_ID}.json

    export SERVICE_ACCOUNT_KEY_PATH=LOCAL_KEY_PATH
  6. 下载服务帐号的私钥 JSON 文件:

    gcloud iam service-accounts keys create ${SERVICE_ACCOUNT_KEY_PATH} \
       --iam-account=${SERVICE_ACCOUNT_NAME}@${PROJECT_ID}.iam.gserviceaccount.com

注册集群

在以下命令中,将 MEMBERSHIP_NAME 替换为一个唯一表示要在 Hub 中注册的集群的名称。

gcloud container hub memberships register MEMBERSHIP_NAME \
    --gke-cluster=${CLUSTER_LOCATION}/${CLUSTER_NAME} \
    --service-account-key-file=${SERVICE_ACCOUNT_KEY_PATH}

该命令会返回如下输出:

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

此服务帐号密钥作为 Secret(名为 creds-gcp)存储在 gke-connect 命名空间中。

如需详细了解集群注册,请参阅 Connect 文档中的注册集群

下载安装文件

在继续操作之前,请验证 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.5.10-asm.2-linux.tar.gz
  2. 下载签名文件并使用 openssl 验证签名:
    curl -LO https://storage.googleapis.com/gke-release/asm/istio-1.5.10-asm.2-linux.tar.gz.1.sig
    openssl dgst -verify - -signature istio-1.5.10-asm.2-linux.tar.gz.1.sig istio-1.5.10-asm.2-linux.tar.gz <<'EOF'
    -----BEGIN PUBLIC KEY-----
    MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEWZrGCUaJJr1H8a36sG4UUoXvlXvZ
    wQfk16sxprI2gOJ2vFFggdq3ixF2h4qNBt0kI7ciDhgpwS8t+/960IsIgw==
    -----END PUBLIC KEY-----
    EOF

    预期输出为 Verified OK

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

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

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

  4. Mac OS

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

    预期输出为 Verified OK

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

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

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

  8. Windows

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

    预期输出为 Verified OK

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

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

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

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

准备资源配置文件

运行 istioctl apply command 以安装 Anthos Service Mesh 时,将在命令行上指定 -f istio-operator.yaml。此文件包含启用网格遥测和网格安全功能所需的项目和集群的相关信息。您需要下载 istio-operator.yaml 及其他资源配置文件并设置项目和集群信息。

如需准备资源配置文件,请执行以下操作:

  1. 安装 kpt(如果您尚未安装):

    gcloud components install kpt
    
  2. (可选)为 Anthos Service Mesh 软件包资源配置文件创建一个新目录。如果您计划设置多个集群,则可能需要使用集群名称作为目录名称。

  3. 切换到您要在其中下载 Anthos Service Mesh 软件包的目录。

  4. 将 Anthos Service Mesh 软件包下载到当前工作目录:

    kpt pkg get \
    https://github.com/GoogleCloudPlatform/anthos-service-mesh-packages.git/asm@release-1.5-asm .
    

  5. 设置集群名称:

      kpt cfg set asm gcloud.container.cluster ${CLUSTER_NAME}

  6. (可选)使用 kpt setter 自定义资源配置文件。默认情况下,这些 setter 使用 gcloud config 的默认值。如果设置 gcloud config 默认值,或者如果您要更改值,请运行以下 setter 方法:

    • 设置项目 ID:

      kpt cfg set asm gcloud.core.project ${PROJECT_ID}
    • 设置默认可用区或区域:

      kpt cfg set asm gcloud.compute.location ${CLUSTER_LOCATION}
  7. (可选)您可以将资源配置文件签入到您自己的源代码控制系统(例如 Cloud Source Repositories),以便您可以跟踪这些文件的更改。

安装 Anthos Service Mesh

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

PERMISSIVE mTLS

istioctl manifest apply --set profile=asm \
  -f asm/cluster/istio-operator.yaml \
  --set values.gateways.istio-ingressgateway.type=NodePort

STRICT mTLS

istioctl manifest apply --set profile=asm \
  -f asm/cluster/istio-operator.yaml \
  --set values.gateways.istio-ingressgateway.type=NodePort \
  --set values.global.mtls.enabled=true

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

验证安装

我们建议您使用 asmctl 分析工具来验证项目、集群和工作负载的基本配置。如果 asmctl 测试失败,则 asmctl 会尽可能推荐解决方案。asmctl validate 命令会运行检查以下项的基本测试:

  1. 在项目中启用 Anthos Service Mesh 所需的 API。
  2. Istio-Ingressgateway 是否已正确配置为调用 Mesh CA。
  3. Istiod 和 Istio-Ingressgateway 的整体运行状况。

如果您运行带有可选 --with-testing-workloads 标志的 asmctl validate 命令,则除了基本测试外,asmctl 还会运行检查以下项的安全测试:

  1. 双向 TLS (mTLS) 通信是否配置正确。
  2. Mesh CA 是否可以颁发证书。

为了运行安全测试,asmctl 会在测试命名空间中的集群上部署工作负载,运行 mTLS 通信测试,输出结果,并删除测试命名空间。

如需运行 asmctl,请执行以下操作:

  1. 确保已设置 gcloud application-default 凭据:

     gcloud auth application-default login
    
  2. 获取身份验证凭据以与集群进行交互(如果尚未这样做):

     gcloud container clusters get-credentials ${CLUSTER_NAME}
    
  3. 如需同时运行基本和安全测试(假设 istio-1.5.10-asm.2/bin 位于 PATH 中),请运行以下命令:

    asmctl validate --with-testing-workloads
    

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

    [asmctl version 0.3.0]
    Using Kubernetes context: example-project_us-central1-example-cluster
    To change the context, use the --context flag
    Validating enabled APIs
    OK
    Validating ingressgateway configuration
    OK
    Validating istio system
    OK
    Validating sample traffic
    Launching example services...
    Sent traffic to example service http code: 200
    verified mTLS configuration
    OK
    Validating issued certs
    OK
    

部署示例应用

启用 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
      namespace: istio-system
    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

清理

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

  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}