从 Istio 1.11 或更高版本迁移到 Anthos Service Mesh

本教程介绍了如何将应用从使用 Istio 的 Google Kubernetes Engine (GKE) 集群迁移到使用代管式 Anthos Service Mesh(Google 符合 Istio 的全代管式服务网格)的新集群。

在本教程中,您将执行以下操作:

  1. 创建新的 Google Kubernetes Engine 集群,并在该集群上安装 Istio 和 Istio 入站流量网关。此集群将用作您要从中迁移出的现有集群。
  2. Online Boutique 示例应用部署到使用 Istio 的集群上。
  3. 在同一个 Google Cloud 项目中创建另一个 Google Kubernetes Engine 集群。
  4. 在第二个集群上启用代管式 Anthos Service Mesh 并部署 Anthos Service Mesh 入站流量网关。
  5. 将 Online Boutique 部署到使用 Anthos Service Mesh 的集群上,以便从使用 Istio 的集群复制部署。
  6. 在使用 Istio 的集群上使用 Istio 的流量分配功能,将 50% 的用户流量从使用 Istio 的集群迁移到使用 Anthos Service Mesh 的集群。
  7. 将使用 Istio 的集群的域名系统 (DNS) 条目指向使用 Anthos Service Mesh 的集群,完成从 Istio 到 Anthos Service Mesh 的迁移。

用户流量在使用 Istio 的集群和使用 Anthos Service Mesh 的集群之间按 50-50 的比例分配。每个集群都包含各自的 Online Boutique 部署。

Canary 部署

“Canary 部署”是软件开发中使用的一种技术,用于在向所有用户发布新版本之前测试某些软件的新版本。它涉及逐步增加发送到新版本的流量的百分比。在本教程中,您将设置一个使用代管式 Anthos Service Mesh 的新集群,并将用户流量逐步迁移到该集群。首先将 0% 的用户流量定向到新集群,然后定向 50%,最后定向 100%。在生产环境中,您应该使用更多的较小增量。如果您在任何时候发现新集群无法处理一定比例的流量,则可以通过将百分比降低到 0% 进行回滚。

Canary 控制平面与 Canary 集群

从 Istio 迁移到代管式 Anthos Service Mesh 有两种常用的策略:

  • Canary 控制平面迁移:在此策略中,您将在当前安装了 Istio 的同一集群上预配代管式 Anthos Service Mesh。
  • Canary 集群迁移:在此策略中,您将创建新集群,然后在该集群上预配代管式 Anthos Service Mesh。

在本教程中,您将了解 Canary 集群迁移策略。

费用

本教程使用 Google Cloud 的以下收费组件:

完成本教程后,您可以删除所创建的资源以避免持续产生费用。如需了解详情,请参阅清理

准备工作

  1. 登录您的 Google Cloud 账号。如果您是 Google Cloud 新手,请创建一个账号来评估我们的产品在实际场景中的表现。新客户还可获享 $300 赠金,用于运行、测试和部署工作负载。
  2. 在 Google Cloud Console 中的项目选择器页面上,选择或创建一个 Google Cloud 项目

    转到“项目选择器”

  3. 确保您的 Google Cloud 项目已启用结算功能

  4. 启用所需的 API。

    启用 API

  5. 在 Google Cloud Console 中的项目选择器页面上,选择或创建一个 Google Cloud 项目

    转到“项目选择器”

  6. 确保您的 Google Cloud 项目已启用结算功能

  7. 启用所需的 API。

    启用 API

启动 Cloud Shell

在本教程中,您将使用 Cloud Shell,这是一个托管在 Google Cloud 上的 Shell 环境,可让您管理 Google Cloud 资源。

Cloud Shell 预安装有 Google Cloud CLIkubectlistioctl 命令行。gcloud CLI 为 Google Cloud 提供了主要 CLI。

从本页面的右上角打开 Cloud Shell 会话,点击 ,然后点击确认。本页面下方的框架内会打开一个 Cloud Shell 会话。在该 Cloud Shell 会话中完成以下命令。

下载示例代码

克隆您将使用的 Kubernetes 和 Istio 资源所在的 git 代码库:

  git clone https://github.com/GoogleCloudPlatform/anthos-service-mesh-samples.git
  git clone https://github.com/GoogleCloudPlatform/microservices-demo.git

设置使用 Istio 的集群

