金丝雀升级

通过先运行一个金丝雀部署的新控制平面来完成 Istio 的升级,从而允许您在将所有流量迁移到新版本之前以一小部分工作负载监视升级的效果, 这比原地升级要安全得多,这也是推荐的升级方法。

安装 Istio 时,revision 安装设置可用于同时部署多个独立的控制平面。升级的金丝雀版本可以通过使用不同的 revision,在旧版本的旁边安装启动新版本的 Istio 控制平面。每个修订都是一个完整的 Istio 控制平面实现, 具有自己的 DeploymentService 等。

升级之前

在升级 Istio 之前,建议执行 istioctl x precheck 命令,以确保升级与您的环境兼容。

  1. $ istioctl x precheck
  2. No issues found when checking the cluster. Istio is safe to install or upgrade!
  3. To get started, check out https://istio.io/latest/docs/setup/getting-started/

当使用基于版本的升级时,支持跨越两个次要版本(例如,直接从版本 1.151.17)。 这与原地升级不同,原地升级要求必须升级到每一个中间的次要版本。

控制平面

要安装名为 canary 的新修订版本,您可以按照如下所示设置 revision 字段:

在生产环境中,更好的修订名称将对应 Istio 的版本。但是您必须替换修订名称的 . 字符, 例如 revision=1-23-3 表示 Istio 1.23.3, 因为 . 不是一个有效的修订名称字符。

  1. $ istioctl install --set revision=canary

运行该命令后,您将有两个并行运行的控制平面 Deployment 和 Service:

  1. $ kubectl get pods -n istio-system -l app=istiod
  2. NAME READY STATUS RESTARTS AGE
  3. istiod-1-22-1-bdf5948d5-htddg 1/1 Running 0 47s
  4. istiod-canary-84c8d4dcfb-skcfv 1/1 Running 0 25s
  1. $ kubectl get svc -n istio-system -l app=istiod
  2. NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
  3. istiod-1-22-1 ClusterIP 10.96.93.151 <none> 15010/TCP,15012/TCP,443/TCP,15014/TCP 109s
  4. istiod-canary ClusterIP 10.104.186.250 <none> 15010/TCP,15012/TCP,443/TCP,15014/TCP 87s

您还将看到包括新版本在内的两个 Sidecar 注入配置。

  1. $ kubectl get mutatingwebhookconfigurations
  2. NAME WEBHOOKS AGE
  3. istio-sidecar-injector-1-22-1 2 2m16s
  4. istio-sidecar-injector-canary 2 114s

数据平面

请参阅网关金丝雀升级, 以了解如何运行 Istio Gateway 的特定修订版本的实例。在此示例中,由于我们使用了 default Istio 配置文件,因此 Istio Gateway 不运行特定修订版本的实例,而是原地升级以使用新的控制平面修订版本。 您可以通过运行以下命令来验证 istio-ingress Gateway 是否正在使用 canary 修订版本:

  1. $ istioctl proxy-status | grep "$(kubectl -n istio-system get pod -l app=istio-ingressgateway -o jsonpath='{.items..metadata.name}')" | awk -F '[[:space:]][[:space:]]+' '{print $8}'
  2. istiod-canary-6956db645c-vwhsk

但是,仅安装新版本不会对现有的 Sidecar 代理产生影响。要升级它们,必须将它们配置为指向新的 istiod-canary 控制平面。这是在基于命名空间标签的 Sidecar 注入期间控制的 istio.io/rev

创建一个命名空间 test-ns 并启用 istio-injection。 在 test-ns 命名空间中,部署一个示例 sleep Pod:

  1. 创建命名空间 test-ns

    1. $ kubectl create ns test-ns
  2. 使用 istio-injection 标签标记命名空间。

    1. $ kubectl label namespace test-ns istio-injection=enabled
  3. test-ns 命名空间中启动一个示例 sleep Pod。

    1. $ kubectl apply -n test-ns -f samples/sleep/sleep.yaml

要升级命名空间 test-ns,请删除 istio-injection 标签,然后添加 istio.io/rev 标签以指向 canary 修订版本。为了向后兼容性,istio-injection 标签必须移除,因为它的优先级高于 istio.io/rev

  1. $ kubectl label namespace test-ns istio-injection- istio.io/rev=canary

