Upgrade Ingress Controller
APISIX and API7 Ingress Controller currently have different published upgrade targets. Select the path that matches the installed product and version, update its CRDs before the controller, and verify the traffic paths your deployment uses.
Choose an Upgrade Path
- APISIX Ingress Controller 2.1.0 to 2.2.0: Complete all applicable sections from Prerequisites through Verify the Upgrade.
- API7 Ingress Controller to 2.2.1:
- From 2.1.0, complete all applicable sections from Prerequisites through Verify the Upgrade.
- From 2.2.0, complete Prerequisites and Back Up the Current Deployment, verify Gateway API 1.6 under Upgrade Gateway API CRDs, update the Controller CRDs, then continue with Review API7 2.2.1 Changes.
Every path requires the APISIX CRDs that accompany its target controller. Upgrades from 2.1.0 also introduce Gateway API 1.6, additional APISIX CRDs, stricter validation, and listener-port matching changes.
Review the Release Notes for shared and product-specific changes before starting the upgrade.
API7 Dashboard and API7 Ingress Controller follow separate release schedules. A regenerated deployment command may select a different controller release than your selected upgrade target.
Helm-managed installations use the normal Helm workflow for the controller rollout. For API7 Ingress Controller, regenerate the deployment command in Dashboard, compare its chart and controller image with your upgrade target, and adjust both if necessary before running helm upgrade --install. See API7 Deployment Versions.
For APISIX Ingress Controller, run helm upgrade for the existing release with the selected APISIX installation chart and reviewed values. The APISIX CRD steps below remain separate because Helm does not upgrade existing CRDs from a chart's crds/ directory. Dedicated APISIX chart 1.4.0 renders Gateway API resources as templates under a separate ownership control.
Prerequisites
Before upgrading, confirm the following:
- The cluster runs Kubernetes 1.31 or later.
- You know whether Helm, Argo CD, or Flux manages the controller.
- You know which deployment owner manages the Gateway API and APISIX CRDs. Keep that owner unchanged unless you are following a documented ownership transfer, such as Migrate APISIX Chart 1.3.x Gateway API Ownership. Do not apply CRDs manually when a GitOps or platform release manages them.
- You have selected the compatible controller chart listed in the Helm chart reference. Do not override only the image tag on an older chart because its CRDs, RBAC, and webhook paths are incompatible.
- For API7 Ingress Controller, keep the chart, controller and ADC images, and CRDs from the same controller release. The private-CA connection support requires the compatible ADC sidecar supplied by the chart. Do not combine a Dashboard-generated script that pins a different controller release with the CRDs, webhook paths, or examples in this documentation.
Back Up the Current Deployment
Review Roll Back before making changes, then record the images configured on the current Deployment:
kubectl get deployment <ingress-controller-deployment> -n <namespace> \
-o jsonpath='{.metadata.namespace}{"/"}{.metadata.name}{": "}{range .spec.template.spec.containers[*]}{.image}{" "}{end}{"\n"}'
For an Argo CD or Flux deployment, confirm that the current Git revision and controller configuration can be restored before making changes.
For a Helm release, save the computed values as a rollback reference and export the user-supplied overrides for the upgrade:
helm get values <release-name> -n <namespace> --all -o yaml \
> ingress-controller-computed-values-backup.yaml
helm get values <release-name> -n <namespace> -o yaml \
> ingress-controller-overrides.yaml
Do not pass the computed-values backup to helm upgrade because it contains defaults from the old chart. Review ingress-controller-overrides.yaml for renamed or removed settings, and pass only the migrated user overrides to the new chart.
Upgrade Gateway API CRDs
Both target versions use the Gateway API 1.6.0 standard channel, which includes the v1 TCPRoute, UDPRoute, and TLSRoute APIs used by the controller. If you are upgrading from 2.1.0, update this bundle before rolling out the controller.
API7 Ingress Controller 2.2.0 already requires Gateway API 1.6. If you are upgrading from that version, verify the installed CRDs below and keep their existing owner. You do not need to apply the bundle again unless that owner needs to update it.
If a platform Application, Kustomization, or other GitOps source owns these CRDs, update its pinned bundle to Gateway API 1.6 and reconcile that source. Do not run the manual command against platform-managed CRDs because doing so can change field ownership and create drift.
For dedicated APISIX chart 1.4.0, set crds.gatewayAPI.enabled=false when the platform or another release owns Gateway API.
For a manually managed bundle, use server-side apply because the CRDs exceed the client-side annotation size limit:
kubectl apply --server-side --force-conflicts \
-f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.6.0/standard-install.yaml
Verify that the API server serves the versions used by the controller:
kubectl get crd tcproutes.gateway.networking.k8s.io \
-o jsonpath='{range .spec.versions[?(@.served==true)]}{.name}{"\n"}{end}'
kubectl get crd udproutes.gateway.networking.k8s.io \
-o jsonpath='{range .spec.versions[?(@.served==true)]}{.name}{"\n"}{end}'
Both outputs should include v1.
Migrate APISIX Chart 1.3.x Gateway API Ownership
For direct Helm releases and Flux HelmReleases, Gateway API objects installed from chart 1.3.x do not have the release annotations required by the 1.4.0 template lookup. Before upgrading, move the Gateway API bundle to a pinned platform owner:
- Add the installed Gateway API 1.6 bundle, including its admission policy and binding, to a pinned platform source such as a Flux Kustomization.
- Reconcile that source with server-side apply, then verify that every CRD reports an
Establishedcondition and the admission resources are present. - Set
crds.gatewayAPI.enabled=falsein the controller release and inspect the rendered diff to confirm that it no longer includes the Gateway API bundle. - Upgrade the controller only after the platform-owned bundle is verified.
Do not add Helm ownership annotations manually. Annotations alone do not establish compatible field ownership and can cause apply conflicts.
Argo CD renders the 1.4.0 templates without querying live ownership, so the existing controller Application can continue tracking the Gateway API bundle. Inspect its rendered diff before synchronization. Follow Transfer CRD Ownership Safely only when moving the bundle to a platform Application.
Upgrade Controller CRDs
Upgrade the APISIX CRDs through their existing owner before rolling out the controller:
- If a separate platform Application or Kustomization owns them, update its pinned APISIX CRD source and reconcile it before reconciling the controller.
- If the Argo CD controller Application or Flux HelmRelease owns the bundled CRDs, update the chart and CRD settings in Git and follow the tool-specific upgrade procedure. Do not apply the CRDs manually.
For a direct Helm deployment whose APISIX CRDs are not managed by another reconciler, download the compatible controller chart and apply its APISIX CRD file. Helm installs resources from a chart's crds/ directory but does not upgrade existing CRDs during helm upgrade. Applying the APISIX CRDs is therefore a separate prerequisite before the normal controller upgrade.
For APISIX Ingress Controller, download and apply the APISIX CRDs:
helm pull apisix/apisix-ingress-controller \
--version 1.4.0 \
--untar --untardir <chart-download-directory>
kubectl apply --server-side --force-conflicts \
-f <chart-download-directory>/apisix-ingress-controller/crds/apisixic-crds.yaml
For API7 Ingress Controller, download and apply the APISIX CRDs:
helm pull api7/api7-ingress-controller \
--version 0.1.28 \
--untar --untardir <chart-download-directory>
kubectl apply --server-side --force-conflicts \
-f <chart-download-directory>/api7-ingress-controller/crds/apisix-crds.yaml
If you install APISIX Ingress Controller through the APISIX umbrella chart, use the controller chart version declared as its dependency. After the CRD owner finishes reconciling, confirm that the selected source contains the new policy CRD:
kubectl get crd l4routepolicies.apisix.apache.org
Review 2.2.0 Configuration Changes
The following compatibility changes apply when upgrading either controller from 2.1.0. If you are upgrading API7 Ingress Controller from 2.2.0, continue to Review API7 2.2.1 Changes.
Cross-Namespace Consumer Credentials
A Consumer that references a credential Secret in another namespace now requires a ReferenceGrant in the Secret namespace. Create the grant before rolling out the controller. Without it, the controller no longer programs the credential. See Configure Cross-Namespace References.
CSRF Annotations
An Ingress with k8s.apisix.apache.org/enable-csrf: "true" must also set a non-empty k8s.apisix.apache.org/csrf-key. When the admission webhook is enabled, it rejects an Ingress with a missing or empty key. If the webhook is disabled or bypassed, Kubernetes can accept the Ingress, but the controller logs an annotation error and omits the CSRF plugin when translating the route.
Fix every affected Ingress before the rollout so that routes intended to use CSRF protection are not published without it. See the CSRF annotation reference.
Plugin Configuration
Malformed plugin config values are no longer published as empty configuration. The controller fails translation for resources such as ApisixRoute and PluginConfig. For a Consumer, it logs the error, omits the malformed plugin, and continues translating the remaining consumer configuration. Inspect controller logs and resource status for previously ignored configuration, especially for security plugins such as ip-restriction.
Listener-Port Matching
The controller binary defaults listener_port_match_mode to off when the field is omitted. That prevents injecting a server_port match when a Gateway listener uses a Service port such as 80 but the gateway receives the connection on a container port such as 9080.
Helm does not always install that binary default:
| Install surface | Effective mode after upgrade |
|---|---|
| API7 Ingress Controller chart | off |
| APISIX Ingress Controller chart, including the APISIX umbrella chart | auto |
Upgrading with the APISIX chart keeps or sets auto. To get off on that path, set config.listenerPortMatchMode=off on the dedicated chart or ingress-controller.config.listenerPortMatchMode=off on the umbrella chart.
If you set the mode to explicit or auto, it also applies to TCPRoute and UDPRoute. Review the routes and listeners that meet the injection conditions in the configuration reference. Whenever the controller injects a server_port predicate, the declared Gateway listener port must match the corresponding physical HTTP, TLS, or stream listener. Review all HTTP, gRPC, TCP, and UDP listeners before retaining either mode.
Manually Managed Webhooks
The chart updates the TCPRoute and UDPRoute webhook rules and paths from v1alpha2 to v1. If you manage ValidatingWebhookConfiguration outside the chart, update both rules[].apiVersions and clientConfig.service.path:
| Resource | API version | Webhook path |
|---|---|---|
| TCPRoute | v1 | /validate-gateway-networking-k8s-io-v1-tcproute |
| UDPRoute | v1 | /validate-gateway-networking-k8s-io-v1-udproute |
API7 Ingress Controller chart 0.1.26 introduced a change to the default webhook.failurePolicy, from Fail to Ignore. This prevents an unavailable cluster-scoped webhook from blocking changes to resources owned by another controller. To retain fail-closed admission, set the value to Fail explicitly and ensure the webhook is highly available.
The webhook Service forwards port 443 to the controller's webhook port, which is 9443 by default. If a NetworkPolicy restricts the controller pod, allow TCP traffic to the configured webhook port.
Review API7 2.2.1 Changes
This section applies whenever the target is API7 Ingress Controller 2.2.1, whether the installed version is 2.1.0 or 2.2.0.
Routes Stop When They Are No Longer Accepted
API7 Ingress Controller 2.2.1 removes previously synchronized configuration when a route leaves a managed Gateway or no parent listener accepts it. Verify that routes intended to remain active have an accepted parent and listener before upgrading.
A temporarily missing Gateway or GatewayClass does not trigger removal because the controller cannot yet determine ownership.
Routes Stop When Their Plugin Configuration Is Deleted
An ApisixRoute or Ingress that references a deleted ApisixPluginConfig now stops serving instead of retaining the last synchronized plugins. Remove the reference before deleting the plugin configuration, or restore the missing object before upgrading.
Listener Protocols
API7 Ingress Controller 2.2.1 restricts HTTPRoute and GRPCRoute traffic to the protocols accepted by their attached listeners. Confirm that clients and health probes use HTTPS for routes attached only to HTTPS listeners and HTTP for routes attached only to HTTP listeners.
ApisixRoute Service Ports
API7 Ingress Controller 2.2.1 rejects an ApisixRoute backend whose servicePort is empty or does not match a port on the referenced Service. Correct these values before upgrading so affected routes are not rejected.
Upgrade the Deployment
After the CRDs are established, use the normal deployment workflow. If you manage a NetworkPolicy for the controller, update it in the same rollout to allow the required webhook traffic.
- For API7 Ingress Controller managed directly with Helm, regenerate the deployment script for the existing gateway group in Dashboard. Keep the existing release name, namespace,
config.controllerName, andconfig.leaderElection.id. For a 2.2.1 target, confirm that the command sets both--version 0.1.28and--set "deployment.image.tag=2.2.1"; update both selections if Dashboard still generates the earlier release. Retain the target chart's ADC image default, review any custom overrides, then runhelm upgrade --install. - For APISIX Ingress Controller managed directly with Helm, refresh the chart repository metadata and run
helm upgradefor the existing release with the selected APISIX installation chart and the reviewedingress-controller-overrides.yamlfile. - For Argo CD or Flux, update the CRD source and controller chart or manifest pin in Git. Reconcile the CRD owner first, wait for the required CRDs to become established, and then reconcile the controller. Follow the Argo CD or Flux procedure for the selected ownership model.
Wait for the rollout to complete:
kubectl rollout status deployment/<ingress-controller-deployment> -n <namespace>
Verify the Upgrade
Confirm the configured images and the webhook endpoints created by the upgraded release. Substitute the name of its ValidatingWebhookConfiguration:
kubectl get deployment <ingress-controller-deployment> -n <namespace> \
-o jsonpath='{range .spec.template.spec.containers[*]}{.image}{"\n"}{end}'
kubectl get validatingwebhookconfiguration <validating-webhook-configuration> \
-o jsonpath='{range .webhooks[*]}{.clientConfig.service.namespace}{"/"}{.clientConfig.service.name}{"\t"}{.clientConfig.service.path}{"\t"}{range .rules[*].apiVersions[*]}{.}{" "}{end}{"\n"}{end}' \
| grep -E 'v1-(tcp|udp)route'
Each TCPRoute and UDPRoute row should show the expected webhook Service, its v1 path, and the v1 API version.
List the Gateway API and policy resources:
kubectl get gateway,httproute,grpcroute,tcproute,udproute,tlsroute -A
kubectl get backendtrafficpolicy,l4routepolicy -A
Confirm that Gateways report the expected Programmed condition and Routes report the expected Accepted and ResolvedRefs conditions for their current generation. The policy listing confirms that the resources still exist; verify their behavior with the traffic checks below and inspect controller logs if the observed behavior differs.
Verify the traffic paths used in your environment:
- HTTP and gRPC routes return the expected responses.
- TLSRoute termination presents the expected certificate and routes by SNI.
- TCPRoute and UDPRoute traffic reaches the selected listener and backend.
- Downstream mTLS accepts a valid client certificate and rejects a missing certificate.
- Cross-namespace Consumer credentials work only when a matching
ReferenceGrantexists. - With the admission webhook enabled, applying an Ingress with CSRF enabled and no key is rejected. If the webhook is disabled, confirm that no Ingress has CSRF enabled without a non-empty key.
For an API7 Ingress Controller 2.2.1 target, also verify the following:
- Routes that should remain active report an accepted parent and continue serving traffic.
- HTTP-only and HTTPS-only routes work over their accepted listener protocol.
- If
controlPlane.caCertis configured, synchronization succeeds with control-plane certificate verification enabled. - If a v1alpha1 plugin uses
secretRef, its behavior reflects the referenced Secret and still updates after the Secret changes.
Roll Back
Use the same deployment owner to roll back the controller:
- For a direct Helm deployment, run
helm history <release-name> -n <namespace>to identify the pre-upgrade revision, then runhelm rollback <release-name> <revision> -n <namespace> --wait. Keep the saved values as a reference; do not pass them tohelm rollback. - For Argo CD, revert the controller version and values in Git by following the Argo CD rollback procedure. Do not run
helm rollbackor edit the Deployment directly. - For Flux, revert the controller version and values in Git by following the Flux rollback procedure. Do not run
helm rollbackor edit the Deployment directly.
Do not delete or downgrade Gateway API or APISIX CRDs during rollback. Deleting a CRD also deletes its custom resources. Keep the installed CRDs under their existing owner, and verify that they remain compatible with the older controller.
When rolling API7 Ingress Controller back from 2.2.1 to 2.2.0, the controller no longer processes controlPlane.caCert or v1alpha1 plugin secretRef. Before rollback, replace any dependency on these fields with configuration supported by 2.2.0. Keep the newer CRDs installed.
When rolling either controller back to 2.1.0, the older controller does not reconcile L4RoutePolicy and may not watch the Gateway API v1 L4 resource paths. Treat TCP, UDP, and TLS routing as unavailable until you restore a compatible controller. If a resource caused the rollback, remove or correct it instead of downgrading cluster-wide CRDs.