Migrate from ingress-nginx to NGINX Gateway Fabric and the akash-gateway chart. For a new cluster, use Provider installation (prep) and Provider installation (install) end-to-end instead.
Time: About 30–45 minutes of hands-on work, plus certificate wait time.
Prerequisites
You need working TLS for the Gateway in namespace akash-gateway: TLS Secrets wildcard-ingress-tls and akash-default-tls (chart defaults for listeners https-wildcard and https-custom), and Certificate resources in Ready state where you use Let’s Encrypt. You may use a self-signed placeholder for akash-default-tls as in prep STEP 9 until you replace it.
Check your cluster:
kubectl -n akash-gateway get certificate,secretkubectl -n akash-gateway describe certificate wildcard-ingressIf you are not there yet
-
New cert-manager / first-time Let’s Encrypt for the provider — Complete Provider installation (prep) – STEP 9. The Provider installation (install) document does not install cert-manager. If you are following the full prep doc in order, do STEP 8 (Gateway API and NGF) before STEP 9 so NGF and port 443 match what the Gateway stack needs, or install NGF only once: skip duplicate NGF work between prep and this guide’s STEP 2 below.
-
cert-manager already on the cluster, but certificates for deployers are still attached to the old install (for example
ingress-nginx) — Run TLS migration to Gateway API first, then return here.
What you’ll install
- Gateway API CRDs (experimental, includes
TCPRoute) - NGINX Gateway Fabric with host ports 80, 443, 8443, 8444, 5002
- The
akash-gatewayHelm release (Gateway,TCPRoutes, HTTPS for deployers)
Before you begin
- Prerequisites satisfied (or you will complete TLS migration to Gateway API in parallel)
- Provider on v0.11.2 before upgrading to v0.12.0
kubectland Helm 3ingress-nginxon TCP 8443 and 8444 today- Host ports 80, 443, 8443, 8444, and 5002 available on your nodes
- cert-manager and a
ClusterIssuer(as required by the prerequisite step)
STEP 1: Install Gateway API CRDs
Install the Gateway API CRDs (experimental channel, includes TCPRoute) from NGINX Gateway Fabric. These are required before deploying NGINX Gateway Fabric.
kubectl kustomize "https://github.com/nginx/nginx-gateway-fabric/config/crd/gateway-api/experimental?ref=v2.5.1" | kubectl apply --server-side -f -Verify the CRDs are installed:
kubectl get crd | grep gateway.networking.k8s.ioExpected output:
gatewayclasses.gateway.networking.k8s.iogateways.gateway.networking.k8s.iohttproutes.gateway.networking.k8s.iotcproutes.gateway.networking.k8s.io...STEP 2: Install NGINX Gateway Fabric
If you already installed NGINX Gateway Fabric from Provider installation (prep) – STEP 8 with the same host ports and settings, do not install it again; continue at STEP 3.
On your control plane node, save the following as /root/provider/values-nginx-gateway-fabric.yaml:
nginxGateway: gatewayClassName: nginx gwAPIExperimentalFeatures: enable: true leaderElection: enable: true config: logging: level: info snippets: enable: true resources: requests: cpu: 1000m memory: 1Gi limits: cpu: 1000m memory: 1Gi
nginx: kind: daemonSet service: type: ClusterIP container: hostPorts: - port: 80 containerPort: 80 - port: 443 containerPort: 443 - port: 8443 containerPort: 8443 - port: 8444 containerPort: 8444 - port: 5002 containerPort: 5002 resources: requests: cpu: 1000m memory: 1Gi limits: cpu: 1000m memory: 1GiNote: gwAPIExperimentalFeatures.enable: true is required for TCPRoute support. nginx.kind: daemonSet with ClusterIP service type means NGINX binds directly to host ports on each node rather than using a LoadBalancer. Include port 443 so deployers can reach HTTPS on the Gateway without a second NGF upgrade.
Firewall: allow 443/tcp in addition to your existing provider ports.
Install NGINX Gateway Fabric via Helm:
cd /root/provider
helm install ngf oci://ghcr.io/nginx/charts/nginx-gateway-fabric \ --create-namespace \ -n nginx-gateway \ -f values-nginx-gateway-fabric.yamlVerify the installation:
kubectl -n nginx-gateway get podsExpected output:
NAME READY STATUS RESTARTS AGEngf-nginx-gateway-fabric-xxxxxxxxxx-xxxxx 2/2 Running 0 60sSTEP 3: Install the Akash Gateway (Gateway + TCPRoutes)
The akash-gateway Helm chart creates the Gateway resource, TCPRoutes, and HTTPS listeners named https-wildcard and https-custom. It expects TLS Secrets wildcard-ingress-tls and akash-default-tls (defaults).
Satisfy the prerequisites so wildcard-ingress-tls and akash-default-tls exist in akash-gateway before or alongside this install. If you are still moving Let’s Encrypt off the old stack, do TLS migration to Gateway API first. New clusters follow Provider installation (prep) – STEP 9 and Provider installation (install).
Pass the same domain you use for the provider (for example with -f /root/provider/provider.yaml) so the wildcard host *.ingress.<domain> matches your DNS; only keys this chart uses are read from the file.
helm repo add akash https://akash-network.github.io/helm-chartshelm repo update akash
helm install akash-gateway akash/akash-gateway \ -n akash-gateway \ --create-namespace \ -f /root/provider/provider.yamlVerify
kubectl -n akash-gateway get gateway akash-gatewaykubectl -n akash-services get tcproutesExpected output:
# GatewayNAME CLASS ADDRESS PROGRAMMED AGEakash-gateway nginx True 30s
# TCPRoutesNAME AGEakash-provider-8443 15sakash-provider-8444 15sSTEP 4: Upgrade Provider to v0.12.0
With the Gateway resources in place, upgrade the Akash provider Helm charts to v0.12.0.
Update Helm Repo
helm repo update akashVerify the expected chart versions are available:
helm search repo akashExpected output:
NAME CHART VERSION APP VERSIONakash/akash-hostname-operator 16.0.0 0.12.0akash/akash-inventory-operator 16.0.0 0.12.0akash/akash-ip-operator 16.0.0 0.12.0akash/akash-node 17.1.1 2.0.1akash/provider 16.0.0 0.12.0Backup Current Chart Values
cd /root/providerfor i in $(helm list -n akash-services -q | grep -vw akash-node); do helm -n akash-services get values $i > ${i}.pre-v0.12.0.values; doneUpgrade Operators
helm -n akash-services upgrade akash-hostname-operator akash/akash-hostname-operatorhelm -n akash-services upgrade inventory-operator akash/akash-inventory-operatorWith persistent storage (adjust storage class to match your setup):
helm -n akash-services upgrade inventory-operator akash/akash-inventory-operator \ --set inventoryConfig.cluster_storage[0]=default \ --set inventoryConfig.cluster_storage[1]=beta3 \ --set inventoryConfig.cluster_storage[2]=ramWith IP leasing (MetalLB):
helm -n akash-services upgrade akash-ip-operator akash/akash-ip-operatorUpgrade Provider
cd /root/provider
helm upgrade akash-provider akash/provider \ -n akash-services \ -f provider.yaml \ --set bidpricescript="$(cat price_script_generic.sh | openssl base64 -A)"Verify Pod Versions
Allow a minute or two for Kubernetes to apply the changes, then confirm all pods are running v0.12.0:
kubectl -n akash-services get pods -o custom-columns='NAME:.metadata.name,IMAGE:.spec.containers[*].image'All provider, hostname-operator, and inventory-operator images should reference 0.12.0.
STEP 5: Uninstall ingress-nginx
With the provider upgraded and NGINX Gateway Fabric handling all traffic on ports 80, 443, 8443, 8444, and 5002, ingress-nginx is no longer needed and can be removed.
helm uninstall ingress-nginx -n ingress-nginxVerify all ingress-nginx resources are removed:
kubectl -n ingress-nginx get podsExpected output:
No resources found in ingress-nginx namespace.Verification
Check Provider Endpoints
Verify that the provider endpoints are accessible through the new gateway:
# Replace provider.example.com with your provider domaincurl -k https://provider.example.com:8443/statusVerify TCPRoute Status
kubectl -n akash-services describe tcproute akash-provider-8443kubectl -n akash-services describe tcproute akash-provider-8444Look for ResolvedRefs and Accepted conditions showing True in the output.
Check NGINX Gateway Fabric Logs
kubectl -n nginx-gateway logs -l app.kubernetes.io/name=nginx-gateway-fabric -c nginx-gatewayVerify No Port Conflicts
Confirm no two processes are bound to the same host ports:
# Run on each node in your clusterss -tlnp | grep -E ':(80|443|8443|8444|5002)\s'Each port should appear only once, owned by the NGINX Gateway Fabric process.
Troubleshooting
Issue: Gateway Shows Programmed: False
Symptoms:
kubectl get gateway akash-gatewayshowsPROGRAMMED: False- TCPRoutes remain unresolved
Diagnosis:
kubectl -n akash-gateway describe gateway akash-gatewaySolution:
Verify NGINX Gateway Fabric pods are running and the GatewayClass was registered:
kubectl -n nginx-gateway get podskubectl get gatewayclass nginxIf the GatewayClass is missing, the Helm install may have failed. Re-run the Helm install from Step 2.
Issue: TCPRoute ResolvedRefs is False
Symptoms:
kubectl describe tcproute akash-provider-8443shows backend not found
Diagnosis:
kubectl -n akash-services get service akash-providerSolution:
Confirm the akash-provider service exists in the akash-services namespace and exposes the expected ports:
kubectl -n akash-services get service akash-provider -o yaml | grep -A 20 portsThe service must have ports 8443 and 8444 defined.
Issue: Port Conflict on Node
Symptoms:
- NGINX Gateway Fabric pods fail to start or crash-loop
- Error in pod logs:
bind: address already in use
Solution:
Check which process holds the port on the affected node:
ss -tlnp | grep -E ':(80|443|8443|8444|5002)\s'If ingress-nginx still holds the ports, ensure it was fully uninstalled in Step 5:
helm list -n ingress-nginxIf the release still exists, uninstall it:
helm uninstall ingress-nginx -n ingress-nginxRelated resources
- TLS migration to Gateway API — old
Certificateand Secrets →akash-gateway - Provider installation (prep) —
provider.yaml, DNS, NGF, STEP 8–9 (Let’s Encrypt, TLS Secrets) - Provider installation (install) —
helm installforakash-gateway, operators, andakash/provider - Provider installation (prep) – STEP 9 (TLS) — cert-manager,
wildcard-ingress-tls/akash-default-tls, troubleshooting - Updates & maintenance
- Provider verification
- NGINX Gateway Fabric
- Kubernetes Gateway API