Ivan Velichko Profile picture
Aug 7, 2021 24 tweets 6 min read Read on X
How to grasp Containers and Docker (Mega Thread)

When I started using containers back in 2015, I thought they were tiny virtual machines with a subsecond startup time.

It was easy to follow tutorials from the Internet on how to put your Python or Node.js app into a container...
But thinking of containers as of VMs is an extremely leaking abstraction. It doesn't allow you to judge:

- what's doable and what's not
- what's idiomatic and what's not
- what's safe enough and what's not

So, I started looking for the Docker implementation details.
Docker is a behemoth doing many different things. There is plenty of materials on Docker but:

- it's either shallow and introductory container tutorials
- it's something deeply technical and hard to follow for a newbie

So, it took me a while to structure things in my head.
I find the following learning order helpful:

1. Containers (low-level Linux impl)
2. Images (why do you need them)
3. Managers (many containers, one host)
4. Orchestrators (many hosts, one app)
1. Containers are not VMs.

A container is an isolated (namespaces) and restricted (cgroups, capabilities, seccomp) process.
To start a process you need to fork/exec an executable. But to start a containerized process, you need to prepare a box first - create namespaces, configure cgroups, etc.

Container Runtime is a special kind of (lower-level) software to run containers.

iximiuz.com/en/posts/imple…
Runc is the most widely used Container Runtime.

It's a command-line tool!

To run a container it needs a bundle:

- a JSON file with container params (path to executable, env vars, etc)
- a folder with an executable and other files (if any) to put into a container fs
Oftentimes, a bundle contains files that closely resemble a typical Linux distribution (/var, /usr, /lib, /etc, ...)

When runc launches a container with such a bundle, the process inside sees its filesystem as a typical OS.

But it's not required!

iximiuz.com/en/posts/not-e…
2. Images aren't mandatory to run containers.

You probably already noticed that. Container Runtimes just need normal folders.

Images solve the storage and distribution problem efficiently. Not the launching problem.

Read here how:

iximiuz.com/en/posts/you-d…
In the popularized by Docker workflow, you need an image to start a container.

The reality is actually reverse.

You can start containers without images. But you cannot build images without running containers!

Read here why:

iximiuz.com/en/posts/you-n…
3. Containers are for efficient server packing.

Much like real containers - they were invented to increase the amount of stuff a typical ship could take on board.

A typical server now runs tens or hundreds of containers. Thus, they need to coexist. Hence, a manager is needed.
A Container Runtime focuses on a single container start.

A Container Manager focuses on making many containers happily coexist on a single host.

Pulling images, unpacking bundles, configuring the inter-container network, storing container logs, etc.

iximiuz.com/en/posts/conma…
containerd is the most widely used container manager daemon.

Much like runc, it started as a component of Docker but was extracted into a dedicated project.

containerd can work with runc or any other runtime that implements the containerd-shim interface.
And we are ready to explain Docker!

Docker has two parts.

dockerd - a higher-level daemon sitting in front of containerd daemon.

docker - a command-line client to interact with dockerd.

Docker's task is to make the container workflows developer-friendly.
Docker can

- build/pull/push/scan images
- launch/pause/inspect/kill containers
- create networks/forward ports
- etc etc

But there is a dedicated piece of software for each such task individually.

Checkout

- podman
- buildah
- skopeo
- kaniko
- etc
4. Coordinating containers running on different hosts is hard.

Remember Docker Swarm? Docker was already quite monstrous when the multi-host container orchestration was added into the same daemon.

One more Docker's responsibility...
Omitting the issue with the bloated daemon, Docker Swarm seemed nice.

But another orchestrator won the competition. Kubernetes!

Docker Swarm is either obsolete or in maintenance mode since ~2020.
Kubernetes joins multiple servers (nodes) into a coherent cluster.

Every such node has a container manager on it. It used to be dockerd, but it's deprecated now. containerd and cri-o are two popular choices of slimmer container managers nowadays.
There is a lot of tasks for the container orchestrator.

How to group containers into higher-level primitives (pods)?

How to interconnect nodes with running containers into a common network?

How to provide service discovery?

et cetera, et cetera...

iximiuz.com/en/posts/servi…
Containers, Kubernetes, and AWS ECS enabled teams to create isolated services more easily.

It helped to solve lots of administrative problems, especially for bigger companies.
But it created lots of new tech problems that didn't exist on the traditional VM-based setups!

Managing lots of distributed services turned out to be really hard.

And that's how a Zoo of Cloud Native projects came to be.

iximiuz.com/en/posts/makin…
Last but not least, don't forget to check out this article for more details on Containerization and Orchestration domains

iximiuz.com/en/posts/journ…
My latest take on the nature of _standard_ containers

iximiuz.com/en/posts/oci-c…
Learning Containers - The Hard Way 👇

Turned the above thread into a detailed blog post with:

- Recommended Containers Learning Path
- 20+ links to in-depth container materials

iximiuz.com/en/posts/conta…

• • •

Missing some Tweet in this thread? You can try to force a refresh
 

Keep Current with Ivan Velichko

Ivan Velichko Profile picture

Stay in touch and get notified when new unrolls are available from this author!

Read all threads

This Thread may be Removed Anytime!

PDF

Twitter may remove this content at anytime! Save it as PDF for later use!

