Load balance containers in an Azure Container Service DC/OS cluster

In this article, we explore how to create an internal load balancer in a DC/OS managed Azure Container Service using Marathon-LB. This configuration enables you to scale your applications horizontally. It also allows you to take advantage of the public and private agent clusters by placing your load balancers on the public cluster and your application containers on the private cluster. In this tutorial, you:

  • Configure a Marathon Load Balancer
  • Deploy an application using the load balancer
  • Configure and Azure load balancer

You need an ACS DC/OS cluster to complete the steps in this tutorial. If needed, this script sample can create one for you.

This tutorial requires the Azure CLI version 2.0.4 or later. Run az --version to find the version. If you need to upgrade, see Install Azure CLI 2.0.

Launch Azure Cloud Shell

The Azure Cloud Shell is a free Bash shell that you can run directly within the Azure portal. It has the Azure CLI preinstalled and configured to use with your account. Click the Cloud Shell button on the menu in the upper-right of the Azure portal.

Cloud Shell

The button launches an interactive shell that you can use to run all of the steps in this topic:

Screenshot showing the Cloud Shell window in the portal

Load balancing overview

There are two load-balancing layers in an Azure Container Service DC/OS cluster:

Azure Load Balancer provides public entry points (the ones that end users access). An Azure LB is provided automatically by Azure Container Service and is, by default, configured to expose port 80, 443 and 8080.

The Marathon Load Balancer (marathon-lb) routes inbound requests to container instances that service these requests. As we scale the containers providing our web service, the marathon-lb dynamically adapts. This load balancer is not provided by default in your Container Service, but it is easy to install.

Configure Marathon Load Balancer

Marathon Load Balancer dynamically reconfigures itself based on the containers that you've deployed. It's also resilient to the loss of a container or an agent - if this occurs, Apache Mesos restarts the container elsewhere and marathon-lb adapts.

Run the following command to install the marathon load balancer on the public agent's cluster.

dcos package install marathon-lb

Deploy load balanced application

Now that we have the marathon-lb package, we can deploy an application container that we wish to load balance.

First, get the FQDN of the publicly exposed agents.

az acs list --resource-group myResourceGroup --query "[0].agentPoolProfiles[0].fqdn" --output tsv

Next, create a file named hello-web.json and copy in the following contents. The HAPROXY_0_VHOST label needs to be updated with the FQDN of the DC/OS agents.

  "id": "web",
  "container": {
    "type": "DOCKER",
    "docker": {
      "image": "yeasy/simple-web",
      "network": "BRIDGE",
      "portMappings": [
        { "hostPort": 0, "containerPort": 80, "servicePort": 10000 }
  "instances": 3,
  "cpus": 0.1,
  "mem": 65,
  "healthChecks": [{
      "protocol": "HTTP",
      "path": "/",
      "portIndex": 0,
      "timeoutSeconds": 10,
      "gracePeriodSeconds": 10,
      "intervalSeconds": 2,
      "maxConsecutiveFailures": 10

Use the DC/OS CLI to run the application. By default Marathon deploys the the applicaton to the private cluster. This means that the above deployment is only accessible via your load balancer, which is usually the desired behavior.

dcos marathon app add hello-web.json

Once the application has been deployed, browse to the FQDN of the agent cluster to view load balanced application.

Image of load balanced application

Configure Azure Load Balancer

By default, Azure Load Balancer exposes ports 80, 8080, and 443. If you're using one of these three ports (as we do in the above example), then there is nothing you need to do. You should be able to hit your agent load balancer's FQDN, and each time you refresh, you'll hit one of your three web servers in a round-robin fashion.

If you use a different port, you need to add a round-robin rule and a probe on the load balancer for the port that you used. You can do this from the Azure CLI, with the commands azure network lb rule create and azure network lb probe create.

Next steps

In this tutorial, you learned about load balancing in ACS with both the Marathon and Azure load balancers including the following actions:

  • Configure a Marathon Load Balancer
  • Deploy an application using the load balancer
  • Configure and Azure load balancer

Advance to the next tutorial to learn about integrating Azure storage with DC/OS in Azure.