Getting started with Azure Kubernetes Series — Part 1
Azure Kubernetes Service is one of the most popular way of deploying and managing containerized applications. Azure Kubernetes Service (AKS) is fully managed. It comes with serverless Kubernetes, an integrated continuous integration and continuous delivery (CI/CD) experience, enterprise level security and many more things.
Note:- If you want to follow along, you can refer git repo here AKS.
This is First part of six part series. Here, we will be covering below topics
- Getting Started with docker
- Use docker compose for multi container apps
- Container orchestration using Kubernetes
- Deploy multi container apps to AKS ( Azure Kubernetes Service)
- Debugging and monitoring AKS
- CI/CD with Docker and Kubernetes
I will first go ahead and create simple MVC project with .Net command as shown below.
It has dropped me below assets
I have added Dockerfile as well. I have pasted snippet for the same as shown below:
Let me explain what I have done here step by step.
- First I am pulling Microsoft Image from the location as mentioned above
- From tells which is the base image, I am going to use for containerizing the application
- This is sdk image which I named as build-env
- I also have WORKDIR with the name AKSWeb.
- NuGet.config is also there. For container, I need to specifically tell where are the dependencies located?
- Hence, for that I will created a NuGet.config file at the root level and provide below settings to it.
All .net core dependencies are at this myget location and nuget api package is located at api.nuget.org. It will pull all the required packages from this location. Afterwards, I did the below changes.
- Specify what is the working directory
- I do a .Net restore. Its looking at my .csproj file and its going to scan the file, look for dependencies and restore the same.
- I then copy all these dependencies into this container.
- Run this dotnet publish command and I do this in release configuration and I put the output into the release folder.
- Run this dotnet publish command and I do this in release configuration and I put the output into the release folder.
- Once, the output is generated, then I need to put it into runtime image version, which is again provided by Microsoft. This is meant for production lite environment.
- I create workdir within that image.
- Then I copy the build output from build-env to this new image.
- And, finally entry-point is what should be the first executable or dll.
Let me have a look of existing docker images with the command docker images.
I can see many different images are already there. Many are my custom images of different micro-service project. You can try docker — help for different command options. I can also use docker container ls. So, it returned me one running container as shown below.
Whats the difference between container and image.
To answer this, image is just an application and container is the instance of image, which you will be running basically. Having said that, let’s go ahead and create a container. But, before I create a container, I should use docker file to build that image. I will build using docker build . command
It started pulling the image. For the first time, it will take sometime. But for subsequent builds, it will be quite faster. But, it failed at the end with following reason.
Here, in my docker file I had, NuGet.config, but actually in file system, I had NuGet.config. Hence, I renamed the file in src directory and then built again.
Here, it again failed. But this time with a different reason. Its actually looking for some file inside obj folder. Here, we forgot to use .dockerignore file. This file tells which directory should be excluded while building the docker image. In this directory, we usually put obj/ and bin/ like shown below.
Having said that, now when I go an build the same, it should build fine
As you see, all the steps are successfully completed. You can ignore this warning message at the bottom of the screen as we are running this image in linux environment. When I say, docker images, we can see that docker image built without any tag or name.
That is why we should build the image with the tag name. Here the convention is my dockerhub username followed by image name. I can also specify version number if i want. docker build — tag rahulsahay19/aksweb:v1 .
Now when I do docker images, I can easily track my required image.
To run the image I can use docker run command with the following syntax.
docker run — name v1 -p 8080:80 rahulsahay19/aksweb:v1
Here, I am saying run my image with the name v1 against the port 8080 on my machine mapped from port 80 from container. Having said that, it will run successfully, as shown below
And now, when I navigate to port 8080 on my machine, it will produce the below site
Awesome. Its insanely fast. Now, I can stop the same using Ctrl+C command. However, now again when I try to run the same command, it will produce the below output
Its failed because with the same name already one container running. Hence, before running another time, I can go ahead and delete the container using docker rm v1. And, then I should try to run the command again, that will work. I can also stop the running container using docker stop v1 command. At this moment, site will become unreachable.
I can also drill down inside the image using command docker inspect v1.
Another advantage of containers is like I can publish multiple versions by changing my program and I can run parallely multiple versions side by side off-course on different ports. Entire software development process becomes very easy with this. Like I can do unit test very fast. I don’t have to wait for the entire long lengthy process to raise the ticket and get the developer or tester assigned to it and then you will get started.
And size of my docker image is very less. Its just 265MB. So, now let’s build the 2nd part which is web api. Also, when I am running my container, you can see the status with docker ps command.
Here, you can see the first one. Now, let’s go ahead and stop the same. To stop it, we need to say docker stop ea7. ea7 is the first three letters of the container id. Its just need to be unique enough to identify the same.
On successful stop, it will return the container id. Now, let’s go ahead and push this image to dockerhub. For that I will do docker login first.
Here, I logged in with my dockerhub username and password. Currently, I have only one image in my dockerhub.
Now, let’s go ahead and push another one with below command.
docker push rahulsahay19/aksweb:v1
It successfully pushed the image on dockerhub.
Now anyone can pull this image from dockerhub and run the container based on this image.
Containers break these myth also, that it only work on my machine.
Now, let’s go ahead and create this web api project.
I have done little-bit of code restructuring as well. Now, I have moved all the dotnet related code under src folder like shown below.
We have to repeat the same steps for containerizing this app as well. Hence, I will copy Dockerfile, .dockerignore, and NuGet file into this project and make relevant changes.
I will go ahead and build this docker file.
Now, my docker build completed.
As part of build process, many intermediary build also get generated without any name, hence tagged with <none>. We don’t need these images actually and we can get rid off them by using docker system prune command.
Let’s go ahead and run the project using
docker run — name v1 -p 8081:80 rahulsahay19/aksapi:v1
This time, I am running on port 8081.
Let’s move on the third part of the story wherein we will be using sql-server linux version. For this, I don’t need to create any new image rather we will reuse the same which is provided by Microsoft. Below is the command for the same. You can get the same from http://bit.ly/docker-sqlserer.
docker run -e “ACCEPT_EULA=Y” -e “SA_PASSWORD=AKSLearn(!)” `
-p 1433:1433 — name sql1 `
-d mcr.microsoft.com/mssql/server:2017-latest
When I do docker ps, I can see that sql instance is working.
This I can verify from the sqlserver instance as well.
Here, I have entered the same sa password, which i passed during creation. Now, when I connect the same, I can see its connected and I can see the built in dbs.
I am running SQL-Sever 2017 latest edition on container and just exposing port on the host machine. And from local express edition, I am able to connect to sql. Here, I have dropped the below script just to initialize the db.
These files, you can also refer from repository itself. Upon successful execution, it will create db and corresponding tables as well.
Now, let’s write a new query.
Therefore, this is the general workflow of any containerized app.
In the next section, we will continue other part of the series.
Thanks,
Rahul Sahay
Happy Coding
In case of any questions, you can reach out to me https://twitter.com/rahulsahay19