Reputation: 549
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
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 defaultServiceType
...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
andClusterIP
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