container pod what it is - Murray-LIANG/forgetful GitHub Wiki
What Even Is A Container And A Kubernetes Pod
Container
The word container
doesn't mean anything super precise. Basically there are a few new Linux kernel features (namespaces
and cgroups
) that let you isolate processes from each other. When you use those features, you call it containers
.
Basically these features let you pretend you have something like a virtual machine, except it's not a virtual machine at all, it's just processes running in the same Linux kernel.
Namespaces
namespaces
is a Linux feature which could separate your processes from the other processes on the same computer.
There are a bunch of different kinds:
- pid - you become PID 1 and then your children are other processes. All the other programs are gone.
- network - you can run programs on any port you want without it conflicting with what's already running.
- mount - you can mount and unmount file systems without it affecting the host filesystem.
unshare
command makes it easy to run your processes inside a namespace.
$ sudo unshare --fork --pid --mount-proc bash
List all the processes inside the namespace. You can only see two processes.
root@mint-dev-vm:~/git/microservices-example# ps aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.0 24456 5236 pts/4 S 10:48 0:00 bash
root 14 0.0 0.0 39112 3528 pts/4 R+ 10:51 0:00 ps aux
Then we run top
inside the namespace. We can check it's PID from the regular PID namespaces.
➜ ~/git/cinder git:(850013325) ✗
$ sudo ps -elf | grep top
0 S root 114177 114063 0 80 0 - 10856 poll_s 10:50 pts/4 00:00:00 top
The PID of top
is 3 in the new namespace and 114177 in the regular namespace.
nsenter
command allows you enter the namespace of another running program.
➜ ~/git/cinder git:(850013325) ✗
$ sudo nsenter -t 114063 --pid bash
Cgroups
We now isolate our processes from our old world.
What if I want to limit how much memory or CPU one of my programs is using? cgroups
could help.
$ # Create a cgroup to just limit memory.
$ sudo cgcreate -a ryan -g memory:mymemgroup
$ ls -l /sys/fs/cgroup/memory/mymemgroup
$ # Limit the quota of memory to 10MB.
$ sudo echo 10000000 > /sys/fs/cgroup/memory/mymemgroup/memory.kmem.limit_in_bytes
$ # Run `bash` under cgroup limitation.
$ sudo cgexec -g memory:mymemgroup bash
Kubernetes Pod
When you run a container with Docker normally, Docker creates namespaces and cgroups for each container so they map one to one.
However, with some extra command line arguments, you can combine Docker containers using a single namespace.
$ docker run -d --name ghost \
--net=container:nginx --ipc=container:nginx --pid=container:nginx ghost
In the above example, ghost
container uses namespaces of nginx
. These namespaces allow these two Docker containers to discover and communicate with each other.
This way you could combine namespaces and cgroups with multiple processes, we can see that's exactly what Kubernetes Pods are. Pods allow you to specify the containers that you want to run and Kubernetes automates setting up the namespaces and cgroups in the right way. So, Pods are Containers running in same namespaces.
Once we have our containers set up this way, each process feels
like it's running on the same machine. They can talk to each other on localhost, they can use shared volumes. They can even use IPC or send each other signals like HUP
or TERM
.
With Pods, you can put different services in different containers. Kubernetes manages each container and has insight into its state. That way it can provide services like restarting it when it crashes or automated logging.
Without Pods, you can just put all services into one container to let them feel like running on the same machine and use a supervisord
to keep all services running. Services might be crashing but Docker would have no idea.