Slim containers are faster (less stuff to move around) and more secure (fewer places for vulnerabilities to sneak in). However, these benefits of slim containers come at a price - such containers lack (the much-needed at times) exploration and debugging tools. It might be quite challenging to tap into a container that was built from a distroless or slim base image or was minified using DockerSlim or alike. Over the years, I've learned a few tricks how to troubleshoot slim containers, and it's time for me to share.
Last week at KubeCon, there was a talk about Kubernetes ephemeral containers. The room was super full - some people were even standing by the doors trying to sneak in. "This must be something really great!" - thought I and decided to finally give Kubernetes ephemeral containers a try.
So, below are my findings - traditionally sprinkled with a bit of containerization theory and practice 🤓
TL;DR: Ephemeral containers are indeed great and much needed. The fastest way to get started is the
kubectl debug command. However, this command might be tricky to use if you're not container-savvy.
Containers could have become a lightweight VM replacement. However, the most widely used form of containers, standardized by Docker/OCI, encourages you to have just one
process service per container. Such an approach has a bunch of pros - increased isolation, simplified horizontal scaling, higher reusability, etc. However, there is a big con - in the wild, virtual (or physical) machines rarely run just one service.
While Docker tries to offer some workarounds to create multi-service containers, Kubernetes makes a bolder step and chooses a group of cohesive containers, called a Pod, as the smallest deployable unit.
When I stumbled upon Kubernetes a few years ago, my prior VM and bare-metal experience allowed me to get the idea of Pods pretty quickly. Or so thought I... 🙈
Starting working with Kubernetes, one of the first things you learn is that every pod gets a unique IP and hostname and that within a pod, containers can talk to each other via localhost. So, it's kinda obvious - a pod is like a tiny little server.
After a while, though, you realize that every container in a pod gets an isolated filesystem and that from inside one container, you don't see processes running in other containers of the same pod. Ok, fine! Maybe a pod is not a tiny little server but just a group of containers with a shared network stack.
But then you learn that containers in one pod can communicate via shared memory! So, probably the network namespace is not the only shared thing...
This last finding was the final straw for me. So, I decided to have a deep dive and see with my own eyes:
- How Pods are implemented under the hood
- What is the actual difference between a Pod and a Container
- How one can create Pods using Docker.
And on the way, I hope it'll help me to solidify my Linux, Docker, and Kubernetes skills.
Just kidding, it's not... But fear not and read on!
You can find a Russian translation of this article here.
Working with containers always feels like magic. In a good way for those who understand the internals and in a terrifying - for those who don't. Luckily, we've been looking under the hood of the containerization technology for quite some time already and even managed to uncover that containers are just isolated and restricted Linux processes, that images aren't really needed to run containers, and on the contrary - to build an image we need to run some containers.
Now comes a time to tackle the container networking problem. Or, more precisely, a single-host container networking problem. In this article, we are going to answer the following questions:
- How to virtualize network resources to make containers think each of them has a dedicated network stack?
- How to turn containers into friendly neighbors, prevent them from interfering, and teach to communicate well?
- How to reach the outside world (e.g. the Internet) from inside the container?
- How to reach containers running on a machine from the outside world (aka port publishing)?
While answering these questions, we'll setup a container networking from scratch using standard Linux tools. As a result, it'll become apparent that the single-host container networking is nothing more than a simple combination of the well-known Linux facilities:
- network namespaces;
- virtual Ethernet devices (veth);
- virtual network switches (bridge);
- IP routing and network address translation (NAT).
And for better or worse, no code is required to make the networking magic happen...