Today’s blog post is going to be the 1st of a series: I am going to share reading notes on some of my favourites books. These notes and summaries are intended to give an overview and hopefully get you to buy and read these great (e-)books.
These notes are not meant to be exhaustive, they list whatever was relevant to me when I read the book. You might think that I missed some important points along the way and hopefully you’ll be able to fill the gap(s) by digging into these books yourself.
*/!\ Important /!\* There might be some copy-paste information within these posts.
Let’s start with a book on Kubernetes: The Kubernetes book, by Nigel Poulton (non affiliated link). It is a great introduction to Kubernetes.
In the rest of this post we’ll often k8s as a short name for Kubernetes.
- k8s is an orchestrator of containerised apps - k8s follows the declarative state: - we declare a desired state - k8s deploys it and maintains a watch loop to check that the state is conform and tries to recover if not - At a high level - we start with pods as the basic k8s object. - We wrap them in a ReplicaSet for scalability, resiliency and desired state. - Then we add a deployment for rolling updates and simple rollbacks. - the key unit for k8s is the Pod - It’s a sandbox to run containers in. - Pods are mortal. If one dies, another one gets created. They are deployed indirectly via Deployments - All containers in a pod share the IP address, hostname, sockets, memory, volumes and more. - Intra pod communication can happen via the pods localhost interface. - Containers inside pods expose unique ports to the outside world.
Chapter 1 — Kubernetes principles of operation
A Kubernetes cluster is made up of one or more masters, and a bunch of nodes.
The masters are in-charge of the cluster and make all the decisions about which nodes to schedule application services on. They also monitor the cluster, implement changes, and respond to events.
The nodes are where our application services run. They also report back to the masters and watch for changes to the work they’ve been scheduled.
To deploy Kubernetes applications we define a Deployment via a YAML or JSON manifest file. This manifest file tells Kubernetes two important things:
- What our app should look like – what images to use, ports to expose, networks to join, how to perform update etc.
- How many replicas of each part of the app to run (scale)
Then we give the file to the Kubernetes master which takes care of deploying it on the cluster.
But it doesn’t stop there. Kubernetes is constantly monitoring the Deployment to make sure it is running exactly as requested. If something isn’t as it should be, Kubernetes tries to get back on track.
Masters (control plane)
The master only looks after the state of the cluster.
The API server
It is the front end into the kubernetes master. We POST manifest files to it, these get validated and the work they define get deployed to the cluster.
The cluster store
If the API server is the brain, the cluster is the memory. The config and state of the cluster gets persistently stored here.
The controller manager
The controller manager (kube controller manager) implements a few functions that tend to sit in loops and watch for changes.
It watches for new workloads and assigns them to nodes.
The declarative model and desired state
In kubernetes the two concepts work like this:
- we declare the desired state of our application (microservice) in a manifest file
- we POST it to the API server
- kubernetes stores this in the cluster store as the application’s desired state
- kubernetes deploys the application on the cluster
- kubernetes implements watch loops to make sure the cluster doesn’t vary from desired state
Pods and containers
Kubernetes runs containerised apps but those containers always run inside of pods.
The pod itself doesn’t actually run anything, it’s just a sandbox to run containers in. As an example, all containers in the same pod will share the same IP address.
Pods as the atomic unit
Pods are the minimum unit of scaling in k8s. If you need to scale your app, you add more pods.
Pods are mortal. If they die unexpectedly, we don’t bother trying to bring them back to life. Instead k8s starts another one in its place, it’s a new one with the same requirements.
We normally deploy pods indirectly via ReplicaSet or Deployment.
Chapter 2 — Installing kubernetes
A good number of tools are available these days for starting with Kubernetes. Here are a shortlist to kickstart and/or get into Kubernetes for real:
Play with kubernetes
Play with kubernetes (PWK) is a web based kubernetes playground that you can use for free.
Another option for playing with kubernetes is to set up a minikube and interact with it via the k8s client kubectl.
You can also install k8s on AWS using the kops tool.
Chapter 3 — Working with pods
A pod is a shared execution environment for one or more containers (in practice, most pods only have one container).
How do we deploy pods
To deploy a pod we define it in a manifest file and then POST that manifest file to the API server.
The anatomy of a pod
All containers in a pod share the IP address, hostname, sockets, memory, volumes and more.
Under the hood, a pod is another container. This means that containers running inside pods are containers running inside of containers.
Every pod in the cluster has its own IP addresses that’s fully routable on the pod overlay network.
Intra pod communication can happen via the pods localhost interface. Containers inside pods expose unique ports to the outside world.
Chapter 4 — ReplicaSets
A very important point about ReplicaSets is that one ReplicaSet can only manage one pod type. That pod type can be replicated on multiple pods.
A ReplicaSet defines two important things:
- the pod template
- the desired number of replicas
The pod template tells what type of pod to deploy (container image, network ports, labels). The desired number tells how many of these pods to deploy.
ReplicaSets ans k8s follow the declarative model. You describe your desired state without having to get into the detail of how to get there. k8s does the job of matching your current state with your desired state. (the imperative model is a list of commands to get to an end goal)
ReplicaSets implement a background loop that is constantly monitoring the cluster. If the current state doesn’t match the desired state, it wakes up the master and kubernetes tries to fix the situation.
- All k8s manifest files start by declaring the version of the API to use.
- The kind field tells which kind of object is being defined.
- The spec section is where the main configuration lives.
Chapter 5 — Kubernetes services
Pods IPs are unreliable. Every service gets its own stable IP address. Services use labels to dynamically associate with a set of pods. These two points are what allows a service to provide stable networking to a dynamic set of pods.
Labels and loose coupling
Pods and services are loosely coupled via labels and label selectors.
For a service to match a set of pods, and therefore provide stable networking and load balance, it only needs to match some of the pods labels. However, for a pod to match a service, the pod must match all of the values in the service’s label selector.
Chapter 6 — Kubernetes Deployments
Deployments are all about rolling updates and seamless rollbacks. At a high level, we start with pods as the basic k8s object. We wrap them in a ReplicaSet for scalability, resiliency and desired state. Then we add a deployment for rolling updates and simple rollbacks.
Rolling updates with deployments
With a deployment we create a manifest file and POST it to the API server. That gets given to the deployment controller and the app gets deployed on the cluster. Behind the scenes we get a ReplicaSet and a bunch of pods. We get rolling updates with zero downtime.
The old ReplicaSets stick around and don’t get deleted. They don’t manage any pods but they still exist. This makes them a great option for reverting back to previous versions. We simply wind one of the old ReplicaSets up and wind the current one down.
- Elasticsearch and Python
- Get started with Elasticsearch
- Introduction to Protobuf
- Stream processing with Python Faust: Part II – Streaming pipeline
- Stream processing with Python Faust: Part I – General Concepts
- Get started with Kafka
- App Store optimization (ASO) basics
- Persisting data in Docker: Docker volumes
- How to add a shadow behind iOS Buttons in Swift
- How to share an image on Instagram with iOS Swift