从Istio原地灰度迁移至ASM

服务网格 ASM(Service Mesh)支持将使用Istio社区版的集群直接迁移到ASM中。本文介绍如何将使用Istio社区版的集群迁移到ASM。

迁移流程

将使用Istio的集群迁移到ASM,需要进行以下四个阶段的操作。

image

Migrating阶段,集群中的注入行为仍然保持您为Istio设定的注入规则,并默认注入Istio Sidecar。在启用了Sidecar注入的命名空间中,您可以通过修改Pod Label,显式为该工作负载声明注入ASM网格代理。

image

迁移条件

  • 待迁移的K8s集群需要满足以下条件:

    • 集群版本为1.21及以上版本。若您的集群低于该版本,且该集群是阿里云容器服务K8s集群,请参见手动升级集群

    • 集群中安装的Istio版本为1.10及以上。

  • 您需要为迁移创建新的ASM实例,版本为1.24及以上。具体操作,请参见创建ASM实例

操作步骤

步骤一:将待迁移的集群加入ASM

您可以参考文档添加集群到ASM实例,并在添加集群时勾选“忽略istio-system命名空间检查”选项,将已安装Istio的阿里云容器服务K8s集群或已注册到阿里云容器服务的自建集群添加到ASM。若待迁移的集群为尚未注册至阿里云容器服务,您可以通过ACK One的注册集群功能将其注册到容器服务,然后通过ASM控制台将集群添加到ASM。

待迁移的集群加入ASM后,ASM实例中将自动创建ASMMigrateFromIstio资源,整个迁移过程将由此资源控制。您可以执行以下命令,查看此资源内容。

kubectl --kubeconfig=${ASM_KUBECONFIG} get asmmigratefromistio

预期输出:

apiVersion: istio.alibabacloud.com/v1beta1
kind: ASMMigrateFromIstio
metadata:
  name: default
spec:
  desiredState: Init
  retryCounter: 0
  advancedOptions:
    disableIstioSystemLabelReconciliation: false
status:
  message: ""
  retryCounter: 0
  state: Init

以下是此资源的部分配置项说明。

字段名

类型

介绍

取值

spec.desiredState

string

目标迁移状态,用户可以修改该值以进入指定的迁移状态。

重要

该值只能以固定流转顺序变化:

Init -> SetupIstioForMigrate -> Migrating -> Finished。

  • Init(当前状态)

  • SetupIstioForMigrate

  • Migrating

  • Finished

spec.retryCounter

int32

由于切换状态时ASM控制面会进行一些必要的检查,以确保满足离开当前状态进入新状态的标准。该检查在修改desiredState后将自动触发,若检查未通过,您需要根据提示信息调整状态后修改该值以触发重新检查。

0~2147483647

spec.advancedOptions

object

高级选项。

spec.advancedOptions.disableIstioSystemLabelReconciliation

bool

是否禁用ASMistio-system命名空间的label同步,在目标集群中存在东西向网关时,应当将该值设置为true

  • true:禁用ASMistio-system命名空间标签istio-injection: disable的同步。

  • false:默认值,启用ASMistio-system命名空间标签istio-injection: disable的同步。

status.retryCounter

int32

反映retryCounter是否正确调谐,如果最后一次修改调谐成功,则该值等于spec.retryCounter。

只读

status.state

string

当前实际状态。在切换状态后,如果状态成功切换至spec.desiredState指定的状态,则status.state的值将等于spec.desiredState的值。

只读

status.message

string

如果状态切换失败,该字段将表示失败原因,如果该字段不为空,则用户应当按照该字段给出的提示信息进行处理,并在处理完毕后修改spec.retryCounter触发重试。

只读

ASMMigrateFromIstio状态切换

当迁移的准备工作已经可以进入下一个阶段时,您需要手动切换ASMMigrateFromIstio资源的状态。例如,当前阶段为Init阶段,切换状态到SetupIstioForMigrate则表明进入了下一个阶段。

