Are you still unsure whether Kubernetes is right for you? Are you still unsure what it can really do? That’s ok. I get it because I’ve been there too. That’s why I'm going to give you a high-level overview of Kubernetes’ key components and the kinds of problems that they solve.
TLDR - Containers make it easy to install an application and then run it without any dependency conflicts. In other words, they make your programs portable and easy to run.
Why Use Containers?
There are two main problems that you're likely to encounter when you try to install and run an application on a computer.
- Your application conflicts with another app on the machine. For example, your app uses Python 3.8 but another program uses an older version of Python. (Insidious failures ensue.)
- It's often challenging to install an app and all of the dependencies--especially when you have to do so on a number of different machines with their varying setups.
What Containers Do
A Docker Container is like a small, light weight virtual machine for an OS process. It has two main benefits:
- A container prevents dependency conflicts by isolating processes in the container from things outside of the container. No more well-it-works-on-my-machine bugs.
- A container bundles an application with all of its dependencies. This makes deployments simple and reliable.
What is a Pod?
A Pod is a Kubernetes component which contains one or more Docker containers. It is arguably the most fundamental object in Kubernetes, and the smallest deployable component. (You can't directly deploy a "naked" container.)
- If a container crashes and terminates, it will be automatically restarted in the pod.
- A pod's containers share things like their IP, ports, persistent storage, etc.
- A pod co-locates its containers on the same node/machine.
What is a Controller?
A Controller acts like cruise control for pods. It watches over a set of pods and makes sure the desired number of them are running at all times. A controller's purpose is to provide pod resiliency.
- If a pod's host node dies or if the pod gets evicted, then its controller starts up a replacement pod.
- There are multiple types of controllers--Deployments, DaemonSets, StatefulSets....
- Some controllers facilitate zero-downtime pod updates and rollbacks.
What is a Service?
A Service is a load-balancer for a set of pod replicas (a pod and all of its duplicates). A service also acts as a reliable communications proxy for pods which may die and be replaced. Thus, you can send a request to the service, and it will find a pod to fulfill your request.
- A Kubernetes service load-balances TCP/IP messages for a set of pod replicas.
- Normally, pods cannot communicate with things outside of the cluster. But with some service types they can.
TLDR - A Volume provides truly persistent storage for containers.
What's the Reason for Volumes?
Here's the problem: when you save a file in a container, that file will only last as long as the container exists. If the container crashes or gets terminated, the file is gone forever. That's not acceptable for programs like databases.
What Volumes Do
- A volume provides persistent storage that lasts beyond the life cycle of containers and pods.
- By using a volume, containers in a pod can also share data.
- There are many types of volumes (local, nfs, awsElasticBlockStore, azureDisk, etc.).
What is a Secret?
A Secret is a Kubernetes component which stores sensitive data like database passwords and API keys.
The Benefits of Secrets
- You don't need to bake sensitive info into your code, config files, etc. This keeps it out of source control, and thus out of the hands of people who don't have a need to know.
- As a precaution, secret data is only distributed to pods that use it.
- Secrets stored by your cluster can be encrypted.
What is a ConfigMap?
ConfigMaps store your application's non-sensitive configuration information. (I know that configMaps may appear pointless, but they're actually extremely handy in practice.)
When should I use a ConfigMap?
There are two scenarios in which configMaps shine.
- You should use a configMap to store cluster-specific config data. You should not bake that information directly into the images from which you create your containers.
- Use a configMap to store any properties that you anticipate needing to modify somewhat frequently. This enables you to modify config properties without having to rebuild your Docker images and redeploy the corresponding Docker containers.
What does an Ingress do?
Ingress objects are the new-and-improved way of enabling clients outside of the cluster to communicate with your cluster's pods and services.
- It provides HTTP-level load-balancing--otherwise known as "path-based routing". Ingress objects are used to route requests to the appropriate backing service based on the incoming HTTP request path.
- It can also provide TLS termination. Let me explain. Messages between a client and the ingress object can be encrypted via HTTPS. The ingress decrypts these messages and then routes them to the appropriate backing service. The reverse is also true. This removes the TLS encryption burden from the applications running in your pods.
- It can be used to facilitate name-based virtual hosting. That's a fancy way of saying that you can host multiple websites which share the same IP address. By hosting multiple sites on the cluster, you can make more efficient use of your hardware and save money!
What is a Network Policy?
A Network Policy is a pod-level firewall. It dictates who can send messages to a pod and vice versa. It also dictates which ports a pod can listen on.
Why Use a Network Policy?
A network policy is an optional tool for securing communications within your cluster. Network policies make it harder for hackers to infiltrate your cluster, or exfiltrate data from your cluster.
Horizontal Pod Autoscalers
Why Horizontal Pod Autoscalers Exist
Let's say there are two Nginx server pods handling traffic to a concert tickets website. When a popular band is listed, the poor little Nginx pods struggle not to crash under the load. What we need is to scale up the number of Nginx pods. That's where HPAs come into play.
What is a Horizontal Pod Autoscaler?
An HPA is a component which monitors the resource usage of set of pod replicas. The HPA will automatically scale up or down the number of replicas to meet a predefined resource usage level. That means less pager duty for you and more free time for concerts!
In the previous section, we went over the main Kubernetes components that you are likely to use. In the following section, I'm going to give you a tour of some optional advanced capabilities.
Why Container Probes?
Recall that if a container crashes and terminates, it will be automatically restarted. (Hooray!) However, if a containerized application deadlocks, the container won't be restarted because the pod has no way of knowing that the container is in a bad state. The solution: Container Probes.
What is a Container Probe?
A probe is a user-defined container health-check. After you create a container probe, Kubernetes has a way to detect when a container is in a bad state. Unhealthy containers then can be restarted automatically.
In addition to health probes, there are also liveness probes. They let a Kubernetes service temporarily redirect traffic away from a pod that is temporarily incapacitated/busy to the other replicas.
Pod and Container Security
There are a number of ways in which you can further lock down pods and containers. Here are three good examples.
- You can prevent a containerized application from running as the root user. You don't want to run as root in case a hacker gains access.
- You can force the container's file system to be read only.
- You can even add or drop individual Linux kernel capabilities, such as removing the ability to change the owner of a file.
These security features are really handy because the less power that a hacker has, the harder it is for them to do damage.
Resource Requests and Limits
What are Requests and Limits?
A container's Resource Limit is an optional way to specify the upper bounds on the CPU and memory that the container can consume. Similarly, the optional Resource Request specifies the minimum amount of compute resources that you want allocated to the container.
Why use Requests and Limits?
You specify a resource request or limit when you want to guarantee a certain quality of service for a specific container. This helps prevent a greedy container from consuming resources that you would rather be allocated to more important containers.
Advanced Pod Scheduling
Kubernetes automatically determines the node on which a pod will run. But in some cases, you may want to control where a pod gets deployed to. This is often done to improve performance using domain-specific knowledge that is not inherently available to Kubernetes.
Affinity and Anti-Affinity
Four of the tools at your disposal are pod affinity and anti-affinity, and node affinity and anti-affinity. Here are a couple of examples:
- You can use Node Affinity to ensure that a particular pod only runs on a particular node. For example, maybe your cluster only has one node with a lot of memory, and you want to make sure that the pod running the in-memory sorting algorithm only gets deployed there.
- Pod Anti-Affinity is useful when you want to make sure that two particular pods are not scheduled onto the same node at the same time. For instance, it might be prudent to make sure that multiple high frequency stock trading pods don't run on the same machine because they are CPU-intensive applications.
That's it! I hope you found this series helpful. Keep coding. Keep learning!