将 Compute Engine 虚拟机添加到 Anthos Service Mesh

本页面介绍如何将 Compute Engine 虚拟机 (VM) 添加到 Google Kubernetes Engine (GKE) 上的 Anthos Service Mesh。本页面介绍如何安装 Anthos Service Mesh 1.10.6,以及为添加虚拟机准备集群的选项。

  • 如果您已安装 Anthos Service Mesh 1.9 or a 1.10 patch release,本页面显示了如何升级到 Anthos Service Mesh 1.10.6,并使用添加虚拟机所需的选项。

  • 如果您有 Anthos Service Mesh 1.9,并且不希望升级,请参阅Anthos Service Mesh 1.9 指南,了解如何将虚拟机添加到 Anthos Service Mesh 1.9。

  • 如果您使用的是早期版本的 Anthos Service Mesh,则必须先将 Anthos Service Mesh 升级到 1.9 或更高版本

本页面提供了用于安装集群内控制层面的命令行。

简介

借助 Anthos Service Mesh,您可以管理、观察和保护在代管式实例组 (MIG) 上运行的服务,以及在网格中的 Google Kubernetes Engine (GKE) 集群上运行的服务。这样您就可以对网格中的 Compute Engine 实例执行以下操作:

  • 管理流量。
  • 强制执行 mTLS。
  • 对服务流量应用访问权限控制。
  • 安全地访问 Google Cloud 服务。
  • 收集指标、日志记录和跟踪记录数据。
  • 使用 Google Cloud Console 监控服务。

这使不适合或尚未准备好进行容器化的旧版应用可以利用 Anthos Service Mesh 功能,并将这些工作负载与其余服务集成在一起。

运作方式

ASM 提供了两个相关的自定义资源定义 (CRD) 来代表虚拟机工作负载:

  • WorkloadGroup 代表共享共同属性的虚拟机工作负载的逻辑组。这类似于 Kubernetes 中的 Deployment。
  • WorkloadEntry 表示虚拟机工作负载的单个实例。 这类似于 Kubernetes 中的 Pod。
  • Service 可以选择 WorkloadGroup,并按照与 Pod 类似的方式使 ASM 将流量路由到虚拟机实例。这可让虚拟机像网格中的任何其他工作负载一样工作。

您可以为每个 Compute Engine 实例组创建一个 Compute Engine 实例模板,该模板会为该实例组中的每个 Compute Engine 实例指定服务代理。在安装期间,该代理会引导服务代理,设置流量拦截并监控服务代理在 Compute Engine 实例的生命周期内的运行状况。该代理与 Anthos Service Mesh 控制层面连接,然后自动将每个 Compute Engine 实例注册为相应 WorkloadGroupWorkloadEntry。这让 Anthos Service Mesh 可以将每个实例视为服务端点,就像集群中的 Kubernetes pod 一样。您还可以为虚拟机工作负载创建 Kubernetes 服务,就像为 Kubernetes pod 创建 Kubernetes 服务一样。

如需横向扩容 Compute Engine 实例上的工作负载数量,从 MIG 大小下限 (0) 开始,请参阅自动扩缩实例组

服务代理依赖于虚拟机管理器,以确保代理已安装在 MIG 中的每个虚拟机中。如需详细了解实例组和虚拟机管理,请参阅代管式实例组 (MIG)虚拟机管理器

支持的 Linux 发行版

操作系统版本 支持
Debian 10
Debian 9
Centos 8
Centos 7

如需详细了解操作系统发行版,请参阅 Debian 支持CentOS 支持

限制

  • 网格控制层面必须为 Anthos Service Mesh 1.9 或更高版本。
  • 仅支持使用 Compute Engine 实例模板创建的 Compute Engine 代管式实例组。
  • 集群和虚拟机必须位于同一网络中、同一项目中,并且使用单个网络接口。
  • 您可以在不订阅 GKE Enterprise 的情况下使用此功能,但 Google Cloud 控制台中的某些界面元素和功能仅限 GKE Enterprise 订阅者使用。如需了解订阅者和非订阅者可以使用的内容,请参阅 GKE Enterprise 和 Anthos Service Mesh 界面差异

前提条件

须知事项:

查看 Cloud 项目、GKE Enterprise 许可和前提条件中所述的一般要求。

集群要求

在继续操作之前,请确保您的集群符合 GKE 要求。此外,Anthos Service Mesh 虚拟机支持要求:

  • 安装 Anthos Service Mesh 时,您可以将 Mesh CA 指定为证书授权机构 (CA)。
  • 您不能替换 Stackdriver 以进行遥测。安装 Anthos Service Mesh 时,系统会默认配置 Stackdriver。
  • 您的集群已注册到机群。但是,如果集群未注册,则虚拟机安装过程会在指定的项目中注册集群。

使用入门

