Skip to main content

Understand Kubernetes Object - Init Containers

Background

This is the fifth part of the series on building highly scalable multi-container apps using AKS. So far in this series we have covered following topics.

In this post we will get familiar with the concept of init containers. Lets first understand the need for init-containers. In our application we have the TechTalksWeb API which depends on the persistent data stored in MS SQL Server database. It takes few seconds for the SQL Server container to start and to initialize the static data. In the meantime the web API container will start and try to connect to the database container. It will fail if the database container is not yet initialized. In such situation, Kubernetes provides an object named init-container. It ensures that the initialization tasks are completed before the dependent container can be started.

In our case we will make use of the init-container to initialize the database. The web API container will be started only after the database service is successfully started.

We will be performing following actions during this post

  • Use Docker-compose to build and publish images to DockerHub
  • Setup init container using Kubernetes manifest file to initialize the TechTalksDB inside the SQlserver 2017 container image
  • Deploy services in one go using kubectl

Pre-requisites

Build Docker images for following components:

  • TechTalksWeb
  • TechTalksAPI
  • TechtalksDB

I find it easier to use Docker-compose to stich the services together. We can then build, tag and push these images using docker-compose instead of building them individually. Once the images are pushed to Dockerhub container registry, we can deploy web front, web api and the database containers using Kubernetes manifest.


Here is an example of the compose file which I use for composing the multiple services. I recently presented a hands on session specifically around stitching multi-container apps using Docker-compose for  Azure User Group. The video of the session is available  at Engineers.sg site.

We will be using a sql script to initilalize our database with static data. The initializedb.sql script is straightforward. It initializes the database if it does not exists. It creates tables to store static data like categories, level etc.

Set up init container

In the code snippet above, we can see that the spec has a section named init-containers on line number 21. Here we specify the image to be used which is named nileshgule/sqlclient. At the time of building this image, we are copying the initializedb.sql script. We specify the command to be executed using sqlcmd command line utility.

/opt/mssql-tools/bin/sqlcmd -S db-deployment -U sa -P January2018 -d master -i initialize-database.sql

This is then followed by the regular containers section on line 28. The containers will be instantiated only after the init container has completed its work. This ensures that the TechTalksDB database is fully initialized before the API tries to connect to the SQL server.

Deploy services in one shot

Earlier we saw how we can deploy a service using kubectl command and passing an individual manifest file to it. The kubectl command is quite flexible and provides us a convenient way using a single command to recursively deploy multiple objects.  Under the Minikube folder, we have multiple sub-folders which contain manifest files for each type of service. Instead of running kubectl create or apply command with individual filenames, I can run following command to recursively apply all the manifest files with one single command

kubectl apply –recursive –filename .

At the time when I was building the demo for Azure Bootcamp presentation, I had multiple services running using Minikube. I am using a subset of those services here. To deploy only 3 services along with the namespace, I executed the commands shown below in the specific order.

kubectl apply

The same set of commands  are also available as Powershell script and can be executed in one go by running the script. The apply command will apply only the changes to the desired state configuration. If the current state matches the expected state no changes would be done. The end result of this command is as shown below

Kubernetes dashboard

The techtalksapi we can see contains two images. If we dive deep into the Pods section & click on the techtalks API related pod, we can see the following details

tech talks API detailed events

Notice that the techtalkapi:v1 pod is only created after the sqlclient container is fully started.

We can also see the service discovery working to perfection. The WebAPI refers to the sql database using its service name db-deployment on line 35 in the manifest file. Normally we would have provided a fully qualified connection string to connect to sql database server. In the future post we will look into the aspects related to resourcing needs in detail.

Conclusion

As we saw in this post, the concept of init-containers is quite powerful in ensuring that dependent services are up and running. Ideally you would implement a resilient mechanism like exponential backoff to handle failures. We will cover that part in future post. The complete source code is available on Github.

Until next time, Code with Passion and Strive for Excellence.

Comments

  1. I just couldn't depart your website before suggesting that I actually enjoyed the usual info an individual supply to your visitors?
    Is gonna be back ceaselessly in order to investigate cross-check new posts

    ReplyDelete
  2. I'm gone to say to my little brother, that he should also visit this webpage on regular basis to get updated
    from latest news update.

    ReplyDelete
  3. I know this site gives quality depending articles or reviews and extra stuff, is there any other web site which presents
    these kinds of stuff in quality?

    ReplyDelete
  4. Hi, I do believe this is a great web site. I stumbledupon it ;) I may return once again since i have
    bookmarked it. Money and freedom is the best way to change, may
    you be rich and continue to help others.

    ReplyDelete
  5. I blog frequently and I seriously appreciate your content.
    This article has really peaked my interest. I'm going to take
    a note of your blog and keep checking for new details about once
    per week. I opted in for your Feed as well.

    ReplyDelete
  6. Pretty! This has been an incredibly wonderful post. Thanks for supplying
    these details.

    ReplyDelete
  7. With havin so much content do you ever run into any issues of plagorism or
    copyright infringement? My blog has a lot of completely unique content I've either authored myself or outsourced but it appears a lot of it
    is popping it up all over the web without my authorization. Do you know any methods to
    help protect against content from being ripped off? I'd really appreciate it.

    ReplyDelete

Post a Comment

Popular Posts

Unit Test Application Configuration Settings

BackgroundAll the post I had written this month so far were related to the Entity Framework learning series. This time I thought of taking a diversion and share a quick method of unit testing setting which might be stored in the Application Configuration file (App.config) of a DotNet application. Unit Test Application Configuration SettingsLets fire up Visual Studio and create a simple console application. You can name it whatever you want. I have named the project as AppConfigTest. Once the project is created right click on Add and select Add New Item option in the solution explorer window. Select Application Configuration File option and click Add. This will automatically name the new file as App.config.Since this file used to configure settings at application level there is a possibility of someone changing these setting unknowingly. It can lead to severe problems later. It might also happen that the settings are different in different environments like development machines, test s…

Build custom SQL Server 2017 Linux Docker image

BackgroundIn the earlier series of posts on continuous deployment of multi-container apps, I had used two containers for ASP.Net Core MVC web site and ASP.Net Core Web API. This post is a sort of continuation. In the earlier version we were using in memory database to store the data. This approach is useful in a proof of concept or a quick demo application. In an enterprise scenario we would use some sort  of persistent data store to store the data. It is very easy to containerize the stateless services and web front ends. When we move towards stateful processing, things start to get interesting.Containers by their very nature are supposed to be ephemeral. This means that containers can be stopped and destroyed and a new one built and put in place with minimum setup and configuration. If we destroy the container and replace it with a new one what happens to the data stored inside the container? Can we use containers to run database related processes? How can the stateless containers c…

Integrate SQL Server 2017 Linux with ASP.NET Core using Docker

In the previous post, we saw how to initialize a SQL Server 2017 on Linux database running inside Docker container. This post is continuation of my exploration about Docker containers for stateful applications. In this post we will explore how to integrate the SQ Server 2017 on Linux container with ASP.Net Core Web API also running inside a Docker container. We will perform following activitiesUpdate Docker compose file to build the SQL server imageUpdate Web API project to use SQL Server Database instead of In memory databaseBuild and run the application containers using Docker compose commandsQuery Data from SQL container using the MVC web front endUpdate Docker compose file to build the SQL server imageDocker provides Docker Compose as a tool for defining and running multi-container Docker applications. I already have an existing docker compose file which I have been using for my series of post on implementing continuous deployment of multi container apps. In a compose file we defi…