Canary Upgrades

Upgrading Istio can be done by first running a canary deployment of the new control plane, allowing you to monitor the effect of the upgrade with a small percentage of the workloads, before migrating all of the traffic to the new version. This is much safer than doing an in place upgrade and is the recommended upgrade method.

When installing Istio, the revision installation setting can be used to deploy multiple independent control planes at the same time. A canary version of an upgrade can be started by installing the new Istio version’s control plane next to the old one, using a different revision setting. Each revision is a full Istio control plane implementation with its own Deployment, Service, etc.

Control plane

To install a new revision called canary, you would set the revision field as follows:

In a production environment, a better revision name would correspond to the Istio version. However, you must replace . characters in the revision name, for example, revision=1-6-8 for Istio 1.6.8, because . is not a valid revision name character.

  1. $ istioctl install --set revision=canary

After running the command, you will have two control plane deployments and services running side-by-side:

  1. $ kubectl get pods -n istio-system -l app=istiod
  2. NAME READY STATUS RESTARTS AGE
  3. istiod-786779888b-p9s5n 1/1 Running 0 114m
  4. istiod-canary-6956db645c-vwhsk 1/1 Running 0 1m
  1. $ kubectl get svc -n istio-system -l app=istiod
  2. NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
  3. istiod ClusterIP 10.32.5.247 <none> 15010/TCP,15012/TCP,443/TCP,15014/TCP 33d
  4. istiod-canary ClusterIP 10.32.6.58 <none> 15010/TCP,15012/TCP,443/TCP,15014/TCP,53/UDP,853/TCP 12m

You will also see that there are two sidecar injector configurations including the new revision.

  1. $ kubectl get mutatingwebhookconfigurations
  2. NAME CREATED AT
  3. istio-sidecar-injector 2020-03-26T07:09:21Z
  4. istio-sidecar-injector-canary 2020-04-28T19:03:26Z

Data plane

Unlike istiod, Istio gateways do not run revision-specific instances, but are instead in-place upgraded to use the new control plane revision. You can verify that the istio-ingress gateway is using the canary revision by running the following command:

  1. $ istioctl proxy-config endpoints $(kubectl -n istio-system get pod -l app=istio-ingressgateway -o jsonpath='{.items..metadata.name}').istio-system --cluster xds-grpc -ojson | grep hostname
  2. "hostname": "istiod-canary.istio-system.svc"

However, simply installing the new revision has no impact on the existing sidecar proxies. To upgrade these, you must configure them to point to the new istiod-canary control plane. This is controlled during sidecar injection based on the namespace label istio.io/rev.

To upgrade the namespace test-ns, remove the istio-injection label, and add the istio.io/rev label to point to the canary revision. The istio-injection label must be removed because it takes precedence over the istio.io/rev label for backward compatibility.

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

After the namespace updates, you need to restart the pods to trigger re-injection. One way to do this is using:

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

When the pods are re-injected, they will be configured to point to the istiod-canary control plane. You can verify this by looking at the pod labels.

For example, the following command will show all the pods using the canary revision:

  1. $ kubectl get pods -n test-ns -l istio.io/rev=canary

To verify that the new pods in the test-ns namespace are using the istiod-canary service corresponding to the canary revision, select one newly created pod and use the pod_name in the following command:

  1. $ istioctl proxy-config endpoints ${pod_name}.test-ns --cluster xds-grpc -ojson | grep hostname
  2. "hostname": "istiod-canary.istio-system.svc"

The output confirms that the pod is using istiod-canary revision of the control plane.

Uninstall old control plane

After upgrading both the control plane and data plane, you can uninstall the old control plane. For example, the following command uninstalls a control plane of revision 1-6-5:

  1. $ istioctl x uninstall --revision 1-6-5

If the old control plane does not have a revision label, uninstall it using its original installation options, for example:

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

Confirm that the old control plane has been removed and only the new one still exists in the cluster:

  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

Note that the above instructions only removed the resources for the specified control plane revision, but not cluster-scoped resources shared with other control planes. To uninstall Istio completely, refer to the uninstall guide.

Uninstall canary control plane

If you decide to rollback to the old control plane, instead of completing the canary upgrade, you can uninstall the canary revision using istioctl x uninstall --revision=canary.

However, in this case you must first reinstall the gateway(s) for the previous revision manually, because the uninstall command will not automatically revert the previously in-place upgraded ones.

Make sure to use the istioctl version corresponding to the old control plane to reinstall the old gateways and, to avoid downtime, make sure the old gateways are up and running before proceeding with the canary uninstall.

See also

In-place Upgrades

Upgrade or downgrade Istio in place.

Managing Gateways with Multiple Revisions [experimental]

Configuring and upgrading Istio with gateways.

DNS Certificate Management

Provision and manage DNS certificates in Istio.

Secure Webhook Management

A more secure way to manage Istio webhooks.

Demystifying Istio’s Sidecar Injection Model

De-mystify how Istio manages to plugin its data-plane components into an existing deployment.

Canary Deployments using Istio

Using Istio to create autoscaled canary deployments.