按照使用入门中的步骤执行以下操作:

如果您尚未安装 Anthos Service Mesh,请继续阅读下一部分。如果您已安装 Anthos Service Mesh,请按照现有安装中的步骤操作。

新安装

通过准备 Anthos Service Mesh 1.10 控制层面,为虚拟机设置 Anthos Service Mesh 集群。

以下命令展示了如何使用 --option vm 安装 Anthos Service Mesh 集群控制层面,以准备用于添加虚拟机的控制层面。

./asmcli install \
  --project_id PROJECT_ID \
  --cluster_name CLUSTER_NAME \
  --cluster_location CLUSTER_LOCATION \
  --output_dir DIR_PATH \
  --enable_all \
  --ca mesh_ca \
  --option vm
  • --project_id--cluster_name--cluster_location 指定集群所在的项目 ID、集群名称以及集群区域或地区。
  • --output_dir添加此选项可指定 asmcli 在其中下载 anthos-service-mesh 软件包并提取安装文件的目录,其中包含 istioctl、示例和清单。否则,asmcli 会将文件下载到 tmp 目录。您可以指定相对路径或完整路径。环境变量 $PWD 不适用于此处
  • --enable_all 允许脚本执行以下操作:
    • 授予所需的 IAM 权限
    • 启用所需的 Google API。
    • 在集群上设置用于标识网格的标签。
    • 如果尚未注册集群,请注册集群

  • --ca mesh_ca使用 Mesh CA 作为证书授权机构。asmcli将 Mesh CA 配置为使用机群工作负载身份
  • --option vm准备集群以在服务网格中添加虚拟机。

如果您在集群上运行现有工作负载,请重新部署工作负载,然后返回此页面以添加虚拟机

现有安装

如果您的集群上已安装 Anthos Service Mesh,请执行以下步骤:

  1. 向集群注册集群(如果您尚未注册)。

  2. 运行以下命令以准备并验证您的 Anthos Service Mesh 安装是否已准备好用于虚拟机工作负载。

    ./asmcli experimental vm prepare-cluster \
        --project_id PROJECT_ID \
        --cluster_name CLUSTER_NAME \
        --cluster_location CLUSTER_LOCATION
    

    成功后,该命令会输出以下内容:

    The cluster is ready for adding VM workloads.
    Please follow the Anthos Service Mesh for Compute Engine VM user guide to add
    Compute Engine VMs to your mesh.
    

该命令将执行以下操作:

  1. 启用虚拟机自动注册:通过将 PILOT_ENABLE_WORKLOAD_ENTRY_AUTOREGISTRATIONPILOT_ENABLE_CROSS_CLUSTER_WORKLOAD_ENTRY 变量设置为 true 来完成此操作。启用此功能后,系统将向 WorkloadGroup 注册新的虚拟机实例,并创建新的 WorkloadEntry CR 以将流量路由到该虚拟机。使用 asmcli 安装的所有 Anthos Service Mesh 1.9 及更高版本控制层面都将默认启用虚拟机自动注册。

  2. 安装扩展网关:此网关名为 eastwest 网关,并在 Anthos Service Mesh 配置软件包中定义。此操作还会将控制层面公开给虚拟机。

  3. 安装 IdentityProvider CRD 并注册 Google IdentityProvider CR,以使虚拟机能够对 Anthos Service Mesh 控制层面进行身份验证并安全地与其余服务网格进行通信。

  4. 如果在 asmcli 脚本中使用 --enable_all--enable_registration,请将将集群注册到队列并启用工作负载身份

  5. 在队列中启用 Service Mesh 功能。此功能将管理必要政策,以允许虚拟机安全地与网格进行通信。

安装入站流量网关

