Docker at large scale
In one of my previous posts I showed how can we utilize Docker to easily package and deploy our applications. Setting up services are pretty straightforward until we use 1-3 servers with no need of load balancers and very little communications between our services. If we are building microservices based architectures, running large scale web applications or just using a cluster of machines things get complicated really fast.
How should I configure my services so they can find each other? How can I scale my app? How can I make an update with no service outage? And the questions can go on, running a cluster is not an easy task to do. Luckily we have some great tools that can help us.
I'm going to introduce you the basic concepts of Kubernetes, a Docker cluster management tool by Google, that can answer all questions above. I have to mention that there are other tools with similar capabilities available such as Docker Swarm or Apache Mesos, but today we are talking about Kubernetes a.k.a K8s.
Kubernetes basic concepts
So Kubernetes is a cluster management software for Docker containers. It deploys and distributes your containers over a set of machines. Helps you load balance, provides service discovery, rolling updates and many other useful features out of the box. It is created by Google and is based on their 15 years of experience using software containers for application management. This post is a theoretical overview, an actual working example will be the theme of an upcoming separate post. Lets start with the basic concepts and terminology.
There are core services and others that are running on every node of the cluster, lets take a quick look of the architecture:
- API server: The API server provides a RESTful API for clients. Using this component we can control our Kubernetes cluster. There are 2 clients available officially: kubectl, a command line client and a web based UI.
- etcd: etcd is a distributed key value store, Kubernetes uses it for sharing secrets, storing state and configuration data.
- Controller Manager: Controller manager manages the controllers.
- Scheduler: The scheduler is responsible for scheduling pods to nodes.
- Kubelet: Kubelets are the agents running on every node in the cluster, doing what the API server tells them.
- Service proxy: Service proxies are also deployed on all nodes, these are responsible for load balancing and service discovery.
There are some major K8s API objects that you must know in order to understand how the system works. The Pods Deployments and Services are only the 3 most important ones. Many other are available. Also these are high level objects that control and take care for lower level ones, but you can also manage those (like replication controllers or replication sets) if you want to.
Pods are the units of scheduling in K8s. a Pod can contain Docker containers, data volumes for persistent storage and namespaces. We usually put 1 container per pod. A pod is an undivideable unit, everything in a pod will be scheduled on a machine, so only put more containers in one if it's not making sense to deploy those on separate machines. If you have a webapp with a database a backend server and an apache web server, that means 3 separate pod definitions.
Pods also have labels. Labels have a very important role in Kubernetes. You can put them on pods, they are basically key value pairs like role=frontend stage=production version=1.0 and so on. Later on when we configure the different mechanisms of K8s we are going to use these labels to select which pods should be managed by each component.
Like everything in Kubernetes Pods can be defined in YAML files.
Deployments are high level API objects in Kubernetes. They are defining deployments (hence the name), you can define the container to run, the count of replicas you desire and many other properties. The deployment will create replication sets that take care of the number of running instances at any time.
Services are named load balancers. They have a static IP address and a DNS name. You can assign a set of labels to a service and it will distribute load between the matching pods. This is the way for service discovery in Kubernetes. For a classic 3 tiered application you should have a Deployment for each layer with a sufficient number of replicas, and have a Service on top of each layer. Calling the Service of the database layer database-service you can use this name in your backend code as the database address.
This is a very brief introduction to the basic concepts of cluster management with Kubernetes. Keep an eye on the blog for some follow up posts for more detailes on this very interesting technology.
If you can't wait, feel free to check out the documentation.