以下为切换到各阶段的命令示例。

  • SetupIstioForMigrate

    kubectl --kubeconfig=${ASM_KUBECONFIG} patch asmmigratefromistio default --type='merge' -p '{"spec":{"desiredState":"SetupIstioForMigrate"}}'
  • Migrating

    kubectl --kubeconfig=${ASM_KUBECONFIG} patch asmmigratefromistio default --type='merge' -p '{"spec":{"desiredState":"Migrating"}}'
  • Finished

    kubectl --kubeconfig=${ASM_KUBECONFIG} patch asmmigratefromistio default --type='merge' -p '{"spec":{"desiredState":"Finished"}}'

SetupIstioForMigrate状态为例,您可以通过以下方式查看状态是否切换成功。

kubectl get asmigratefromistio default -o yaml

预期输出:

apiVersion: istio.alibabacloud.com/v1beta1
kind: ASMMigrateFromIstio
metadata:
  name: default
spec:
  desiredState: SetupIstioForMigrate
  retryCounter: 0
status:
  message: ""
  retryCounter: 0
  state: SetupIstioForMigrate

status.state的值为SetupIstioForMigrate,则说明状态已经成功切换。

说明

status.state值未按照预期切换,请按照status.message的提示信息进行处理,并在处理完成后将spec.retryCounter的值+1进行重试。

启用Istio东西向网关的集群需要进行的额外设置

ASM默认禁用了istio-system命名空间的自动注入,然而由于Istio东西向网关Pod创建后,需要依赖MutatingWebhook手动替换其镜像,该特性依赖istio-system命名空间不能被显式禁止注入。因此,若您的集群中启用了东西向网关,则您应执行以下命令,使ASM控制面不强制禁止istio-system命名空间的注入。

kubectl --kubeconfig=${ASM_KUBECONFIG} patch asmmigratefromistio default --type='merge' -p '{"spec":{"advancedOptions":{"disableIstioSystemLabelReconciliation": true}}}' 

然后手动清理掉ASM已经同步至istio-system上的标签:

  1. 编辑istio-system命名空间配置。

    kubectl --kubeconfig=${ACK实例kubeconfig文件路径} edit ns istio-system
  2. 手动移除标签istio-injection: disable,并保存退出。

步骤二:配置Istio做好迁移准备

  1. 切换状态到SetupIstioForMigrate

    重要

    执行此命令后,由于ASM需要为Istiod进行相应的配置,因此Istiod将会滚动重启以满足迁移需要。

  2. 为了使迁移过程中,Istio Sidecar能够与ASM Sidecar进行正确的mTLS通信,进入此阶段后,ASM将为Istio配置中新增以下配置:

    defaultConfig:
      proxyMetadata:
        PROXY_CONFIG_XDS_AGENT:"true"

    同时,您需要手动重启所有已注入Istio Sidecar的工作负载,以使该项配置在所有工作负载上生效。您可以通过执行以下命令,确认指定Pod是否已经满足条件:

    kubectl get pod ${POD名称} -o yaml|grep PROXY_CONFIG_XDS_AGENT

    若输出不为空,则表明该工作负载已经满足条件。当集群中所有注入Istio Sidecar的工作负载满足该条件后,可以进入Migrating状态。

步骤三:开始迁移