Anthos Service Mesh 允许您将网关部署和管理为服务网格的一部分。网关描述了在网格边缘运行的负载均衡器,用于接收传入或传出 HTTP/TCP 连接。网关是 Envoy 代理,可让您精确控制进出网格的流量。

  1. 为入站流量网关创建命名空间(如果您还没有命名空间)。网关是用户工作负载,最佳做法是不应部署在控制平面命名空间中。将 GATEWAY_NAMESPACE 替换为您的命名空间名称。

    kubectl create namespace GATEWAY_NAMESPACE
    
  2. 通过在网关命名空间中应用修订版本标签,在网关上启用自动注入功能。边车注入器网络钩子会使用修订版本标签将注入的代理与特定控制平面修订版本相关联。您使用的修订版本标签取决于您部署的是代管式 Anthos Service Mesh 还是集群内控制平面

    1. 使用以下命令查找 istiod 的修订版本标签:

      kubectl -n istio-system get pods -l app=istiod --show-labels
      

      输出类似于以下内容:

      NAME                                READY   STATUS    RESTARTS   AGE   LABELS
      istiod-asm-1106-2-5788d57586-bljj4   1/1     Running   0          23h   app=istiod,istio.io/rev=asm-1106-2,istio=istiod,pod-template-hash=5788d57586
      istiod-asm-1106-2-5788d57586-vsklm   1/1     Running   1          23h   app=istiod,istio.io/rev=asm-1106-2,istio=istiod,pod-template-hash=5788d57586

      在输出中的 LABELS 列下,记下 istiod 修订版本标签的值,该值位于前缀 istio.io/rev= 之后。在此示例中,该值为 asm-1106-2

    2. 将修订版本标签应用于命名空间。在以下命令中,REVISION 是您在上一步中记下的 istiod 修订版本标签的值。

      kubectl label namespace GATEWAY_NAMESPACE istio-injection- istio.io/rev=REVISION --overwrite
      

    您可以忽略输出中的 "istio-injection not found" 消息。这意味着命名空间之前没有 istio-injection 标签,对于 Anthos Service Mesh 的新安装或新部署,这是预期现象。如果命名空间同时具有 istio-injection 和修订版本标签,自动注入将失败,因此 Anthos Service Mesh 文档中的所有 kubectl label 命令都包含移除 istio-injection 标签。

  3. 切换到您在 --output_dir 中指定的目录。

  4. 您可以按原样部署位于 samples/gateways/istio-ingressgateway/ 目录中的示例入站流量网关配置,也可以根据需要对其进行修改。

    kubectl apply -n GATEWAY_NAMESPACE -f samples/gateways/istio-ingressgateway
    

详细了解网关的最佳做法

添加虚拟机

在本部分中,您将根据使用 gcloud 创建的实例模板将 Compute Engine 实例添加到网格中。gcloud 仅会为服务代理代理生成必要的配置。要在实例模板中添加更多配置,请参阅 gcloud 参考指南了解详情。

