使用基于 Canary 版的方法迁移到 Mesh CA

若要从 Istio CA(也称为 CitadelCitadel)迁移到 Cloud Service Mesh 证书授权机构 (Mesh CA),需要迁移信任根。在 Cloud Service Mesh 1.10 之前,如果您想要从 Google Kubernetes Engine (GKE) 上的 Istio 迁移到采用 Mesh CA 的 Cloud Service Mesh,则需要安排停机,因为 Cloud Service Mesh 无法加载多个根证书。因此,在迁移期间,新部署的工作负载信任新的根证书,而其他工作负载则信任旧的根证书。使用由不同根证书签名的证书的工作负载无法相互进行身份验证。这意味着在迁移期间,双向 TLS (mTLS) 流量会中断。仅当使用 Mesh CA 的证书重新部署控制层面和所有命名空间中的所有工作负载时,整个集群才会完全恢复。如果您的网格中有多个集群带有向其他集群上的工作负载发送请求的工作负载,则还需要更新这些集群上的所有工作负载。

对于以下使用场景,请按照本指南中的步骤操作:

  • 从 GKE 上的 Istio 迁移到使用 Mesh CA 的 Cloud Service Mesh 1.18.7-asm.26 集群内控制平面。
  • 从使用 Istio CA 的 Cloud Service Mesh 1.15 or a 1.16 patch release 升级到使用 Mesh CA 的 Cloud Service Mesh 1.18.7-asm.26 集群内控制平面。

限制

  • 所有 GKE 集群都必须位于同一 Google Cloud 项目中

前提条件

按照安装依赖工具并验证集群中的步骤操作:

所需工具

在迁移期间,您将运行 Google 提供的工具 migrate_ca,针对集群中的每个 Pod 验证以下内容:

  • Istio CA 和 Mesh CA 的根证书。
  • 由 Istio CA 和 Mesh CA 颁发的工作负载 mTLS 证书。
  • Istio CA 和 Mesh CA 配置的信任网域。

此工具具有以下依赖项:

  • awk
  • grep
  • istioctl:运行 asmcli install 会下载与您要安装的 Cloud Service Mesh 版本匹配的 istioctl 版本。
  • jq
  • kubectl
  • openssl

迁移概览

如需迁移到 Mesh CA,请遵循基于修订版本的迁移过程(也称为“Canary 升级”)。在基于修订版本的迁移中,新的控制层面修订版本会与现有控制层面一起部署。然后,您可以逐步将工作负载移至新的修订版本,从而可全程监视迁移的效果。在迁移过程中,身份验证和授权可在使用 Mesh CA 的工作负载与使用 Istio CA 的工作负载之间完全正常运行。

以下是向 Mesh CA 迁移的概览:

  1. 分发 Mesh CA 信任根。

    1. 安装新的控制平面修订版本,该修订版本使用 Istio CA,其中包含将分发 Mesh CA 信任根的选项。

    2. 将工作负载迁移到新的控制层面(按命名空间划分),并测试您的应用。当所有工作负载都成功迁移到新的控制层面后,请移除旧的控制层面。

  2. 迁移到 Mesh CA。现在,所有 Sidecar 代理都配置了旧的信任根和 Mesh CA 信任根,您可以迁移到 Mesh CA 而无需停机。同样,您采用基于修订版本的迁移过程:

    1. 安装启用了 Mesh CA 的控制层面修订版本。

    2. 将工作负载迁移到新的控制层面修订版本(按命名空间划分),并测试您的应用。当所有工作负载都成功迁移到新的控制层面后,请移除旧的控制层面。

    3. 移除与旧 CA 关联的集群中的 CA Secret,并重启新的控制层面。

分发 Mesh CA 信任根

在可迁移到 Mesh CA 之前,网格中的所有 GKE 集群都必须具有 Cloud Service Mesh 1.10 或更高版本,并且所有集群都必须配置一个控制平面选项,用于触发 Mesh CA 的信任根来分发给集群上所有工作负载的代理。完成此过程后,每个代理都配置有旧信任根和新信任根。通过此方案,当您迁移到 Mesh CA 时,使用 Mesh CA 的工作负载将能够向使用旧 CA 的工作负载进行身份验证。