命名空间更新后,您需要重新启动 Pod 才能触发重新注入。 一种重启命名空间 test-ns 中所有 Pod 的方法是:

  1. $ kubectl rollout restart deployment -n test-ns

当 Pod 被重新注入时,它们将被配置为指向 istiod-canary 控制平面。您可以使用 istioctl proxy-status 来验证。

  1. $ istioctl proxy-status | grep "\.test-ns "

输出会展示命名空间下所有正在使用修订版本的 Pod。

稳定修订标签

如果您正在使用 Helm, 请参考 Helm 升级文档.

在将命名空间移动到新版本时,手动的重新标记命名空间可能既乏味又容易出错。 修订标签解决了这个问题。 修订标签是指向修订的稳定标识符,可用于避免重新标记命名空间。 网格管理员可以简单地更改标签以指向新的修订版,而不是重新标记命名空间。所有标有该标签的命名空间将同时更新。

用法

考虑到一个安装了 1-22-11-23-3 两个修订版本的集群。集群管理员创建了一个 prod-stable 修订标签, 以指向较旧的 1-22-1 稳定版本,并创建一个 prod-canary 修订标签,用以指向较新的 1-23-3 修订版本。 可以通过以下命令达到该状态:

  1. 安装两套修订版本的控制平面:

    1. $ istioctl install --revision=1-22-1 --set profile=minimal --skip-confirmation
    2. $ istioctl install --revision=1-23-3 --set profile=minimal --skip-confirmation
  2. 创建 stablecanary 修订版本标签,将其与各自的修订相关联:

    1. $ istioctl tag set prod-stable --revision 1-22-1
    2. $ istioctl tag set prod-canary --revision 1-23-3
  3. 为应用命名空间打标签,将其与各自的修订版本相关联:

    1. $ kubectl create ns app-ns-1
    2. $ kubectl label ns app-ns-1 istio.io/rev=prod-stable
    3. $ kubectl create ns app-ns-2
    4. $ kubectl label ns app-ns-2 istio.io/rev=prod-stable
    5. $ kubectl create ns app-ns-3
    6. $ kubectl label ns app-ns-3 istio.io/rev=prod-canary
  4. 在每个命名空间中部署一个 sleep Pod 示例:

    1. $ kubectl apply -n app-ns-1 -f samples/sleep/sleep.yaml
    2. $ kubectl apply -n app-ns-2 -f samples/sleep/sleep.yaml
    3. $ kubectl apply -n app-ns-3 -f samples/sleep/sleep.yaml
  5. 使用 istioctl proxy-status 命令验证应用程序与控制平面的映射:

    1. $ istioctl ps
    2. NAME CLUSTER CDS LDS EDS RDS ECDS ISTIOD VERSION
    3. sleep-78ff5975c6-62pzf.app-ns-3 Kubernetes SYNCED SYNCED SYNCED SYNCED NOT SENT istiod-1-23-3-7f6fc6cfd6-s8zfg 1.23.3
    4. sleep-78ff5975c6-8kxpl.app-ns-1 Kubernetes SYNCED SYNCED SYNCED SYNCED NOT SENT istiod-1-22-1-bdf5948d5-n72r2 1.22.1
    5. sleep-78ff5975c6-8q7m6.app-ns-2 Kubernetes SYNCED SYNCED SYNCED SYNCED NOT SENT istiod-1-22-1-bdf5948d5-n72r2 1-22.1

修订、标签和命名空间之间的结果映射如下所示:

两个命名空间指向了 prod-stable 而一个指向了 prod-canary
两个命名空间指向了 prod-stable 而一个指向了 prod-canary

除了标记的命名空间之外,集群管理员还可以通过以下 istioctl tag list 命令查看此映射:

  1. $ istioctl tag list
  2. TAG REVISION NAMESPACES
  3. default 1-22-1 ...
  4. prod-canary 1-23-3 ...
  5. prod-stable 1-22-1 ...

当集群管理员对标记为 prod-canary 的控制面、命名空间的稳定性感到满意后, istio.io/rev=prod-stable 可以通过修改 prod-stable 修订标记来更新, 以指向更新的 1-23-3 修订版本。

  1. $ istioctl tag set prod-stable --revision 1-23-3 --overwrite

