The purpose of this post is to provide a condensed, more chronologically ordered view into the various networking concepts and components that need to be taken into account when deploying Azure Container Apps (ACA). By presenting and meshing the concepts of Vnet integration, public vs. private environments, and service discovery, I believe that you can more efficiently understand the networking landscape of ACA. Though not required, if you have some background with Kubernetes, understanding these networking concepts can become easier, as well.
Note: If you're new to ACA and Kubernetes, feel free to glide through this section and go straight to the Agenda.
When first diving into Container Apps, it helps to understand that it's an abstracted form of Kubernetes under the hood. With that in mind, it helps to translate some ACA terms to the more well-known Kubernetes terms. Please note that these terms are conceptually synonymous and not literally synonymous as it pertains to the implementation of the ACA service.
Container App Environment
Kubernetes Service and Deployment
Container App Instances
Container Environment Public/Private Endpoint
Layer-7 Load Balancer Endpoint/Service
By association of the above terms, we can assert the following statements about ACA which also apply to basic Kubernetes clusters:
We'll be touching base on the networking considerations for the following ACA concepts:
App Environments host your apps, but of course.
App Environment integrate internal DNS to allow apps withn the environment to interface with one another, if so desired.
App Environments can have a public endpoint or private endpoint. You have the option or obligation to integrate with a Vnet, respectively. If integrating with a Vnet, zone redundancy is also an option.
Traffic flows can be different despite the use of similar configurational terminology. It's important to distinguish this. I go into more detail in future sections below.
If Vnet integration is desired, a Container App Environment will require exclusive access to a subnet with a minimum size of /23. After the creation of your first Container App, in addition to the ACA and ACA Environment resources created in the portal, an MC_ Resource Group (RG) will also be created for you.
Network Security Groups (NSGs) are the only viable method of securing directional traffic for a subnet hosting your ACA environment. User-defined routes are currently not supported, and inherently, neither are Firewalls (yet). Please refer here for appropriate allow rules needed: Securing a custom VNET in Azure Container Apps | Microsoft Docs
Through DNS resolution, apps can communicate through HTTP/s with one another if the destination app is configured to accept HTTP/s ingress. HTTP/80 and HTTPS/443 are the only acceptable protocols that apps can accept traffic in (at the time of this publishing).
When publishing an app, you have the option of enabling HTTP/s ingress to receive requests from other Apps in that Environment.
Furthermore, you have the option of allowing ingress from outside the environment. Depending on the endpoint configured on the environment, external traffic is classified as:
Reference properties.configuration.ingress.external property below:
kind: containerapp location: uksouth name: hello resourceGroup: aca type: Microsoft.App/containerApps tags: tagname: value properties: managedEnvironmentId: /subscriptions/redacted/resourceGroups/aca/providers/Microsoft.App/managedEnvironments/managedEnvironment-aca-aks-vnet-private-uksouth configuration: activeRevisionsMode: Multiple ingress: external: true allowInsecure: false targetPort: 80 traffic: - latestRevision: true weight: 30 transport: Auto
Translating the yaml above: the presence of ingress asserts that an app accepts HTTP/s ingress within the environment. The external property confirms whether the app will accept traffic from the internet or the Vnet for public or private endpoint environments, respectively. The absence of ingress asserts no ingress is allowed from anywhere for this particular app, including the environment where it's hosted.
For more details refer to: HTTP Ingress
Note: You can have a public environment, and an app with ingress disabled. This effectively isolates it completely. For a workload in which this is applicable, please refer to Background Processing.
Depending on whether external ingress is allowed, your Container App will receive a different FQDN. We'll go into more detail on that in the next section.
Your Container Apps will be reachable through an FQDN:
The external FQDN is:
The internal FQDN is:
The environmentID is generated upon creation of the App Environment and cannot be specified by the user. Thus, it's important to confirm the environmentID prior to creating your apps for the purpose of specifying appropriate Container App env variables which will allow for intra environment communication through the use of an app's fully qualified domain name (FQDN).
The following command will retrieve the environmentID after the creation of the environment:
az containerapp env show --name <environmentName> --resource-group <resourceGroupName> -o tsv --query properties.defaultDomain
Note: If your environment integrates Dapr, your Apps will integrate the appropriate Dapr sidecar. If your app is coded to send requests to it accordingly, the knowledge of apps' FQDN becomes less important thanks to Dapr's service invocation building block.
As previously discussed,
Below you'll see an example of an Azure Private DNS Zone created for environment *.bravebay-8135f561.uksouth.azurecontainerapps.io.
The internal load balancer IP can be found in the MC_ resource group created for your vnet-integrated environment. The above DNS zone asserts that all subdomains for this zone should be resolved to IP 10.241.0.248. When the DNS zone is linked to the integrated Vnet, resources within that Vnet will be able to resolve and reach your Container App. You can also link this private DNS zone to multiple Vnets globally to have resources local to that Vnet resolve the same IP address. With the use of Vnet peering, you can have your requests routed accordingly.
If your Container App is set to ActiveRevisionsMode:Multiple, you have the option of load balancing between revisions.
Within the portal, this process is straight forward. Within the Container App blade, you:
For declarative deployments, yaml can be provided, e.g. az containerapp update --yaml sample.yml --name <containerAppName> --resource-group <rgName>
Below you can see an example of a Container App yaml declaration. These deployments don't necessarily act in an idempotent fashion when it comes to traffic weights for revisions.
The example above asserts the following depending on whether the template for a revision results in the creation of a new revision, the update of an existing revision, or whether the template is not included at all:
Note: If a revision's traffic weight is explicitly declared in the yaml by name, and it's also the latest revision, the traffic values of the explicit declaration and the latestRevision will be summed.
To add a custom domain and cert
Note: If using new certificate, you must have an existing SNI domain certificate to upload it.
It's important to understand the traffic flows for your app depending on whether it's in a public or private environment. It's also important to know the traffic flow of your Vnet resources depending on these same variables. Performing DNS resolution also introduces additional wrinkles depending on these very same variables, as well. It's also important to understand how an App classifies traffic as external. A simple understanding of these overarching items makes the networking landscape of ACA much easier to understand.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.