本步骤将进入Migrating阶段,在此阶段您可以自由选择为工作负载注入Istio SidecarASM网格代理,直到将所有Istio Sidecar替换为ASM网格代理。

  1. 切换状态到Migrating。在成功进入Migrating状态后,您应当先将Istio API全部应用至ASM,然后按照以下的步骤分别将Istio Sidecar、入口网关、出口网关和东西向网关迁移至ASM对应组件。

  2. (可选)部署ASM跨集群网关。

    ASM中,注入了网格代理的工作负载在设计跨集群通信时会自动选用ASM跨集群网关进行通信,对应Istio的东西向网关。因此,如果您启用了东西向网关,为了确保将Istio Sidecar替换为ASM网格代理后能够正常进行跨集群通信,在您为任何工作负载注入ASM网格代理之前,您需要首先部署ASM跨集群网关

    您应当根据当前Istio的集群网络配置,在ASM控制台为集群配置其对应的网络名称,为已经部署Istio东西向网关的集群勾选启用跨集群网关。具体操作,请参见为集群指定网络配置,并启用跨集群网格代理

    image

    说明

    这里的配置需要与Istio的配置一致。例如,Istio为集群a配置了network-1,集群b配置了network-2,则ASM中必须保持一致。

  3. Istio Sidecar迁移至ASM网格代理。

    $ kubectl --kubeconfig=${K8s集群kubeconfig文件路径} -n ${命名空间} patch ${Deployment名称} --type='merge' -p '{"spec":{"template":{"metadata":{"labels":{"sidecar.asm.aliyun.com/inject":"true"}}}}}'
    重要

    由于此命令修改了工作负载label,会导致工作负载滚动重启,该过程中流量是否有损取决于应用协议是否支持优雅下线(HTTP/HTTP2/GRPC)以及Istio Sidecar是否正确配置了优雅下线,以及应用的行为是否符合优雅下线的要求(所有请求一定能够在优雅下线的等待时间内返回)。请尽可能选择业务低峰期进行。

  4. Istio入口网关迁移至ASM入口网关。

    Istio入口网关平滑迁移至ASM入口网关。具体操作,请参见自建Istio IngressGateway如何迁移至ASM网关

  5. Istio出口网关迁移至ASM出口网关。若待迁移集群已经启用了出口网关,请按照以下操作进行迁移。

    1. ASM中创建出口网关。具体操作,请参见创建出口网关。并按需创建其他资源(例如,用于注册外部服务的ServiceEntry,用于为出口网关启用转发端口的网关规则,以及用于将流量定向到出口网关的虚拟服务。具体操作,请参见ASM上访问外部服务的流量管理)。

    2. 修改需要迁移的外部服务对应的虚拟服务,使其指向ASM出口网关,并设置期望的权重。

      以下为此虚拟服务的配置示例。完整示例内容,请参见Egress gateway for HTTP traffic

      apiVersion: networking.istio.io/v1
      kind: VirtualService
      metadata:
        name: direct-cnn-through-egress-gateway
      spec:
        hosts:
        - edition.cnn.com
        gateways:
        - istio-egressgateway
        - mesh
        http:
        - match:
          - gateways:
            - mesh
            port: 80
          route:
          - destination:
              host: istio-egressgateway.istio-system.svc.cluster.local
              port:
                number: 80
            weight: 99
          - destination: # 新增一个destination,指向出口网关,并根据需要调整其权重
              host: asm-egressgateway.istio-system.svc.cluster.local # 假设您的ASM出口网关叫asm-egressgateway
              port:
                number: 80
            weight: 1

      在此YAML中,发往edition.cnn.com的流量将按照99 : 1的比例分别路由到Istio IngressgatewayASM Egressgateway。您可以根据需要逐步调整此比例,直到全部流量被迁移到ASM出口网关。您可以通过Istio出口网关的访问日志来确定是否仍有流量经过Istio的出口网关。

步骤四:完成迁移

请确保以下工作全部完成后,再进入迁移的下一个阶段。

  • 所有Istio Sidecar已经完全删除。

  • 所有Istio 东西向网关、入口网关、出口网关均已无流量经过。

  • 所有Istio API配置已经导入ASM。

  • 已经注入ASM网格代理的工作负载行为符合预期。

确认无误后,您可以通过对应版本的istioctl命令完成对集群中Istio的卸载:

说明

不同版本的istioctl存在差别,请您务必使用已安装版本对应的istioctl工具进行卸载,以免出现漏删、误删。

$ istioctl --kubeconfig=${K8s集群kubeconfig文件路径} uninstall --purge

卸载完成后,切换状态到Finished。若切换不成功,请按照status.message的提示信息清理Istio的残余资源,并将spec.retryCounter的值+1进行重试,直到status.state显示为Finished状态。至此,迁移全部结束。