Labels

Sunday, January 20, 2019

Virtual Machine vs Containers/Docker & Kubernetes

In simple words .. Just as shipping containers allow goods to be transported by ship, train, or truck regardless of the cargo inside, Software containers act as a standard unit of software deployment that can contain different code and dependencies. Containerizing software this way enables developers and IT professionals to deploy them across environments with little or no modification.

In technical words ..Containerization is an approach to software development in which an application or service, its dependencies, and its configuration (abstracted as deployment manifest files) are packaged together as a Container Image.

The Containerized Application

  • Can be Build/Deployed as a Docker/Container Image (Docker File) to the host operating system (OS).
  • Then Host/Run on top of a Docker Host/Container Host (Docker Engine) that in turn runs on the OS (Linux or Windows).




















Ref Video: 
Few more...

Here is an example to containerize Node.js application and Host on Docker.

Sample code: 

# Manually create a file as .Dockerfile
# Go to root folder of your node application (mynodejsapp)
# Add Two Line Content as below

#1 specify the node base image with your desired version node:
FROM node:10

#2 replace this with your application's default port
EXPOSE 80

# Now Go to Powershell Build and Run the Docker Image:

$ docker build -t mynodejsapp -f ./.DockerFile .   

$ docker run -it --rm --name my-running-app mynodejsapp 

How it is done:

There are already lot of Docker Images available (E.g. Node, Mongo, Ubuntu, Reddis etc). 
Now to create your own image using such available images, 
  • Create a .Dockerfile and
  • Add first line of code as FROM node:10 or FROM ubuntu:latest etc.
Then if you want to further customize the image, add further lines in same file. Like below
  •  COPY  src/  /var/www/html 
  •  WORKDIR /inetpub/wwwroot
  •  COPY ./ /inetpub/wwwroot
  •  Expose 80
Then build this as New Docker Image, using 
$ docker build -t mynodejsapp -f ./.DockerFile . 

Then run this New Docker Image as Docker Container, using Docker  (Note: A Container is a running instance of a Docker Image)
$ docker run -it --rm --name my-running-app mynodejsapp  (This command instructs the Docker Engine to spin up a New Docker Container, using Node 10 Image and map port 80 of the host machine to port 80 of this New Docker Container)

























Docker Architecture:

At a high level, in Docker Architecture, you have Docker Client, Docker Host/Engine and Docker Registry
  • Docker Client is the command line tool that we interact with. 
  • Docker Host, running Docker Daemon listens to the request coming from Docker Client and acts accordingly.
  • Docker Registry - Is a repository of Docker Images. Docker Hub, is a public Docker Registry where anyone can push/pull images.
Docker Image - Is created using Docker File (As in above diagram) and is a package that includes your application code and all it's dependencies.

Docker Containers - It's a running instance of Docker Image. Actually Docker Image becomes Docker Container when they run on Docker Host/Engine.

Publish Docker Image to Docker Hub: To do this, 
  • You need to create a Docker ID/Password from https://hub.docker.com/
  • Register this Docker Id with Docker Client running locally
    • docker login --username=YourDockerId
  • Tag Docker Image with Docker Id
    • docker tag YourDockerImageId YourDockerId/YourDockerHubAccountName
  • Finally push Docker Image to Docker Hub
    • docker push YourDockerId/YourDockerImageId 


Container Orchestration:

Containers have been around for a long time (10+ Yrs) in Linux and recently became available in Windows. Google has used Linux containers successfully for many years and built a platform in which they host many of their own service like Search and Google Maps.

When containers started becoming popular with Docker (Docker Swarm), Google also chose to open-source their Container Orchestrator and is now known as Kubernetes.

Note: In market there are multiple Container Orchestrators -
  •  Docker Swarm – Docker – 
    • Easy to setup with simple command as above in docker CLI - docker run app-name
    • But lacks auto scaling feature to required extent
  • Mesos – Apache  - Tough to setup
  • Kubernetes – Google  - 
    • This is best among. 
    • Connect between Docker and Kubernetes - Kubernetes used Docker Host to host applications in form of Docker Containers
    • Well it's not only Docker, Kubernetes uses 'Rocket' a.k.a. 'rktnetes' or 'Cri-o' too.

    • Easy to setup with simple command as above in Kubernetes CLI - kubectl run --replicas 1000 app-name
    • Setup/Scale-Up thousands of instances of same application with single command as above
    • Kubernetes can scale-up this in rolling fashion too as shown in command below in image
    • And so can rollback too, if something goes wrong.
    • Kubernetes internally manages to increase infrastructure along with scale-up of instances
    • Kubernetes allows to rollout new features in incremental mode where only few nodes will have new features and on alpha-beta testing rolls out on remaining nodes. 
    • Supported on all clouds (AWS, Google, Azure)
    • Support variety of Authentication/Authorization mechanisms























Ref Video - Link 

With Docker, building and managing Container Image  is simple. In theory, you would build your microservice and package it as a Container Image , and the same code will run in production. It gives the phrase “it works on my machine” a whole another meaning.

Container vs Virtual Machine

Thus Containers therefore have a significantly smaller footprint than virtual machine (VM) images.



VMs are a software abstraction of the underlying hardware and therefore are much heavier in terms of memory and processor consumption. So Containers are definitely lightweight compared to VMs.

































VM Operating System runs above the Hypervisor layer. Thus VM believes that it is interacting with the underlying hardware.  Compare this to a Container system, the Container manager allows each application to use the underlying Operating system of the host.

This makes a big difference as multiple applications are essentially sharing the same Operating system kernel and system libraries. As a result, containers allow applications to be deployed faster compared to Virtual Machines that have to be booted from an image.

Advantages of Container compared to Virtual Machine:

  • Small: There relative memory footprint is small compared to a VM (as they do not contain OS). VMs are bulky as it packs everything you need. 
  • Fast: They don’t need to boot the whole operating system like a VM (as they share OS, so gets deployed faster), it's just the application running in the container.
  • Portability: The image can be moved to run in the Container runtime on premises or in the cloud
  • Isolate Applications: Containers also isolate applications from each other on a shared OS. Each container can run a whole web application or a service, as shown below. In this example, Docker host is a container host, and App1, App2, Svc 1, and Svc 2 are containerized applications or services.


  • Scalability -  You can scale out quickly by creating new containers for short-term tasks. From an application point of view, instantiating an image (creating a container) is similar to instantiating a process like a service or web app. 
  • Reliability - When you run multiple instances of the same image across multiple host servers, you typically want each container (image instance) to run in a different host server or VM in different fault domains.
In short, containers offer the benefits of isolation, portability, agility, scalability, and control across the whole application lifecycle workflow. The most important benefit is the environment's isolation provided between Dev and Ops.

WHY SHOULD WE USE DOCKER?
- Docker is a tool that makes it easier to create, deploy, and run applications by using a CONTAINERIZATION APPROACH. 
- These containers are lightweight and take less time to start than traditional servers. 
- These containers also increase performance and lower cost, while offering proper resource management. 
- Another benefit to using Docker is that you no longer need to pre-allocate RAM to each container.


Hope this helps.

Arun