安装新的控制层面修订版本

使用分发 Mesh CA 信任根的选项安装控制层面修订版本。

  1. 按照安装依赖工具并验证集群中的步骤操作,以准备使用 Google 提供的工具 asmcli 安装新的控制层面修订版本。

  2. 请确保您拥有安装 Cloud Service Mesh 1.11 或更高版本的 asmcli 版本。

    ./asmcli --version
    
  3. 运行 asmcli install。在以下命令中,将占位符替换为您的值。

     ./asmcli install \
       --fleet_id FLEET_PROJECT_ID \
       --kubeconfig KUBECONFIG_FILE \
       --enable_all \
       --ca citadel \
       --ca_cert CA_CERT_FILE_PATH \
       --ca_key CA_KEY_FILE_PATH \
       --root_cert ROOT_CERT_FILE_PATH \
       --cert_chain CERT_CHAIN_FILE_PATH \
       --option ca-migration-citadel \
       --revision_name REVISION_1 \
       --output_dir DIR_PATH
    
  • --fleet_id队列宿主项目的项目 ID。
  • --kubeconfigkubeconfig 文件的路径。您可以指定相对路径或完整路径。环境变量 $PWD 不适用于此处。
  • --output_dir添加此选项可指定 asmcli 在其中下载 anthos-service-mesh 软件包并提取安装文件的目录,其中包含 istioctl、示例和清单。否则,asmcli 会将文件下载到 tmp 目录。您可以指定相对路径或完整路径。环境变量 $PWD 不适用于此处。
  • --enable_all:允许该工具执行以下操作:
    • 授予所需的 IAM 权限
    • 启用所需的 Google API。
    • 在集群上设置用于标识网格的标签。
    • 如果尚未注册集群,请注册集群

  • -ca citadel:为避免停机,请指定 Istio CA(citadel 选项对应于 Istio CA)。此时不要切换到 Mesh CA。
  • --ca_cert:中间证书
  • --ca_key:中间证书的密钥
  • --root_cert:根证书
  • --cert_chain:证书链
  • --option ca-migration-citadel:当您重新部署工作负载时,此选项会触发新的信任根,以分发给工作负载的 Sidecar 代理。
  • REVISION_1:推荐。修订版本标签是在控制平面上设置的键值对。修订版本标签键始终为 istio.io/rev。默认情况下,工具会根据 Cloud Service Mesh 版本设置修订版本标签的值,例如:asm-1187-26。建议您添加此选项,并将 REVISION_1 替换为描述安装的名称,例如 asm-1187-26-distribute-root。名称必须是 DNS-1035 标签,并且必须包含小写字母数字字符或 -,以字母字符开头,并以字母数字字符结尾(例如 my-nameabc-123)。

将工作负载迁移到新的控制层面