如需将虚拟机添加到网格,请按以下步骤操作:

  1. 设置要在后续步骤中使用的以下环境变量。为每个虚拟机工作负载设置以下变量:

    • WORKLOAD_NAME 是虚拟机所属工作负载的名称,必须是符合标准的 DNS-1123 子网域(包含小写字母数字字符)。
    • WORKLOAD_VERSION 是虚拟机所属的工作负载的版本。可选。
    • WORKLOAD_SERVICE_ACCOUNT 是虚拟机运行所用的服务 GCP 服务账号。
    • WORKLOAD_NAMESPACE 是工作负载的命名空间。
    • ASM_INSTANCE_TEMPLATE 是要创建的实例模板的名称。Compute Engine 实例模板名称不允许使用下划线。
  2. 如果虚拟机工作负载尚不存在,请为其提供命名空间:

    kubectl create ns WORKLOAD_NAMESPACE
    
  3. 使用控制层面修订版本标记命名空间。

    如需查看如何查找显示为 REVISION 的控制层面修订版本的示例,请参阅部署和重新部署工作负载

    kubectl label ns WORKLOAD_NAMESPACE istio-injection- istio.io/rev=REVISION --overwrite
    
  4. 为要注册的虚拟机创建 WorkloadGroup

    kubectl apply -f - << EOF
    apiVersion: networking.istio.io/v1alpha3
    kind: WorkloadGroup
    metadata:
      name: WORKLOAD_NAME
      namespace: WORKLOAD_NAMESPACE
    spec:
      metadata:
        labels:
          app.kubernetes.io/name: WORKLOAD_NAME
          app.kubernetes.io/version: WORKLOAD_VERSION
        annotations:
          security.cloud.google.com/IdentityProvider: google
      template:
        serviceAccount: WORKLOAD_SERVICE_ACCOUNT
    EOF
    
    字段 说明
    name 虚拟机所属的工作负载的名称。
    namespace 工作负载所属的命名空间。
    app.kubernetes.io/name 推荐用于 Kubernetes 应用的标签。您可以为虚拟机工作负载使用自己的标签。
    app.kubernetes.io/version 推荐用于 Kubernetes 应用的标签。您可以为虚拟机工作负载使用自己的标签。
    serviceAccount 虚拟机和项目使用的服务账号身份,该身份将用作 SPIFFE 格式的工作负载身份的一部分。如需了解详情,请参阅服务账号
    security.cloud.google.com/IdentityProvider 虚拟机将使用的身份提供商,应已在集群中注册。对于 Compute Engine 虚拟机,该身份提供商应设置为 googleIdentityProvider 会告知控制层面如何对虚拟机的凭据进行身份验证以及在哪里提取虚拟机的服务账号。
  5. 使用带有 --mesh 标志的 gcloud beta compute instance-templates create 命令为您的 Anthos Service Mesh Compute Engine 实例创建实例模板。

    gcloud 会验证集群前提条件,为 Anthos Service Mesh 添加虚拟机标签,为服务代理生成自定义元数据配置并创建新的实例模板。

    如果您的实例模板包含需要网络连接的启动脚本,则该脚本应能够灵活应对暂时性的网络连接问题。如需了解如何针对临时网络中断增加弹性的示例,请参阅演示应用

    如需详细了解如何创建实例模板,请参阅创建实例模板

    gcloud beta compute instance-templates create \
    ASM_INSTANCE_TEMPLATE \
    --mesh gke-cluster=CLUSTER_LOCATION/CLUSTER_NAME,workload=WORKLOAD_NAMESPACE/WORKLOAD_NAME \
    --project PROJECT_ID
    
  6. 为您创建的每个 MIG 设置以下环境变量:

    • INSTANCE_GROUP_NAME 是要创建的 Compute Engine 实例组的名称。
    • ASM_INSTANCE_TEMPLATE 是要创建的实例模板的名称。Compute Engine 实例模板名称不允许使用下划线。
    • INSTANCE_GROUP_ZONE 是要创建的 Compute Engine 实例组的可用区。
    • PROJECT_ID 是在其中创建集群的项目的 ID。
    • SIZE 是要创建的实例组的大小。创建实例组后,该名称可以更改。
    • WORKLOAD_NAME 是虚拟机所属的工作负载的名称。
    • WORKLOAD_NAMESPACE 是工作负载的命名空间。
  7. 使用上一步中创建的变量,为虚拟机工作负载创建代管式实例组:

    gcloud compute instance-groups managed create INSTANCE_GROUP_NAME \
    --template ASM_INSTANCE_TEMPLATE \
    --zone=INSTANCE_GROUP_ZONE \
    --project=PROJECT_ID \
    --size=SIZE
    

    如需横向扩容 Compute Engine 实例上的工作负载数量,从可用区级或区域级 MIG 大小 (0) 开始,请参阅自动扩缩实例组。如需详细了解如何创建组,请参阅 gcloud compute instance-groups managed create

    当您的实例启动时,它会自动使用集群中的 Anthos Service Mesh 控制层面进行身份验证,并且控制层面会将每个虚拟机注册为 WorkloadEntry

  8. 当 MIG 中的虚拟机实例完成启动后,您可以使用以下命令查看工作负载命名空间中的注册虚拟机:

    kubectl get workloadentry -n WORKLOAD_NAMESPACE
    
  9. 添加 Kubernetes Service 以公开上面添加的虚拟机工作负载。请务必让服务为上面注册的虚拟机 WorkloadGroup 选择相应的标签,以便正确路由流量。

    以下示例会在命名空间 WORKLOAD_NAMESPACE 中创建名为 WORKLOAD_NAME 的 Kubernetes 服务,此服务会在 HTTP 端口 80 下公开具有 app.kubernetes.io/name: WORKLOAD_NAME 标签的虚拟机工作负载。

    kubectl apply -f - << EOF
    apiVersion: v1
    kind: Service
    metadata:
      name: WORKLOAD_NAME
      namespace: WORKLOAD_NAMESPACE
      labels:
        asm_resource_type: VM
    spec:
      ports:
      - port: 80
        name: http
      selector:
        app.kubernetes.io/name: WORKLOAD_NAME
    EOF
    

    如需详细了解如何创建 Kubernetes 服务,请参阅 https://kubernetes.io/docs/concepts/services-networking/service/#defining-a-service

  10. 如需在虚拟机上使用示例应用,请参阅部署示例应用

在集群内控制层面升级后重新部署工作负载

如果您在上一部分中升级了 Anthos Service Mesh,并且您的工作负载正在集群上运行,请将其切换到新的控制层面

