Acorn from the Eyes of a Docker Compose User

In the last article of our series on the Acorn Platform as a Service for Kubernetes, I introduced the architecture and the design of the Acorn deployment framework. This tutorial will compare Acorn with Docker Compose and Kubernetes object definitions.
Before going further, make sure you followed the steps to install Acorn on Minikube explained in the previous tutorial.
Step 1: Exploring Azure Vote Microservices Application
Let’s choose a simple containerized application popular among Docker developers — the Azure Vote application.
The application consists of two layers — a Python Flask frontend and a Redis backend. Each layer of this microservices application is deployed as a container.
To explore the deployment artifact, clone the GitHub repository and open the file azure-vote-all-in-one-redis.yaml
1 |
git clone https://github.com/Azure-Samples/azure-voting-app-redis.git |
1 |
cd azure-voting-app-redis |
The directory consists of all the assets, including the Docker Compose file and the source code.
azure-voting-app-redis
│ azure-vote-all-in-one-redis.yaml
│ docker-compose.yaml
│ LICENSE
│ README.md
│
├───azure-vote
│ │ app_init.supervisord.conf
│ │ Dockerfile
│ │ Dockerfile-for-app-service
│ │ sshd_config
│ │
│ └───azure-vote
│ │ config_file.cfg
│ │ main.py
│ │
│ ├───static
│ │ default.css
│ │
│ └───templates
│ index.html
│
└───jenkins-tutorial
config-jenkins.sh
deploy-jenkins-vm.sh
Launch the app with Docker Compose and access the web application.
1 |
docker-compose up |
Now that we have a working Docker Compose application let us map the concepts to Acorn.
Step 2: Porting Azure Vote Application to Acorn
Technically speaking, we don’t need to port the application. Since the building blocks for Docker Compose, Acorn, and Kubernetes are container images, we will focus on mapping the definition to Acorn.
Open the Docker Compose file and take a look at the service definition.
Line number 3 to 9 define the Redis service by pulling the image, setting the environment variable to enable a blank password, and exposing the port. The remaining lines build the container image from the Dockerfile residing in the azure-vote
directory, connecting the web application to the Redis backend and exposing it on port 8080.
Let’s now create the Acorn definition for the same application. Create a directory called Acorn, which contains the Acornfile.
1 |
mkdir Acorn && cd Acorn |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
containers: { "azure-vote-back": { image: "mcr.microsoft.com/oss/bitnami/redis:6.0.8" ports: { expose: "azure-vote-back:6379/tcp" } env: { "ALLOW_EMPTY_PASSWORD": "yes" } } "azure-vote-front": { build: "../azure-vote" ports: { publish: "80/http" } env: { "REDIS": "azure-vote-back" } } } |
Run the application with the below command:
1 |
acorn run . |
Get the URL of the application by running acorn apps
command.
Accessing the minikube IP after modifying the host header shows the Azure Vote application in the browser.
It is obvious that the Acornfile is similar to the Docker Compose file.
The definitions and the structure are similar except for the deployment target. Docker Compose runs in the context of Docker Engine, while Acorn targets a Kubernetes cluster.
Feel free to compare and contrast the Kubernetes YAML file with Acornfile. Acorn simplifies the definition of multicontainer workloads while translating it to respective Kubernetes objects.
You can see how Acorn translates the definition into Kubernetes objects when you explore the namespace created for the Acorn application.
Step 3: Linking Resources with Acorn
PaaS implementations such as Cloud Foundry support binding stateful resources such as databases and cache with one or more stateless services. This approach makes it possible to reuse services without recreating them or dealing with complex synchronization across resources.
Acorn brings binding to Kubernetes applications through a simplified approach. It imitates Cloud Foundry in binding existing services. In the Acornfile for Azure Vote application, we have a Redis service that we can bind to a service deployed in another application.
To explore this concept, create a new directory and an Acornfile with the below contents:
1 2 3 4 5 |
containers: { "redis-cli": { image: "redis:6.2.7" } } |
This file creates an Acorn application with a single microservice based on the Redis image. The idea is to leverage the Redis client CLI in this application to access the Redis server running in the Azure Vote application.
Launch the application with the below command:
1 |
acorn run --name redis-client --link silent-sun:azure-vote-back . |
Notice the switch --link
that links the current application (redis-client) with azure-vote-back service belonging to the silent-sun Acorn app.
Access the container with the acorn exec
command.
Let’s connect to the Redis host to access the key/value data stored by the Azure Vote application.
We are now able to reuse one Redis backend for multiple clients. It’s interesting to see that the Redis client can connect to the server with the hostname mentioned in the Azure Vote Acornfile.
Behind the scenes, Acorn has created a service with the redis-client app namespace. What’s unique about this service is that it is of the type ExternalName. According to Kubernetes documentation, an ExternalName Service is a special case of Service that does not have selectors and uses DNS names instead. In this case, the DNS name azure-vote-back simply points to the service residing in the Azure Vote application namespace, silent-sun.
Using ExternalName service to bind services across applications is a clever way of leveraging Kubernetes primitives to imitate PaaS capabilities.
In the next part of this series, we will explore the workflow involved in iterating over the code in development environments and moving Acorn applications to a production environment. Stay tuned.