现在,修订版、标记和命名空间之间更新后的映射关系如下所示:

命名空间标签没有变化,但现在所有命名空间都指向 {{< istio_full_version_revision >}}
命名空间标签没有变化,但现在所有命名空间都指向 {{< istio_full_version_revision >}}

当在带有 prod-stable 标签的命名空间中重新启动注入工作负载,将导致这些工作负载使用 1-23-3 控制平面。 请注意,将工作负载迁移到新版本时不需要重新标记命名空间。

  1. $ kubectl rollout restart deployment -n app-ns-1
  2. $ kubectl rollout restart deployment -n app-ns-2

使用 istioctl proxy-status 命令验证应用程序与控制平面的映射:

  1. $ istioctl ps
  2. NAME CLUSTER CDS LDS EDS RDS ECDS ISTIOD VERSION
  3. sleep-5984f48bc7-kmj6x.app-ns-1 Kubernetes SYNCED SYNCED SYNCED SYNCED NOT SENT istiod-1-23-3-7f6fc6cfd6-jsktb 1.23.3
  4. sleep-78ff5975c6-jldk4.app-ns-3 Kubernetes SYNCED SYNCED SYNCED SYNCED NOT SENT istiod-1-23-3-7f6fc6cfd6-jsktb 1.23.3
  5. sleep-7cdd8dccb9-5bq5n.app-ns-2 Kubernetes SYNCED SYNCED SYNCED SYNCED NOT SENT istiod-1-23-3-7f6fc6cfd6-jsktb 1.23.3

默认版本

标签 default 指向的修订版本被认为是默认的修订版本,并具有额外的语义含义。 默认版本的功能如下:

  • istio-injection=enabled 命名空间选择器、sidecar.istio.io/inject=true 对象选择器和 istio.io/rev=default 选择器注入 Sidecar。
  • 验证 Istio 资源。
  • 从非默认的修订版本中窃取 leader 锁并执行单例网格任务(例如更新资源状态)。

要将修订版本 1-23-3 设为默认版本,请运行以下命令:

  1. $ istioctl tag set default --revision 1-23-3

当使用 default 标签和现有的未修订版本的 Istio 安装方式一起使用时, 建议删除旧的 MutatingWebhookConfiguration(通常称为 istio-sidecar-injector), 以避免新旧控制平面同时尝试注入。

卸载旧的控制平面

升级控制平面和数据平面之后,您可以卸载旧的控制平面。 例如,以下命令卸载修订版本的控制平面 1-22-1

  1. $ istioctl uninstall --revision 1-22-1 -y

如果旧的控制平面没有修订版本标签,请使用其原始安装选项将其卸载,例如:

  1. $ istioctl uninstall -f manifests/profiles/default.yaml -y

确认旧的控制平面已被移除,并且集群中仅存在新的控制平面:

  1. $ kubectl get pods -n istio-system -l app=istiod
  2. NAME READY STATUS RESTARTS AGE
  3. istiod-canary-55887f699c-t8bh8 1/1 Running 0 27m

请注意,以上说明仅删除了用于指定控制平面修订版的资源,而未删除与其他控制平面共享的集群作用域资源。 要完全卸载 Istio,请参阅卸载指南

卸载金丝雀控制平面

如果您决定回滚到旧的控制平面,而不是完成金丝雀升级,则可以使用以下命令卸载金丝雀修订版:

  1. $ istioctl uninstall --revision=canary -y

但是,在这种情况下,您必须首先手动重新安装先前版本的网关,因为卸载命令不会自动还原先前原地升级的网关。

确保使用与 istioctl 旧控制平面相对应的版本来重新安装旧网关,并且为避免停机, 请确保旧网关已启动并正在运行,然后再进行金丝雀卸载。

清理

  1. 清理已创建的修订版本标签:

    1. $ istioctl tag remove prod-stable
    2. $ istioctl tag remove prod-canary
  2. 清理用于金丝雀升级的命名空间与修订标签的例子:

    1. $ kubectl delete ns istio-system test-ns
  3. 清理用于金丝雀升级的命名空间与修订版本的例子:

    1. $ kubectl delete ns istio-system app-ns-1 app-ns-2 app-ns-3