Product: VMware Tanzu Application Platform
Component: Cloud Native Runtimes
Affected versions: TAP v1.3/CNR v2.0
How can I successfully migrate to CNR v2.0?
CNR v2.0 will no longer ship with Contour. This means that CNR will not be usable without a compatible ingress provider (Contour only at this moment) already installed on the cluster.
All customers relying on CNR provided Contour in any form will experience varying levels of impact and downtime when upgrading to CNR 2.0. The various upgrade scenarios and levels of impact are explored further in the Upgrade Scenarios section below.
On the other hand, customers relying on only TAP Contour (the default configuration for TAP) should not experience any problems during this upgrade related to removing CNR Contour.
Because CNR 1.3 introduced a breaking change to mixing TAP and CNR Contour, many customers may have already moved away from relying on CNR Contour.
The best way to upgrade is to first switch away from using a CNR created Contour, and then onto a TAP created Contour. How this is done will depend on your current CNR configuration and your tolerance for downtime.
cnrs: ingress: reuse_crds: true external: namespace: tanzu-system-ingress internal: namespace: tanzu-system-ingress
This is the default configuration in TAP. If you are using CNR from TAP installed with a profile, you can follow the TAP upgrade process as you would normally.
If you have installed CNR 1.3 individually from the TAP package repository, CNR is configured to use TAP Contour, and the CNR 2.0.x package is available, then you can run tanzu package install cloud-native-runtimes -p cnrs.tanzu.vmware.com -v 2.0.0 --values-file <values.yaml> -n tap-install to upgrade the package version.
cnrs: ingress: reuse_crds: false external: namespace: "" internal: namespace: "" excluded_packages: contour.tanzu.vmware.com
In this case, the Contour installed on the cluster comes from CNR. That means, if we delete CNR, or upgrade to a version of CNR without Contour, there will be no ingress provider on the cluster.
The smoothest way to get past this is to switch off of CNR Contour before upgrading.
ingress: external namespace: tanzu-system-ingress internal namespace: tanzu-system-ingress
Note: If workloads are created in this state for some reason, they will not be accessible until Contour is installed in the tanzu-system-ingress namespace. Existing workloads will remain available via the orphaned Contour installation.
Kubectl delete namespace contour-external Kubectl delete namespace contour-internal Kubectl delete clusterrolebindings.rbac.authorization.k8s.io knative-contour-external Kubectl delete clusterrolebindings.rbac.authorization.k8s.io knative-contour-internal
Update config values, as reuse_crds value will no longer exist.
cnrs: ingress: reuse_crds: true external: namespace: "" internal: namespace: ""
This scenario is broken as of CNR 1.3 / TAP 1.2. We don't support this configuration.
Getting out of this is a little more straightforward, since a Contour (hopefully a TAP provided one) is already installed. Just reconfigure the values to provide the namespace of the existing Contour instance.
This will delete the CNR created Contour. Then proceed to upgrade like in the first scenario.
cnrs: ingress: reuse_crds: true external: namespace: "" internal: namespace: tanzu-system-ingress
This scenario is broken as of CNR 1.3 / TAP 1.2. We don't support this configuration.
Getting out of this is a little more straightforward, since a Contour (hopefully a TAP provided one) is already installed. Just reconfigure the values to provide the namespace of the existing Contour instance.
This will delete the CNR created Contour. Then proceed to upgrade like in the first scenario.
cnrs: ingress: reuse_crds: true external: namespace: tanzu-system-ingress internal: namespace: ""
This scenario is broken as of CNR 1.3 / TAP 1.2. We don't support this configuration.
Getting out of this is a little more straightforward, since a Contour (hopefully a TAP provided one) is already installed. Just reconfigure the values to provide the namespace of the existing Contour instance.
This will delete the CNR created Contour. Then proceed to upgrade like in the first scenario.
#@ load("@ytt:overlay", "overlay") #@ def add_orphan_annotation(): metadata: #@overlay/match missing_ok=True annotations: #@overlay/match missing_ok=True kapp.k14s.io/delete-strategy: orphan #@ end #! Start with CRDs #@overlay/match by=overlay.subset({"kind":"CustomResourceDefinition","metadata":{"labels":{"networking.knative.dev/ingress-provider": "contour"}}}), expects=[5,10] --- #@ add_orphan_annotation() #! Now do all external stuff #@overlay/match by=overlay.subset({"kind":"Namespace","metadata":{"name":"contour-external"}}) --- #@ add_orphan_annotation() #@overlay/match by=overlay.subset({"kind":"ClusterRoleBinding","metadata":{"name":"knative-contour-external"}}) --- #@ add_orphan_annotation() #@overlay/match by=overlay.subset({"kind":"ServiceAccount","metadata":{"name":"contour", "namespace": "contour-external"}}) --- #@ add_orphan_annotation() #@overlay/match by=overlay.subset({"kind":"ServiceAccount","metadata":{"name":"envoy", "namespace": "contour-external"}}) --- #@ add_orphan_annotation() #@overlay/match by=overlay.subset({"kind":"ServiceAccount","metadata":{"name":"contour-certgen", "namespace": "contour-external"}}) --- #@ add_orphan_annotation() #@overlay/match by=overlay.subset({"kind":"RoleBinding","metadata":{"name":"contour", "namespace": "contour-external"}}) --- #@ add_orphan_annotation() #@overlay/match by=overlay.subset({"kind":"Role","metadata":{"name":"contour-certgen", "namespace": "contour-external"}}) --- #@ add_orphan_annotation() #@overlay/match by=overlay.subset({"kind":"ConfigMap","metadata":{"name":"contour", "namespace": "contour-external"}}) --- #@ add_orphan_annotation() #@overlay/match by=overlay.subset({"kind":"Job","metadata":{"name":"contour-certgen-v1.19.1", "namespace": "contour-external"}}) --- #@ add_orphan_annotation() #@overlay/match by=overlay.subset({"kind":"Service","metadata":{"name":"contour", "namespace": "contour-external"}}) --- #@ add_orphan_annotation() #@overlay/match by=overlay.subset({"kind":"Service","metadata":{"name":"envoy", "namespace": "contour-external"}}) --- #@ add_orphan_annotation() #@overlay/match by=overlay.subset({"kind":"Deployment","metadata":{"name":"contour", "namespace": "contour-external"}}) --- metadata: #@overlay/match missing_ok=True annotations: #@overlay/match missing_ok=True kapp.k14s.io/delete-strategy: orphan spec: template: metadata: #@overlay/match missing_ok=True annotations: #@overlay/match missing_ok=True kapp.k14s.io/delete-strategy: orphan #@overlay/match by=overlay.subset({"kind":"DaemonSet","metadata":{"name":"envoy", "namespace": "contour-external"}}) --- metadata: #@overlay/match missing_ok=True annotations: #@overlay/match missing_ok=True kapp.k14s.io/delete-strategy: orphan spec: template: metadata: #@overlay/match missing_ok=True annotations: #@overlay/match missing_ok=True kapp.k14s.io/delete-strategy: orphan #! Now do internal #@overlay/match by=overlay.subset({"kind":"Namespace","metadata":{"name":"contour-internal"}}) --- #@ add_orphan_annotation() #@overlay/match by=overlay.subset({"kind":"ClusterRoleBinding","metadata":{"name":"knative-contour-internal"}}) --- #@ add_orphan_annotation() #@overlay/match by=overlay.subset({"kind":"ServiceAccount","metadata":{"name":"contour", "namespace": "contour-internal"}}) --- #@ add_orphan_annotation() #@overlay/match by=overlay.subset({"kind":"ServiceAccount","metadata":{"name":"envoy", "namespace": "contour-internal"}}) --- #@ add_orphan_annotation() #@overlay/match by=overlay.subset({"kind":"ServiceAccount","metadata":{"name":"contour-certgen", "namespace": "contour-internal"}}) --- #@ add_orphan_annotation() #@overlay/match by=overlay.subset({"kind":"RoleBinding","metadata":{"name":"contour", "namespace": "contour-internal"}}) --- #@ add_orphan_annotation() #@overlay/match by=overlay.subset({"kind":"Role","metadata":{"name":"contour-certgen", "namespace": "contour-internal"}}) --- #@ add_orphan_annotation() #@overlay/match by=overlay.subset({"kind":"ConfigMap","metadata":{"name":"contour", "namespace": "contour-internal"}}) --- #@ add_orphan_annotation() #@overlay/match by=overlay.subset({"kind":"Job","metadata":{"name":"contour-certgen-v1.19.1", "namespace": "contour-internal"}}) --- #@ add_orphan_annotation() #@overlay/match by=overlay.subset({"kind":"Service","metadata":{"name":"contour", "namespace": "contour-internal"}}) --- #@ add_orphan_annotation() #@overlay/match by=overlay.subset({"kind":"Service","metadata":{"name":"envoy", "namespace": "contour-internal"}}) --- #@ add_orphan_annotation() #@overlay/match by=overlay.subset({"kind":"Deployment","metadata":{"name":"contour", "namespace": "contour-internal"}}) --- metadata: #@overlay/match missing_ok=True annotations: #@overlay/match missing_ok=True kapp.k14s.io/delete-strategy: orphan spec: template: metadata: #@overlay/match missing_ok=True annotations: #@overlay/match missing_ok=True kapp.k14s.io/delete-strategy: orphan #@overlay/match by=overlay.subset({"kind":"DaemonSet","metadata":{"name":"envoy", "namespace": "contour-internal"}}) --- metadata: #@overlay/match missing_ok=True annotations: #@overlay/match missing_ok=True kapp.k14s.io/delete-strategy: orphan spec: template: metadata: #@overlay/match missing_ok=True annotations: #@overlay/match missing_ok=True kapp.k14s.io/delete-strategy: orphan