One of the big “lightbulb moments” I see when people are learning Kubernetes is the moment when they understand how applications communicate with each other. It often takes a big shift in your thinking to understand how your application can talk to another application in Kubernetes. The answer is networking.
The networking layer of Kubernetes is highly configurable, with lots of plugins and options. This means that the exact way pods communicate depends on how your Kubernetes cluster has been deployed.
But, there are some basic facts about pod-to-pod communication, which generally hold true for all Kubernetes clusters:
In Kubernetes, each Pod has an IP address. A Pod can communicate with another Pod by directly addressing its IP address, but the recommended way is to use Services. A Service is a set of Pods, which can be reached by a single, fixed DNS name or IP address.
In reality, most applications on Kubernetes use Services as a way to communicate with each other. Using a Service is much more flexible than addressing another Pod directly, because Pods can be restarted frequently, which means that addressing them by name or IP is a very brittle approach.
Simple pod-to-pod communication
To understand how Pods communicate in Kubernetes, first let’s look at basic Pod-to-Pod communication.
In Kubernetes, each Pod has its own IP address. At a very primitive level, Pods can communicate with each other using their IP address.
This means that whenever you need to address another Pod, you can do it directly, using its IP address. This gives Pods similar characteristics to virtual machines (VMs), where each Pod has its own IP address, can expose ports, and address other VMs on the network by IP address and port.
Even if a Pod has more than one container, it still has just one IP address. You can see this shown in the picture above.
How does a frontend pod communicate with a backend pod?
In a typical web application architecture, we might have a frontend application which talks to a backend. The backend could be something like an API or a database. In Kubernetes, we would realise this as two Pods, one for the frontend, one for the backend.
We could configure the front-end to talk to the backend directly by its IP address. But the frontend would need to keep track of the backend’s IP address, which can be tricky, because the IP address changes as the Pod is restarted or moved onto a different Node. So, to make our solution less brittle, we link the two applications using a Service.
Create the Pod and give it a label - The Pod is usually created through another object like a Deployment, a StatefulSet, or, in OpenShift, a DeploymentConfig. The Pod is assigned a the label in its JSON or YAML, like
Create a Service which selects the backend Pod - A Service is created which selects all Pods that match the given label. This is done by specifying a
selectorin the Service definition. In this example, the Service is called
my-apiand it selects Pods with the label
The app communicates with the backend using the service name as the hostname - The app can now address the API using the Service name as the hostname. So if the app talks to the backend over HTTP then it would look like
If the Pods die, or they need to be restarted, this won’t affect the app, because it will still communicate with the API pods via the Service, which has a stable IP address.
With container based applications, we generally try to follow the Single Responsibility Principle. This means that each container should generally fulfil a single responsibility, or concern.
How do containers in the same Pod communicate?
Sometimes, you need to run more than one container in the same Pod.
Multiple containers in the same Pod share the same IP address. They can communicate with each other by addressing
localhost. For example, if a container in a Pod wants to reach another container in the same Pod on port 8080, it can use the address
Because multi-container Pods share the same IP address and communicate on
localhost, this means that two containers can’t share the same port, if they’re in the same Pod.
For example, you couldn’t have two containers in the same Pod which expose port
8080, because there would be a conflict. So, you need to make sure you’re running services on different ports.
Note: If you’re considering running more than one container in a Pod, then bear in mind that this approach isn’t recommended for most n-tier applications, such as an app server and a database, which should usually be in separate Pods.
In Kubernetes, pods can communicate with each other a few different ways:
Containers in the same Pod can connect to each other using
localhost, and then the port number exposed by the other container.
A container in a Pod can connect to another Pod using its IP address. To find out the IP address of a Pod, you can use
oc get pods.
A container can connect to another Pod through a Service. A Service has an IP address, and also usually has a DNS name, like
Got any thoughts on what you've just read? Anything wrong, or no longer correct? Sign in with your GitHub account to leave a comment.
(All comments get added as Issues in our GitHub repo here, using the comments tool Utterances)