迁移多集群网格

跨越多个集群的网格遵循与单集群网格相同的阶段。本节介绍每个阶段新增的内容,以及迁移集群的顺序。

请先阅读迁移单集群网格:其中的每个步骤都适用于网格中的每个集群,本节中的页面仅介绍其中的差异。

如何迁移集群

  • global 集群负责编排网格。其步骤——冻结 Mesh v1 控制器、删除网格资源、卸载插件——只运行一次,并涵盖所有集群。
  • 迁移单集群网格中的其他每条命令都针对相应集群运行一次,每个集群各运行一次。
  • 迁移顺序中有两个固定节点。在任何集群的第一个工作负载迁移之前,每个集群都必须拥有其 Mesh v2 控制平面;在多网络网格中,还必须拥有其 Mesh v2 东西向网关。并且,在任何集群上停用 Mesh v1 之前,每个集群都必须通过 Mesh v2 提供其工作负载和网关。在这两个节点之间,集群会逐个迁移,以便已迁移的工作负载在另一端始终能找到同一代的控制平面和网关。
  • 证书颁发机构是共享的:每个集群都有一个由同一个根证书签署的中间证书。Mesh v2 会重新使用每个集群的 cacerts secret,因此在整个迁移过程中,各集群之间的工作负载证书始终相互信任。
  • 允许每个控制平面读取其他集群的远程 secret 会原样复用。Mesh v2 会通过标签发现这些 secret,与 Mesh v1 完全相同。
  • 网格的自定义配置按集群收集,并按每个集群的 Mesh v2 方式表示,请参阅收集自定义 Istio 配置。同一网格中的集群很少具有完全相同的控制平面设置。

跨集群探针

本页和下面两个页面中的检查都会从一个工作负载调用网格中的某个服务,并使用相同的变量命名该服务。请将这些变量设置为一个在两个集群中都拥有 Pod 的服务,并在整个迁移过程中保留这些值。将 <namespace-they-run-in>、<deployment-that-makes-the-call>、<its-application-container>、<service-it-calls> 和 <port-of-that-service> 替换为你自己的值:

export MESH_NAMESPACE=<namespace-they-run-in>
export CLIENT=<deployment-that-makes-the-call>
export APP_CONTAINER=<its-application-container>
export TARGET_APP=<service-it-calls>
export TARGET_SERVICE="${TARGET_APP}.${MESH_NAMESPACE}.svc.cluster.local"
export APP_PORT=<port-of-that-service>

该服务会被命名两次,这是有意为之。TARGET_APP 是它的短名称,其 EndpointSlice 就是使用该短名称标记的;TARGET_SERVICE 是它的完全限定名称,服务的 Envoy 集群也以此名称命名。使用短名称提供的 proxy-config endpoint --cluster "outbound|${APP_PORT}||${TARGET_SERVICE}" 会输出其标头而不输出任何行——这与服务的跨集群端点已消失时的输出相同。请求可以使用任一形式。

APP_PORT 是服务的端口,而不是其 Pod 监听的端口。

确定网络拓扑

迁移步骤取决于集群是共享一个网络,还是每个集群使用一个网络。请在开始之前确定这一点。将 <context-of-the-first-cluster> 和 <context-of-the-second-cluster> 替换为你自己的值。

export CTX_CLUSTER1=<context-of-the-first-cluster>
export CTX_CLUSTER2=<context-of-the-second-cluster>
export V1_REVISION=1-22

for ctx in "${CTX_CLUSTER1}" "${CTX_CLUSTER2}"; do
  echo "== ${ctx}"
  kubectl --context "${ctx}" -n istio-system get istiooperators.install.istio.io -l '!asm.cpaas.io/component' -o json \
    | jq -r '.items[0] | "   meshID=\(.spec.values.global.meshID // "") network=\(.spec.values.global.network // "") clusterName=\(.spec.values.global.multiCluster.clusterName // "")"'
  echo "   east-west gateways:"
  kubectl --context "${ctx}" -n istio-system get svc -l topology.istio.io/network --no-headers 2>/dev/null \
    | awk '{print "     " $1, $2, $4}'
