How to call other services in Kubernetes

May 14, 2020·

2 min read

In a scenario where you have multiple services running in one cluster, you will want them to communicate with each other. There are multiple ways to approach interservice communication; pubsub channel (like Redis), queues/topics (like RabbitMQ or Azure Service Bus) or plain ole HTTP calls. Let's briefly discuss this last option but let me introduce you to Kubenet really quick.

As I mentioned in my previous articles on Kubernetes, intracluster communication is facilitated by something called Kubenet. Kubenet is a basic network plugin that does its job well but doesn't come with any bells and whistles like cross-node networking or policy management. If you're hosting your K8s cluster on Azure (or any other serious cloud provider), they will set up all the routing rules for your nodes and in some cases give you control over network policy configuration. In fact, Azure has an Advanced networking mode which gives you more control over the networking aspect of your cluster. You can read about Kubenet and Azure CNI here.

In essence, kubenet's job is to assign IP addresses to pods and resolve service hostnames to these IP addresses. When you add a new deployment with a pod and service, it's automatically assigned an IP address and immediately discoverable on your cluster. Let's say you've added a service like this:

apiVersion: v1
kind: Service
metadata:
  name: fancyapi-service
  namespace: integration
spec:
  selector:
    app: fancyapi
  ports:
    - name: http
      protocol: TCP
      port: 80
      targetPort: 5000
  type: ClusterIP

Kubenet will assign this service an IP address (which you can view via kubectl get svc). To access this service from another service, you don't need to worry about using that IP address -- you can just use the name of this service; fancyapi-service.

An example in C# would look like this:

using (var client = new HttpClient()) {
  var result = await client.GetAsync($"http://fancyapi-service/v1/fancyproducts");
  if (result.IsSuccessStatusCode) {
    return JsonConvert.DeserializeObject<List<Product>>(await result.Content.ReadAsStringAsync());
  }
  return null;
}

We instantiate a new HTTP client (inside an async Task method) and call the fancyapi-service to get a list of products from the v1 controller. Kubenet will resolve fancyapi-service to the correct IP address and route the traffic appropriately. Easy as pie!

Did you find this article valuable?

Support Paul K by becoming a sponsor. Any amount is appreciated!