对于虚拟机工作负载,请创建新的实例模板并对 MIG 中的虚拟机执行滚动更新:

  1. 使用以下命令查找 istiod 的修订版本标签:

    kubectl -n istio-system get pods -l app=istiod --show-labels
    

    此命令的输出类似如下所示。请注意,迁移的输出与升级的输出略有不同。以下示例输出来自迁移。

    NAME                                         READY   STATUS    RESTARTS   AGE   LABELS
    istiod-7744bc8dd7-qhlss                      1/1     Running   0          49m   app=istiod,istio.io/rev=default,istio=pilot,pod-template-hash=7744bc8dd7
    istiod-asm-1106-2-85d86774f7-flrt2   1/1     Running   0          26m   app=istiod,istio.io/rev=asm-1106-2,istio=istiod,pod-template-hash=85d86774f7
    istiod-asm-1106-2-85d86774f7-tcwtn   1/1     Running   0          26m   app=istiod,istio.io/rev=asm-1106-2,istio=istiod,pod-template-hash=85d86774f7
    1. 在输出中的 LABELS 列下,记下新版本的 istiod 修订版本标签中的值,该值位于前缀 istio.io/rev= 之后。在此示例中,该值为 asm-1106-2

    2. 另请注意旧版 istiod 的修订版本标签中的值。 将工作负载移至新版本后,您需要使用此值删除旧版本的 istiod。在示例输出中,旧版 istiod 的修订版本标签中的值为 default

  2. 将修订版本标签添加到命名空间,并移除 istio-injection 标签(如果存在)。在以下命令中,将 REVISION 更改为与 istiod 的新修订版本匹配的值。

    kubectl label namespace NAMESPACE istio.io/rev=REVISION istio-injection- --overwrite

    如果您在输出中看到 "istio-injection not found",则可以忽略它。这意味着命名空间之前没有 istio-injection 标签。如果命名空间同时具有 istio-injection 和修订版本标签,自动注入将失败,因此 Anthos Service Mesh 文档中的所有 kubectl label 命令都包含移除 istio-injection 标签。

  3. 使用 gcloud 创建新的实例模板。如果您有适用于同一工作负载的实例模板,请务必包含相同配置。

    gcloud beta compute instance-templates create NEW_ASM_INSTANCE_TEMPLATE \
    --mesh gke-cluster=CLUSTER_LOCATION/CLUSTER_NAME,workload=WORKLOAD_NAMESPACE/WORKLOAD_NAME \
    --project PROJECT_ID
    
  4. 对工作负载的现有 MIG 执行滚动更新。

    如需了解详情,请参阅开始基本滚动更新

    gcloud compute instance-groups managed rolling-action start-update INSTANCE_GROUP_NAME \
    --version=template=NEW_ASM_INSTANCE_TEMPLATE \
    --zone=INSTANCE_GROUP_ZONE
    
  5. 测试虚拟机工作负载,以确保其按预期工作。

升级虚拟机应用

如果您的应用有任何更新(包括对 WorkloadGroup 的更改和/或对源实例模板的更改),则需要新实例模板来更新虚拟机工作负载的 MIG。

应用 WorkloadGroup 更改和/或创建新的来源实例模板后,您将为 Anthos Service Mesh 创建新的实例模板,并对 MIG 中的虚拟机执行滚动更新。

  1. 使用 gcloud 创建新的实例模板。

    gcloud beta compute instance-templates create NEW_ASM_INSTANCE_TEMPLATE \
    --mesh gke-cluster=CLUSTER_LOCATION/CLUSTER_NAME,workload=WORKLOAD_NAMESPACE/WORKLOAD_NAME \
    --project PROJECT_ID
    
  2. 对工作负载的现有 MIG 执行滚动更新。 如需详细了解如何使用 MIG 滚动更新,请参阅开始基本滚动更新

    gcloud compute instance-groups managed rolling-action start-update INSTANCE_GROUP_NAME \
    --version=template=NEW_ASM_INSTANCE_TEMPLATE \
    --zone=INSTANCE_GROUP_ZONE
    
  3. 测试虚拟机工作负载,以确保其按预期工作。

部署一个示例应用

如需演示新的网格配置是否正常运行,您可以安装 Bookinfo 示例应用。此示例会在虚拟机上运行 MySQL 数据库,并且评分服务会从数据库中读取评分值。

在集群上安装 BookInfo

