Skip to main content
Version: Deploy Next

Migrate Off Installer-Managed Ingress Controllers

From Deploy 26.3, Digital.ai Deploy no longer includes ingress controllers as packaged Helm subcharts or as installer-deployed components. This guide is for administrators upgrading a Kubernetes or OpenShift installation that currently relies on an installer-managed ingress controller. It explains what changed, how to identify which controller you use, and how to move to an external ingress controller.

If you also run Digital.ai Release in the same namespace, apply the equivalent steps to the Release custom resource (digitalaireleases.xlr.digital.ai).

What Changed

The following components are removed from the installer and Helm charts starting with Deploy 26.3:

ComponentSourceStatus
nginx-ingress-controllerBitnami Helm subchartRemoved from the Deploy Helm chart. Bitnami's community chart distribution for this controller is no longer supported upstream.
haproxy-ingresshaproxy-ingress Helm subchartRemoved from the Deploy Helm chart.
ingress-nginx-controllerKubernetes community manifest (installed and managed by the installer)No longer installed or upgraded by the installer.

Ingress itself is still fully supported by Deploy. It is no longer managed or deployed by the installer. You are expected to bring your own, already-installed ingress controller, or opt out and configure ingress later.

caution

None of the three removed components can be automatically migrated to an external ingress controller by the installer. Moving off them requires manual custom resource (CR) changes, described below, before or during your upgrade to 26.3 or later.

New Installations

When installing Deploy 26.3 or later, you are not prompted to install an ingress controller. Choose one of the following:

  • External ingress controller (recommended): Ensure an ingress controller is already installed in your cluster and select the external ingress option during installation. Provide the ingress class name that matches your controller.
  • No ingress: Select none during installation. The application is accessible within the cluster but does not expose an external hostname. You can configure ingress later by editing the CR.

Installations Still on 25.3 or 26.1

The ingress-nginx-controller option remains selectable in 25.3 and 26.1 and continues to work there. Because the upstream project is retired and no longer maintained, use external (pointing at a controller you already manage) instead of ingress-nginx-controller, even if you are staying on 25.3 or 26.1 for now. This avoids running an unmaintained ingress controller and avoids the manual cleanup described below when you later upgrade to 26.3 or later.

Upgrading to 26.3 or Later

The steps depend on which ingress controller your current installation uses. Identify it first, then follow the matching section.

These steps use the default namespace digitalai. If Deploy is installed in a different namespace, replace digitalai in the commands with your namespace.

Step 1: Identify the Current Ingress Controller

# Bitnami nginx-ingress-controller (deployed as a Helm subchart)
kubectl get pods -n digitalai -l app.kubernetes.io/name=nginx-ingress-controller

# haproxy-ingress (deployed as a Helm subchart)
kubectl get pods -n digitalai -l app.kubernetes.io/name=haproxy-ingress

# ingress-nginx-controller (installed via Kubernetes manifest, dai-prefixed resources)
kubectl get pods -n digitalai -l app.kubernetes.io/name=ingress-nginx

Record your current ingress configuration before making any changes:

kubectl get ingress -n digitalai -o yaml
kubectl get route -n digitalai -o yaml # OpenShift only

Note the hostname, path, ingress class or annotations, and any TLS secret names in use. You need these to reconfigure spec.ingress manually.

Step 2: Install or Confirm Your External Ingress Controller

Make sure a supported external ingress controller is already installed and working in your cluster before upgrading. See Common Ingress Controllers if you need to choose or install one.

Step 3: Identify Your Deploy CR Name

List the CR names in your namespace:

kubectl get digitalaideploys.xld.digital.ai -n digitalai

Typical default names created by installer flows are:

  • Deploy: dai-xld (or on OpenShift, dai-ocp-xld; custom-namespace variant dai-xld-<namespace> or dai-ocp-xld-<namespace>)

Use the exact CR name returned above if it differs from dai-xld.

Step 4: Controller-Specific Migration Actions Before Upgrade

Follow the section that matches the controller identified in Step 1.

If Currently Using Bitnami nginx-ingress-controller

Set .spec.nginx-ingress-controller.install to false in the Deploy CR:

kubectl patch digitalaideploys.xld.digital.ai dai-xld -n digitalai --type merge \
-p '{"spec":{"nginx-ingress-controller":{"install":false}}}'

No separate manual deletion step is required for this controller.

note

The .spec.nginx-ingress-controller key does not exist in the Deploy CRD schema in 26.3 or later, because the Bitnami subchart is removed from the Helm chart. Apply this patch only on your current pre-26.3 version, before upgrading. Once you are on 26.3 or later, this key no longer exists and setting it has no effect.

If Currently Using haproxy-ingress

Set .spec.haproxy-ingress.install to false in the Deploy CR:

kubectl patch digitalaideploys.xld.digital.ai dai-xld -n digitalai --type merge \
-p '{"spec":{"haproxy-ingress":{"install":false}}}'

No separate manual deletion step is required for this controller.

note

The .spec.haproxy-ingress key does not exist in the Deploy CRD schema in 26.3 or later, because the subchart is removed from the Helm chart. Apply this patch only on your current pre-26.3 version, before upgrading.

If Currently Using ingress-nginx-controller

Continued use of ingress-nginx-controller is not supported going forward. The installer no longer ships or upgrades it.

The spec.ingress values are carried forward from your old CR, but the preserved values may be stale or empty. You must manually edit spec.ingress after upgrade to point at a real, already-running external ingress controller. The upgrade does not do this for you.

Remove the ingress-nginx-controller resources.

