Author : MD TAREQ HASSAN | Updated : 2021/05/05
What Is Application Gateway Ingress Controller?
- Application Gateway Ingress Controller (AGIC) is a combination of K8s ingress controller and Azure Application Gateway. Combindly they provide K8s ingress (http/https traffic to K8s services)
- AGIC eliminates need for multiple load balancers (uses single load balancer)
- AGIC provides url routing for internet or intranet applications using single public IP address
- Azure Application Gateway provides SSL termication, WAF etc.
How Does AGIC Work?
- When ingress is enabled in AKS, K8s ingress controller is deployed to AKS cluster as Pod
- Based on the ingress rules specified (in ingress manifest file), AGIC will instruct Azure Resource Manager (ARM)
- ARM will deploy Azure Application Gateway and configure it accordingly so that traffic is routed to K8s services properly
- AGIC monitors a subset of Kubernetes Resources for changes and te state of the AKS cluster is translated to Application Gateway specific configuration and applied to ARM
AGIC Add-on with Existing Application Gateway
Points to be noted When AGIC addon is enabled with existing Application Gateway
- A user defined managed idenity named
ingressapplicationgateway-<aks-cluster-name>
is created in node resource group (AKS infrastructure resource group) ingressapplicationgateway-<aks-cluster-name>
will have “Contributor” role at node resource groupingressapplicationgateway-<aks-cluster-name>
must have “Contributor” role at existing Application Gateway (or at the resource group where Application Gateway belongs)- Create new User Assigned Managed Identity and assign role (i.e. in case of Pulumi Azure Native) or you might need to add “Contributor” role manually
Enabling AGIC Add-on
Prerequisites
- Create an Application Gateway
- If Application Gateway is in different VNet (Hub VNet), do either of followings
- Connect 2 VNets (Hub and Spoke) with VNet peering
- A VNet peer will automatically be created when AGIC add-on is enabled in portal
Enable AGIC in Azure portal (AKS Add-on)
- Azure portal > AKS
- Settings: Networking > Enable ingress controller
- Select existing ‘Application gateway’ or new ‘Application gateway’ will be provisioned
Creating A Basic Ingress
See:
Using custom domain
- Purchase App Service Domain and a DNS zone will automatically be created with it
- Add records for Public IP of Application Gateway
- Alias record for Public IP of Application Gateway
- CNAME record for DNS label (FQDN) of Public IP of Application Gateway
- In K8s manifest file > Ingress section: ‘
host: <url_of_app_gateway_ip>
’ - K8s manifest yaml sample
Ingress For Multiple APIs
- API project setup
API.Foo
&API.Bar
: https://github.com/hovermind/AKSDeployDemos- APIs are served under base uri
/api
(i.e./api/foo/foo-list
) - Routing in API projects are defined accordingly to serve under same domain
- See: API controller in ASP.Net Core
- Push API images (publish from Visual Studio or push from DevOps pipeline) to Azure Container Registry (ACR)
- Create ingresses for APIs
Create 2 API Projects: API.Foo and API.Bar
‘API.Foo’ project (Foo microservice): Controllers/FooController.cs
using Microsoft.AspNetCore.Mvc;
namespace API.Foo.Controllers
{
[ApiController]
[Route("api/foo")]
public class FooController : ControllerBase
{
[HttpGet("")]
public string Index()
{
return "FooController.Index()";
}
[HttpGet("test")]
public string Test()
{
return "FooController.Test()";
}
[HttpGet("bax")]
public string Bax()
{
return "FooController.Bax()";
}
}
}
‘API.Bar’ project (Bar microservice): Controllers/BarController.cs
using Microsoft.AspNetCore.Mvc;
namespace API.Bar.Controllers
{
[ApiController]
[Route("api/bar")]
public class BarController : ControllerBase
{
[HttpGet("")]
public string Index()
{
return "BarController.Index()";
}
[HttpGet("test")]
public string Test()
{
return "BarController.Test()";
}
[HttpGet("bax")]
public string Bax()
{
return "BarController.Bax()";
}
}
}
Publish API Projects To ACR
- Create Azure container registry (ACR)
- Publish “
API.Foo
” and “API.Bar
” projects to ACR
Create Ingresses
- Assuming that a DNS label i.e. “
agic-gateway-pip.japaneast.cloudapp.azure.com
” is given to public IP of Application Gateway - Ingress host: “
agic-gateway-pip.japaneast.cloudapp.azure.com
” - “
backend-path-prefix
” annotation (“appgw.ingress.kubernetes.io/backend-path-prefix
”) will be used:- Foo API ingress: “
/api/foo/
” - Bar API ingress: “
/api/bar/
”
- Foo API ingress: “
- Ingress paths:
- Foo API: “
path: /api/foo/*
” - Bar API: “
path: /api/bar/*
”
- Foo API: “
- Ingress paths will be overridden by “
backend-path-prefix
” and therefore we designed our API accordingly:- ”
/api/foo/*
” –> “/api/foo/” and “/api/bar/*
” –> “/api/bar/” - Example
- Request url: “
agic-gateway-pip.japaneast.cloudapp.azure.com/api/foo/test
” - Backend (API running as K8s Pod):
FooController.Test()
- Request url: “
- ”
Deploy and Test
- K8s manifest file: Deployment, service and ingress yaml sample
- Testing
- Go to: http://agic-gateway-pip.japaneast.cloudapp.azure.com/api/foo
- Check that
FooController
actions are being called accordingly
Links
- https://github.com/Azure/application-gateway-kubernetes-ingress/tree/master/docs
- https://docs.microsoft.com/en-us/azure/application-gateway/ingress-controller-overview
- https://docs.microsoft.com/en-us/azure/aks/ingress-basic
- https://docs.microsoft.com/en-us/azure/application-gateway/tutorial-ingress-controller-add-on-new
- https://docs.microsoft.com/en-us/azure/application-gateway/tutorial-ingress-controller-add-on-existing