创建集群并安装 Istio

在本部分中,您将创建使用 Istio 的集群。实际上,这是您已经在使用的集群。

  1. PROJECT_ID 替换为您的项目 ID 并创建一个新集群:

    gcloud container clusters create cluster-with-istio \
      --project=PROJECT_ID \
      --zone=us-central1-a \
      --machine-type=e2-standard-2 --num-nodes=3
    
  2. 重命名集群上下文,以便更轻松地使用集群:

    kubectl config rename-context \
      gke_PROJECT_ID_us-central1-a_cluster-with-istio \
      cluster-with-istio
    
  3. 检查集群上下文是否已重命名:

    kubectl config get-contexts --output="name"
    
  4. 在集群上安装 Istio。为简单起见,您将安装 Istio 的默认配置文件以及与 istioctl 安装匹配的版本。

    istioctl install
    

    系统会要求您输入“y”,然后按 Enter 键。

    输出类似于以下内容:

    This will install the Istio X.Y.Z default profile with ["Istio core" "Istiod" "Ingress gateways"] components into the cluster. Proceed? (y/N)
    ✔ Istio core installed
    ✔ Istiod installed
    ✔ Ingress gateways installed
    ✔ Installation complete
    Making this installation the default for injection and validation.
    

部署 Online Boutique

  1. 将 Online Boutique 部署到名为 onlineboutique 的单独命名空间中。创建此命名空间:

    kubectl \
      --context cluster-with-istio \
      create namespace onlineboutique
    
  2. 部署 Online Boutique 的 12 项服务,其中包括用于模拟用户流量的负载生成器:

    kubectl \
      --namespace=onlineboutique \
      --context=cluster-with-istio \
      apply -f microservices-demo/release/kubernetes-manifests.yaml
    
  3. 上一步还部署了一项名为 frontend-external(类型为 LoadBalancer)的服务,该服务分配有公共 IP 地址。但是,您只希望通过 Istio 入站流量网关部署允许公共入站流量。删除 frontend-external 服务资源:

    kubectl \
      --namespace=onlineboutique \
      --context=cluster-with-istio \
      delete service frontend-external
    
  4. 部署 Istio Gateway 资源和 Istio VirtualService 资源,以供公共流量访问 Online Boutique:

    kubectl \
      --namespace=onlineboutique \
      --context=cluster-with-istio \
      apply -f microservices-demo/istio-manifests/frontend-gateway.yaml
    
  5. 获得 Istio 入站流量网关的公共 IP 地址:

    kubectl \
      --namespace istio-system \
      --context=cluster-with-istio \
      get service --output jsonpath='{.items[0].status.loadBalancer.ingress[0].ip}'
    
  6. 复制 istio-ingressgateway 服务的公共 IP 地址,然后通过网络浏览器访问它。您将看到 Online Boutique 示例应用。

设置使用代管式 Anthos Service Mesh 的新集群

创建集群并预配代管式 Anthos Service Mesh

