Multi-site hosting with Application Gateway for Containers - Ingress API
This document helps you set up an example application that uses the Ingress API to demonstrate hosting multiple sites on the same Kubernetes Ingress resource / Application Gateway for Containers frontend. Steps are provided to:
- Create an Ingress resource with two hosts.
Background
Application Gateway for Containers enables multi-site hosting by allowing you to configure more than one web application on the same port. Two or more unique sites can be hosted using unique backend services. See the following example scenario:
Prerequisites
If you used the BYO deployment strategy, ensure that you set up your Application Gateway for Containers resources and ALB Controller.
If you used the ALB managed deployment strategy, ensure provisioning of your ALB Controller and the Application Gateway for Containers resources via the ApplicationLoadBalancer custom resource.
Deploy sample HTTP application:
Apply the following deployment.yaml file on your cluster to create a sample web application to demonstrate path, query, and header based routing.kubectl apply -f https://raw.githubusercontent.com/MicrosoftDocs/azure-docs/refs/heads/main/articles/application-gateway/for-containers/examples/traffic-split-scenario/deployment.yaml
This command creates the following on your cluster:
- A namespace called
test-infra
- Two services called
backend-v1
andbackend-v2
in thetest-infra
namespace - Two deployments called
backend-v1
andbackend-v2
in thetest-infra
namespace
- A namespace called
Deploy the required Ingress resource
- Create an Ingress
kubectl apply -f - <<EOF
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-01
namespace: test-infra
annotations:
alb.networking.azure.io/alb-name: alb-test
alb.networking.azure.io/alb-namespace: alb-test-infra
spec:
ingressClassName: azure-alb-external
rules:
- host: contoso.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: backend-v1
port:
number: 8080
- host: fabrikam.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: backend-v2
port:
number: 8080
EOF
Once the ingress resource is created, ensure the status shows the hostname of your load balancer and that both ports are listening for requests.
kubectl get ingress ingress-01 -n test-infra -o yaml
Example output of successful Ingress creation.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
alb.networking.azure.io/alb-frontend: FRONTEND_NAME
alb.networking.azure.io/alb-id: /subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourcegroups/yyyyyyyy/providers/Microsoft.ServiceNetworking/trafficControllers/zzzzzz
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"networking.k8s.io/v1","kind":"Ingress","metadata":{"annotations":{"alb.networking.azure.io/alb-frontend":"FRONTEND_NAME","alb.networking.azure.io/alb-id":"/subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourcegroups/yyyyyyyy/providers/Microsoft.ServiceNetworking/trafficControllers/zzzzzz"},"name"
:"ingress-01","namespace":"test-infra"},"spec":{"ingressClassName":"azure-alb-external","rules":[{"host":"example.com","http":{"paths":[{"backend":{"service":{"name":"echo","port":{"number":80}}},"path":"/","pathType":"Prefix"}]}}],"tls":[{"hosts":["example.com"],"secretName":"listener-tls-secret"}]}}
creationTimestamp: "2023-07-22T18:02:13Z"
generation: 2
name: ingress-01
namespace: test-infra
resourceVersion: "278238"
uid: 17c34774-1d92-413e-85ec-c5a8da45989d
spec:
ingressClassName: azure-alb-external
rules:
- host: contoso.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: backend-v1
port:
number: 8080
- host: fabrikam.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: backend-v2
port:
number: 8080
status:
loadBalancer:
ingress:
- hostname: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.fzyy.alb.azure.com
ports:
- port: 80
protocol: TCP
Test access to the application
Now we're ready to send some traffic to our sample application, via the FQDN assigned to the frontend. Use the following command to get the FQDN.
fqdn=$(kubectl get ingress ingress-01 -n test-infra -o jsonpath='{.status.loadBalancer.ingress[0].hostname}')
Next, specify the server name indicator using the curl command, contoso.com
for the frontend FQDN should return a response from the backend-v1 service.
fqdnIp=$(dig +short $fqdn)
curl -k --resolve contoso.com:80:$fqdnIp http://contoso.com
Via the response we should see:
{
"path": "/",
"host": "contoso.com",
"method": "GET",
"proto": "HTTP/1.1",
"headers": {
"Accept": [
"*/*"
],
"User-Agent": [
"curl/7.81.0"
],
"X-Forwarded-For": [
"xxx.xxx.xxx.xxx"
],
"X-Forwarded-Proto": [
"http"
],
"X-Request-Id": [
"dcd4bcad-ea43-4fb6-948e-a906380dcd6d"
]
},
"namespace": "test-infra",
"ingress": "",
"service": "",
"pod": "backend-v1-5b8fd96959-f59mm"
}
Next, specify server name indicator using the curl command, fabrikam.com
for the frontend FQDN should return a response from the backend-v1 service.
fqdnIp=$(dig +short $fqdn)
curl -k --resolve fabrikam.com:80:$fqdnIp http://fabrikam.com
Via the response we should see:
{
"path": "/",
"host": "fabrikam.com",
"method": "GET",
"proto": "HTTP/1.1",
"headers": {
"Accept": [
"*/*"
],
"User-Agent": [
"curl/7.81.0"
],
"X-Forwarded-For": [
"xxx.xxx.xxx.xxx"
],
"X-Forwarded-Proto": [
"http"
],
"X-Request-Id": [
"adae8cc1-8030-4d95-9e05-237dd4e3941b"
]
},
"namespace": "test-infra",
"ingress": "",
"service": "",
"pod": "backend-v2-594bd59865-ppv9w"
}
Congratulations, you've installed ALB Controller, deployed a backend application, and routed traffic to two different backend services using different hostnames with the Ingress API on Application Gateway for Containers.