Migrating gateways
Phase 4 of the migration. For each Mesh v1 gateway you deploy a Mesh v2 gateway next to it, move traffic over, and scale the Mesh v1 gateway to zero. The Gateway and VirtualService resources are not changed: the new deployment is selected by the same labels as the old one.
Migrate the workloads behind a gateway first, see Migrating workloads.
Everything on this page is scoped to GATEWAY_NAMESPACE and GATEWAY_NAME. Run the whole page for one gateway — collect its configuration, deploy the Mesh v2 gateway next to it, shift the traffic, verify — before you set the two variables to the next gateway and start again.
TOC
Collect the gateway configurationChoose how the Mesh v2 gateway is injectedDeploy the Mesh v2 gatewayShift trafficProtect the resources generated for external servicesVerificationCollect the gateway configuration
List the Mesh v1 gateways
Replace <gateway-namespace> and <gateway-name> with one of the gateways the first command lists.
Check the gateways of the control plane itself
The listing above covers the gateways the platform manages. The Mesh v1 control plane deploys one of its own, istio-ingressgateway in istio-system, and a multi-network mesh adds istio-eastwestgateway next to it. Neither is a GatewayDeploy resource, so neither is listed above and no step of this page touches them. Phase 5 deletes them together with the control plane.
Example output
Nothing under routed through them means these gateways carry no routes, and losing them in Phase 5 changes nothing. A Gateway listed there serves traffic that no step of this page has migrated: deploy a Mesh v2 gateway for it with the steps below, using the labels printed for its deployment as the selector labels.
In a multi-network mesh, istio-eastwestgateway appears here and is routed through. It is not migrated on this page: Migrating a multi-network mesh deploys its Mesh v2 replacement in Phase 2, before any workload moves.
Read the selectors, the service and the certificates
The Mesh v2 gateway pods must carry every label that selects the Mesh v1 gateway today: the selector of the gateway Service, and the selector of each Gateway resource that is served by this gateway.
Example output
Record three things:
- The union of the selector labels —
app: ingress-1andistio: gw-ingress-1in the example. A Mesh v2 gateway that carries only theServiceselector receives traffic but has no listeners, and every request returns 404. - Whether the gateway
Serviceis owned by aGatewayDeployresource. It usually is, which means Kubernetes deletes the service together with the Mesh v1 resources in Phase 5 unless the owner reference is removed. - Whether the gateway namespace carries an
istio.io/revlabel. The steps below differ.
Choose how the Mesh v2 gateway is injected
Run this command only when the gateway namespace already carries a revision label. Mesh v1 injects its gateways with a template (asm-gateway) that does not exist in Mesh v2, so once the namespace points at the Mesh v2 revision, a Mesh v1 gateway pod can no longer be created. Existing pods keep running, but a rollback then means switching the label back, not scaling the old gateway up. Deploy and verify the Mesh v2 gateway immediately after switching the label. When the gateway shares its namespace with mesh workloads, Phase 3 already switched the label and the gateway is waiting in this state: migrate it right after those workloads.
Deploy the Mesh v2 gateway
The Mesh v2 gateway carries the selector labels of the Mesh v1 gateway, so the existing Service starts load-balancing across both of them the moment the new pod becomes ready. Complete the certificate and permission steps below before you create the deployment, and run the verification immediately after. To send all traffic back to the Mesh v1 gateway at any point, scale the Mesh v2 deployment to zero.
Copy the TLS certificates into the gateway namespace
Mesh v1 resolves a credentialName in the gateway namespace first and falls back to istio-system. Mesh v2 runs upstream Istio, which only looks in the namespace of the gateway workload. Certificates created through the web console are stored in istio-system, so copy each one that a Gateway of this gateway references:
The lookup follows the resolution order of Mesh v1: the gateway namespace first, istio-system second. A certificate of the same name in a third namespace is a different certificate and is not copied — the gateway would serve it to clients without any check reporting a problem, because a wrong certificate is as ACTIVE as the right one.
Leave the original secret in place: the Mesh v1 gateway still uses it until Phase 5.
Create the service account and the SDS permissions
istiod only sends a certificate to a gateway whose service account may read secrets in its namespace. Without this role the certificate stays in WARMING state: the gateway keeps answering its HTTP routes, and every TLS handshake on its HTTPS port is reset.
Deploy the gateway
The deployment below is a standard gateway injection deployment. It carries the selector labels of the Mesh v1 gateway so that the existing Service and Gateway resources select it, plus a label of its own so that you can scale the two generations independently.
inject.istio.io/templates: gatewaymakes the injected proxy a gateway rather than a sidecar, andimage: autolets the control plane fill in the proxy image.sidecar.istio.io/inject: "true"is required because the mesh keeps the injection policy of Mesh v1, where a pod is injected only when it opts in.istio.io/revselects the Mesh v2 control plane. Remove this label when the namespace already carries the revision label.- Replace the last two labels with the union of the selectors you collected: every label used by the gateway
Serviceand by theGatewayresources. The values in this example follow the Mesh v1 naming,app: <gateway>andistio: <namespace>-<gateway>. - The
securityContextsatisfies theRestrictedPod Security Admission profile. Gateways installed through injection are your own deployments, so this is set here rather than on theIstioresource. See Pod Security Admission.
Recreate the access logging configuration
The Telemetry resource that enables access logging for a Mesh v1 gateway selects pods by labels that only Mesh v1 sets, and it is deleted with its owner in Phase 5. Create an equivalent that matches the Mesh v2 gateway:
Verify the Mesh v2 gateway
proxy-config reads the configuration from the proxy of the pod, not from a control plane, so unlike proxy-status it takes no --revision.
- The listeners match the ports of the
Gatewayresources. No listeners means the pod labels do not match theGatewayselectors. - If the gateway serves HTTPS, every
kubernetes://<credential>secret isACTIVE. A secret inWARMINGstate means the certificate is missing in this namespace, or the service account may not read it — half of the HTTPS requests fail while this is the case. A gateway that serves only HTTP — itscredentialswere empty when you collected the configuration — lists nokubernetes://secret, and this check does not apply.
If either check fails, scale the deployment to zero, fix the cause, and scale it back up:
Shift traffic
Both deployments are selected by the same Service, so the ratio of traffic follows the replica counts.
Scale the Mesh v2 gateway to the size of the Mesh v1 gateway
Half of the requests now reach the Mesh v2 gateway. Check every route of this gateway, including the HTTPS ones, before you continue.
GATEWAY_REPLICAS is the size the Mesh v1 gateway has to be scaled back to if this gateway is rolled back. The next step sets its replica count to zero, so it cannot be read from the cluster afterwards — this is why it is also written to the backup.
Scale the Mesh v1 gateway to zero
Keep the deployment: until Phase 5 it is the fastest way back if the new gateway misbehaves. Decommissioning Mesh v1 deletes it.
Protect the resources generated for external services
Binding an external service to an egress gateway makes Mesh v1 generate Gateway, VirtualService and DestinationRule resources. Annotate them so that the Mesh v1 controllers stop managing them and leave them in place when the platform resources are deleted:
The name of a generated resource holds the external service, the gateway namespace and the gateway name, which is what the filter matches. Mesh v1 also generates resources whose names do not follow that pattern — a DestinationRule next to the ServiceEntry of each external service, and one per service that has a load balancing policy. They are not selected here, and they do not need to be: their owner is the ServiceEntry or the Endpoints of a service rather than a Mesh v1 resource, so Phase 5 does not delete them and Mesh v2 keeps reading them as they are. ${BACKUP_DIR}/asm-generated-resources.txt from Phase 0 lists all of them with their owner:
Go through that list once here. Nothing has to be annotated, but after the migration these resources have no controller that maintains them, and they are yours to edit or delete from now on.
Verification
- Every route of the gateway answers as before, over HTTP and, if the gateway serves it, over HTTPS.
- The probes report no failures during the traffic shift.
kubectl -n "${GATEWAY_NAMESPACE}" get deployshows the Mesh v1 gateway at 0 replicas and the Mesh v2 gateway at its full replica count.kubectl get gateways.networking.istio.io,virtualservices.networking.istio.io -Areturns the same resources as before the migration. The migration does not change them.- Access logs are still produced by the new gateway pods.
Repeat for every gateway — ingress and egress — then continue with Decommissioning Mesh v1.