How can I connect to Kubernetes pod within the same cluster with HTTP request?

4/22/2021

I have 2 pods (both are docker image) in my Kubernetes cluster, I'm using EKS from AWS. One of the pod is an API service, another one is a console application.

I would need the console application sends HTTP request to the API without using any exposing service such as Load Balancer or NodePort.

I came across accessing the service within same cluster with the Kube-DNS name such as below:

my-api.default.svc.cluster.local:5007

However, when I deploy the console application, my console application is throwing this error:

Only 'http' and 'https' schemes are allowed. (Parameter 'requestUri')
 ---> System.ArgumentException: Only 'http' and 'https' schemes are allowed. (Parameter 'requestUri')
   at System.Net.Http.HttpRequestMessage.InitializeValues(HttpMethod method, Uri requestUri)
   at System.Net.Http.HttpRequestMessage..ctor(HttpMethod method, String requestUri)

From the error, I understood that this is because the Kube-DNS name is not exactly a web request URI since it is not started with http nor https.

My question is, is there anyway that I could turn it into a HTTP request? Will simply adding the http works?

Or is there any other way that I could connect to the API without exposing the API service?

-- Corene
amazon-eks
kubernetes

1 Answer

4/22/2021

What you are searching for is a ClusterIP Service, you can look at the various types on Kubernetes documentation ( https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types )

ClusterIP: Exposes the Service on a cluster-internal IP. Choosing this value makes the Service only reachable from within the cluster. This is the default ServiceType.

This means that if you create a service for the API Pod you are trying to reach, you will then be able to reach it like you expect, with the Kube-DNS name, something like the following:

service-name.namespace.svc.cluster.local

or, if you are in the same namespace, just:

service-name

Which means that you'll be able to make an http or https request to the service by:

http://service-name # will resolve if Pods are in the same namespace, default to port 80
http://service-name.namespace.svc.cluster.local # will default to port 80
http://service-name.namespace.svc.cluster.local:5007
https://service-name.namespace.svc.cluster.local:5007 # will go with https

Once the name resolves inside the cluster, you can access it like if you are accessing a normal named resource, specify the protocol, the port and so on. You can test with curl or wget if the endpoint resolves (from inside another Pod)

As for how to declare a ClusterIP service, here's an example:

apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  selector:
    app: MyApp # this needs to match with Pods labels (https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/)
  ports:
    - name: my-name
      protocol: TCP
      # you could re-target the port to expose a port on the API server but use another on the client
      port: 5007
      targetPort: 5007
-- AndD
Source: StackOverflow