按照以下步骤操作可以部署 BookInfo 应用的服务,并且 Sidecar 代理会与每项服务一起注入。 BookInfo 应用将部署在 default 命名空间中。

  1. 在安装了 Anthos Service Mesh 的计算机的命令行上,转到您在下载脚本步骤中创建的 Anthos Service Mesh 安装目录的根目录。

  2. 如需启用自动 Sidecar 注入,请根据您的 Anthos Service Mesh 控制层面类型选择以下说明。

    使用以下命令查找 istiod 上的标签,其中包含要在后续步骤中使用的修订版本标签值。

    kubectl -n istio-system get pods -l app=istiod --show-labels
    

    输出类似于以下内容:

    NAME                                READY   STATUS    RESTARTS   AGE   LABELS
    istiod-asm-1106-2-5788d57586-bljj4   1/1     Running   0          23h   app=istiod,istio.io/rev=asm-1106-2,istio=istiod,pod-template-hash=5788d57586
    istiod-asm-1106-2-5788d57586-vsklm   1/1     Running   1          23h   app=istiod,istio.io/rev=asm-1106-2,istio=istiod,pod-template-hash=5788d57586
    

    在输出中的 LABELS 列下,记下 istiod 修订版本标签的值,该值位于前缀 istio.io/rev= 之后。在此示例中,该值为 asm-1106-2

  3. 将修订版本标签应用于 default 命名空间。

    在以下命令中,REVISION 是您在上一步中记下的 istiod 修订版本标签的值。

    kubectl label namespace default istio-injection- istio.io/rev=REVISION --overwrite
    

    您可以忽略输出中的 "istio-injection not found" 消息。这意味着命名空间之前没有 istio-injection 标签,对于 Anthos Service Mesh 的新安装或新部署,这是预期现象。如果命名空间同时具有 istio-injection 和修订版本标签,自动注入将失败,因此 Anthos Service Mesh 文档中的所有 kubectl label 命令都包含移除 istio-injection 标签。

  4. 使用 kubectl 将应用部署到默认命名空间:

    kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml
    
  5. 通过运行以下命令确认是否已正确部署应用:

    kubectl get services
    

    预期输出:

    NAME                       CLUSTER-IP   EXTERNAL-IP         PORT(S)              AGE
    details                    10.0.0.31    <none>        9080/TCP             6m
    kubernetes                 10.0.0.1     <none>        443/TCP              7d
    productpage                10.0.0.120   <none>        9080/TCP             6m
    ratings                    10.0.0.15    <none>        9080/TCP             6m
    reviews                    10.0.0.170   <none>        9080/TCP             6m

    kubectl get pod
    

    预期输出:

    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. 最后,为应用定义入站流量网关路由:

    kubectl apply -f samples/bookinfo/networking/bookinfo-gateway.yaml
    

    预期输出:

    gateway.networking.istio.io/bookinfo-gateway created
    virtualservice.networking.istio.io/bookinfo created
  7. 确认产品页面是否可访问。 在以下命令中,GATEWAY_NAMESPACE 是 Istio 网关的命名空间。

    export INGRESS_HOST=$(kubectl -n GATEWAY_NAMESPACE get service istio-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
    export INGRESS_PORT=$(kubectl -n GATEWAY_NAMESPACE get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="http2")].port}')
    export GATEWAY_URL="${INGRESS_HOST}:${INGRESS_PORT}"
    curl -s "http://${GATEWAY_URL}/productpage" | grep -o "<title>.*</title>"
    

    预期输出:

    <title>Simple Bookstore App</title>
    

创建 Compute Engine 实例并安装 MySQL

在此步骤中,您将为虚拟机上运行的 MySQL 实例创建 Compute Engine 实例模板。如需了解详细步骤,请参阅包含虚拟机的 Bookinfo

  1. 创建启动脚本以安装 MySQL 并在启动时添加评分数据库。请注意,如果您使用的是 CentOS,则 mariadb-server 需要长达 10 分钟才能准备就绪。

    Debian

    cat << "EOF" > init-mysql
    #!/bin/bash
    
    # Wait until Envoy is ready before installing mysql
    while true; do
      rt=$(curl -s 127.0.0.1:15000/ready)
      if [[ $? -eq 0 ]] && [[ "${rt}" -eq "LIVE" ]]; then
        echo "envoy is ready"
        break
      fi
      sleep 1
    done
    
    # Wait until DNS is ready before installing mysql
    while true; do
      curl -I productpage.default.svc:9080
      if [[ $? -eq 0 ]]; then
        echo "dns is ready"
        break
      fi
      sleep 1
    done
    
    sudo apt-get update && sudo apt-get install -y mariadb-server
    
    sudo sed -i '/bind-address/c\bind-address  = 0.0.0.0' /etc/mysql/mariadb.conf.d/50-server.cnf
    
    cat <<EOD | sudo mysql
    # Grant access to root
    GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' IDENTIFIED BY 'password' WITH GRANT OPTION;
    
    # Grant root access to other IPs
    CREATE USER 'root'@'%' IDENTIFIED BY 'password';
    GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' WITH GRANT OPTION;
    FLUSH PRIVILEGES;
    quit
    EOD
    
    sudo systemctl restart mysql
    
    curl -LO https://raw.githubusercontent.com/istio/istio/release-1.10/samples/bookinfo/src/mysql/mysqldb-init.sql
    
    mysql -u root -ppassword < mysqldb-init.sql
    EOF
    

    CentOS

    cat << "EOF" > init-mysql
    #!/bin/bash
    
    # Wait until Envoy is ready before installing mysql
    while true; do
      rt=$(curl -s 127.0.0.1:15000/ready)
      if [[ $? -eq 0 ]] && [[ "${rt}" -eq "LIVE" ]]; then
        echo "envoy is ready"
        break
      fi
      sleep 1
    done
    
    # Wait until DNS is ready before installing mysql
    while true; do
      curl -I productpage.default.svc:9080
      if [[ $? -eq 0 ]]; then
        echo "dns is ready"
        break
      fi
      sleep 1
    done
    
    sudo yum update -y && sudo yum install -y mariadb-server
    
    # Wait until mysql is ready
    while true; do
      rt=$(which mysql)
      if [[ ! -z "${rt}" ]]; then
        echo "mysql is ready"
        break
      fi
      sleep 1
    done
    
    sudo sed -i '/bind-address/c\bind-address  = 0.0.0.0' /etc/my.cnf.d/mariadb-server.cnf
    
    sudo systemctl restart mariadb
    
    cat > grantaccess.sql << EOD
    
    GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' IDENTIFIED BY 'password' WITH GRANT OPTION;
    
    CREATE USER 'root'@'%' IDENTIFIED BY 'password';
    GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' WITH GRANT OPTION;
    FLUSH PRIVILEGES;
    EOD
    
    until sudo mysql < grantaccess.sql; do
       sleep 1
    done
    
    sudo systemctl restart mariadb
    
    curl -LO https://raw.githubusercontent.com/istio/istio/release-1.10/samples/bookinfo/src/mysql/mysqldb-init.sql
    
    mysql -u root -ppassword < mysqldb-init.sql
    EOF
    
  2. 为 MySQL 工作负载创建 WorkloadGroup

    kubectl apply -f - << EOF
    apiVersion: networking.istio.io/v1alpha3
    kind: WorkloadGroup
    metadata:
      name: mysql
      namespace: default
    spec:
      metadata:
        labels:
          app.kubernetes.io/name: mysql
        annotations:
          security.cloud.google.com/IdentityProvider: google
      template:
        serviceAccount: WORKLOAD_SERVICE_ACCOUNT
    EOF
    
  3. 使用 gcloud 创建新的实例模板,以便为网格准备实例,并添加上述启动脚本。

    Debian

    gcloud beta compute instance-templates create asm-mysql-instance-template \
    --mesh gke-cluster=CLUSTER_LOCATION/CLUSTER_NAME,workload=default/mysql \
    --project PROJECT_ID \
    --metadata-from-file=startup-script=init-mysql \
    --image-project=debian-cloud --image-family=debian-10 --boot-disk-size=10GB
    

    CentOS

    gcloud beta compute instance-templates create asm-mysql-instance-template \
    --mesh gke-cluster=CLUSTER_LOCATION/CLUSTER_NAME,workload=default/mysql \
    --project PROJECT_ID \
    --metadata-from-file=startup-script=init-mysql \
    --image-project=centos-cloud --image-family=centos-8 --boot-disk-size=20GB
    
  4. 使用新创建的实例模板创建 Compute Engine MIG。

    gcloud compute instance-groups managed create mysql-instance \
    --template asm-mysql-instance-template \
    --zone=us-central1-c \
    --project=PROJECT_ID \
    --size=1
    

