Let's say I am creating a chat app with microservice architecture. I have 2 services:
Gateway service: responsible for user authentication (API endpoint /api/v1/users
), and routing requests to appropriate service.
Messaging service: responsible for creating, retrieving, updating, and deleting messages (API endpoint /api/v1/messages
).
If I use Docker Compose or Kubernetes, how does my gateway service know which service should it forwards to if there is a request sending to /api/v1/messages
API endpoint?
I used to write my own dynamic service discovery middleware (https://github.com/zicodeng/tahc-z/blob/master/servers/gateway/handlers/dsd.go). The idea is that I pre-register services with API endpoints they are responsible for. And my gateway service relies on request resource path to decide which service this request should be forwarded to. But how do you do this with Docker Compose or Kubernetes? Do I still need to keep my own version of dynamic service discovery middleware?
Thanks in advance!
If you are using Kubernetes, here are the high level steps:
Here is sample manifest/yaml files: (change docker images, ports etc as needed)
apiVersion: v1
kind: Service
metadata:
name: svc-gateway
spec:
ports:
- port: 80
selector:
app: gateway
---
apiVersion: v1
kind: Service
metadata:
name: svc-messaging
spec:
ports:
- port: 80
selector:
app: messaging
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: deployment-gateway
spec:
replicas: 1
template:
metadata:
labels:
app: gateway
spec:
containers:
- name: gateway
image: gateway/image:v1.0
ports:
- containerPort: 80
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: deployment-messaging
spec:
replicas: 1
template:
metadata:
labels:
app: messaging
spec:
containers:
- name: messaging
image: messaging/image:v1.0
ports:
- containerPort: 80
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: ingress-for-chat-application
spec:
rules:
- host: chat.example.com
http:
paths:
- backend:
serviceName: svc-gateway
servicePort: 80
path: /api/v1/users
- backend:
serviceName: svc-messaging
servicePort: 80
path: /api/v1/messages
If you have other containers running in the same namespace and would like to communicate with these services you can directly use their service names.
For example: curl http://svc-messaging
or curl http://svc-gateway
You don't need to run your own service discovery, that's taken care by Kubernetes!
Some visuals: