升级 Istio

本页介绍如何将现有的 Istio 部署(包括控制平面和 sidecar 代理)升级到新版本。 升级过程可能涉及新的二进制文件以及配置和 API schemas 等其他更改。升级过程可能导致一些服务停机。为了最大限度地减少停机时间,请使用多副本以保证 Istio 控制平面组件和应用程序具有高可用性。

在下面的步骤中,我们假设 Istio 组件在 istio-system namespace 中安装和升级。

控制平面升级

Istio 控制平面组件包括:Citadel、Ingress 网关、Egress 网关、Pilot、Policy、Telemetry 和 Sidecar 注入器。我们可以使用 Kubernetes 的滚动更新机制来升级控制平面组件。

首先,生成需要的 Istio 控制平面 yaml 文件,例如:

$ helm template --namespace istio-system --set global.proxy.image=proxy \
  --values install/kubernetes/helm/istio/values-istio.yaml \
  install/kubernetes/helm/istio >> install/kubernetes/istio.yaml

或者

$ helm template --namespace istio-system --set global.proxy.image=proxy \
  --values install/kubernetes/helm/istio/values-istio-demo-auth.yaml \
  install/kubernetes/helm/istio >> install/kubernetes/istio-demo-auth.yaml

如果使用 1.9 之前的 Kubernetes 版本,则应添加 --set sidecarInjectorWebhook.enabled=false

接下来,只需直接应用所需的 Istio 控制平面 yaml 文件的新版本,例如,

$ kubectl apply -f install/kubernetes/istio.yaml

或者

$ kubectl apply -f install/kubernetes/istio-demo-auth.yaml

滚动更新过程会将所有 deployment 和 configmap 升级到新版本。完成此过程后,您的 Istio 控制面应该会更新为新版本。使用 Envoy v1 和 v1alpha1 路由规则(route rule)的现有应用程序应该可以继续正常工作而无需任何修改。如果新控制平面存在任何关键问题,您都可以通过应用旧版本的 yaml 文件来回滚更改。

Sidecar 升级

控制平面升级后,已经运行 Istio 的应用程序仍将使用旧版本的 sidecar。要想升级 sidecar,您需要重新注入它。

如果您使用自动 sidecar 注入(automatic sidecar injection),您可以通过对所有 pod 进行滚动升级来升级 sidecar,这样新版本的 sidecar 将被自动重新注入。一些技巧可以重新加载所有 pod。例如,有一个 bash 脚本 可以通过 patch 优雅结束时长(grace termination period)来触发滚动更新。

如果您使用手动注入,可以通过执行以下命令来升级 sidecar:

$ kubectl replace -f <(istioctl kube-inject -f $ORIGINAL_DEPLOYMENT_YAML)

如果 sidecar 以前被注入了一些定制的注入配置文件,您需要将配置文件中的版本标签更改为新文件版本并像下面这样重新注入 sidecar:

$ kubectl replace -f <(istioctl kube-inject \
     --injectConfigFile inject-config.yaml \
     --filename $ORIGINAL_DEPLOYMENT_YAML)

迁移到新的网络 API

一旦升级了控制平面和 sidecar,您就可以逐步更新 deployment 以使用新的 Envoy sidecar。你可以通过以下选项之一使用来做到这一点:

  • 添加以下内容到您的 deployment 的 pod annotation 中:

    kind: Deployment
    ...
    spec:
      template:
        metadata:
          annotations:
            sidecar.istio.io/proxyImage: docker.io/istio/proxyv2:0.8.0

    然后将您的 deployment 替换为更新的应用 yaml 文件:

    $ kubectl replace -f $UPDATED_DEPLOYMENT_YAML

或者

  • 使用将 docker.io/istio/proxyv2:0.8.0 作为代理镜像的 injectConfigFile。如果没有 injectConfigFile,您可以 生成一个。如果需要在多个 deployment 定义中添加 sidecar.istio.io/proxyImage annotation,推荐使用 injectConfigFile

    $ kubectl replace -f <(istioctl kube-inject --injectConfigFile inject-config.yaml -f $ORIGINAL_DEPLOYMENT_YAML)

