Migrate to Envoy Gateway
Upbound recommends migrating from the Ingress API to the Gateway API for routing traffic to control planes. This changes addresses critical security issues and aligns with the Kuberenetes community decision to retire ingress-nginx in March 2026.
How?
To migrate from ingress-nginx to Envoy Gateway, you must delete your current ingress resource and controller and install the Gateway API implementation with TLS passthrough enabled.
1. Remove existing Ingress resources
Delete the Ingress resource and ingress-nginx controller:
kubectl -n upbound-system delete ingress mxe-router-ingress
helm -n ingress-nginx delete ingress-nginx
This step forces downtime for API access through spaces-router until the Gateway API configuration is complete.
2. Install a Gateway API controller
Install a Gateway API implementation that supports TLS passthrough and TLSRoute.
The following example uses Envoy Gateway:
export ENVOY_GATEWAY_VERSION=v1.2.4
helm -n envoy-gateway-system upgrade --install --wait --wait-for-jobs \
--timeout 300s --create-namespace envoy-gateway \
oci://docker.io/envoyproxy/gateway-helm \
--version "${ENVOY_GATEWAY_VERSION}"
3. Create GatewayClass resource
Create a GatewayClass resource appropriate for your cloud provider.
kubectl apply -f - --server-side <<EOF
apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata:
name: spaces
spec:
controllerName: gateway.envoyproxy.io/gatewayclass-controller
parametersRef:
group: gateway.envoyproxy.io
kind: EnvoyProxy
name: spaces-proxy-config
namespace: envoy-gateway-system
EOF
4. Create Gateway resource
Create a Gateway resource in the upbound-system namespace.
kubectl apply -f - --server-side <<EOF
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: spaces
namespace: upbound-system
spec:
gatewayClassName: spaces
listeners:
- name: tls
port: 443
protocol: TLS
allowedRoutes:
namespaces:
from: Same
tls:
mode: Passthrough
EOF
During installation or upgrade, you can use the Spaces Helm chart to create the Gateway automatically with these parameters:
gatewayAPI.gateway.provision=truegatewayAPI.gateway.className=spaces
5. Get the load balancer hostname
Check the externally routable hostname for the Gateway's load balancer.
The Helm gatewayAPI.host parameter requires this hostname.
For Envoy Gateway, inspect the LoadBalancer service:
kubectl get service -n envoy-gateway-system \
-l gateway.envoyproxy.io/owning-gateway-name=spaces \
-o jsonpath='{.items[0].status.loadBalancer.ingress[0].hostname}'
6. Upgrade the Spaces Helm release
Upgrade the Spaces installation with Gateway API parameters:
helm -n upbound-system upgrade spaces \
oci://xpkg.upbound.io/spaces-artifacts/spaces \
--version "${SPACES_VERSION}" \
--set "ingress.provision=false" \
--set "gatewayAPI.host=${GATEWAY_HOSTNAME}" \
--set "account=${UPBOUND_ACCOUNT}" \
--reuse-values \
--wait
7. Restart spaces-router (Optional)
If the gatewayAPI.host value differs from the previous ingress.host value,
restart the spaces-router pod to regenerate the certificate with the correct SAN
(Subject Alternative Name):
kubectl -n upbound-system rollout restart deployment spaces-router
kubectl -n upbound-system rollout status deployment spaces-router