Try unrolling a thread yourself!

how to unroll video
  1. Follow @ThreadReaderApp to mention us!

  2. From a Twitter thread mention us with a keyword "unroll"
@threadreaderapp unroll

Practice here first or read more on our help page!

More from @iximiuz

Jul 4
Grasping Kubernetes Pods, Deployments, and Services 🧵

...through the lens of "old school" Virtual Machines.

Before the rise of Cloud Native:

- A VM was a typical deployment unit (a box)
- A group of VMs would form a service
- Everyone would build their own Service Discovery Image
Then, Docker containers showed up.

A container attempted to become a new deployment unit...

However, Docker's restriction of having a single process per container was too limiting. Many apps weren't built that way, and people needed more VM-ish boxes. Image
Kubernetes got the deployment unit right.

In Kubernetes, a minimal runnable thing is a Pod - a group of semi-fused containers.

Now, you can run (and scale!) the main app and its satellite daemons (sidecars) as a single unit. Image
Read 6 tweets
Jun 20
SSH Tunnels - A Visual Guide To Port Forwarding 🧵

One of my favorite parts of SSH is tunneling. With just the regular ssh client, you can do wonders!

1. Local Port forwarding

Access private ports of a remote machine using local tools (your browser, a fancy DB UI client, etc) Image
2. Local Port Forwarding with a Bastion Host

A more flexible and auditable variant of local port forwarding.

Typical use: A poor man's way to access services in a private VPC (when you don't have time to set up SSM or any other "proper" solution). Image
3. Remote Port Forwarding

Handy when you need to quickly expose a local service to the outside world, but your laptop doesn't have a public IP.

Of course, for that, you'll need a public-facing "ingress gateway". But fear not! Any server with an SSH daemon on it will do! Image
Read 6 tweets
Jan 28
Docker vs. containerd vs. Podman 🧵

Containers are everywhere, and Docker is the most popular (and user-friendly) way of running them. But it's definitely not the only way!

I prepared a series of exercises to help you explore the alternative single-host runtimes 👇 Image
To set up a baseline, I recommend starting with Docker.

Try launching a container and inspecting it:

- What is it exactly that you just launched?
- Is it a single process? A lightweight VM?
- Can you find the IP address of the container?

labs.iximiuz.com/challenges/sta…
Image
Docker relies on containerd, a lower-level container runtime, to run its containers. It is possible to use containerd from the command line directly, but the UX might be quite rough at times.

contaiNERD CTL (nerdctl) to the rescue!

Try it out 👉 labs.iximiuz.com/challenges/sta…
Image
Read 5 tweets
Jan 10
What Actually Happens When You Publish a Container Port? Mini-🧵

docker run -p 8080:80 nginx

Have you ever wondered what `-p 8080:80` in the above command does? Then read on! Image
When you launch Nginx (or any other service), it opens a socket on a certain address - e.g., 172.17.0.3:80.

Clients that can reach this IP address can access the service. Image
However, when a service runs in a container, its socket will likely be on the container's primary IP address.

...which may or may not be reachable from the host!

Hence, port forwarding. Or, as Docker calls it - port publishing. Image
Read 8 tweets
Nov 27, 2023
How Container Networking Works 🧵

1. Network namespaces - a Linux facility to virtualize network stacks.

Every container gets its own isolated network stack with (virtual) network devices, a dedicated routing table, a scratch set of iptables rules, and more. Image
2. Virtual Ethernet Devices (veth) - a means to interconnect network namespaces.

Container's network interfaces are invisible from the host - the latter runs in its own (root) network namespace.

To punch through a network namespace, a special Virtual Ethernet Pair can be used. Image
3. The need for a (virtual) switch device.

When multiple containers run in the same IP network, leaving the host ends of the veth devices dangling in the root namespaces will make the routes clash. So, you won't be able to reach (some of) the containers. Image
Read 6 tweets
Nov 17, 2023
What is Service Discovery - in general, and in Kubernetes 🧵

Services (in Kubernetes or not) tend to run in multiple instances (containers, pods, VMs). But from the client's standpoint, a service is usually just a single address.

How is this single point of entry achieved? Image
1⃣ Server-Side Service Discovery

A single load balancer, a.k.a reverse proxy in front of the service's instances, is a common way to solve the Service Discovery problem.

It can be just one Nginx (or HAProxy) or a group of machines sharing the same address 👇 Image
2⃣ Client-Side Service Discovery

The centralized LB layer is relatively easy to provision, but it can become a bottleneck and a single point of failure.

An alternative solution is to distribute the rosters of service addresses to every client and let them pick an instance. Image
Read 7 tweets

Did Thread Reader help you today?

Support us! We are indie developers!


This site is made by just two indie developers on a laptop doing marketing, support and development! Read more about the story.

Become a Premium Member ($3/month or $30/year) and get exclusive features!

Become Premium

Don't want to be a Premium member but still want to support us?

Make a small donation by buying us coffee ($5) or help with server cost ($10)

Donate via Paypal

Or Donate anonymously using crypto!

Ethereum

0xfe58350B80634f60Fa6Dc149a72b4DFbc17D341E copy

Bitcoin

3ATGMxNzCUFzxpMCHL5sWSt4DVtS8UqXpi copy

Thank you for your support!

Follow Us!

:(