迁移到 Mesh CA

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

本页面介绍如何在停机时间最短或无停机的情况下从 Istio CA 迁移到 Mesh CA。对于以下使用场景,请按照本指南中的步骤操作:

  • 从 GKE 上的 Istio 迁移到使用 Mesh CA 的 Anthos Service Mesh 1.10.6-asm.2 集群内控制层面。
  • 从使用 Istio CA 的 Anthos Service Mesh 1.9 or a 1.10 patch release 升级到使用 Mesh CA 的 Anthos Service Mesh 1.10.6-asm.2 集群内控制层面。

限制

  • 只有 GKE 支持 Mesh CA。
  • 所有 GKE 集群都必须位于同一 Google Cloud 项目中

前提条件

本指南假定您具备以下各项:

所需工具

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

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

此脚本具有以下依赖项:

  • awk
  • grep
  • istioctl:运行 install_asm 脚本时,它会下载与您要安装的 Anthos Service Mesh 版本匹配的 istioctl 版本。
  • jq
  • kubectl
  • openssl

迁移概览

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

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

  1. 分发 Mesh CA 信任根。

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

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

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

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

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

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

分发 Mesh CA 信任根

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

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

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

  1. 请按照在 GKE 上安装 Anthos Service Mesh 中的步骤,准备好使用 Google 提供的脚本 install_asm 来安装新的控制层面修订版本。

  2. 请确保您拥有安装 Anthos Service Mesh 1.10 或更高版本的 install_asm 版本。

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

    • PROJECT_ID:必填。在其中创建集群的项目的 ID。

    • CLUSTER_NAME:必填。集群的名称。

    • CLUSTER_LOCATION:必填。集群所在的地区或区域。

    • REVISION_1:推荐。修订版本标签是在控制层面上设置的键值对。修订版本标签键始终为 istio.io/rev。默认情况下,脚本会根据 Anthos Service Mesh 版本设置修订版本标签的值,例如:asm-1106-2。建议您添加此选项,并将 REVISION_1 替换为描述安装的名称,例如 asm-1106-2-distribute-root。该名称必须是 DNS-1035 标签,并且必须包含小写字母数字字符或 -,以字母字符开头,并以字母数字字符结尾(例如 my-name'abc-123)。用于验证的正则表达式为:'[a-z]([-a-z0-9]*[a-z0-9])?')

    • DIR_PATH :必填。脚本下载 anthos-service-mesh 软件包和 Anthos Service Mesh 安装文件(包含 istioctl、示例和清单)的目录的相对路径。

    • OVERLAYS:可选。如果您想启用可选功能,请对于每个功能,在 --custom_overlay 中添加叠加文件的名称。如果您未启用可选功能,请删除此行和上一行的反斜杠。

      ./install_asm \
        --project_id  PROJECT_ID \
        --cluster_name CLUSTER_NAME \
        --cluster_location CLUSTER_LOCATION \
        --mode install \
        --ca citadel \
        --enable_all \
        --option ca-migration-citadel \
        --revision_name REVISION_1  \
        --output_dir DIR_PATH \
        OVERLAYS
      

    以下命令行参数是必需的:

    • --ca citadel:为避免停机,请指定 Istio CA(citadel 选项对应于 Istio CA)。此时不要切换到 Mesh CA。

    • --option ca-migration-citadel:当您重新部署工作负载时,此选项会触发新的信任根,以分发给工作负载的 Sidecar 代理。

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

如需完成新信任根的分发,您需要使用修订版本标签 istio.io/rev=asm-1106-2-distribute-root 为您的命名空间添加标签,然后重启工作负载。重启工作负载后,如需测试工作负载,请运行脚本以验证边车代理是否同时配置了 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/release-1.10-asm/scripts/ca-migration/migrate_ca > migrate_ca
    
  3. 设置脚本上的可执行位:

    chmod +x migrate_ca
    
  4. migrate_ca 脚本会调用 istioctl,这取决于版本。install_asm 脚本会在您为 --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 列下,记下新修订版本的标签值,该值与您在运行 install_asm 时指定的修订版本标签匹配。在此示例中,该值为 asm-1106-2-distribute-root

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

  6. istio-ingressgateway 切换到新的修订版本。在以下命令中,确保 REVISION_1 与新修订版本的标签值相匹配。

    kubectl patch service -n istio-system istio-ingressgateway --type='json' -p='[{"op": "replace", "path": "/spec/selector/service.istio.io~1canonical-revision", "value": "REVISION_1"}]'

    预期输出:

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

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

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

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

    kubectl rollout restart deployment -n NAMESPACE
    
  9. 验证 pod 是否配置为指向新版 istiod

    kubectl get pods -n NAMESPACE -l istio.io/rev=REVISION_1
    
  10. 测试您的应用,验证工作负载是否正常工作。

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

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

    ./migrate_ca check-root-cert
    

    预期输出:

    Namespace: foo
    httpbin-66cdbdb6c5-pmzps.foo trusts [CITADEL MESHCA]
    sleep-64d7d56698-6tmjm.foo trusts [CITADEL MESHCA]
  13. 如果您确信应用按预期正常运行,请继续执行转换到新版 istiod 的步骤。如果您的应用出现问题,请按照以下步骤回滚。

    完成转换

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

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

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

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

      迁移

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

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

      升级

      如果您是从旧版 Anthos 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 迁移还是从旧版 Anthos Service Mesh 升级。

      迁移

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

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

      升级

      如果您是从旧版 Anthos 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. 切换回旧版 istio-ingressgatewqy。在以下命令中,将 OLD_REVISION 替换为旧修订版本。

      kubectl patch service -n istio-system istio-ingressgateway --type='json' -p='[{"op": "replace", "path": "/spec/selector/service.istio.io~1canonical-revision", "value": "OLD_REVISION"}]'
      
    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-1106-2-distribute-root -n istio-system
      

      预期输出如下所示:

      istiooperator.install.istio.io "installed-state-asm-1106-2-distribute-root" deleted

迁移到 Mesh CA

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

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

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

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

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

    • PROJECT_ID:必填。在其中创建集群的项目的 ID。

    • CLUSTER_NAME:必填。集群的名称。

    • CLUSTER_LOCATION:必填。集群所在的地区或区域。

    • REVISION_2:推荐。将 REVISION_2 替换为描述安装的名称,例如 asm-1106-2-meshca-ca-migration。该名称必须是 DNS-1035 标签,并且必须包含小写字母数字字符或 -,以字母字符开头,并以字母数字字符结尾(例如 my-name'abc-123)。用于验证的正则表达式为:'[a-z]([-a-z0-9]*[a-z0-9])?')

    • DIR_PATH :必填。脚本下载 anthos-service-mesh 软件包和 Anthos Service Mesh 安装文件(包含 istioctl、示例和清单)的目录的相对路径。

    • OVERLAYS:可选。如果您想启用可选功能,请对于每个功能,在 --custom_overlay 中添加叠加文件的名称。如果您未启用可选功能,请删除此行和上一行的反斜杠。

    ./install_asm \
      --project_id  PROJECT_ID \
      --cluster_name CLUSTER_NAME \
      --cluster_location CLUSTER_LOCATION \
      --mode install \
      --ca mesh_ca \
      --enable_all \
      --option ca-migration-meshca \
      --revision_name REVISION_2 \
      --output_dir DIR_PATH \
      OVERLAYS
    

    以下命令行参数是必需的:

    • --ca mesh_ca:您现在可以切换到 Mesh CA,因为 Mesh CA 信任根已分发。

    • --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-1106-2-distribute-root-65d884685d-6hrdk      1/1     Running   0          67m   asm-1106-2-distribute-root
    istio-ingressgateway-asm-1106-2-distribute-root65d884685d-94wgz       1/1     Running   0          67m   asm-1106-2-distribute-root
    istio-ingressgateway-asm-1106-2-meshca-ca-migration-8b5fc8767-gk6hb   1/1     Running   0          5s    asm-1106-2-meshca-ca-migration
    istio-ingressgateway-asm-1106-2-meshca-ca-migration-8b5fc8767-hn4w2   1/1     Running   0          20s   asm-1106-2-meshca-ca-migration
    istiod-asm-1106-2-distribute-root-67998f4b55-lrzpz                    1/1     Running   0          68m   asm-1106-2-distribute-root
    istiod-asm-1106-2-distribute-root-67998f4b55-r76kr                    1/1     Running   0          68m   asm-1106-2-distribute-root
    istiod-asm-1106-2-meshca-ca-migration-5cd96f88f6-n7tj9                1/1     Running   0          27s   asm-1106-2-meshca-ca-migration
    istiod-asm-1106-2-meshca-ca-migration-5cd96f88f6-wm68b                1/1     Running   0          27s   asm-1106-2-meshca-ca-migration
    1. 在输出中的 REV 列下,记下新版本的修订版标签的值。在此示例中,该值为 asm-1106-2-meshca-ca-migration

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

  2. istio-ingressgateway 切换到新的修订版本。在以下命令中,将 REVISION_2 的值更改为新版本修订版本标签的值。

    kubectl patch service -n istio-system istio-ingressgateway --type='json' -p='[{"op": "replace", "path": "/spec/selector/service.istio.io~1canonical-revision", "value": "REVISION_2"}]'

    预期输出:

    service/istio-ingressgateway patched
  3. 将新的修订版本标签添加到命名空间。在以下命令中,将 NAMESPACE 替换为要添加标签的命名空间。

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

    kubectl rollout restart deployment -n NAMESPACE
    
  5. 验证 pod 是否配置为指向新版 istiod

    kubectl get pods -n NAMESPACE -l istio.io/rev=REVISION_2
    
  6. 测试您的应用,验证工作负载是否正常工作。确保 mTLS 通信在旧命名空间中的工作负载与新命名空间中的工作负载之间正常运行。

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

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

    完成转换

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

    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. 切换回之前的 istio-ingressgatewqy。在以下命令中,将 OLD_REVISION 替换为旧修订版本。

      kubectl patch service -n istio-system istio-ingressgateway --type='json' -p='[{"op": "replace", "path": "/spec/selector/service.istio.io~1canonical-revision", "value": "OLD_REVISION"}]'
      
    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