This article is talking about the book of Kubernetes Patterns, Reuseable Elements for Designing Cloud-Native Applications by Bilgin Ibryam & Roland Huß.
As a developer with cloud-native applications, I can’t wait for sharing my ideas about this book. Like the book of Design Patterns: Elements of Reusable Object-Oriented Software by the Gang of Four, this book introduces some common use cases, best practices and principles for Kubernetes. No matter what kind of Kubernetes you are working on, managed (by cloud platforms, eg: AWS, GCP, etc.) or on-premise, it could be definitely helpful.
I would try to summarize the points I learned or found interesting or important and also add my corresponding experiences. It really covers lots of scenarios in the work you might meet so I highly recommend this book if you are working or will work with Kubernetes.
In the first chapter of Introduction, some basic but important Kubernetes concepts are introduced which are required to read this book but not enough. Another recommendation for readers is to know Kubernetes platform a little and be aware of its architecture and mechanism, that helps you understand the patterns more comprehensively.
The Path to Cloud Native
There are four levels of abstraction in a cloud-native application:
- Code level — high quality code is always important.
- Domain-Driven Design — approaches of software design.
- Microservices architectural style — principles and practices for distributed applications.
- Containers — as a standard way for packaging and running distributed applications.
The term of cloud native describes principles, patterns and tools to automate containerized microserivces at scale.
That is my favorite table when I read the book first time. As a software developer, the terms in OOP, design principles and design patterns are the common words and they did a great job to interpret the distributed primitives. For example, if you don’t quite understand the difference between Container image and Container itself, comparing with Class vs. Object or Instance. Then, it would clearly tell you that Container image is like the code while Container is the runtime Object of the image.
Containers are the build blocks for Kubernetes-based cloud native applications. As mentioned above, the container is like a runtime instance but could be place in multiple servers as the runtime instance could be launched in different processes in a single machine.
For container images, it is more like classes or modules and can be reused in different environments. A container image typically including runtime depenencies, resource requirements, exposed APIs runs as a single process and is owned by a single team.
A Pod is the basic unit in Kubernetes for scheduling and deployment and provides runtime isolation for containers inside it. All the containers in the same Pod share filesystem, networking and process namespaces. Here are some charactoristics of a Pod:
- A Pod is the atomic unit of scheduling.
- A Pod ensure colocation of containers. The containers in the same Pod could communicate to each other via IPC, local filesystem and networking.
- A Pod has an IP address, name and port range that are shared by all containers belonging to it. Therefore, it should be careful to configure the port number for the containers hosted in the same Pod to avoid port conflicts.
The Service is an Kubernetes abstraction that binds the Service name to an IP address and port number permanently so it represents a named entry point of an application.
A label is mostly like a tag for Kubernetes resources and it could be informational or for query filters. There are some examples for label usage:
- ReplicaSet uses it to keep instances of a Pod running.
- The scheduler uses labels for colocating or spreading Pods to the proper Nodes.
- A label can be used for marking some Pods as a logical group.
- Some informational label can be also used as metadata.
Note, removing label is quite risky since the label usage is not straightforward.
Annotations are similar with informational labels and dedicated for indicating metadata. The biggest difference between annotations and labels is annotations are non-searchable.
Namespace is another important primitive in Kubernetes, which is a logical pool of resources inside a Kubernete cluster. Therefore, a more common use case is to representing difference software environments such as development, testing, integration testing and production. Some other characteristics of namespaces are:
- A namespace itself is also managed as a Kubernetes resource.
- A namespace can scope resources, like containers, Pods, Services and ReplicateSets. The name of those resources must be unique within a namespace.
- Namespaces do NOT isolate the resources physically which means the resources in difference namespaces can access each other.
- The resources of namespaces themself, Nodes and PersisitentVolumes are NOT scoped by namespaces and they have unique cluster-wide names.
- Each Kubernetes Service gets a corresponding DNS address containing the namespace, like:
- ResourceQuotas apply constraints per namespace.
Next, I would like elaborate the most valuable part, the Kubernetes Patterns, in my following posts. Some patterns are more like principles which are recommended but not required. However, you would definitely benefit from them for both managing and maintaining your Kubernetes environment.