如需完成新信任根的分发,您需要使用修订版本标签 istio.io/rev=<var>REVISION_1</var>-distribute-root 为您的命名空间添加标签,然后重启工作负载。重启工作负载后,如需测试工作负载,请运行工具以验证 Sidecar 代理是否同时配置了 Mesh CA 的旧信任根和新信任根。

  1. 设置 kubectl 的当前上下文。在以下命令中,如果您有一个单地区集群,请将 --region 更改为 --zone

    gcloud container clusters get-credentials CLUSTER_NAME \
        --project=PROJECT_ID \
        --region=CLUSTER_LOCATION
    
  2. 下载验证工具:

    curl https://raw.githubusercontent.com/GoogleCloudPlatform/anthos-service-mesh-packages/master/scripts/ca-migration/migrate_ca > migrate_ca
    
  3. 设置工具上的可执行位:

    chmod +x migrate_ca
    
  4. migrate_ca 工具会调用 istioctl,这取决于版本。asmcli 工具会在您为 --output_dir 指定的目录中向 istioctl 添加符号链接。确保目录位于路径的开头。在以下命令中,将 ISTIOCTL_PATH 替换为包含工具下载的 istioctl 的目录。

    export PATH=ISTIOCTL_PATH:$PATH
    which istioctl
    echo $PATH
    
  5. 获取 istiodistio-ingressgateway 上的修订版本标签。

    kubectl get pod -n istio-system -L istio.io/rev
    

    输出内容类似如下:

    NAME                                                             READY   STATUS    RESTARTS   AGE   REV
    istio-ingressgateway-5fd454f8ff-t7w9x                            1/1     Running   0          36m   default
    istio-ingressgateway-asm-195-2-distribute-root-c6ccfbdbd-z2s9p   1/1     Running   0          18m   asm-195-2-distribute-root
    istio-ingressgateway-asm-195-2-distribute-root-c6ccfbdbd-zr2cs   1/1     Running   0          18m   asm-195-2-distribute-root
    istiod-68bc495f77-shl2h                                          1/1     Running   0          36m   default
    istiod-asm-195-2-distribute-root-6f764dbb7c-g9f8c                1/1     Running   0          18m   asm-195-2-distribute-root
    istiod-asm-195-2-distribute-root-6f764dbb7c-z7z9s                1/1     Running   0          18m   asm-195-2-distribute-root
    1. 在输出中的 REV 列下,记下新修订版本的标签值,该值与您在运行 asmcli install 时指定的修订版本标签匹配。在此示例中,该值为 asm-1187-26-distribute-root

    2. 将工作负载移至新的修订版本后,您需要删除 istiod 的旧修订版本。请记下旧的 istiod 修订版本的标签中的值。示例输出显示了从使用 default 修订版本的 Istio 进行迁移的操作。

  6. 将修订版本标签添加到命名空间,并移除 istio-injection 标签(如果存在)。在以下命令中,将 NAMESPACE 替换为要添加标签的命名空间。

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

    如果您在输出中看到 "istio-injection not found",则可以忽略它。这意味着命名空间之前没有 istio-injection 标签。如果命名空间同时具有 istio-injection 和修订版本标签,自动注入行为未定义,因此 Cloud Service Mesh 文档中的所有 kubectl label 命令都会明确确保仅设置一个标签。

  7. 重启 pod 以触发重新注入。

    kubectl rollout restart deployment -n NAMESPACE
    
  8. 测试您的应用,验证工作负载是否正常工作。

  9. 如果您的其他命名空间中存在工作负载,请重复上述步骤以标记命名空间并重启 Pod。

  10. 验证集群上所有工作负载的 Sidecar 代理是否配置了旧根证书和新根证书:

    ./migrate_ca check-root-cert
    

    预期输出:

    Namespace: foo
    httpbin-66cdbdb6c5-pmzps.foo trusts [CITADEL MESHCA]
    sleep-64d7d56698-6tmjm.foo trusts [CITADEL MESHCA]
  11. 如果需要迁移网关,请按照 Canary 版升级(高级)中的步骤安装新的网关部署。请注意下列重要事项:

    • 使用 REVISION_1 作为修订版本标签。
    • 将网关资源部署到与旧版安装的网关相同命名空间中,以执行零停机迁移。确保指向旧网关的服务资源现在也应包含新部署。
    • 请勿删除旧网关部署,直到确定您的应用运行正常(下一步之后)。
  12. 如果您确信应用按预期正常运行,请继续执行转换到新版 istiod 的步骤。如果您的应用出现问题,请按照以下步骤回滚。

    完成转换

    如果您确信应用按预期正常运行,请移除旧控制平面以完成到新版本的转换。

    1. 切换到 anthos-service-mesh GitHub 代码库中的文件所在的目录。

    2. 配置验证 Webhook 以使用新的控制平面。

      kubectl apply -f asm/istio/istiod-service.yaml
      
    3. 删除旧 istio-ingressgateway 部署。要运行的命令取决于您是从 Istio 迁移还是从旧版 Cloud Service Mesh 升级:

      迁移

      如果您是从 Istio 迁移,旧的 istio-ingressgateway 没有修订版本标签。

      kubectl delete deploy/istio-ingressgateway -n istio-system
      

      升级

      如果您是从旧版 Cloud Service Mesh 升级,请在以下命令中将 OLD_REVISION 替换为旧版 istio-ingressgateway 的修订版本标签。

      kubectl delete deploy -l app=istio-ingressgateway,istio.io/rev=OLD_REVISION -n istio-system --ignore-not-found=true
      
    4. 删除 istiod 的旧修订版本。要使用的命令取决于您是从 Istio 迁移还是从旧版 Cloud Service Mesh 升级。

      迁移

      如果您是从 Istio 迁移,旧的 istio-ingressgateway 没有修订版本标签。

      kubectl delete Service,Deployment,HorizontalPodAutoscaler,PodDisruptionBudget istiod -n istio-system --ignore-not-found=true
      

      升级

      如果您是从旧版 Cloud Service Mesh 升级,在以下命令中,请确保 OLD_REVISION 与旧版 istiod 的修订版本标签匹配。

      kubectl delete Service,Deployment,HorizontalPodAutoscaler,PodDisruptionBudget istiod-OLD_REVISION -n istio-system --ignore-not-found=true
      
    5. 移除旧版 IstioOperator 配置。

      kubectl delete IstioOperator installed-state-OLD_REVISION -n istio-system
      

      预期输出如下所示:

      istiooperator.install.istio.io "installed-state-OLD_REVISION" deleted

    回滚

    如果您在使用新版 istiod 测试应用时遇到问题,请按照以下步骤回滚到之前的版本:

    1. 删除在第 11 步中安装的新网关部署。

    2. 重新为您的命名空间添加标签,以启用旧版 istiod 的自动注入。使用的命令取决于您在旧版本使用的是修订版本标签还是 istio-injection=enabled

      • 如果您使用修订版本标签来进行自动注入,请使用以下命令:

        kubectl label namespace NAMESPACE istio.io/rev=OLD_REVISION --overwrite
        
      • 如果您使用的是 istio-injection=enabled,请使用以下命令:

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

      预期输出:

      namespace/NAMESPACE labeled
    3. 确认命名空间上的修订版本标签与旧版 istiod 的修订版本标签一致:

      kubectl get ns NAMESPACE --show-labels
      
    4. 重启 pod 以触发重新注入,以使代理具有之前的版本:

      kubectl rollout restart deployment -n NAMESPACE
      
    5. 移除新的 istio-ingressgateway 部署。

      kubectl delete deploy -l app=istio-ingressgateway,istio.io/rev=REVISION_1 -n istio-system --ignore-not-found=true
      
    6. 移除 istiod 的新修订版本。

      kubectl delete Service,Deployment,HorizontalPodAutoscaler,PodDisruptionBudget istiod-REVISION_1 -n istio-system --ignore-not-found=true
      
    7. 移除新的 IstioOperator 配置。

      kubectl delete IstioOperator installed-state-asm-1187-26-distribute-root -n istio-system
      

      预期输出如下所示:

      istiooperator.install.istio.io "installed-state-asm-1187-26-distribute-root" deleted

