Mohit Bhatt
Mohit Bhatt

Reputation: 33

How do resources talk to each other from different namespaces?

Conditions: I have a 3 tier application to deploy using Kubernetes. I have created two namespaces for backend and frontend respectively.

Problem: I want to know how would my backend talk to the frontend or vice versa.

In simple words, how do backend and frontend communicate if they are in different namespaces?

Upvotes: 2

Views: 1764

Answers (4)

Harsh Manvar
Harsh Manvar

Reputation: 30160

Your application will talk to each other using the Kubernetes service.

So generally traffic flows moves inside K8s cluster is like

Incoming traffic to any specifc application > Kubernetes service > Kubernetes deployment > PODs > Containers

So now imagine all your application running inside on Virutal environment. Where they can talk to each other using just the service name. Instead of using IP now you can use service to resolve to IP automatically. Same we do with www.google.com IP managed by DNS automatically.

For cross namespace also you have to give the service name.

service-y.namespace-b.svc.cluster.local

The format will be something like

<servicename>.<namespace>.svc.cluster.local

where your .svc.cluster.local will be auto appended if don't use also.

Kubernetes service : https://kubernetes.io/docs/concepts/services-networking/service/

Here is example connecting & deploying the application using different services : https://kubernetes.io/docs/tutorials/stateful-application/mysql-wordpress-persistent-volume/

Service 1 will connect to service 2 using just by name.

MySQL service name is : wordpress-mysql

WordPress will get connected to MySQL using just service passing to environment.

      - image: wordpress:4.8-apache
        name: wordpress
        env:
        - name: WORDPRESS_DB_HOST
          value: wordpress-mysql

now if it's another namespace you just need to append namespace name.

          - image: wordpress:4.8-apache
            name: wordpress
            env:
            - name: WORDPRESS_DB_HOST
              value: wordpress-mysql.my-new-namespace.svc.cluster.local

Upvotes: 1

Mikolaj S.
Mikolaj S.

Reputation: 3224

You should create services for frontend and backend, and then you can communicate using:

  • (Recommended) a DNS names of the services <service-name>.<namespace-name>.svc.cluster.local which will be always the same
  • (Not recommended) a IP address of the services (but they will be different with each re-creation of the service)

Example and further explanation below.

Let's create deployments with 3 replicas - one in default namespace, one in test namespace:

kubectl create deployment nginx --image=nginx --replicas=3
kubectl create deployment nginx --image=nginx --replicas=3 -n test

For each deployment we will create service type ClusterIP using kubectl expose(It's the same if I had created a service from a yaml file:):

kubectl expose deployment nginx --name=my-service --port=80
kubectl expose deployment nginx --name=my-service-test --port=80 -n test

Time to get IP addresses of the services:

user@shell:~$ kubectl get svc
NAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
kubernetes   ClusterIP   10.96.0.1       <none>        443/TCP   64d
my-service   ClusterIP   10.107.224.54   <none>        80/TCP    12m

And in test namespace:

user@shell:~$ kubectl get svc -n test
NAME              TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)   AGE
my-service-test   ClusterIP   10.110.51.62   <none>        80/TCP    8s

I will exec into pod in default namespace and curl IP address of the my-service-test in second namespace:

user@shell:~$ kubectl exec -it nginx-6799fc88d8-w5q8s -- sh
# curl 10.110.51.62
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>

Okay, it's working... Let's try with hostname:

# curl my-service-test
curl: (6) Could not resolve host: my-service-test

Not working as expected. Let's check /etc/resolv.conf file:

# cat resolv.conf
nameserver 10.96.0.10
search test.svc.cluster.local svc.cluster.local cluster.local
options ndots:5

It's looking for hostnames only in namespace where pod is located.

So pod in the test namespace will have something like:

# cat resolv.conf
nameserver 10.96.0.10
search test.svc.cluster.local svc.cluster.local cluster.local
options ndots:5

Let's try to curl my-service-test.test.svc.cluster.local from pod in default namespace:

# curl my-service-test.test.svc.cluster.local
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>

It's working.

If you have problems, make sure you have a proper CNI plugin installed for your cluster - also check this article - Cluster Networking for more details. If you are using some cloud provided solution (like AWS EKS or GCP GKE) you should have it by default.

Also check these:

Upvotes: 1

Eisa Qasemi
Eisa Qasemi

Reputation: 826

applications can communicate with other services outside their namespace , just use the correct dns name

<Service Aame>.<Namespace Name>.svc.cluster.local

Upvotes: 1

Blender Fox
Blender Fox

Reputation: 5635

There's two ways: internal-only and external.

For both, create a kubernetes service for the front and back end services.

For external, the service type must LoadBalancer. You install the External DNS plugin which will let you create an external DNS name that you can access by the other service. This will also allow you to access the service outside the cluster if you wish.

For internal, you make the service type ClusterIP or NodePort. When you create the service, you can then access them using the format: service-name.namespace.svc.cluster.local

For example, an nginx service running on the namespace internal would be accessed as the DNS name nginx.internal.svc.cluster.local

This service cannot be accessed outside of the cluster.

You can sometimes drop the cluster.local part, but I include it as habit.

Upvotes: 1

Related Questions