适用于 Azure Kubernetes 服务的开源 Istio 到基于 Istio 的服务网格加载项的迁移指南

本文提供有关将现有 开源 (OSS) Istio 安装迁移到 Azure Kubernetes 服务(AKS)的基于 Istio 的服务网格加载项的指导。 采用 AKS Istio 加载项可以简化作,提供 Azure 集成,并简化 Istio 升级和管理。

建议使用“Canary 群集迁移”策略。 此方法涉及设置启用了 Istio 加载项的新 AKS 群集,逐步迁移工作负载和配置,然后在删除旧群集之前切换流量。 此方法允许在隔离环境中进行彻底测试,从而最大程度地降低风险。

重要

本文提供一般指南。 它并不旨在详尽地涵盖所有迁移方案。

先决条件

在开始之前,请检查 Istio 加载项限制网格配置允许列表 ,以确定设置是否使用 Istio 加载项不支持或阻止的任何功能。 若要迁移,需要在目标群集的配置中禁用此类功能。 之后,请确保满足以下要求:

  • 已安装 Azure CLI 2.57.0 或更高版本。 可以运行 az --version 来验证版本。 若要安装或升级,请参阅 安装 Azure CLI
  • 运行开放源代码 Istio 的现有 AKS 群集,它将是“源群集”。源群集中的 Istio 版本必须是 AKS 中受支持的 Istio 修订版。 阅读 这些步骤 以查看版本是否受支持。
  • 工作负荷部署清单(部署、服务等的 YAML 文件)。 本指南以 bookinfo 应用程序 为例。
  • 现有的 Istio 自定义资源配置(适用于VirtualServicesDestinationRulesGatewaysAuthorizationPolicies等的 YAML 文件)。 本指南使用 bookinfo 示例目标规则
  • 熟悉 Istio 概念和应用程序体系结构。

迁移步骤

Canary 群集迁移涉及以下关键阶段:

  1. 预配新的 AKS 群集:创建启用了 Istio 服务网格加载项的新 AKS 群集。 这是你的“目标群集”。
  2. 迁移工作负载和配置:调整现有 Istio 配置并将其应用到新群集,例如VirtualServicesGateways,和工作负载。
  3. 全面测试:验证应用程序在新 Istio 网格中是否正常运行。
  4. 转移流量:更新负载均衡器配置,以将流量定向到在新群集上运行的应用程序。
  5. 删除旧群集:新群集稳定并处理生产流量后,请删除旧群集。

设置环境变量。

export SOURCE_CLUSTER=<source-cluster-name>
export TARGET_CLUSTER=<target-cluster-name>
export TARGET_RESOURCE_GROUP=<resource-group-name>
export LOCATION=<location>

设置源群集

为了说明目的,让我们使用要迁移的示例工作负荷设置源群集。 如果已有要迁移工作负载的群集,请跳过此步骤。

# Install Istio
istioctl install -y --context $SOURCE_CLUSTER

# Enable sidecar injection for the default namespace
kubectl label --context $SOURCE_CLUSTER namespace default istio-injection=enabled

# Install the bookinfo application
kubectl apply --context $SOURCE_CLUSTER -f https://raw.githubusercontent.com/istio/istio/release-1.26/samples/bookinfo/platform/kube/bookinfo.yaml

# Create some sample Destination Rules
kubectl apply --context $SOURCE_CLUSTER -f https://raw.githubusercontent.com/istio/istio/release-1.26/samples/bookinfo/networking/destination-rule-all.yaml

# Enable the external ingress gateway
kubectl apply --context $SOURCE_CLUSTER -f https://raw.githubusercontent.com/istio/istio/release-1.26/samples/bookinfo/networking/bookinfo-gateway.yaml

为外部入口主机和端口设置环境变量:

