DEV Community

Arsh Sharma
Arsh Sharma

Posted on • Edited on

Networking in Kubernetes

When working with Kubernetes we have different microservices running in different containers. Now, these different containers might be part of the same pod or present in different pods. Very often these microservices need to interact with each other. This is where the concept of Networking comes into place.

We'll be taking a look at Networking in two situations in this article:

  1. Pod Internal
  2. Between Different Pods

We have already learned a bit about what a Kubernetes service is in a previous article. To give you a brief recap, services in K8s gave us a stable IP address that doesn't change all the time and they also can be configured to allow access from the outside world which is not possible by default.

In this article, I'm going to assume that microservice A is making a request to microservice B. If microservice B was running locally on port 5000 the code in microservice A would look something like this:

const response = await axios.get(`http://localhost:5000/something/`);
Enter fullscreen mode Exit fullscreen mode

Note the above example is in JavaScript but the concepts discussed will be true regardless of the language and framework you use.

But since we aren't running the microservices locally let us modify the code to use an environment variable:

const response = await axios.get(`http://${process.env.SOME_ADDRESS}/something/`);
Enter fullscreen mode Exit fullscreen mode

We will now be having a look at what values to use for this environment variable depending on different cases.

Pod Internal

Let's say that the two different containers are running in the same pod. The change we have to make in this case is fairly simple.

For pod internal communication, K8s allows us to send a request to the localhost address. So you would simply use localhost as a value for the environment variable SOME_ADDRESS. Yes, it is that easy!

Between Different Pods

When an app running in one pod has to make a request to another app in another pod the situation gets a bit trickier. There are three different values we can use for the SOME_ADDRESS environment variable in this case. Let's have a look at them one by one.

Using ClusterIP

If we run

kubectl get services
Enter fullscreen mode Exit fullscreen mode

we will be able to see all the services currently running in our K8s cluster. In the output of this command, there would be a column titled ClusterIP. This would show you the IP Address which you can use to reach that service from inside the cluster.

Since pods are inside the cluster, they would have no problem using this IP Address. So we can simply use the IP address of the service we want to reach as the value of the SOME_ADDRESS environment variable.

But manually finding the address each time can be a bit cumbersome so let's have a look at a better way of doing so.

Using Automatically Generated Environment Variables

There are many reasons to love Kubernetes. One of them is that it gives us automatically generated environment variables (which we can directly use in our code) that have info about all the services running in our cluster.

The pattern for these generated variables is based on the name of the service. So if your service has a name some-service the generated environment variable for that would be SOME_SERVICE_SERVICE_HOST.

Basically, you would take your service name, make it all caps, replace '-' with '_' and add '_SERVICE_HOST' in the end. So the code snippet above would now look like this:

const response = await axios.get(`http://${process.env.SOME_SERVICE_SERVICE_HOST}/something/`);
Enter fullscreen mode Exit fullscreen mode

K8s is so awesome, isn't it?!

It gives you one more way :P

Using CoreDNS

K8s clusters by default come with a built-in service called CoreDNS. It is a Domain Name Service, which helps with creating domain names. Here we're talking about cluster internal domain names. This means these can't be used outside the cluster but are perfect for inter pod communication.

CoreDNS creates domain names like this:
service name + . + namespace the service is a part of

By default, our deployments and services get assigned to the default namespace unless we specify otherwise. So the value for our environment variable, in this case, would be: some-service.default.

And this is it! You should now be able to facilitate communication between different microservices successfully regardless of whether they are in the same pod or not.

Thanks for reading! :)

If you have any feedback for me or just want to talk feel free to connect with me on Twitter. I'll be more than happy to hear from you! :D

Top comments (1)

Collapse
 
sachinmaurya profile image
Sachin • Edited

Thank you Arsh for simplifying kubernetes concept !!
This series was Kool :p