Test
Test

Reputation: 549

how do you set up two microservices that communicate with each other, one being public and one private, using Kubernetes?

I think that you can configure this in the -service.yaml. For example I have a frontend and a backend. The frontend should be public and my backend should be private. So how do you set up two microservices that communicate with each other, one being public and one private, using Kubernetes?

frontend-service.yaml

apiVersion: v1
kind: Service
metadata:
  creationTimestamp: null
  labels:
    app: frontend
  name: frontend
spec:
  ports:
  - port: 8081
    protocol: TCP
    targetPort: 8081
  selector:
    app: frontend
  type: LoadBalancer
status:
  loadBalancer: {}

backend-service.yaml

apiVersion: v1
kind: Service
metadata:
  creationTimestamp: null
  labels:
    app: backend
  name: backend
spec:
  ports:
  - port: 8080
    protocol: TCP
    targetPort: 8080
  selector:
    app: backend
  type: LoadBalancer
status:
  loadBalancer: {}

What I tried

kubectl apply -f frontend-deploy.yaml
kubectl get pods
kubectl apply -f frontend-service.yaml
kubectl get service
kubectl apply -f backend-deploy.yaml
kubectl get pods
kubectl apply -f backend-service.yaml
kubectl get service
kubectl expose deployment frontend --type=LoadBalancer --name=frontend-service.yaml

Upvotes: 1

Views: 1188

Answers (1)

Mikolaj S.
Mikolaj S.

Reputation: 3224

You should use ClusterIP type for the private / internal services which will make your application only available within the cluster:

  • 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

...and LoadBalancer type for the public services which are designed to receive requests from the outside the cluster:

  • LoadBalancer: Exposes the Service externally using a cloud provider's load balancer. NodePort and ClusterIP Services, to which the external load balancer routes, are automatically created.

Example:

Let's say that I have created frontend and backend deployments - frontend on 8081 port and backend on 8080. Services yamls are similar to yours (I used LoadBalancer for the frontend, and ClusterIP for the backend). Fronted service is available at the 80 port, backend at the 8080:

apiVersion: v1
kind: Service
metadata:
  labels:
    app: frontend
  name: frontend
spec:
  ports:
  - port: 80
    protocol: TCP
    targetPort: 8081
  selector:
    app: frontend
  type: LoadBalancer
---
apiVersion: v1
kind: Service
metadata:
  labels:
    app: backend
  name: backend
spec:
  ports:
  - port: 8080
    protocol: TCP
    targetPort: 8080
  selector:
    app: backend
  type: ClusterIP

Let's check the services:

$ kubectl get svc
NAME                                TYPE           CLUSTER-IP     EXTERNAL-IP      PORT(S)        AGE
backend                             ClusterIP      10.36.9.41     <none>           8080/TCP       19m
frontend                            LoadBalancer   10.36.4.172    xx.xxx.xxx.xxx   80:32126/TCP   19m

As can see, both services have ClusterIP (used for communication inside the cluster) and frontend service has a LoadBalancer with public IP.

Let's exec into a pod and send request to the frontend and backend using just a service name:

root@my-nginx-deployment-5bbb68bb8f-jgvrk:/# curl backend:8080
"hello world backend"
root@my-nginx-deployment-5bbb68bb8f-jgvrk:/# curl frontend:80
"hello world frontend"

It's working properly, because the pod that I exec into is in the same namespace (default). For communication between different namespaces you should use <service-name>.<namespace>.svc.cluster.local or ClusterIP:

root@my-nginx-deployment-5bbb68bb8f-jgvrk:/# curl backend.default.svc.cluster.local:8080
"hello world backend"
root@my-nginx-deployment-5bbb68bb8f-jgvrk:/# curl 10.36.9.41:8080
"hello world backend"

This is how communication inside cluster works in Kubernetes

For requests outside the cluster use LoadBalancer IP (EXTERNAL-IP in the kubectl get svc command):

user@shell-outside-the-cluster:~$ curl xx.xxx.xxx.xxx
"hello world frontend"

Consider using Ingress when you have multiple applications which you want to expose publicly.

Also check these:

Upvotes: 1

Related Questions