在本部分中,您将创建要迁移到的集群。您将预配代管式 Anthos Service Mesh 并部署 Online Boutique,以便从使用 Istio 的集群复制部署。

  1. 将您的项目编号存储到环境变量中:

    export PROJECT_NUMBER=$(gcloud projects \
      describe PROJECT_ID --format='get(projectNumber)')
    
  2. 创建新集群:

    gcloud container clusters create cluster-with-managed-asm \
      --project=PROJECT_ID --zone=us-central1-a \
      --machine-type=e2-standard-4 --num-nodes=2 \
      --workload-pool PROJECT_ID.svc.id.goog \
      --labels mesh_id=proj-${PROJECT_NUMBER}
    
  3. 重命名集群上下文,以便更轻松地使用集群:

    kubectl config rename-context \
      gke_PROJECT_ID_us-central1-a_cluster-with-managed-asm \
      cluster-with-managed-asm
    
  4. 检查集群上下文是否已重命名:

    kubectl config get-contexts --output="name"
    
  5. 在项目的舰队上启用 Anthos Service Mesh。舰队是 Kubernetes 集群及其他可共同管理的资源的逻辑分组。

    gcloud container fleet mesh enable --project PROJECT_ID
    

    输出类似于以下内容:

    Waiting for Feature Service Mesh to be created...done.
    
  6. 将集群注册到项目的舰队:

    gcloud container fleet memberships register cluster-with-managed-asm-membership \
      --gke-cluster=us-central1-a/cluster-with-managed-asm \
      --enable-workload-identity \
      --project PROJECT_ID
    

    输出类似于以下内容:

    Waiting for membership to be created...done.
    Created a new membership [projects/your-project-id/locations/global/memberships/cluster-with-gke-membership] for the cluster [cluster-with-gke-membership]
    Generating the Connect Agent manifest...
    Deploying the Connect Agent on cluster [cluster-with-gke-membership] in namespace [gke-connect]...
    Deployed the Connect Agent on cluster [cluster-with-gke-membership] in namespace [gke-connect].
    Finished registering the cluster [cluster-with-gke-membership] with the Fleet.
    
  7. 在集群上启用代管式 Anthos Service Mesh:

    gcloud container fleet mesh update \
      --management automatic \
      --memberships cluster-with-managed-asm-membership \
      --project PROJECT_ID
    

    输出类似于以下内容:

    Waiting for Feature Service Mesh to be updated...done.
    
  8. 验证已为集群预配代管式 Anthos Service Mesh 并且可供使用:

    gcloud container fleet mesh describe --project PROJECT_ID
    

    Anthos Service Mesh 可能需要大约 10 分钟才能完成预配且可在集群上使用。如果您看到 controlPlaneManagement.state: DISABLEDcontrolPlaneManagement.state: PROVISIONING,则需要每隔几分钟重新运行一次上述命令,直到您看到 controlPlaneManagement.state: ACTIVE

    输出类似于以下内容:

    createTime: '2022-07-06T01:05:39.110120474Z'
    membershipSpecs:
      projects/123456789123/locations/global/memberships/cluster-with-managed-asm-membership:
        mesh:
          management: MANAGEMENT_AUTOMATIC
    membershipStates:
      projects/123456789123/locations/global/memberships/cluster-with-managed-asm-membership:
        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.'
          updateTime: '2022-07-06T01:19:24.243993678Z'
    name: projects/your-project-id/locations/global/features/servicemesh
    resourceState:
      state: ACTIVE
    spec: {}
    state:
      state: {}
    updateTime: '2022-07-06T01:19:27.475885687Z'
    

部署 Anthos Service Mesh 的入站流量网关

  1. 将 Anthos Service Mesh 的入站流量网关部署到名为 asm-ingress 的单独命名空间中。创建此命名空间:

    kubectl \
      --context cluster-with-managed-asm \
      create namespace asm-ingress
    
  2. 使用 istio.io/rev=asm-managed 标签将 asm-ingress 命名空间添加到服务网格,并启用自动边车代理注入。

    kubectl \
      --context cluster-with-managed-asm \
      label namespace asm-ingress 'istio.io/rev=asm-managed'
    
  3. 部署 Anthos Service Mesh 入站流量网关

    kubectl \
      --context cluster-with-managed-asm \
      --namespace=asm-ingress \
      apply -f anthos-service-mesh-samples/docs/shared/asm-ingress-gateway/asm-gateway-deployment-svc.yaml
    kubectl \
      --context cluster-with-managed-asm \
      --namespace=asm-ingress \
      apply -f anthos-service-mesh-samples/docs/shared/asm-ingress-gateway/gateway.yaml
    

    输出类似于以下内容:

    namespace/asm-ingress configured
    serviceaccount/asm-ingressgateway configured
    service/asm-ingressgateway configured
    deployment.apps/asm-ingressgateway configured
    gateway.networking.istio.io/asm-ingressgateway configured
    

