This tutorial is adapted from Web Age course Microservices Development Bootcamp with Immersive Project.
1.1 What is Kubernetes
Kubernetes is Greek for “helmsman” or “pilot”. It was originally founded by Joe Beda, Brendan Burns and Craig McLuckie. Afterward, other Google engineers also joined the project. The original codename of Kubernetes within Google was Project Seven, a reference to a Star Trek character. The seven spokes on the wheel of the Kubernetes logo is a nod to that codename. Kubernetes is commonly referred to as K8s. It is an open-source system for automating deployment, scaling, and management of containerized applications. It was originally designed by Google and donated to the Cloud Native Computing Foundation. It provides a platform for automating deployment, scaling, and operations of application containers across clusters of hosts. It supports a range of container tools, including Docker.
1.2 What is a Container?
Over the past few years, containers have grown in popularity. Containers provide operating-system-level virtualization. It is a computer virtualization method in which the kernel of an operating system allows the existence of multiple isolated user-space instances, instead of just one. Such instances are called containers. A container is a software bucket comprising everything necessary to run the software independently. There can be multiple containers in a single machine and containers are completely isolated from one another as well as from the host machine. Containers are also called virtualization engines (VEs) or Jails (e.g. FreeBSD jail). Containers look like real computers from the point of view of programs running in them. Items usually bundled into a container include Application, dependencies, libraries, binaries, and configuration files.
1.3 Container – Uses
- OS-level virtualization is commonly used in virtual hosting environments.
- A container is useful for packaging, shipping, and deployment of any software applications that are presented as lightweight, portable, and self-sufficient containers, that will run virtually anywhere.
- It is useful for securely allocating finite hardware amongst a large number of mutually-distributing users.
- System administrators may also use it for consolidating server hardware by moving services on separate hosts into containers on a single server.
- Container is useful for packaging everything the app needs into a container and migrating that from one VM to another, to server or cloud without having to refactor the app.
- Container usually imposes little to no overhead, because programs in virtual partitions use the OS’ normal system call interface and do not need to be subjected to emulation or be run in an intermediate virtual machines.
- Container doesn’t require support in hardware to perform efficiently.
1.4 Container – Pros
- Containers are fast compared to hardware-level virtualization, since there is no need to boot up a full virtual machine.A Container allows you to start apps in a virtual, software-defined environment much more quickly.
- The average container size is within the range of tens of MB while VMs can take up several gigabytes. Therefore a server can host significantly more containers than virtual machines.
- Running containers is less resource intensive than running VMs so you can add more computing workload onto the same servers.
- Provisioning containers only take a few seconds or less, therefore, the data center can react quickly to a spike in user activity.
- Containers can enable you to easily allocate resources to processes and to run your application in various environments.
- Using containers can decrease the time needed for development, testing, and deployment of applications and services.
- Testing and bug tracking also become less complicated since you there is no difference between running your application locally, on a test server, or in production.
- Containers are a very cost effective solution. They can potentially help you to decrease your operating cost (less servers, less staff) and your development cost (develop for one consistent runtime environment).
- Using containers, developers are able to have truly portable deployments. This helps in making Continuous Integration / Continuous Deployment easier.
- Container-based virtualization are a great option for microservices, DevOps, and continuous deployment.
1.5 Container – Cons
- Compared to traditional virtual machines, containers are less secure. Containers share the kernel, other components of the host operating system, and they have root access. This means that containers are less isolated from each other than virtual machines, and if there is a vulnerability in the kernel it can jeopardize the security of the other containers as well.
- A container offers less flexibility in operating systems. You need to start a new server to be able to run containers with different operating systems.
- Networking can be challenging with containers. Deploying containers in a sufficiently isolated way while maintaining an adequate network connection can be tricky.
- Developing and testing for containers requires training. Whereas writing applications for VMs, which are in effect the same as physical machines, is a straightforward transition for development teams.
- Single VMs often run multiple applications. Whereas containers promotes a one-container one-application infrastructure. This means containerization tends to lead to a higher volume of discreet units to be monitored and managed.
1.6 Composition of a Container
At the core of container technology are:
- Control Groups (cgroups)
- Union filesystems
1.7 Control Groups
Control groups (cgroups) work by allowing the host to share and also limit the resources each process or container can consume. This is important for both, resource utilization and security. It prevents denial-of-service attacks on host’s hardware resources.
Namespaces offer another form of isolation for process interaction within operating systems. It limits the visibility a process has on other processes, networking, filesystems, and user ID components. Container processes are limited to see only what is in the same namespace. Processes from containers or the host processes are not directly accessible from within the container process.
Containers run from an image, much like an image in the VM or Cloud world, it represents state at a particular point in time. Container images snapshot the filesystems. The snapshot tend to be much smaller than a VM. The container shares the host kernel and generally runs a much smaller set of processes. The filesystem is often layered or multi-leveled., e.g. Base layer can be Ubuntu with an application such as Apache or MySQL stacked on top of it.
- Docker – Docker Swarm
- Rocket (rkt)
- Apache Mesos
- Linux Containers (LXC)
- Oracle Solaris Containers
The microservice architectural style is an approach to developing a single application as a suite of small services. Each service runs in its own process and communicates with lightweight mechanisms, often an HTTP resource API. These services are built around business capabilities and independently deployable by fully automated deployment machinery.
1.12 Microservices and Containers / Clusters
Containers are excellent for microservices, as it isolates the services. Containerization of single services makes it easier to manage and update these services. Docker has led to the emergence of frameworks for managing complex scenarios, such as, how to manage single services in a cluster, how to manage multiple instances in a service across hosts , how to coordinate between multiple services on a deployment and management level. Kubernetes allows easy deployment and management of multiple Docker containers of the same type through an intelligent tagging system. With Kubernetes, you describe the characteristics of the image, e.g. number of instances, CPU, RAM, you would like to deploy.
1.13 Microservices and Orchestration
Microservices can benefit from deployment to containers. Issue with containers is, they are isolated. Microservices might require communication with each other. Container orchestration can be used to handle this issue. Container orchestration refers to the automated arrangement, coordination, and management of software containers. Container orchestration also helps in tackling challenges, such as service discovery, load balancing, secrets/configuration/storage management, health checks, auto-[scaling/restart/healing] of containers and nodes, zero-downtime deploys.
1.14 Microservices and Infrastructure-as-Code
In the old days, you would write a service and allow the Operations (Ops) team to deploy it to various servers for testing, and eventually production. Infrastructure-as-Code solutions helps in shortening the development cycles by automating the set up of infrastructure. Popular infrastructure-as-code solutions include Puppet, Chef, Ansible, Terraform, and Serverless. In the old days, servers were treated as part of the family. Servers were named, constantly monitored, and carefully updated. Due to containers and infrastructure-as-code solutions, these days the servers (containers) are often not updated. Instead, they are destroyed, then recreated. Containers and infrastructure-as-code solutions treat infrastructure as disposable.
1.15 Kubernetes Container Networking
Microservices require a reliable way to find and communicate with each other. Microservices in containers and clusters can make things more complex as we now have multiple networking namespaces to bear in mind. Communication and discovery requires traversing of container IP space and host networking. Kubernetes benefits from getting its ancestry from the clustering tools used by Google for the past decade. Many of the lessons learned from running and networking two billion containers per week have been distilled into Kubernetes.
1.16 Kubernetes Networking Options
Docker creates three types of networks by default:
- bridged – this is the default choice. In this mode, the container has its own networking namespace and is then bridged via virtual interfaces to the host network. In this mode, two containers can use the same IP range because they are completely isolated.
- ◊ host – in this mode, performance is greatly benefited since it removes a level of network virtualization; however, you lose the security of having an isolated network namespace.
- none – creates a container with no external interface. Only a loopback device is shown if you inspect the network interfaces.
- host, and none.
- In all these scenarios, we are still on a single machine, and outside of a host mode, the container IP space is not available, outside the machine. Connecting containers across two machines then requires NAT and port mapping for communication.
Docker user-defined networks
- Docker also supports user-defined networks via network plugins.
bridge driver – allows creation of networks somewhat similar to default bridge driver.
overlay driver – uses a distribution key-value store to synchronize the network creation across multiple hosts.
Macvlan driver – uses the interface and sub-interfaces on the host. It offers a more efficient network virtualization and isolation as it bypasses the Linux bridge.
- Provides an overlay network for Docker containers
- Gives a full subnet to each host/node enabling a similar pattern to the Kubernetes practice of a routable IP per pod or group of containers.
- Uses built-in routing functions of the Linux kernel.
- It can be used for anything from small-scale deploys to large Internetscale installations.
- There is no need for additional NAT, tunneling, or overlays.
- It merges both Calico for network policy and Flannel for overlay into one solution.
1.17 Kubernetes Networking – Balanced Design
Using unique IP address at the host level is problematic as the number of containers grow. Assigning an IP address to each container can also be overkill. In cases of sizable scale, overlay networks and NATs are needed in order to address each container. Overlay networks add latency. You have to pick between fewer containers with multiple applications per container (unique IP address for each container) or multiple containers with fewer applications per container (Overlay networks / NAT)
Kubernetes provides a platform for automating deployment, scaling, and operations of application containers across clusters of hosts. Kubernetes supports a range of container tools, including Docker. Containers are useful for packaging, shipping, and deployment of any software applications that are presented as lightweight, portable, and selfsufficient containers, that will run virtually anywhere. Microservices can benefit from containers and clustering. Kubernetes offers container orchestration.