停用 Mesh v1

迁移的阶段 5。手动移除 Mesh v1,且顺序确保 Mesh v2 控制平面、网关服务和证书不受影响。

切勿从平台 UI 删除 Mesh v1

创建 Mesh v2 Istio 资源后,切勿从平台 UI 删除 Mesh v1 服务网格,也切勿删除 ServiceMesh 资源并将清理工作交给 Mesh v1 控制器。 Mesh v1 的删除流程会删除整个 istio-system 命名空间,包括运行在其中的 Mesh v2 控制平面。请按照本页中的手动操作步骤执行。

此阶段无法回滚

直到阶段 4为止,每个步骤都可以撤销。移除 Mesh v1 控制平面后,若要回退,则意味着需要根据回滚迁移中的说明,从备份重新安装 Mesh v1。在下面的检查清单通过之前,请勿开始此阶段。

开始之前

此阶段会删除用于派生 shell 变量的资源,并在之后继续使用这些变量。请从阶段 0中写入的文件加载这些变量,而不是再次派生:

source "${BACKUP_DIR}/vars.env"
echo "${V1_REVISION} ${V2_REVISION} ${MESH_GROUP} ${CLUSTER_NAMES}"

任何值都不得为空。使用空的 V1_REVISION 运行步骤时,不会删除任何内容,也不会报告错误,并会使网格处于部分清理状态。

该文件包含描述网格的信息。单个步骤要操作的对象不在其中,也不应放入其中:MESH_NAMESPACE 和 WORKLOAD 指定一个工作负载,GATEWAY_NAMESPACE 和 GATEWAY_NAME 指定一个网关,此阶段及其验证步骤都会使用这些变量。请按照阶段 3和阶段 4中的方式,对每个要检查的对象重新设置这些变量。将它们留空比设置错误更糟糕:kubectl -n "" 不会失败,而是回退到 kubeconfig 选择的任意命名空间,并报告在那里未找到任何内容,看起来就像检查已通过一样。

Mesh v1 未为任何工作负载提供服务