done

示例输出

== cluster-1
   meshID=mesh-1 network=mesh-1-a1b2c clusterName=cluster-1
   east-west gateways:
     istio-eastwestgateway LoadBalancer 10.0.0.10
== cluster-2
   meshID=mesh-1 network=mesh-1-d3e4f clusterName=cluster-2
   east-west gateways:
     istio-eastwestgateway LoadBalancer 10.0.0.20
你看到的内容拓扑后续操作
每个集群有不同的 network,并且每个集群都有一个东西向网关多网络迁移多网络网格
所有集群上的 network 都相同,或者完全没有 network,并且没有东西向网关单网络迁移单网络网格

如果一个集群的 Pod 可以直接访问另一个集群的 Pod,那么该网格就是单网络,即使 network 的值因意外而在各集群之间不同。在确定之前请先检查:

PEER=$(kubectl --context "${CTX_CLUSTER2}" -n "${MESH_NAMESPACE}" get endpointslices \
  -l "kubernetes.io/service-name=${TARGET_APP}" \
  -o jsonpath='{.items[0].endpoints[0].addresses[0]}:{.items[0].ports[0].port}')
kubectl --context "${CTX_CLUSTER1}" -n "${MESH_NAMESPACE}" exec "deploy/${CLIENT}" -c "${APP_CONTAINER}" -- \
  curl -s -o /dev/null -w '%{http_code}\n' --max-time 5 "http://${PEER}/"

地址和端口来自另一个集群中 TARGET_APP 的端点:Pod 的地址以及该 Pod 监听的端口。这是唯一使用 Pod 端口而不是 APP_PORT 的检查——在 服务 端口上向 Pod 地址发送请求时,无论哪种拓扑,sidecar 都会以 503 响应,因此无法提供任何信息。

结果拓扑
200单网络:另一个集群的 Pod 直接响应
503,或连接失败——000,以及 curl 返回退出代码 7多网络:该地址无法从此集群路由到

对本地集群中的 Pod 执行相同的命令,作为对照。它必须返回 200。如果没有,则表示该检查测量的是其他因素——错误的端口、不提供 HTTP 的工作负载,或拒绝调用的策略——其跨集群结果没有意义。

一次处理一个集群

CTX_CLUSTER1 和 CTX_CLUSTER2 用于标识网格中的两个集群,并在整个迁移过程中保持这些值不变。它们会出现在用于比较集群或同时对两个集群执行操作的命令中。

其他所有命令都只作用于一个集群,并将其命名为 ${CTX}。将其设置为你当前正在处理的集群,并在切换到下一个集群时再次设置:

export CTX="${CTX_CLUSTER1}"
kubectl config get-contexts "${CTX}"

不包含 --context 的命令会针对 kubeconfig 当前选定的上下文运行,而在多集群迁移期间,该上下文很少是你想要操作的集群。本节中的每条命令都会显式传递该参数。

迁移单集群网格中的命令不会这样做:它们会作用于 kubeconfig 当前选定的集群。在为某个集群运行其中一个页面的命令前,先选择 ${CTX},切换到下一个集群时再重新选择:

kubectl config use-context "${CTX}"
kubectl config current-context

选定的上下文存储在 kubeconfig 文件中,因此读取该文件的每个 shell 都会共享该上下文——当你处理另一个集群时,持续运行的流量探针或检查会跟随上下文切换,并报告错误集群的结果。如果两个集群的步骤同时运行,请为每个集群分别提供一份 kubeconfig 副本,在 kubectl config view --flatten --raw > "${HOME}/.kube/${CTX}" 中选择该集群的上下文,并将 KUBECONFIG 指向 shell 所操作集群对应的副本。