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

<ol>
<li><p>Gateway service: responsible for user authentication (API endpoint <code>/api/v1/users</code>), and routing requests to appropriate service.</p></li>
<li><p>Messaging service: responsible for creating, retrieving, updating, and deleting messages (API endpoint <code>/api/v1/messages</code>).</p></li>
</ol>

<p>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 <code>/api/v1/messages</code> API endpoint?</p>

<p>I used to write my own dynamic service discovery middleware (<a href="https://github.com/zicodeng/tahc-z/blob/master/servers/gateway/handlers/dsd.go" rel="nofollow noreferrer">https://github.com/zicodeng/tahc-z/blob/master/servers/gateway/handlers/dsd.go</a>). 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?</p>

<p>Thanks in advance!</p>

Zico Deng
<p>If you are using Kubernetes, here are the high level steps:</p>

<ol>
<li>Create your micro-service Deployments/Workloads using your docker images</li>
<li>Create Services pointing to these deployments</li>
<li>Create Ingress using Path Based rules pointing to the services</li>
</ol>

<p>Here is sample manifest/yaml files: (change docker images, ports etc as needed)</p>

<pre><code>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
</code></pre>

<p>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.</p>

<p>For example:
<code>curl http://svc-messaging</code> or <code>curl http://svc-gateway</code></p>

<p>You don't need to run your own service discovery, that's taken care by Kubernetes!</p>

<p>Some visuals:</p>

<p>Step 1:
<a href="https://i.stack.imgur.com/XmqWW.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/XmqWW.png" alt="deployments"></a></p>

<p>Step 2:
<a href="https://i.stack.imgur.com/OO6yB.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/OO6yB.png" alt="services"></a></p>

<p>Step 3:
<a href="https://i.stack.imgur.com/adRzU.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/adRzU.png" alt="ingress"></a></p>