迁移到 Mesh CA

现在,所有工作负载的 Sidecar 代理均配置了 Mesh CA 的旧信任根和新信任根,因此迁移到 Mesh CA 的步骤与您分发 Mesh CA 信任根时的步骤类似:

安装启用了 Mesh CA 的新控制层面

您可以使用 asmcli install 安装已启用 Mesh CA 的新控制层面修订版本。

  1. 如果您自定义了以前的安装,则需要在运行 asmcli install 时指定相同的叠加文件

  2. 运行 asmcli install。在以下命令中,将占位符替换为您的值。

     ./asmcli install \
       --fleet_id FLEET_PROJECT_ID \
       --kubeconfig KUBECONFIG_FILE \
       --output_dir DIR_PATH \
       --enable_all \
       --ca mesh_ca \
       --root_cert ROOT_CERT_FILE_PATH \
       --cert_chain CERT_CHAIN_FILE_PATH
       --option ca-migration-meshca \
      --revision_name REVISION_2 \
      --output_dir DIR_PATH \
      OVERLAYS
    
      • --fleet_id舰队宿主项目的 ID。
      • --kubeconfigkubeconfig 文件的路径。您可以指定相对路径或完整路径。环境变量 $PWD 不适用于此处。
      • --output_dir添加此选项可指定 asmcli 在其中下载 anthos-service-mesh 软件包并提取安装文件的目录,其中包含 istioctl、示例和清单。否则,asmcli 会将文件下载到 tmp 目录。您可以指定相对路径或完整路径。环境变量 $PWD 不适用于此处。
      • --enable_all:允许该工具执行以下操作:
        • 授予所需的 IAM 权限
        • 启用所需的 Google API。
        • 在集群上设置用于标识网格的标签。
        • 如果尚未注册集群,请注册集群

      • --ca mesh_ca:您现在可以切换到 Mesh CA,因为 Mesh CA 信任根已分发。
      • REVISION_2:推荐。将 REVISION_2 替换为描述安装的名称,例如 asm-1187-26-meshca-ca-migration。名称必须是 DNS-1035 标签,并且必须包含小写字母数字字符或 -,以字母字符开头,并以字母数字字符结尾(例如 my-nameabc-123)。
      • --option ca-migration-migration:在重新部署工作负载时,此选项会将代理配置为使用 Mesh CA 信任根。