export INGRESS_NS=<ingress-namespace>
export INGRESS_SVC=<ingress-service-name>
export SOURCE_INGRESS_HOST_EXTERNAL=$(kubectl --context $SOURCE_CLUSTER -n $INGRESS_NS get service $INGRESS_SVC -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
export SOURCE_INGRESS_PORT_EXTERNAL=$(kubectl --context $SOURCE_CLUSTER -n $INGRESS_NS get service $INGRESS_SVC -o jsonpath='{.spec.ports[?(@.name=="http2")].port}')
export SOURCE_GATEWAY_URL_EXTERNAL=$SOURCE_INGRESS_HOST_EXTERNAL:$SOURCE_INGRESS_PORT_EXTERNAL

检索源群集中安装的示例应用程序的外部地址:

echo $SOURCE_GATEWAY_URL_EXTERNAL

从上一命令的输出导航到 URL,并确认显示示例应用程序的产品页。 或者,还可以用于 curl 确认示例应用程序可访问。 例如:

curl -s "http://${SOURCE_GATEWAY_URL_EXTERNAL}/productpage" | grep -o "<title>.*</title>"

创建目标群集

按照以下步骤创建启用了 Istio 加载项的新 AKS 群集。 可以在源群集所在的同一资源组或不同的资源组中创建此群集。 在安装过程中,必须选择在源群集上安装的同一 Istio 修订版。 阅读 这些步骤 进行修订选择。 如果在源群集中使用以下任一 Istio 功能,请按照相应的指南在目标群集上配置功能:

  1. 网格配置
  2. 部署和保护入口网关
    • 对于安全入口网关的迁移,除了上述指南之外,还需要将以下服务器定义添加到网关:
      - hosts:
        - productpage.bookinfo.com
        port:
        name: http
        number: 80
        protocol: HTTP
      
      验证向目标群集的入口网关发出 HTTP 请求:
      curl "http://TARGET_GATEWAY_URL_EXTERNAL/productpage" | grep "<title>.*</title>"
      
      此配置还允许不安全的 HTTP 传入流量流向入口网关的 istio 入口网关,这是使用流量转移迁移流量时所需的。 迁移完成后,应删除此额外的服务器。
  3. 部署出口网关(预览版)
  4. 插件 CA 证书
    • 如果要设置自己的 CA 证书,则需要在群集中启用加载项的同时设置此证书。 有关详细信息,请阅读指南。

迁移工作负荷和配置

用于 az aks get-credentials 获取新群集的凭据:

az aks get-credentials -g $TARGET_RESOURCE_GROUP -n $TARGET_CLUSTER

在目标群集中安装工作负荷和 Istio 自定义资源配置:

export ASM_REVISION=asm-X-Y

# Enable sidecar injection for the default namespace. istio-injection labelling
# does not work in the Istio add-on
kubectl label --context $TARGET_CLUSTER namespace default istio.io/rev=$ASM_REVISION

# Install the bookinfo application
kubectl apply --context $TARGET_CLUSTER -f https://raw.githubusercontent.com/istio/istio/release-1.26/samples/bookinfo/platform/kube/bookinfo.yaml

# Install some demo Destination Rules
kubectl apply --context $TARGET_CLUSTER -f https://raw.githubusercontent.com/istio/istio/release-1.26/samples/bookinfo/networking/destination-rule-all.yaml

验证 Sidecar 注入是否成功,方法是确保所有容器都已准备好在应用程序 Pod(s)中,并检查 istio-proxy Pod(s)输出中的 kubectl describe 容器,例如:

kubectl describe pod --context $TARGET_CLUSTER -n default <pod-name>

注释

如何安装工作负荷和配置取决于基础结构设置。 可以使用 Velero 等工具从源群集从工作负荷进行备份,并将其应用于目标群集,也可以使用 GitOps 工具(如 Flux 或 Argo CD)。

测试 Istio 加载项

按照以下步骤在目标群集中启用外部 Istio 入口网关

为目标群集入口主机和端口设置环境变量

export TARGET_INGRESS_HOST_EXTERNAL=$(kubectl --context $TARGET_CLUSTER -n aks-istio-ingress get service aks-istio-ingressgateway-external -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
export TARGET_INGRESS_PORT_EXTERNAL=$(kubectl --context $TARGET_CLUSTER -n aks-istio-ingress get service aks-istio-ingressgateway-external -o jsonpath='{.spec.ports[?(@.name=="http2")].port}')
export TARGET_GATEWAY_URL_EXTERNAL=$TARGET_INGRESS_HOST_EXTERNAL:$TARGET_INGRESS_PORT_EXTERNAL

检索目标群集中安装的示例应用程序的外部地址:

echo $TARGET_GATEWAY_URL_EXTERNAL

从上一命令的输出导航到 URL,并确认显示示例应用程序的产品页。 或者,还可以用于 curl 确认示例应用程序可访问。 例如:

curl -s "http://${TARGET_GATEWAY_URL_EXTERNAL}/productpage" | grep -o "<title>.*</title>"

将流量迁移到目标群集

在源群集中添加 ServiceEntry 以在 Istio 的内部服务注册表中设置域以指向目标群集:

kubectl apply --context $SOURCE_CLUSTER -f - <<EOF
# This ServiceEntry instructs the mesh to direct HTTP requests from
# the mesh that target v2.example.com to the specified IP address.
apiVersion: networking.istio.io/v1
kind: ServiceEntry
metadata:
  name: target-cluster-http
spec:
  hosts:
  - v2.example.com
  location: MESH_EXTERNAL
  ports:
  - number: 80
    name: http
    protocol: HTTP
  resolution: STATIC
  endpoints:
  - address: $TARGET_INGRESS_HOST_EXTERNAL
EOF

安装 Istio 入口网关时,我们创建了一个 Istio 网关来访问它。 更新其 VirtualService,以拆分源群集与目标群集之间的流量。 建议从重定向到目标群集的少量请求开始:

kubectl apply --context $SOURCE_CLUSTER -f - <<EOF
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
  name: bookinfo
spec:
  hosts:
  - "*"
  gateways:
  - bookinfo-gateway
  http:
  - match:
    - uri:
        exact: /productpage
    - uri:
        prefix: /static
    - uri:
        exact: /login
    - uri:
        exact: /logout
    - uri:
        prefix: /api/v1/products
    route:
    - destination:
        port:
          number: 9080
        host: productpage # The name of the Service inside the cluster you're migrating away from.
      weight: 90
    - destination:
        port:
          number: 80
        host: v2.example.com # The temporary domain name of the frontend inside the cluster with managed ASM.
      weight: 10
EOF

验证请求的 90 个% 是否包括源群集中的 Pod 名称,其他 10 个% 包括目标群集中的 Pod 名称:

for i in {1..100}; do curl -s http://$SOURCE_INGRESS_HOST_EXTERNAL/productpage | awk '/Reviews served by/ {getline; print}' | uniq; done | sort | uniq -c | while read count pod; do ctx="unknown"; for c in $SOURCE_CLUSTER $TARGET_CLUSTER; do if kubectl --context=$c get pod $pod &>/dev/null; then ctx=$c; fi; done; echo "$ctx $count $pod"; done | sort | column -t

应会看到如下所示的输出:

$SOURCE_CLUSTER    14  reviews-v1-849f9bc5d6-vcd56
$SOURCE_CLUSTER    18  reviews-v3-6d5d98f5c4-ljcwj
$SOURCE_CLUSTER    20  reviews-v2-5c757d5846-s9fx9
$TARGET_CLUSTER    13  reviews-v3-6d5d98f5c4-pfv75
$TARGET_CLUSTER    14  reviews-v2-5c757d5846-p58wm
$TARGET_CLUSTER    21  reviews-v1-849f9bc5d6-mbs74

可以逐渐增加重定向到目标群集的请求百分比,直到源群集不再为任何请求提供服务。

删除源群集

对测试感到满意并将所有请求转移到目标群集后,即可删除源群集。 如果有 DNS 设置,请确保更新域以使用目标群集的 IP 地址。

概要

我们希望本演练提供了有关如何将用户管理的 Istio 安装迁移到 Azure Kubernetes 服务的基于 Istio 的服务网格加载项的指导。 尽管具体步骤可能取决于你的安装,但我们建议遵循此常规策略来执行迁移。