Pod fundamentals
- Every pod has a unique IP address
- IP addressed are reachable from all other pods in the k8 cluster
The smallest unit or component is a POD and not a Container. And considering that POD always contains one main container, for example, you might have a POD with postgres container or elasticsearch container, or your own application.
Some people may be asking why the need for abstracting the container with a pod if there is anyways just one main application running inside. So in this blog I’m going to explain to you why having a POD as an abstraction over container is such an important concept in Kubernetes.
I’m going to give you a comparison between POD and container, and I will show you in which cases you would need to have multiple containers inside one pod, and how these containers then will communicate with each other. At its core, Kubernetes networking has one important fundamental concept,
which is that every POD has a unique IP address and
that IP address is reachable from all the other pods in the
cluster. So that’s the main concept. Now, why is it important
and valuable to have this POD component with its own IP address?
You see, one main challenge on distributed infrastructure with multiple servers is how to allocate ports to services and applications running on servers without getting conflicts.
Since obviously
you can only allocate one port once on a single host with
containers, you would soon face this challenge because this is
how container port mapping works. Let’s say for example, a PostgreSQL
container where inside the container the Postgres application
starts at port 5432.
Now when you start containers
directly on your machine, what you do is you bind
your host port to the application port in the container.
And to see that in practice, we can start postgres docker container.
So this is the part where we map or we bind the port
on the host to the port of the application running inside
the docker container. So it doesn’t have to be the same port.
I can also give it a completely different one. So let’s write 5000
and if I execute this command,
Postgres container started, and if we check here with docker
ps, I will see that port
5000 on the host machine is mapped to this
one here. So now the application is reachable by the
host port. Now that I have one postgres
already running, I could start another
postgres container that will also run at the same port,
but bind it on a different port on my host.
So this will work as well. So if
I go here now and say docker ps I
will see two postgres applications bound to different
ports on the host. And this is how containers
work. The problem with this is when you have hundreds
of containers running on your servers, how can you keep track of
what ports are still free on the host to bind them?
So soon enough with this type of port allocation,
it will become difficult to have an overview. And the
way Kubernetes solves this problem is by abstracting the
containers using pods where POD is like its own
small machine with its own IP address, usually with one
main container running inside. For example, you might
have a POD where postgres container is running.
When a POD is created on a node, it gets
its own network namespace and a virtual ethernet connection
to connect it to the underlying infrastructure network.
So a POD is a host just like your laptop.
Both have IP addresses and a range of ports they can allocate to
its containers. This means you don’t have to worry about port mappings
on the server where POD is running and only inside the pod itself.
But since you anyways usually have just one main container,
or sometimes maybe maximum up to six containers inside a
pod, you won’t get conflicts there because you have a pretty good overview
of what containers are running inside. This means that on one server
you can have, for example 10 microservice applications that
all run on port 8080 inside 10 different pods.
And you won’t have any conflicts because they all run on
self contained isolated machines which are pods.
Another reason why POD abstraction over container is useful is
that you can easily replace the container runtime in kubernetes.
So for example, if you replace docker runtime with an other container
runtime, Kubernetes configuration will stay the same because
it’s all on the POD level. It means that Kubernetes isn’t
tied up to any particular container runtime implementation.
Now as I mentioned at the beginning, sometimes POD might have
two or more containers inside. This is a case
when you need to run a helper or site application to
your main application. Like for example for
synchronizing when you have multiple database pods or
for backing up your applic at certain intervals.
So would have this backup sidecar container within your
application container, or it could be a scheduler or maybe authentication
gateway. So there are many use cases where
you might end up having more than one containers inside a
pod. Now the question is how do these containers
communicate with each other inside the pod? Remember, POD is
an isolated virtual host with its own network namespace,
and containers inside all run in this network namespace.
This means that containers can talk to each other via local host
and a port number, just like when you’re running multiple applications on
your own laptop.
Also, have you noticed that in a Kubernetes cluster, when you run Docker
containers there is this POS container always
per each pod. These are called sendbox containers whose
only job is to reserve and hold the POD network namespace
that’s shared by all the containers in a pod. So post container
makes it possible for the containers to communicate with each other.
And also if a container dies and a new one gets
created, POD will stay and keep its IP address.
But know that if the pod itself dies, it gets recreated
and a new pod will get assigned a different IP address.