接下来,使用 istioctl experimental convert-networking-config 来转换现有的 ingress 或路由规则:

  1. 如果您的 yaml 文件包含比 ingress 定义(如 deployment 或 service 定义)更多的定义,请将 ingress 定义移出到单独的 yaml 文件中,以供 istioctl experimental convert-networking-config 工具处理。

  2. 执行以下命令以生成新的网络配置文件,将其中的 FILE* 替换为 ingress 文件或弃用的路由规则文件。 提示:请确保使用 -f 来为一个或多个 deployment 提供所有文件。

    $ istioctl experimental convert-networking-config -f FILE1.yaml -f FILE2.yaml -f FILE3.yaml > UPDATED_NETWORK_CONFIG.yaml
  3. 编辑 UPDATED_NETWORK_CONFIG.yaml 以更新所有 namespace 引用为您需要的 namespace。convert-networking-config 工具有一个已知问题,导致 istio-system namespace 的使用不正确。此外,请确保 hosts 值的正确性。

  4. 部署更新的网络配置文件。

    $ kubectl replace -f UPDATED_NETWORK_CONFIG.yaml

当您的所有应用程序都已迁移并经过测试后,您可以重复 Istio 升级过程,删除 --set global.proxy.image = proxy 选项。这会将所有后来注入的 sidecar 的默认代理设置为docker.io/istio/proxyv2

通过 annotation 将身份验证策略迁移为启用 per-service 双向 TLS

如果使用 service annotation 覆盖 service 的全局双向 TLS,则需要将其替换为 认证策略目的规则

例如,如果您在启用双向 TLS 的情况下安装 Istio,并使用如下所示的 service annotation 对 service foo 禁用它:

kind: Service
metadata:
  name: foo
  namespace: bar
  annotations:
    auth.istio.io/8000: NONE

您需要用此身份验证策略和目标规则替换它(删除旧 annotation 是可选的)

apiVersion: "authentication.istio.io/v1alpha1"
kind: "Policy"
metadata:
  name: "disable-mTLS-foo"
  namespace: bar
spec:
  targets:
  - name: foo
    ports:
    - number: 8000
    peers:
---
apiVersion: "networking.istio.io/v1alpha3"
kind: "DestinationRule"
metadata:
  name: "disable-mTLS-foo"
  namespace: "bar"
spec:
  host: "foo"
  trafficPolicy:
    tls:
      mode: ISTIO_MUTUAL
    portLevelSettings:
    - port:
        number: 8000
      tls:
        mode: DISABLE

如果您已经有 foo 的目标规则,则必须编辑该规则而不是创建新规则。 创建新的目标规则时,请确保包含其他设置,如load balancerconnection pooloutlier detection(如有必要)。 最后,如果 foo 没有 sidecar,你可以跳过身份验证策略,但仍然需要添加目标规则。

如果 8000 是 service foo 提供的唯一端口(或者您希望禁用所有端口的双向 TLS),则策略可以简化为:

apiVersion: "authentication.istio.io/v1alpha1"
kind: "Policy"
metadata:
  name: "disable-mTLS-foo"
    namespace: bar
  spec:
    targets:
    - name: foo
    peers:
---
apiVersion: "networking.istio.io/v1alpha3"
kind: "DestinationRule"
metadata:
  name: "disable-mTLS-foo"
  namespace: "bar"
spec:
  host: "foo"
trafficPolicy:
  tls:
    mode: DISABLE

mtls_excluded_services 配置迁移到目标规则

如果您在启用双向 TLS 的情况下安装了 Istio,并且使用网格配置 mtls_excluded_services 来在连接这些服务(例如 Kubernetes API server)时禁用双向 TLS,则需要通过添加目标规则来替换它。例如:

apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: "kubernetes-master"
  namespace: "default"
spec:
  host: "kubernetes.default.svc.cluster.local"
  trafficPolicy:
    tls:
      mode: DISABLE

See also

描述了使用 Helm chart 安装 Istio 时可以使用的选项。

部署在 Kubernetes 之中的 Istio 服务网格,将虚拟机和物理机集成进入到服务网格的方法。

基于 GKE 的 Istio 多集群安装。

多 IBM Cloud Private 集群安装 Istio 示例。

介绍两种将 Istio sidecar 注入应用 Pod 的方法:使用 Sidecar 注入 Webhook 自动完成,或使用 istioctl 客户端工具手工完成。

关于 Istio 发布包下载过程的说明。