部署 Online Boutique

  1. 将 Online Boutique 部署到名为 onlineboutique 的单独命名空间中。创建此命名空间:

    kubectl \
      --context cluster-with-managed-asm \
      create namespace onlineboutique
    
  2. 使用 istio.io/rev=asm-managed 标签将 onlineboutique 命名空间添加到服务网格,并启用自动边车代理注入。

    kubectl \
      --context cluster-with-managed-asm \
      label namespace onlineboutique 'istio.io/rev=asm-managed'
    
  3. 部署 Online Boutique 的 12 项服务,包括用于模拟用户流量的负载生成器:

    kubectl \
      --context cluster-with-managed-asm \
      --namespace=onlineboutique \
      apply -f anthos-service-mesh-samples/docs/shared/online-boutique/kubernetes-manifests.yaml
    kubectl \
      --context cluster-with-managed-asm \
      --namespace=onlineboutique \
      apply -f anthos-service-mesh-samples/docs/shared/online-boutique/virtual-service.yaml
    
  4. 获取 Anthos Service Mesh 入站流量网关的公共 IP 地址:

    kubectl \
      --context cluster-with-managed-asm \
      --namespace asm-ingress \
      get service --output jsonpath='{.items[0].status.loadBalancer.ingress[0].ip}'
    
  5. 复制 asm-ingressgateway Service 的公共 IP 地址,然后通过网络浏览器访问它。您将看到 Online Boutique 示例应用。您将在下一部分中使用此公共 IP 地址,因此请将其复制到环境变量中:

    export INGRESS_IP_OF_CLUSTER_WITH_MANAGED_ASM=$( \
      kubectl \
        --context cluster-with-managed-asm \
        --namespace asm-ingress \
        get service --output jsonpath='{.items[0].status.loadBalancer.ingress[0].ip}' \
      )
    

通过 Canary 部署测试使用 Anthos Service Mesh 的集群

在本部分中,您将配置使用 Istio 的集群,以便将流向 Online Boutique 的用户流量的 50% 迁移到使用代管式 Anthos Service Mesh 的集群上的 Online Boutique 实例。为此,您需要将两个 Istio 资源部署到使用 Istio 的集群:

  • ServiceEntry,告知 Istio 有关代管式 Anthos Service Mesh 集群的 Online Boutique 端点
  • VirtualService,告知 Istio 入站流量网关按 50-50 的比例分配流量。
  1. ServiceEntry 资源内设置代管式 Anthos Service Mesh 集群的入站流量网关的 IP 地址:

    sed -i "s/1.2.3.4/${INGRESS_IP_OF_CLUSTER_WITH_MANAGED_ASM}/" anthos-service-mesh-samples/docs/migrate-to-managed-asm/service-entry.yaml
    
  2. ServiceEntry 部署到使用 Istio 的集群:

    kubectl \
      --context cluster-with-istio \
      --namespace onlineboutique \
      apply -f anthos-service-mesh-samples/docs/migrate-to-managed-asm/service-entry.yaml
    
  3. VirtualService 部署到使用 Istio 的集群:

    kubectl \
      --context cluster-with-istio \
      --namespace onlineboutique \
      apply -f anthos-service-mesh-samples/docs/migrate-to-managed-asm/virtual-service.yaml
    
  4. 在网络浏览器中访问使用 Istio 的集群的入站流量网关的 IP 地址:

    kubectl \
      --context cluster-with-istio \
      --namespace istio-system \
      get service
    

    多次刷新 Online Boutique 首页,并且每次都要查看页面的页脚。请注意,50% 的请求由使用代管式 Anthos Service Mesh 的集群上的 Pod 处理。

迁移到使用代管式 Anthos Service Mesh 的集群

本部分假定您拥有域名并且有权访问其 DNS(域名服务器)设置。

  1. 向 DNS 设置添加 A 记录,以将域名(例如 example.com)指向使用 Istio 的集群上运行的入站流量网关的 IP 地址。

  2. 通过在网络浏览器中访问域名来访问 Online Boutique。

  3. 最大限度地减少 DNS 记录的存留时间 (TTL),以确保在需要回滚时可以快速还原 DNS 条目。

  4. 将您的域名的 A 记录设置为使用代管式 Anthos Service Mesh 的集群的入站流量网关的公共 IP 地址。

  5. 迁移成功后,删除使用 Istio 的集群:

    gcloud container clusters delete cluster-with-istio \
      --zone=us-central1-a \
      --project=PROJECT_ID
    

清理

为避免因本教程中使用的资源导致您的 Google Cloud 账号产生费用,请删除包含这些资源的项目,或者保留项目但删除各个资源。

删除项目

  1. 在 Google Cloud 控制台中,进入管理资源页面。

    转到“管理资源”

  2. 在项目列表中,选择要删除的项目,然后点击删除
  3. 在对话框中输入项目 ID,然后点击关闭以删除项目。

删除资源

删除使用代管式 Anthos Service Mesh 的集群:

  gcloud container clusters delete cluster-with-managed-asm \
    --zone=us-central1-a \
    --project=PROJECT_ID

后续步骤