Events
Mar 17, 11 PM - Mar 21, 11 PM
Join the meetup series to build scalable AI solutions based on real-world use cases with fellow developers and experts.
Register nowThis browser is no longer supported.
Upgrade to Microsoft Edge to take advantage of the latest features, security updates, and technical support.
The application routing add-on supports two ways to configure ingress controllers and ingress objects:
An AKS cluster with the application routing add-on.
To connect to the Kubernetes cluster from your local computer, you use kubectl
, the Kubernetes command-line client. You can install it locally using the az aks install-cli command. If you use the Azure Cloud Shell, kubectl
is already installed.
Configure kubectl to connect to your Kubernetes cluster using the az aks get-credentials
command.
az aks get-credentials --resource-group <ResourceGroupName> --name <ClusterName>
The application routing add-on uses a Kubernetes custom resource definition (CRD) called NginxIngressController
to configure NGINX ingress controllers. You can create more ingress controllers or modify existing configuration.
This table shows a mapping between the application routing operator version and the Kubernetes version.
Kubernetes version | Operator version |
---|---|
<1.30 | 0.2.1-patch-7 |
>=1.30 | 0.2.3-patch-5 |
This table shows a reference to properties you can set to configure an NginxIngressController
and the corresponding operator version.
Property | Operator version | Description |
---|---|---|
ingressClassName | 0.1.0+ | The name of the IngressClass that is used for the NGINX Ingress Controller. Defaults to the name of the NginxIngressController if not specified. |
controllerNamePrefix | 0.1.0+ | A name used to prefix the managed NGINX ingress controller resources. Defaults to nginx . |
loadBalancerAnnotations | 0.1.0+ | A set of annotations to control the behavior of the NGINX ingress controller's service by setting load balancer annotations |
scaling | Configuration options for how the NGINX Ingress Controller scales. | |
scaling.minReplicas | 0.2.2+ | The lower limit for the number of Ingress Controller replicas. It defaults to 2 pods. |
scaling.maxReplicas | 0.2.2+ | The upper limit for the number of Ingress Controller replicas. It defaults to 100 pods. |
scaling.threshold | 0.2.2+ | Defines how quickly the NGINX Ingress Controller pods should scale based on workload. Rapid means the Ingress Controller scales quickly and aggressively for handling sudden and significant traffic spikes. Steady prioritizes cost-effectiveness with fewer replicas handling more work. Balanced is a good mix between the two that works for most use-cases. If unspecified, this field defaults to Balanced . |
defaultSSLCertificate | The secret referred to by this property contains the default certificate to be used when accessing the default backend service. If this property is not provided NGINX uses a self-signed certificate. If the tls: section is not set on an Ingress, NGINX provides the default certificate but will not force HTTPS redirect. |
|
defaultSSLCertificate.keyVaultURI | 0.2.2+ | The Azure Key Vault URI where the default SSL certificate can be found. The add-on needs to be configured to use the key vault. |
defaultSSLCertificate.secret | 0.2.2+ | Configures the name and namespace where the default SSL secret is on the cluster. |
defaultSSLCertificate.secret.name | 0.2.2+ | Name of the secret. |
defaultSSLCertificate.secret.namespace | 0.2.2+ | Namespace of the secret. |
Note
Controlling the NGINX ingress controller configuration when enabling the add-on is available in API 2024-06-02-preview
, Kubernetes version 1.30 or later, and the aks-preview Azure CLI extension version 7.0.0b5
or later. To check your AKS cluster version, see Check for available AKS cluster upgrades.
When you enable the application routing add-on with NGINX, it creates an ingress controller called default
in the app-routing-namespace
configured with a public facing Azure load balancer. That ingress controller uses an ingress class name of webapprouting.kubernetes.azure.com
.
You can also control if the default gets a public or an internal IP, or if it gets created at all when enabling the add-on.
Here are the possible configuration options:
None
: The default Nginx ingress controller is not created and will not be deleted if it already exists. Users should delete the default NginxIngressController
custom resource manually if desired.Internal
: The default Nginx ingress controller is created with an internal load balancer. Any annotations changes on the NginxIngressController
custom resource to make it external will be overwritten.External
: The default Nginx ingress controller created with an external load balancer. Any annotations changes on the NginxIngressController
custom resource to make it internal will be overwritten.AnnotationControlled
(default): The default Nginx ingress controller is created with an external load balancer. Users can edit the default NginxIngressController
custom resource to configure load balancer annotations.To enable application routing on a new cluster, use the az aks create
command, specifying the --enable-app-routing
and the --app-routing-default-nginx-controller
flags. You need to set the <DefaultIngressControllerType>
to one of the configuration options described earlier.
az aks create \
--resource-group <ResourceGroupName> \
--name <ClusterName> \
--location <Location> \
--enable-app-routing \
--app-routing-default-nginx-controller <DefaultIngressControllerType>
To update the application routing default ingress controller configuration on an existing cluster, use the az aks approuting update
command, specifying the --nginx
flag. You need to set the <DefaultIngressControllerType>
to one of the configuration options described earlier.
az aks approuting update --resource-group <ResourceGroupName> --name <ClusterName> --nginx <DefaultIngressControllerType>
To create another NGINX ingress controller with a public facing Azure Load Balancer:
Copy the following YAML manifest into a new file named nginx-public-controller.yaml and save the file to your local computer.
apiVersion: approuting.kubernetes.azure.com/v1alpha1
kind: NginxIngressController
metadata:
name: nginx-public
spec:
ingressClassName: nginx-public
controllerNamePrefix: nginx-public
Create the NGINX ingress controller resources using the kubectl apply
command.
kubectl apply -f nginx-public-controller.yaml
The following example output shows the created resource:
nginxingresscontroller.approuting.kubernetes.azure.com/nginx-public created
To create an NGINX ingress controller with an internal facing Azure Load Balancer with a private IP address:
Copy the following YAML manifest into a new file named nginx-internal-controller.yaml and save the file to your local computer.
apiVersion: approuting.kubernetes.azure.com/v1alpha1
kind: NginxIngressController
metadata:
name: nginx-internal
spec:
ingressClassName: nginx-internal
controllerNamePrefix: nginx-internal
loadBalancerAnnotations:
service.beta.kubernetes.io/azure-load-balancer-internal: "true"
Create the NGINX ingress controller resources using the kubectl apply
command.
kubectl apply -f nginx-internal-controller.yaml
The following example output shows the created resource:
nginxingresscontroller.approuting.kubernetes.azure.com/nginx-internal created
To create an NGINX ingress controller with a static IP address on the Azure Load Balancer:
Create an Azure resource group using the az group create
command.
az group create --name myNetworkResourceGroup --location eastus
Create a static public IP address using the az network public ip create
command.
az network public-ip create \
--resource-group myNetworkResourceGroup \
--name myIngressPublicIP \
--sku Standard \
--allocation-method static
Note
If you're using a Basic SKU load balancer in your AKS cluster, use Basic for the --sku
parameter when defining a public IP. Only Basic SKU IPs work with the Basic SKU load balancer and only Standard SKU IPs work with Standard SKU load balancers.
Ensure the cluster identity used by the AKS cluster has delegated permissions to the public IP's resource group using the az role assignment create
command.
Note
Update <ClusterName>
and <ClusterResourceGroup>
with your AKS cluster's name and resource group name.
CLIENT_ID=$(az aks show --name <ClusterName> --resource-group <ClusterResourceGroup> --query identity.principalId -o tsv)
RG_SCOPE=$(az group show --name myNetworkResourceGroup --query id -o tsv)
az role assignment create \
--assignee ${CLIENT_ID} \
--role "Network Contributor" \
--scope ${RG_SCOPE}
Copy the following YAML manifest into a new file named nginx-staticip-controller.yaml and save the file to your local computer.
Note
You can either use service.beta.kubernetes.io/azure-pip-name
for public IP name, or use service.beta.kubernetes.io/azure-load-balancer-ipv4
for an IPv4 address and service.beta.kubernetes.io/azure-load-balancer-ipv6
for an IPv6 address, as shown in the example YAML. Adding the service.beta.kubernetes.io/azure-pip-name
annotation ensures the most efficient LoadBalancer creation and is highly recommended to avoid potential throttling.
apiVersion: approuting.kubernetes.azure.com/v1alpha1
kind: NginxIngressController
metadata:
name: nginx-static
spec:
ingressClassName: nginx-static
controllerNamePrefix: nginx-static
loadBalancerAnnotations:
service.beta.kubernetes.io/azure-pip-name: "myIngressPublicIP"
service.beta.kubernetes.io/azure-load-balancer-resource-group: "myNetworkResourceGroup"
Create the NGINX ingress controller resources using the kubectl apply
command.
kubectl apply -f nginx-staticip-controller.yaml
The following example output shows the created resource:
nginxingresscontroller.approuting.kubernetes.azure.com/nginx-static created
You can verify the status of the NGINX ingress controller using the kubectl get nginxingresscontroller
command.
Note
Update <IngressControllerName>
with name you used when creating the `NginxIngressController``.
kubectl get nginxingresscontroller -n <IngressControllerName>
The following example output shows the created resource. It may take a few minutes for the controller to be available:
NAME INGRESSCLASS CONTROLLERNAMEPREFIX AVAILABLE
nginx-public nginx-public nginx True
You can also view the conditions to troubleshoot any issues:
kubectl get nginxingresscontroller -n <IngressControllerName> -o jsonpath='{range .items[*].status.conditions[*]}{.lastTransitionTime}{"\t"}{.status}{"\t"}{.type}{"\t"}{.message}{"\n"}{end}'
The following example output shows the conditions of a healthy ingress controller:
2023-11-29T19:59:24Z True IngressClassReady Ingress Class is up-to-date
2023-11-29T19:59:50Z True Available Controller Deployment has minimum availability and IngressClass is up-to-date
2023-11-29T19:59:50Z True ControllerAvailable Controller Deployment is available
2023-11-29T19:59:25Z True Progressing Controller Deployment has successfully progressed
Copy the following YAML manifest into a new file named ingress.yaml and save the file to your local computer.
Note
Update <Hostname>
with your DNS host name.
The <IngressClassName>
is the one you defined when creating the NginxIngressController
.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: aks-helloworld
namespace: hello-web-app-routing
spec:
ingressClassName: <IngressClassName>
rules:
- host: <Hostname>
http:
paths:
- backend:
service:
name: aks-helloworld
port:
number: 80
path: /
pathType: Prefix
Create the cluster resources using the kubectl apply
command.
kubectl apply -f ingress.yaml -n hello-web-app-routing
The following example output shows the created resource:
ingress.networking.k8s.io/aks-helloworld created
You can verify the managed Ingress was created using the kubectl get ingress
command.
kubectl get ingress -n hello-web-app-routing
The following example output shows the created managed Ingress. The ingress class, host, and IP address may be different:
NAME CLASS HOSTS ADDRESS PORTS AGE
aks-helloworld webapprouting.kubernetes.azure.com myapp.contoso.com 20.51.92.19 80, 443 4m
You can remove the NGINX ingress controller using the kubectl delete nginxingresscontroller
command.
Note
Update <IngressControllerName>
with name you used when creating the NginxIngressController
.
kubectl delete nginxingresscontroller -n <IngressControllerName>
The NGINX ingress controller supports adding annotations to specific Ingress objects to customize their behavior.
You can annotate the ingress object by adding the respective annotation in the metadata.annotations
field.
Note
Annotation keys and values can only be strings. Other types, such as boolean or numeric values must be quoted, i.e. "true"
, "false"
, "100"
.
Here are some examples annotations for common configurations. Review the NGINX ingress annotations documentation for a full list.
For NGINX, a 413 error is returned to the client when the size in a request exceeds the maximum allowed size of the client request body. To override the default value, use the annotation:
nginx.ingress.kubernetes.io/proxy-body-size: 4m
Here's an example ingress configuration using this annotation:
Note
Update <Hostname>
with your DNS host name.
The <IngressClassName>
is the one you defined when creating the NginxIngressController
.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: aks-helloworld
namespace: hello-web-app-routing
annotations:
nginx.ingress.kubernetes.io/proxy-body-size: 4m
spec:
ingressClassName: <IngressClassName>
rules:
- host: <Hostname>
http:
paths:
- backend:
service:
name: aks-helloworld
port:
number: 80
path: /
pathType: Prefix
You can change the time out that the NGINX ingress controller waits to close a connection with your workload. All time out values are unitless and in seconds. To override the default time out, use the following annotation to set a valid 120-seconds proxy read time out:
nginx.ingress.kubernetes.io/proxy-read-timeout: "120"
Review custom time outs for other configuration options.
Here's an example ingress configuration using this annotation:
Note
Update <Hostname>
with your DNS host name.
The <IngressClassName>
is the one you defined when creating the NginxIngressController
.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: aks-helloworld
namespace: hello-web-app-routing
annotations:
nginx.ingress.kubernetes.io/proxy-read-timeout: "120"
spec:
ingressClassName: <IngressClassName>
rules:
- host: <Hostname>
http:
paths:
- backend:
service:
name: aks-helloworld
port:
number: 80
path: /
pathType: Prefix
By default the NGINX ingress controller uses HTTP
to reach the services. To configure alternative backend protocols such as HTTPS
or GRPC
, use the annotation:
nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
or
nginx.ingress.kubernetes.io/backend-protocol: "GRPC"
Review backend protocols for other configuration options.
Here's an example ingress configuration using this annotation:
Note
Update <Hostname>
with your DNS host name.
The <IngressClassName>
is the one you defined when creating the NginxIngressController
.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: aks-helloworld
namespace: hello-web-app-routing
annotations:
nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
spec:
ingressClassName: <IngressClassName>
rules:
- host: <Hostname>
http:
paths:
- backend:
service:
name: aks-helloworld
port:
number: 80
path: /
pathType: Prefix
To enable Cross-Origin Resource Sharing (CORS) in an Ingress rule, use the annotation:
nginx.ingress.kubernetes.io/enable-cors: "true"
Review enable CORS for other configuration options.
Here's an example ingress configuration using this annotation:
Note
Update <Hostname>
with your DNS host name.
The <IngressClassName>
is the one you defined when creating the NginxIngressController
.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: aks-helloworld
namespace: hello-web-app-routing
annotations:
nginx.ingress.kubernetes.io/enable-cors: "true"
spec:
ingressClassName: <IngressClassName>
rules:
- host: <Hostname>
http:
paths:
- backend:
service:
name: aks-helloworld
port:
number: 80
path: /
pathType: Prefix
By default the controller redirects (308) to HTTPS if TLS is enabled for an ingress. To disable this feature for specific ingress resources, use the annotation:
nginx.ingress.kubernetes.io/ssl-redirect: "false"
Review server-side HTTPS enforcement through redirect for other configuration options.
Here's an example ingress configuration using this annotation:
Note
Update <Hostname>
with your DNS host name.
The <IngressClassName>
is the one you defined when creating the NginxIngressController
.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: aks-helloworld
namespace: hello-web-app-routing
annotations:
nginx.ingress.kubernetes.io/ssl-redirect: "false"
spec:
ingressClassName: <IngressClassName>
rules:
- host: <Hostname>
http:
paths:
- backend:
service:
name: aks-helloworld
port:
number: 80
path: /
pathType: Prefix
In some scenarios, the exposed URL in the backend service differs from the specified path in the Ingress rule. Without a rewrite any request returns 404. This configuration is useful with path based routing where you can serve two different web applications under the same domain. You can set path expected by the service using the annotation:
nginx.ingress.kubernetes.io/rewrite-target": /$2
Here's an example ingress configuration using this annotation:
Note
Update <Hostname>
with your DNS host name.
The <IngressClassName>
is the one you defined when creating the NginxIngressController
.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: aks-helloworld
namespace: hello-web-app-routing
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$2
nginx.ingress.kubernetes.io/use-regex: "true"
spec:
ingressClassName: <IngressClassName>
rules:
- host: <Hostname>
http:
paths:
- path: /app-one(/|$)(.*)
pathType: Prefix
backend:
service:
name: app-one
port:
number: 80
- path: /app-two(/|$)(.*)
pathType: Prefix
backend:
service:
name: app-two
port:
number: 80
Learn about monitoring the ingress-nginx controller metrics included with the application routing add-on with with Prometheus in Grafana as part of analyzing the performance and usage of your application.
Azure Kubernetes Service feedback
Azure Kubernetes Service is an open source project. Select a link to provide feedback:
Events
Mar 17, 11 PM - Mar 21, 11 PM
Join the meetup series to build scalable AI solutions based on real-world use cases with fellow developers and experts.
Register nowTraining
Learning path
Use advance techniques in canvas apps to perform custom updates and optimization - Training
Use advance techniques in canvas apps to perform custom updates and optimization