ACI allows us to start a Docker Container without a cluster, without even a VM.
It is ideal for bursting, recurrent jobs and dev-test.
We are going to focus on ACI in this article.
Fundamentals of Azure Container Instance
In order to create an ACI, we need to point it to a Docker Image from a Docker Registry. That could be the Docker Hub or our own private Azure Container Registry. It could also be any other registry accessible over the internet.
That’s the only mandatory aspect. There are a bunch of options though:
- We can associate a DNS label with the container. That is a prefix to the standard <prefix>.<region>.azurecontainer.io. For instance, myprefix.eastus.azurecontainer.io. ACI will create a public IP with that name.
- We can then map ports. The internal container ports will be map to that public IP.
- The OS type can be either Linux or Windows. Since Windows 2016, Windows also support containers.
- We can customize environment variables.
- We can mount an Azure File Share on the container instance.
- We can throw a command line in there to override the container’s defined one.
The unit of compute the container runs on is the container group. It is possible to run more than one container within a container group. At the time of this writing (early April 2018), this can only be done using ARM Template. That is, it isn’t supported though the CLI or PowerShell.
As explicitly mentioned in the documentation, ACI isn’t meant to replace orchestrators. There exists a connector to Kubernetes, Virtual Kubelet. At the time of this writing (early April 2018), the connector is experimental.
ACI has some limitations at the time of this writing (early April 2018).
ACI isn’t available in every Azure Regions yet. See https://azure.microsoft.com/en-us/global-infrastructure/services/ for up to date availability. At the time of this writing, it is only available in 5 regions. This number will likely grow sooner rather than later.
ACI isn’t able to join an Azure Virtual Network (VNET). This means ACI can’t expose private IPs to other VNET members. It can expose a public IP as we have seen. It also means it cannot reach private IPs.
Here we are going to do something similar but with ACI. We changed the Flask web app slightly. We removed Redis dependency which created an error on purpose.
First, we’ll use Azure Command Line Interface (CLI). This works well from a Linux shell but also on both Windows and Mac.
We’ll then do the same thing using PowerShell.
Create a container instance
Let’s create a container instance.
We need to make sure to have the latest version of the CLI.
Here we define a few shell variables that should be unique to our environment:
|rg||Resource Group||The resource group should be created beforehand|
|cn||Container Name||Name of the Azure resource itself, not the container image name|
|dns||DNS label||Should be unique within the region as it will map to the domain name <dns>.<region>.azurecontainer.io|
rg="aci" cn="mycontainer" dns="flaskdemo" az container create --resource-group $rg --location eastus --name $cn --image vplauzon/get-started:part2-no-redis --dns-name-label $dns --ports 80
This should only take a few seconds to deploy. We can then test it by going to http://<dns>.<region>.azurecontainer.io
This is conform to the Flask (Python code) of the app.
ACI is very fast to deploy. It can hence be used for bursting or quick jobs.
Looking at logs
ACI runs in an inaccessible host. So we can’t use the docker command line to get to familiar features.
A few of those are available through Azure CLI. For instance, if we want to look at the logs of the container:
az container logs --resource-group $rg --name $cn
As shown in the online documentations, we can also attach our standard output to the log streams.
Access the container shell
As shown in the online documentation, we can also access the shell of the container:
az container exec --resource-group $rg --name $cn --exec-command "/bin/bash"
We can then navigate through the directory structure. This shows the container is identical to one running locally. Of course this is how containers should behave.
Let’s quickly run the same sample in PowerShell.
We have to make sure we have the latest version of Azure PowerShell SDK. We need to install the module AzureRm.ContainerInstance.
For creation we have:
$rg="aci" $cn="mycontainer" $dns="flaskdemo" New-AzureRmContainerGroup -ResourceGroupName $rg -Location eastus -Name $cn -Image vplauzon/get-started:part2-no-redis -Port 80
Again, only a few seconds are necessary to see the result.
We can take a look at the logs:
Get-AzureRmContainerInstanceLog -ResourceGroupName $rg -Name $cn -ContainerGroupName $cn
At the time of this writing (early April 2018), it is impossible to execute a command into a container via PowerShell. Therefore, it is impossible to access the shell of a container.
We’ve seen how we can easily deploy a container using Azure Container Instance in seconds.
We could then look at the logs of the container and even connect a shell to the container.
We can do that in Azure CLI, Azure PowerShell and ARM Template (although we didn’t use it here).
ACI has a few limitations today. Mainly that it can only be exposed over public internet. This means that today ACI is more tailored for public facing services or jobs. Those limitations will likely go away in the near future.
The speed at which those containers can be spun up and down makes ACI an excellent tool in an agile context.