Blog Post

Azure PaaS Blog
4 MIN READ

How to build customized container image for Azure Batch

JerryZhangMS's avatar
JerryZhangMS
Icon for Microsoft rankMicrosoft
Mar 10, 2023

Sometimes, users will need to install some necessary software/packages in the environment before the task is executed. This can be easily done by using Start task feature of Azure Batch.

 

But when there are many dependencies to be installed, for example 20 packages in Linux and the installation of some of them will take long time such as Tensorflow, it will cause additional problems such as long start task running time when Azure Batch starts Batch node every time or even possible timeout issue or start task failure issue.

 

In order to avoid this issue, user has two options: Custom image and Container. Both of these two features are supported in Azure Batch. The way of using custom image is already explained here. This blog will mainly explain how to use the container feature.

 

One additional advantage is that for some special scenarios when the Batch task (application) has strong dependencies on a specific Operation System (OS) version, such as the Linux Ubuntu 18.04 which will reach EOL on Apr 30th 2023, what user needs to further consider is only the compatibility between the container OS and the host OS(selected when you create Batch pool) if he  selects the container feature. And it will be easier for user to recreate/modify the environment itself as he only needs to modify the Dockerfile, but not to recreate a new Virtual Machine to capture a new custom image.

 

In this blog, the container image will be based on Linux Ubuntu 20.04. Assume that the Batch application needs a specific Python package called numpy as dependency. This blog will install this package based on a requirement.txt file, capture it into a container image, create a Batch pool based on this container image and verify the environment is good by running Batch task.

 

Note: This is just one simplest example. For real situation, user will need to modify the Dockerfile and include much more his own files when he creates the container image.

 

Pre-requisites:

  • An Azure Batch account
  • An Azure Container Registry
  • The commands and/or the packages of installing dependencies
  • Docker Desktop on Windows (The example used in this blog will all be with Windows OS, including the computer where we create image, the container image OS and the host OS. For Linux system, please kindly change the configuration.)

Step 1: Create the own container image

  1. In order to create a new container image, user needs to prepare the following files:
  • The Docker File
  • Other dependency components which will be needed (For example the requirement.txt in this scenario)

Note: Please pay attention that the Dockerfile should be without any extension name. The Dockerfile.txt will not work.

Docker folder files

Dockerfile:

 

# Use an official Ubuntu 20.04 runtime as a base image
FROM ubuntu:20.04

# Set the working directory to /app
WORKDIR /app

# Copy the current directory contents into the container at /app
ADD . /app

# Install pip3
RUN apt-get update
RUN apt-get -y install python3-pip

# Install numpy package
RUN pip3 install -r requirement.txt

# Make port 80 available to the world outside this container
# EXPOSE 80

 

 

requirement.txt:

requirement.txt context

 

Note: In rare situation, Batch task may need to wait until a request is sent from other client sides to Batch node. In this scenario, please kindly add the EXPOSE {port} line to export the port of the container to host machine. For more details about how to write Dockerfile, please check this official document from Docker.

 

  1. Once the files are prepared, user can start creating the container image.
  • Open Docker Desktop and make sure to login

Docker Desktop UI

  • Right click the tray icon and select Switch to Linux containers.
  • Open Powershell in the folder containing Dockerfile and following command:

 

docker build -t {container_name} .

 

 

The expected result is like the following one. (This step might take lots of time to finish depending on the network speed as Docker is downloading the container image as base.)

Build result of docker image

  • Find the username and password from Azure Container Registry and use the following command to login:

Container Registry Access Key page

 

 

docker login {registry_name}.azurecr.io -u {username} -p {password}

 

 

Docker login command result

 

  • Use the following commands to upload the container from local Docker to Azure Container Registry.

 

docker tag {container_name} {registry_name}.azurecr.io/{repository}
docker push {registry_name}.azurecr.io/{repository}

 

 

container image upload result

 

Until here, the container is successfully created and uploaded into Azure Container Registry.

 

Step 2: Use the container image to run Batch task

  • User can then create a new pool and configure the container related setting in this node. The other configuration can be set as usual.

container registry page when creating Batch pool

 

Container registry list page

 

Batch pool configuration page

  • Once the node is idle, please add a new job with a new task and link it to this new Batch pool. While creating the new task, please remember to select the correct Image. The following example uses a command line to let container python environment import numpy package, set variable a with value 1, then print out the value of variable a.

Batch task creation page

 

The expected output should be just “1”.

stdout result

 

This proved that our container is successfully created and the installation of python package is also good, otherwise there will be an error message reporting the module not found like following one.

error message if package is not installed

 

Conclusion

The real user scenario will be more complicated, but the principal way of creating the customized container will be the same. The example Dockerfile in this blog shows how to:

  1. Run command to install dependencies
  2. Copy the necessary dependency files into Docker image

These two steps are also the main steps which user needs to customize.

Updated Mar 20, 2023
Version 2.0
  • a8gbvrgij80i's avatar
    a8gbvrgij80i
    Copper Contributor

    Dear Jerry,
    Have the same example using batch, docker (python image), and python to deploy resources?
    If not, I would like to co-author with you a new article with this new focus. I can't find an example that brings together batch, docker, and python. But there need for such example is real
    Looking forward to your reply
    Thank you

  • a8gbvrgij80i  Thanks for your attention on this blog.

     

    Actually we don't have exact sample here, but since this blog is not supposed to give step by step guideline, but just to use an example to explain the idea how we can use Docker image to build custom container image and use it on Batch container feature, we don't have a plan to write a new blog for that special scenario.

     

    Some general suggestion will be you can modify the second line of docker file to some other image from Docker and then modify the file in requirement.txt to add other python packages which you want to install. And for the last point about using python, it fully depends on how you would like to use Batch. The Python script can be fully customized.

  • YossiDataYoga's avatar
    YossiDataYoga
    Copper Contributor

    Hi JerryZhangMS 
    When adding a new pool, the image type should be selected. As I see it, it should be "Custom Image - Azure compute gallery" in order to be able to choose Custom container type.
    But when doing so, I'm getting "No Azure compute galleries have replicas in current region for this subscription" (although I created one).
    In your guide, you skipped this part, so I wonder what exactly should be defined and where.
    I also saw that in the API the `imageReference` is mandatory, so I'm not sure what values should it take in case of `containerConfiguration` is passed.
    I guess I'm missing something basic here.

     

    Please, advise.

    Thanks,
    Yossi

  • Hi YossiDataYoga 

     

    Thanks for your reply on this. As you mentioned, we should select "custom image - azure compute gallery" when creating a pool with custom image.

     

    For your question about "No Azure compute galleries have replicas in current region", it could be caused by multiple kinds of issues. It's difficult to just help you on this by discussing on chat here. I would suggest to create a support ticket so that I or my colleague can further assist and see if anything is going wrong there.

     

    For your second question about the imageReference and containerConfiguration, it's a different thing. You can understand like the container is just a Virtual Machine which we create based on one existing machine. In order to be able to create this kind of VM (container), the existing machine (we call it host machine) must be installed with required environment, such as Docker. As documented Pool - Create - REST API (Azure Batch Management) | Microsoft Learn, the imageReference is the configuration of OS image used for host machine, and the containerConfiguration is used by host machine to create container. They are not in same purpose. Imagine that you have a custom image, based on Windows Server 2019, installed with Docker. If we use this custom image to create a pool, it can also be used without creating any container inside it, just as a normal Windows server 2019 OS image.