将工作负载迁移到新的控制层面

为完成安装,您需要使用新的修订版本标签为命名空间添加标签,并重启工作负载。

  1. 获取 istiodistio-ingressgateway 上的修订版本标签。

    kubectl get pod -n istio-system -L istio.io/rev
    

    输出内容类似如下:

    NAME                                                                          READY   STATUS    RESTARTS   AGE   REV
    istio-ingressgateway-asm-1187-26-distribute-root-65d884685d-6hrdk      1/1     Running   0          67m   asm-1187-26-distribute-root
    istio-ingressgateway-asm-1187-26-distribute-root65d884685d-94wgz       1/1     Running   0          67m   asm-1187-26-distribute-root
    istio-ingressgateway-asm-1187-26-meshca-ca-migration-8b5fc8767-gk6hb   1/1     Running   0          5s    asm-1187-26-meshca-ca-migration
    istio-ingressgateway-asm-1187-26-meshca-ca-migration-8b5fc8767-hn4w2   1/1     Running   0          20s   asm-1187-26-meshca-ca-migration
    istiod-asm-1187-26-distribute-root-67998f4b55-lrzpz                    1/1     Running   0          68m   asm-1187-26-distribute-root
    istiod-asm-1187-26-distribute-root-67998f4b55-r76kr                    1/1     Running   0          68m   asm-1187-26-distribute-root
    istiod-asm-1187-26-meshca-ca-migration-5cd96f88f6-n7tj9                1/1     Running   0          27s   asm-1187-26-meshca-ca-migration
    istiod-asm-1187-26-meshca-ca-migration-5cd96f88f6-wm68b                1/1     Running   0          27s   asm-1187-26-meshca-ca-migration
    1. 在输出中的 REV 列下,记下新版本的修订版标签的值。在此示例中,该值为 asm-1187-26-meshca-ca-migration

    2. 另请注意旧版 istiod 的修订版本标签中的值。 将工作负载移至新版本后,您需要使用此值删除旧版本的 istiod。在该示例中,上一个修订版本的修订版本标签的值为 asm-1187-26-distribute-root

  2. 将新的修订版本标签添加到命名空间。在以下命令中,将 NAMESPACE 替换为要添加标签的命名空间。

    kubectl label namespace NAMESPACE istio.io/rev=REVISION_2 --overwrite
    
  3. 重启 pod 以触发重新注入。

    kubectl rollout restart deployment -n NAMESPACE
    
  4. 测试您的应用,验证工作负载是否正常工作。确保 mTLS 通信在旧命名空间中的工作负载与新命名空间中的工作负载之间正常运行。

  5. 如果您的其他命名空间中存在工作负载,请重复上述步骤以标记命名空间并重启 Pod。

  6. 按照就地升级中所述的步骤,将上一部分第 11 步中安装的旧网关部署升级到最新修订版本 REVISION_2

  7. 如果您确信应用按预期正常运行,请继续执行转换到新版控制层面的步骤。如果您的应用出现问题,请按照以下步骤回滚。

    完成转换

    如果您确信应用按预期正常运行,请移除旧控制平面以完成到新版本的转换。

    1. 切换到 anthos-service-mesh GitHub 代码库中的文件所在的目录。

    2. 配置验证 Webhook 以使用新的控制平面。

      kubectl apply -f asm/istio/istiod-service.yaml
      
    3. 删除旧 istio-ingressgateway 部署。在以下命令中,将 OLD_REVISION 替换为旧版 istio-ingressgateway 的修订版本标签。

      kubectl delete deploy -l app=istio-ingressgateway,istio.io/rev=OLD_REVISION -n istio-system --ignore-not-found=true
      
    4. 删除旧的 istiod 修订版本。在以下命令中,将 OLD_REVISION 替换为旧版 istiod 的修订版本标签。

      kubectl delete Service,Deployment,HorizontalPodAutoscaler,PodDisruptionBudget istiod-OLD_REVISION -n istio-system --ignore-not-found=true
      
    5. 移除旧的 IstioOperator 配置。

      kubectl delete IstioOperator installed-state-OLD_REVISION -n istio-system
      

      预期输出如下所示:

      istiooperator.install.istio.io "installed-state-OLD_REVISION" deleted

    回滚

    如果您在使用新的 istiod 修订版本测试应用时遇到问题,请按照以下步骤回滚到先前的修订版本:

    1. 按照就地升级中所述的步骤,将本部分第 6 步中升级的网关部署降级到较早的修订版本 REVISION_1

    2. 为您的命名空间重新添加标签,以使用之前的 istiod 修订版本启用自动注入。

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

      预期输出:

      namespace/NAMESPACE labeled
    3. 确认命名空间上的修订版本标签与旧版 istiod 的修订版本标签一致:

      kubectl get ns NAMESPACE --show-labels
      
    4. 重启 pod 以触发重新注入,以使代理具有之前的版本:

      kubectl rollout restart deployment -n NAMESPACE
      
    5. 移除新的 istio-ingressgateway 部署。

      kubectl delete deploy -l app=istio-ingressgateway,istio.io/rev=REVISION_2 -n istio-system --ignore-not-found=true
      
    6. 移除新版 istiod。确保以下命令中的修订版本标签与您的修订版本匹配。

      kubectl delete Service,Deployment,HorizontalPodAutoscaler,PodDisruptionBudget istiod-REVISION_2 -n istio-system --ignore-not-found=true
      
    7. 移除新版 IstioOperator 配置。

      kubectl delete IstioOperator installed-state-REVISION_2 -n istio-system
      

      预期输出如下所示:

      istiooperator.install.istio.io "installed-state-REVISION_2" deleted

移除 CA Secret 并重启新的控制层面

  1. 保留 Secret 以供在需要时使用:

    kubectl get secret/cacerts -n istio-system -o yaml > save_file_1
    kubectl get secret/istio-ca-secret -n istio-system -o yaml > save_file_2
    
  2. 移除与旧 CA 关联的集群中的 CA Secret:

    kubectl delete secret cacerts istio-ca-secret -n istio-system --ignore-not-found
    
  3. 重启新安装的控制层面。这可确保在网格中运行的所有工作负载中清除旧的信任根。

    kubectl rollout restart deployment -n istio-system