# Deployment, Services, ConfigMap
kubectl delete deployment dai-ingress-nginx-controller -n digitalai
kubectl delete service dai-ingress-nginx-controller dai-ingress-nginx-controller-admission -n digitalai
kubectl delete configmap dai-ingress-nginx-controller -n digitalai

# ServiceAccounts
kubectl delete serviceaccount dai-ingress-nginx dai-ingress-nginx-admission -n digitalai

# Namespaced Roles and RoleBindings
kubectl delete role dai-ingress-nginx dai-ingress-nginx-admission -n digitalai
kubectl delete rolebinding dai-ingress-nginx dai-ingress-nginx-admission -n digitalai

# Admission webhook Jobs and Secret (Jobs may already be completed)
kubectl delete job dai-ingress-nginx-admission-create dai-ingress-nginx-admission-patch -n digitalai --ignore-not-found
kubectl delete secret dai-ingress-nginx-admission -n digitalai --ignore-not-found

# Cluster-scoped resources
kubectl delete clusterrole dai-ingress-nginx dai-ingress-nginx-admission
kubectl delete clusterrolebinding dai-ingress-nginx dai-ingress-nginx-admission
kubectl delete validatingwebhookconfiguration dai-ingress-nginx-admission
kubectl delete ingressclass nginx-dai

On OpenShift, if SCC was enabled, also remove the SecurityContextConstraints:

# The SCC name follows the pattern: dai-ocp-<shortServerName>-ingress-nginx
# (or dai-ocp-<shortServerName>-<namespace>-ingress-nginx if a custom namespace was used)
kubectl delete scc dai-ocp-<shortServerName>-ingress-nginx
note

These resources were deployed into your product namespace, not into a separate ingress-nginx namespace. The nginx-dai IngressClass and the dai-ingress-nginx-admission ValidatingWebhookConfiguration are cluster-scoped and must be removed separately.

Step 5: Reconfigure Ingress in the CR

For all three cases, manually set spec.ingress (or spec.route on OpenShift) to the correct external ingress class, annotations, hostname, path, and TLS configuration. Do this either just before upgrading, or immediately after, before relying on the application being reachable through ingress.

spec:
ingress:
enabled: true
annotations:
kubernetes.io/ingress.class: <your-external-ingress-class>
# add required annotations for your controller
hostname: "<existing-hostname>"
path: /

Step 6: Upgrade Deploy

Run the xl kube upgrade command. From Deploy 26.3, the upgrade prompts you to select the ingress option: choose external and provide the ingress class of your controller, or none to configure ingress later. On OpenShift, answer the Clean IngressNginx Controller prompt as described in Step 4 if it appears. Your spec.ingress and spec.route values from the previous CR are carried forward automatically for installations already using external, none, or route.

For the full upgrade command reference, see XL Kube Command Reference.

Step 7: Validate

# Application URL resolves
curl -I http://<your-hostname>/

# Ingress resource created correctly
kubectl get ingress -n digitalai
kubectl describe ingress -n digitalai <ingress-name>

Common Ingress Controllers

The following table lists provider-default or provider-managed ingress options first, then common self-managed alternatives.

ProviderDefault or managed optionIngress classNotes
AWS (EKS)AWS Load Balancer Controller (ALB)albStandard ingress choice on EKS for L7 HTTP/HTTPS routing.
GKEGKE Ingress controllergce (external), gce-internal (internal)Built-in managed controller in GKE.
Azure (AKS)Application Routing add-on (managed NGINX)webapprouting.kubernetes.azure.comMicrosoft-managed ingress option for AKS.

Common self-managed alternatives across providers:

ControllerCommon ingress classInstall guide
TraefiktraefikTraefik Helm install
HAProxy IngresshaproxyHAProxy Ingress getting started
Azure Application Gateway Ingress Controller (AGIC)azure/application-gatewayAGIC documentation
caution

Do not select ingress-nginx for new installations, and migrate away from it if currently in use, on any supported version. The upstream project is retired and out of maintenance.

CR Ingress Configuration Examples

The following snippets show the spec.ingress block to use in your Deploy CR. For the full set of supported keys, see the Deploy Helm chart README.

HTTP: plain HTTP through an external ingress controller

spec:
ingress:
enabled: true
annotations:
kubernetes.io/ingress.class: nginx
ingress.kubernetes.io/ssl-redirect: "false"
hostname: "deploy.example.com"
path: /

HTTPS: TLS termination at the ingress controller

The ingress controller handles TLS. The application runs HTTP internally.

spec:
ingress:
enabled: true
annotations:
kubernetes.io/ingress.class: nginx
ingress.kubernetes.io/ssl-redirect: "true"
hostname: "deploy.example.com"
path: /
tls: true
extraTls:
- hosts:
- "deploy.example.com"
secretName: "deploy-tls-secret" # pre-created TLS secret

HTTPS: Traefik ingress controller

spec:
ingress:
enabled: true
annotations:
kubernetes.io/ingress.class: traefik
ingress.kubernetes.io/ssl-redirect: "true"
hostname: "deploy.example.com"
path: /
tls: true
extraTls:
- hosts:
- "deploy.example.com"
secretName: "deploy-tls-secret"

AWS: AWS Load Balancer Controller (ALB)

spec:
ingress:
enabled: true
annotations:
kubernetes.io/ingress.class: alb
alb.ingress.kubernetes.io/scheme: internet-facing
alb.ingress.kubernetes.io/target-type: ip
alb.ingress.kubernetes.io/certificate-arn: "arn:aws:acm:<region>:<account>:certificate/<id>"
hostname: "deploy.example.com"
path: /

No ingress: configure later

spec:
ingress:
enabled: false