kubectl get pod -A -o json | jq -r --arg rev "${V1_REVISION}" '.items[]
  | select((.metadata.annotations["sidecar.istio.io/status"] // "") | test("\"revision\":\"" + $rev + "\""))
  | "\(.metadata.namespace)/\(.metadata.name)"'

预期输出:无输出,但已缩放到零的 Mesh v1 网关 pod 除外。

Mesh v1 pod 设置已持久化

for ns in $(kubectl get ns -l "istio.io/rev=${V2_REVISION}" -o jsonpath='{.items[*].metadata.name}'); do
  kubectl -n "${ns}" get deploy -o json > /tmp/deploy.json
  kubectl -n "${ns}" get pod -o json | jq -r --slurpfile d /tmp/deploy.json '
    [.items[] | select(.metadata.annotations["sidecar.istio.io/status"] != null) | .metadata.labels] as $pods
    | $d[0].items[]
    | . as $dep
    | select(any($pods[]; . as $l | ($dep.spec.selector.matchLabels // {}) | to_entries | all(.value == $l[.key])))
    | select(((.spec.template.metadata.annotations // {})["sidecar.istio.io/inject"]
              // (.spec.template.metadata.labels // {})["sidecar.istio.io/inject"] // "") != "true")
    | "\(.metadata.namespace)/\(.metadata.name)"'
done

预期输出:无输出。此处列出的工作负载当前具有 sidecar,但其模板中没有注入设置,因此下次重启时会丢失 sidecar。请返回迁移工作负载。

其余检查清单

  • 每个网关都由其 Mesh v2 部署提供服务,并且 Mesh v1 网关已缩放到零。
  • 准备迁移中的备份已完成且可访问,尤其是网关服务、网关证书和 ${BACKUP_DIR}/asm-owned-resources.txt。
  • 探针正在运行且未报告任何故障。
  • 应用所有者已知晓:从此阶段开始,直到阶段 6结束,跟踪流水线将会中断。

从 global 集群中移除 mesh

删除 Mesh v1 admission webhooks

Mesh v1 controller 的 webhooks 使用 failurePolicy: Fail。先删除它们,这样 controller 缩容后,请求就不会被拒绝。

kubectl --context "${GLOBAL_CONTEXT}" delete mutatingwebhookconfiguration \
  servicemesh-v1alpha1-mutation servicemeshgroup-v1alpha1-mutation --ignore-not-found
kubectl --context "${GLOBAL_CONTEXT}" delete validatingwebhookconfiguration \
  global-asm-controller-validating-webhook-configuration --ignore-not-found

停止 Mesh v1 orchestration controller

kubectl --context "${GLOBAL_CONTEXT}" -n cpaas-system scale deploy global-asm-controller --replicas=0
kubectl --context "${GLOBAL_CONTEXT}" -n cpaas-system get deploy global-asm-controller -o jsonpath='{.spec.replicas}{"\n"}'

继续之前,输出必须为 0。

不要再次启动 controller

删除 ServiceMesh 资源时,controller 会删除 istio-system 命名空间。资源带有删除时间戳后,再次启动 controller 会执行该流程。如果需要恢复平台资源,请改为从备份中恢复。

删除 mesh 资源

for cn in ${CLUSTER_NAMES}; do
  kubectl --context "${GLOBAL_CONTEXT}" -n cpaas-system delete servicemeshs.asm.alauda.io "${cn}" --wait=false
  kubectl --context "${GLOBAL_CONTEXT}" -n cpaas-system patch servicemeshs.asm.alauda.io "${cn}" \
    --type=json -p='[{"op":"remove","path":"/metadata/finalizers"}]' 2>/dev/null || true
done

kubectl --context "${GLOBAL_CONTEXT}" -n cpaas-system delete servicemeshgroups.asm.alauda.io "${MESH_GROUP}" --wait=false
kubectl --context "${GLOBAL_CONTEXT}" -n cpaas-system patch servicemeshgroups.asm.alauda.io "${MESH_GROUP}" \
  --type=json -p='[{"op":"remove","path":"/metadata/finalizers"}]' 2>/dev/null || true

CLUSTER_NAMES 包含此 mesh 的每个集群 — 对于单集群 mesh,则包含一个名称 — 而 MESH_GROUP 是将这些集群关联在一起的组。一个平台可以托管多个 mesh:删除属于其他 mesh 的 ServiceMesh 或 ServiceMeshGroup 会销毁该 mesh。

验证资源已删除,并且集群的 mesh 命名空间仍然存在:

for cn in ${CLUSTER_NAMES}; do
  kubectl --context "${GLOBAL_CONTEXT}" -n cpaas-system get servicemeshs.asm.alauda.io "${cn}" 2>&1 | tail -1
done
kubectl --context "${GLOBAL_CONTEXT}" -n cpaas-system get servicemeshgroups.asm.alauda.io "${MESH_GROUP}" 2>&1 | tail -1
kubectl --context "${GLOBAL_CONTEXT}" -n cpaas-system get servicemeshs.asm.alauda.io,servicemeshgroups.asm.alauda.io
kubectl get ns istio-system -o jsonpath='{.metadata.name} {.status.phase}{"\n"}'

预期结果:此 mesh 的每个资源均为 NotFound,mesh 集群上为 istio-system Active。最后一个列表显示 global 集群上剩余的内容:尚未迁移的 mesh。只有当这是平台上的最后一个 Mesh v1 mesh 时,列表才为空。

卸载 Alauda Service Mesh Essentials 插件

该插件为平台上的每个 Mesh v1 mesh 提供服务,因此此处的操作取决于是否还有 mesh。列出它们 — 要迁移的 mesh 已经消失,其资源已在上一步删除:

kubectl --context "${GLOBAL_CONTEXT}" -n cpaas-system get servicemeshs.asm.alauda.io

然后按照与输出匹配的情况操作。

情况 1 — 列表为空:这是平台上的最后一个 Mesh v1 mesh。卸载插件。

从 Web 控制台中将其删除:在 global 集群上依次选择 Marketplace → Cluster Plugins → Alauda Service Mesh Essentials → Uninstall。

在命令行中,通过删除记录其已安装状态的 ModuleInfo 来卸载集群插件。先将其列出 — CLUSTER 列显示条目所针对的集群,global 表示此插件所针对的集群:

kubectl --context "${GLOBAL_CONTEXT}" get moduleinfoes.cluster.alauda.io -l cpaas.io/module-name=asm-global
kubectl --context "${GLOBAL_CONTEXT}" delete moduleinfoes.cluster.alauda.io -l cpaas.io/module-name=asm-global

插件组件会异步删除,在 ModuleInfo 消失约一分钟后才会移除。继续之前,请检查它们是否已删除:

kubectl --context "${GLOBAL_CONTEXT}" -n cpaas-system get deploy | grep -E 'asm|hermes' || echo "no Mesh v1 components left"

情况 2 — 列表显示其他 mesh:它们仍由插件提供服务。保留插件,并将 global 集群恢复为原来的状态。

跳过情况 1 中的命令,并撤销本节的前两个步骤,即恢复 admission webhooks 和这些 mesh 所使用的 orchestration controller:

kubectl --context "${GLOBAL_CONTEXT}" apply -f "${BACKUP_DIR}/global-webhooks.yaml"
kubectl --context "${GLOBAL_CONTEXT}" -n cpaas-system scale deploy global-asm-controller --replicas=1

其他 mesh 会继续受到管理。对于已迁移的集群,controller 在其插件记录后方找不到 ServiceMesh 资源,并且在记录被清除之前,每隔几秒为每个集群记录一条错误日志。

在两种情况下,已迁移集群的插件记录都会保留在 global 集群上。清除 Mesh v1 插件记录会在此阶段结束时将其删除。

从 mesh 集群中移除 Mesh v1

删除 Mesh v1 admission webhooks

kubectl get mutatingwebhookconfigurations,validatingwebhookconfigurations -o name \
  | grep -E 'asm|gatewaydeploy|microservice' \
  | xargs -r kubectl delete

此操作会删除多个 webhook,包括向 pod 添加 sidecar 设置的 webhook,以及添加 OpenTelemetry 注入注解的 webhook。从现在开始,只有工作负载模板中写入的内容才会应用到其 pod。

停止 Mesh v1 controller

kubectl -n cpaas-system scale deploy asm-controller --replicas=0

保留 Mesh v1 所有的资源

Kubernetes 会连同所有者一起删除资源,除非先移除所有者引用。阶段 0中的 ${BACKUP_DIR}/asm-owned-resources.txt 列出了 Mesh v1 在此集群中所有的资源。检查该列表,并删除你不想保留的行:

列表中的内容是否保留?
你迁移的每个 gateway 的 gateway Service是。删除它会立即中断流量:它是 Mesh v2 gateway pod 所在的服务
由 MicroService 或 GatewayDeploy 所有的 Telemetry 资源否。它们通过只有 Mesh v1 才会设置的标签选择 pod,因此 Mesh v1 消失后会立即停止匹配任何内容。阶段 3和阶段 4已经创建了替代资源
由 ApiAttribute 所有的 EnvoyFilter 资源,以及由 Mesh v1 功能生成但 Mesh v2 不提供的其他任何资源否。保留它们后,它们会成为不再生效的配置

Gateway 证书通常不在列表中:它们不携带所有者引用,会自行留在此阶段。阶段 4已将每个证书复制到其 gateway 的命名空间中,这是 Mesh v2 gateway 读取证书的位置,因此无论如何,迁移后的 gateway 都不再依赖 istio-system 中的原始证书。

在运行下面的命令之前编辑该文件:命令会解除它找到的每一行的关联。保留在文件中的行会永久保留——后续步骤都不会删除它们,并且清理剩余内容仅处理 Telemetry 资源。以这种方式保留下来的 Mesh v1 功能的 EnvoyFilter 是不会应用于任何对象且无人所有的配置。

while read -r kind ns name owner; do
  [ -z "${name}" ] && continue
  keep=$(kubectl -n "${ns}" get "${kind}" "${name}" -o json \
    | jq -c '[.metadata.ownerReferences[]? | select((.apiVersion | test("asm\\.alauda\\.io")) | not)]')
  kubectl -n "${ns}" patch "${kind}" "${name}" --type=merge \
    -p "{\"metadata\":{\"ownerReferences\":${keep}}}" >/dev/null 2>&1
  left=$(kubectl -n "${ns}" get "${kind}" "${name}" \
    -o jsonpath='{range .metadata.ownerReferences[*]}{.apiVersion}/{.kind} {end}')
  echo "${kind} ${ns}/${name} ownerReferences=${left:-none}"
done < "${BACKUP_DIR}/asm-owned-resources.txt"

这里只会移除 Mesh v1 的所有者。资源可能还有第二个合法所有者——你自己的 controller 或其他平台组件;同时解除该所有者的关联会使资源无人管理,并改变迁移后的管理方式。

检查结果,不要相信补丁

报告成功的 patch 仍可能被仍在运行的 controller 恢复。该命令会打印剩余的所有者引用:继续之前,不得再有任何行命名 asm.alauda.io 所有者。

删除 Mesh v1 custom resources

for crd in $(kubectl get crd -o name | sed 's|.*/||' | grep -E '\.asm\.alauda\.io$'); do
  kubectl delete "${crd}" --all -A --wait=false 2>/dev/null
done
for crd in $(kubectl get crd -o name | sed 's|.*/||' | grep -E '\.asm\.alauda\.io$'); do
  kubectl get "${crd}" -A -o json | jq -r '.items[] | "\(.metadata.namespace) \(.metadata.name)"' \
    | while read -r ns name; do
        [ -z "${name}" ] && continue
        kubectl -n "${ns}" patch "${crd}" "${name}" --type=merge -p '{"metadata":{"finalizers":[]}}' 2>/dev/null
      done
done

然后立即检查你解除关联的资源是否仍然存在:

while read -r kind ns name owner; do
  [ -z "${name}" ] && continue
  kubectl -n "${ns}" get "${kind}" "${name}" -o name || echo "MISSING ${kind} ${ns}/${name}"
done < "${BACKUP_DIR}/asm-owned-resources.txt"

缺失的 gateway 服务会立即中断流量。如果发生这种情况,请使用准备迁移中的函数重新创建它——直接应用该文件会重新创建已不存在的 Mesh v1 资源的所有者引用,而该服务会在几秒内再次被删除:

restore_from_backup "${BACKUP_DIR}/gateway-svc-${GATEWAY_NAMESPACE}-${GATEWAY_NAME}.yaml"
kubectl -n "${GATEWAY_NAMESPACE}" get endpointslices -l "kubernetes.io/service-name=${GATEWAY_NAME}"

删除 Mesh v1 安装资源

kubectl delete asms.operator.alauda.io asm --wait=false
kubectl patch asms.operator.alauda.io asm --type=merge -p '{"metadata":{"finalizers":[]}}'
kubectl delete flaggers.operator.alauda.io --all -A --wait=false 2>/dev/null

删除 asm 资源时会运行卸载前检查,统计带有 sidecar 的 pod 数量。由于 Mesh v2 现在会注入这些 pod,该检查永远不会通过,删除操作会被阻塞——移除 finalizer 是解决方法。Mesh v1 operator 随后会删除它安装的组件:controller、collectors、tracing backend 和平台 webhooks。

接管指标采集

Mesh v1 monitors 归安装资源所有,并会随其一起删除。从此刻起,将没有任何对象采集 gateway 和控制平面的指标,因此请立即执行此步骤:它会等待 Mesh v1 monitors 消失,然后解除阶段 1对 Mesh v2 PodMonitor 施加的限制。

while kubectl -n istio-system get podmonitor sidecar-monitor >/dev/null 2>&1 \
  || kubectl -n istio-system get servicemonitor istio-monitor >/dev/null 2>&1; do sleep 5; done
kubectl -n istio-system get podmonitor istio-proxies-monitor -o json \
  | jq '.spec.podMetricsEndpoints[0].relabelings |= map(select(.sourceLabels != ["__meta_kubernetes_pod_container_init"]))' \
  | kubectl replace -f -

然后创建Metrics and Service Mesh的 ServiceMonitor 资源。现在,Mesh v2 资源会采集每个 proxy(包括 gateway)以及控制平面的指标。

替换 mesh 范围的 telemetry 配置

Mesh v1 会在 istio-system 中安装 mesh 范围的 Telemetry 资源,两个控制平面都会读取该资源。该资源由 Mesh v1 控制平面渲染,并会在控制平面删除后继续存在,从而继续配置已失效的 provider。请将其替换为 asm-default,即 Mesh v2 mesh 的 mesh 范围资源——这是Metrics and Service Mesh创建的资源,也是其余 Mesh v2 文档使用的资源:

kubectl -n istio-system get telemetries.telemetry.istio.io -o yaml > "${BACKUP_DIR}/telemetry-istio-system.yaml"
kubectl -n istio-system get telemetries.telemetry.istio.io -l install.operator.istio.io/owning-resource -o name \
  | xargs -r kubectl -n istio-system delete
cat <<EOF | kubectl apply -f -
apiVersion: telemetry.istio.io/v1
kind: Telemetry
metadata:
  name: asm-default
  namespace: istio-system
spec:
  metrics:
    - providers:
        - name: prometheus
      overrides:
        - tagOverrides:
            mesh_id:
              value: xds.node.metadata['MESH_ID']
  tracing:
    - providers:
        - name: zipkin
      randomSamplingPercentage: ${V1_TRACE_SAMPLING}
EOF
  1. 保留 Mesh v1 配置中的 provider 名称,直到阶段 6将其指向新的 collector。迁移 observability stack会同时替换 provider 和此值。

  2. V1_TRACE_SAMPLING 是阶段 0中记录的采样百分比,traceSampling 位于 ${BACKUP_DIR}/v1-mesh-settings.json 中。从这里开始,决定 mesh 追踪量的是此资源,而不是控制平面设置。

  3. mesh_id 标签是 Kiali 用于筛选 mesh 指标的标签。在应用资源且工作负载处理过请求后,在某个 proxy 上检查该标签:

    kubectl -n "${MESH_NAMESPACE}" exec "deploy/${WORKLOAD}" -c istio-proxy -- \
      pilot-agent request GET stats/prometheus \
      | grep '^istio_requests_total' | grep -o 'mesh_id="[^"]*"' | sort -u

    输出为 mesh_id="${MESH_ID}"。显示为 mesh_id="unknown" 的标签表示表达式未解析。proxy 还会保留资源应用前已有的计数器,并将它们存储在之前的标签集下,因此不包含 mesh_id 的序列本身并不表示失败——只有持续增长的序列才反映当前配置。

卸载 Mesh v1 operators

kubectl -n istio-system get subscriptions.operators.coreos.com -o json | jq -r '.items[]
  | select(.spec.name | test("^(asm-operator|flagger-operator|jaeger-operator|opentelemetry-operator)$"))
  | "\(.metadata.name) \(.status.installedCSV // "")"' \
  | while read -r sub csv; do
      kubectl -n istio-system delete subscriptions.operators.coreos.com "${sub}" --ignore-not-found
      [ -n "${csv}" ] && kubectl -n istio-system delete clusterserviceversions.operators.coreos.com "${csv}" --ignore-not-found
    done

其中一些资源可能已经不存在:上一步移除 Mesh v1 安装资源时,会一并删除它安装的组件以及集群中的 Mesh v1 operator。

该筛选条件只匹配 Mesh v1 软件包。Mesh v2 软件包——servicemesh-operator2、kiali-operator 和 opentelemetry-operator2——名称不同,不会受到影响。

删除 Mesh v1 控制平面

先删除 gateway 资源,然后删除控制平面,最后删除 operator。删除 gateway 和控制平面资源时,会等待 Mesh v1 operator 删除它们所管理的内容,因此命令可能需要几分钟才能返回。请让它运行完成:operator 必须先处理这些删除操作,命令的最后几行才会将其删除。

kubectl -n istio-system get istiooperators.install.istio.io -l 'asm.cpaas.io/component=gateway' -o name \
  | xargs -r kubectl -n istio-system delete --timeout=120s

kubectl get deploy -A -l 'install.operator.istio.io/owning-resource' -o json | jq -r '.items[]
  | select(.metadata.labels["istio.io/rev"] == env.V1_REVISION)
  | "\(.metadata.namespace) \(.metadata.name)"' \
  | while read -r ns name; do kubectl -n "${ns}" delete deploy "${name}" --ignore-not-found; done
kubectl -n istio-system delete istiooperators.install.istio.io "${V1_CONTROL_PLANE_IOP}" --timeout=300s

export V1_OPERATOR=$(kubectl -n istio-system get deploy -o name | sed 's|.*/||' | grep '^istio-operator' | head -1)
kubectl -n istio-system delete deploy "${V1_OPERATOR}" --ignore-not-found
kubectl -n istio-system delete sa "${V1_OPERATOR}" --ignore-not-found
kubectl delete clusterrole "${V1_OPERATOR}" --ignore-not-found
kubectl delete clusterrolebinding "${V1_OPERATOR}" --ignore-not-found

删除控制平面资源会移除 Mesh v1 istiod、其管理的 gateway 以及其 revision webhooks。随后删除 operator 会移除负责协调这些资源的组件。

删除 gateway 资源通常会连同其 deployment 一起删除,因为 operator 在处理自身 finalizer 时会清理它管理的内容。上述循环会删除任何残留的 deployment。

该循环还会删除 Mesh v1 控制平面自行部署的 gateway,即 istio-system 中的 istio-ingressgateway,因为它携带控制平面的 revision。阶段 4中已经确定了是否有任何 Gateway 资源通过它路由流量。

NOTE

--cascade=orphan 不会保护 Mesh v1 gateway 资源所管理的资源:operator 会在自身 finalizer 中清理这些资源。这就是为什么之前要解除 gateway 服务与其所有者的关联,以及为什么要在阶段 4中将证书复制到 gateway 命名空间。

清理剩余内容

kubectl delete mutatingwebhookconfiguration "istio-revision-tag-default" "istio-sidecar-injector-${V1_REVISION}" --ignore-not-found
kubectl delete validatingwebhookconfiguration "istiod-default-validator" "istio-validator-${V1_REVISION}-istio-system" --ignore-not-found

for ns in $(kubectl get ns -l cpaas.io/serviceMesh=enabled -o jsonpath='{.items[*].metadata.name}'); do
  kubectl label ns "${ns}" cpaas.io/serviceMesh-
done
for ns in $(kubectl get ns -l "istio.io/rev=${V1_REVISION}" -o jsonpath='{.items[*].metadata.name}'); do
  kubectl label ns "${ns}" istio.io/rev-
done

for crd in $(kubectl get crd -o name | sed 's|.*/||' | grep -E '\.istio\.io$'); do
  kubectl get "${crd}" -A -l 'install.operator.istio.io/owning-resource' -o name 2>/dev/null
done

最后一个循环会列出由 Mesh v1 控制平面渲染、但不会随控制平面一起删除的 Istio 资源。删除它输出的资源。

然后删除仍然存在的 Mesh v1 Telemetry 资源。是否有所有者在此阶段早些时候删除了这些资源,取决于 mesh 的创建方式;仍然存在的资源会选择一个标签——msname 或 asm.cpaas.io/owning-resource——而任何 pod 都不再携带这些标签:

kubectl get telemetries.telemetry.istio.io -A -o json | jq -r '.items[]
  | select((.spec.selector.matchLabels // {}) | keys | any(. == "msname" or . == "asm.cpaas.io/owning-resource"))
  | "\(.metadata.namespace) \(.metadata.name)"' \
  | while read -r ns name; do kubectl -n "${ns}" delete telemetry "${name}"; done

阶段 3和阶段 4中创建的替代资源选择的是工作负载模板所携带的标签,因此不会被此命令匹配。

两个 API 的 custom resource definitions 都会保留:保留 asm.alauda.io 是因为空的定义不会造成影响,而移除它会销毁任何遗留资源;保留 *.istio.io 是因为现在由 Mesh v2 所有。

清除 Mesh v1 插件记录

在 Mesh v1 已从该 mesh 的每个集群中移除后,在 global 集群上执行一次。

Mesh v1 mesh 的每个集群在 global 集群上都有两条记录,用于说明其上安装了哪些 Mesh v1 模块:asm 和 istio。编排控制器会随 mesh 一起创建这些记录,并随 mesh 一起删除,但在删除 mesh 资源时,编排控制器已缩放为零,因此这些记录会遗留下来。两条记录都带有 mesh 组的名称:

kubectl --context "${GLOBAL_CONTEXT}" get moduleinfoes.cluster.alauda.io -l "asm.cpaas.io/meshgroup=${MESH_GROUP}"

选择器用于将平台中的其他 mesh 排除在列表之外:它们的集群仍在运行 Mesh v1,其条目也不是陈旧条目。命令输出的所有内容都属于你迁移的 mesh,其背后的组件已在本页前文手动移除。

删除这些记录。Web 控制台不会在集群插件中列出这两条记录,因此只能使用命令行:

kubectl --context "${GLOBAL_CONTEXT}" delete moduleinfoes.cluster.alauda.io -l "asm.cpaas.io/meshgroup=${MESH_GROUP}"
仅适用于 Mesh v1 已移除的集群

删除其中一条记录就是平台从该集群卸载插件的方式。在仍运行 Mesh v1 的集群上,平台会按其选择的顺序处理卸载——而这正是本页中的手动操作步骤所替代的内容。

如果你为另一个 mesh 恢复了 global-asm-controller,这同样会阻止它重新调谐你迁移的 mesh。之后其日志会报告 0:

if kubectl --context "${GLOBAL_CONTEXT}" -n cpaas-system get deploy global-asm-controller >/dev/null 2>&1; then
  kubectl --context "${GLOBAL_CONTEXT}" -n cpaas-system logs deploy/global-asm-controller --since=60s \
    | grep -c "not found" || true
else
  echo "no controller: the plugin was uninstalled with the last mesh"
fi

只有仍有另一个 Mesh v1 mesh 的平台上才会存在该控制器。如果你卸载了插件,它也会随之被卸载,此时命令会对此进行说明,而不是失败。

验证

for crd in $(kubectl get crd -o name | sed 's|.*/||' | grep -E '\.asm\.alauda\.io$'); do
  printf '%s: ' "${crd}"; kubectl get "${crd}" -A --no-headers 2>/dev/null | wc -l
done
kubectl -n istio-system get deploy
kubectl --context "${GLOBAL_CONTEXT}" -n cpaas-system get deploy | grep -E 'asm|hermes' || echo "no Mesh v1 components on the global cluster"
  • 每种 Mesh v1 资源类型都报告 0。
  • istio-system 包含 Mesh v2 控制平面和 Kiali,不包含任何 Mesh v1 内容。
  • 在 global 集群上:如果这是平台上的最后一个 Mesh v1 mesh,则不应有任何 Mesh v1 组件。如果还剩有其他 mesh,则插件和 global-asm-controller 会保留;被移除的是你迁移的 mesh 的 ServiceMesh 和 ServiceMeshGroup 资源以及该 mesh 的插件记录。
  • 你保留的网关服务、网关证书和遥测资源仍然存在。
  • Kiali 仍会显示网关和工作负载的流量:Mesh v2 监控器已接管监控。
  • 探针报告没有失败。从这里开始,直到阶段 6结束,追踪会中断。

列出已保留的资源:

kubectl -n "${GATEWAY_NAMESPACE}" get svc,secret,telemetry
kubectl get telemetries.telemetry.istio.io -A

继续执行完成迁移。

多集群 mesh

对于跨越多个集群的 mesh,global 集群上的步骤只需运行一次,便会覆盖该 mesh 的所有集群;而 mesh 集群上的步骤则需针对每个集群运行。清除 Mesh v1 插件记录 又是一个 global 步骤,在该 mesh 的最后一个集群完成后运行一次。在每个集群上删除控制平面之前,还需要执行一个额外步骤,参见迁移多集群 mesh。