Reputation: 33
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
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
Reputation: 3224
You should create services for frontend and backend, and then you can communicate using:
<service-name>.<namespace-name>.svc.cluster.local
which will be always the sameExample 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
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
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