How Does Dynamic Service Discovery Work When Using Docker Compose Or Kubernetes?

9/10/2018

Let's say I am creating a chat app with microservice architecture. I have 2 services:

  1. Gateway service: responsible for user authentication (API endpoint /api/v1/users), and routing requests to appropriate service.

  2. 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!

-- Zico Deng
docker
docker-compose
kubernetes
microservices
service-discovery

1 Answer

9/11/2018

If you are using Kubernetes, here are the high level steps:

  1. Create your micro-service Deployments/Workloads using your docker images
  2. Create Services pointing to these deployments
  3. Create Ingress using Path Based rules pointing to the services

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:

Step 1: deployments

Step 2: services

Step 3: ingress

-- leodotcloud
Source: StackOverflow