创建服务

使用以下命令为 MySQL 服务创建 Kubernetes 服务:

kubectl apply -f - << EOF
apiVersion: v1
kind: Service
metadata:
  name: mysql
  namespace: default
  labels:
    asm_resource_type: VM
spec:
  ports:
  - name: mysql
    port: 3306
    protocol: TCP
    targetPort: 3306
  selector:
    app.kubernetes.io/name: mysql
EOF

使用 Anthos 界面信息中心

如需查看您已创建的基于虚拟机的新服务,请点击主左侧导航栏中的 Anthos > 服务网格。系统将显示一个网格中运行的服务的表。您添加的服务以及一些概要指标应显示在该表中,该服务的Type 值为 VM。如需查看来自基于虚拟机的服务的更多遥测数据,请点击服务名称,此时会显示服务级信息中心。

如需详细了解如何使用 Anthos 界面信息中心,请参阅在 Cloud 控制台中探索 Anthos Service Mesh

管理发送到虚拟机工作负载的流量

您可以更改网络规则,以控制流量进出虚拟机的方式。

控制发送到新评分服务的流量(Pod 到虚拟机)

在 BookInfo 中创建另一个评分服务,该服务将使用上面创建的 MySQL 实例作为数据源,并指定强制审核服务使用新的评分服务的路由规则。

  1. 创建一个新的评分服务以使用 MySQL 实例。

    kubectl apply -f - << EOF
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: ratings-v2-mysql-vm
      labels:
        app: ratings
        version: v2-mysql-vm
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: ratings
          version: v2-mysql-vm
      template:
        metadata:
          labels:
            app: ratings
            version: v2-mysql-vm
        spec:
          serviceAccountName: bookinfo-ratings
          containers:
          - name: ratings
            image: docker.io/istio/examples-bookinfo-ratings-v2:1.16.2
            imagePullPolicy: IfNotPresent
            env:
              - name: DB_TYPE
                value: "mysql"
              - name: MYSQL_DB_HOST
                value: mysql.default.svc.cluster.local
              - name: MYSQL_DB_PORT
                value: "3306"
              - name: MYSQL_DB_USER
                value: root
              - name: MYSQL_DB_PASSWORD
                value: password
            ports:
            - containerPort: 9080
    EOF
    
  2. 创建路由规则。

    kubectl apply -f - << EOF
    apiVersion: networking.istio.io/v1alpha3
    kind: VirtualService
    metadata:
      name: reviews
    spec:
      hosts:
      - reviews
      http:
      - route:
        - destination:
            host: reviews
            subset: v3
    ---
    apiVersion: networking.istio.io/v1alpha3
    kind: VirtualService
    metadata:
      name: ratings
    spec:
      hosts:
      - ratings
      http:
      - route:
        - destination:
            host: ratings
            subset: v2-mysql-vm
    EOF
    
  3. 为已创建的服务应用目标规则。

    kubectl apply -f - << EOF
    apiVersion: networking.istio.io/v1alpha3
    kind: DestinationRule
    metadata:
      name: reviews
    spec:
      host: reviews
      subsets:
      - name: v1
        labels:
          version: v1
      - name: v2
        labels:
          version: v2
      - name: v3
        labels:
          version: v3
    ---
    apiVersion: networking.istio.io/v1alpha3
    kind: DestinationRule
    metadata:
      name: ratings
    spec:
      host: ratings
      subsets:
      - name: v1
        labels:
          version: v1
      - name: v2
        labels:
          version: v2
      - name: v2-mysql
        labels:
          version: v2-mysql
      - name: v2-mysql-vm
        labels:
          version: v2-mysql-vm
    EOF
    

验证应用部署

如需查看 BookInfo 应用是否正常运行,您需要将流量发送到入站流量网关。

  • 如果您在 GKE 上安装了 Anthos Service Mesh,请获取您在上述步骤中创建的入站流量网关的外部 IP 地址:

    kubectl get svc istio-ingressgateway -n GATEWAY_NAMESPACE
    

    输出:

    NAME                   TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)                                      AGE
    istio-ingressgateway   LoadBalancer   10.19.247.233   35.239.7.64   80:31380/TCP,443:31390/TCP,31400:31400/TCP   27m

    在此示例中,入站流量服务的 IP 地址为 35.239.7.64

试用应用

  1. 使用 curl 来检查 BookInfo 应用是否在运行:

    curl -I http://EXTERNAL_IP/productpage
    

    如果响应显示 200,则表示该应用与 Anthos Service Mesh 正常配合使用。

  2. 如需查看 BookInfo 网页,请在浏览器中输入以下地址:

    http://EXTERNAL_IP/productpage
    
  3. 在 BookInfo 应用首页上验证,它显示了来自 Reviewer1 的 5 星和来自 Reviewer2 的 4 星评分。

对虚拟机工作负载强制执行安全

对虚拟机工作负载强制执行安全策略与对 Kubernetes 工作负载强制执行安全策略相同。如需了解详情,请参阅 Istio 安全

完成上述步骤后,Compute Engine 虚拟机将拥有 Google 颁发的工作负载证书。在该证书中,SubjectAlternativeName 值会以 spiffe://<workload_identity_pool>/ns/WORKLOAD_NAMESPACE/sa/WORKLOAD_SERVICE_ACCOUNT 的形式显示虚拟机的 Anthos 工作负载身份

如需了解详情,请参阅工作负载身份池

为网格启用 mTLS 严格模式

应用以下 YAML 以在网格范围内强制执行严格 mTLS。

kubectl apply -f - << EOF
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
  name: default
  namespace: istio-system
spec:
  mtls:
    mode: STRICT
EOF

针对服务到服务流量的授权

使用 AuthorizationPolicy 可控制对 Compute Engine 虚拟机上应用与其他网格工作负载(例如 GKE 集群)上的应用的访问权限。

示例:拒绝 Kubernetes 工作负载访问 Compute Engine 虚拟机

以下授权政策会拒绝 Kubernetes 工作负载 ratings 访问为 ratings MySQL 服务器提供服务的 Compute Engine 虚拟机工作负载。

  kubectl apply -f - << EOF
  apiVersion: security.istio.io/v1beta1
  kind: AuthorizationPolicy
  metadata:
    name: mysql-deny
    namespace: default
  spec:
    selector:
      matchLabels:
        app.kubernetes.io/name: mysql
    action: DENY
    rules:
    - from:
      - source:
          principals: ["cluster.local/ns/default/sa/bookinfo-ratings"]
  EOF

应用 AuthorizationPolicy 示例后,您应该会在产品页面上的书评部分中看到 Ratings service is currently unavailable 错误消息。

安装 Cloud Monitoring 代理

您可以安装 Cloud Monitoring 代理,以便收集和监控虚拟机实例中的系统和应用指标。这让您能够监控关键指标,例如该代理上的 CPU 和内存利用率。

如需了解详情,请参阅 Cloud Monitoring 代理文档

问题排查

如需了解问题排查提示,请参阅排查虚拟机支持问题