How to get express-gateway working in kubernetes?

2/1/2021

I'm building a microservice app where I used nginx-ingress to wire-up all my services which worked fine but now I would like to add some advanced features like jwt-authentication. Instead of implementing it in each service I thought I would use an API gateway and chose express-gateway because it seemed simple to setup. I tested everything locally (without docker/kubernetes) and everything worked as expected in less then 5 minutes.

My problem is that I can't get the gateway to pass the request to the actual service. The request reaches the gateway tho. I'm using minikube on Ubuntu and added a host to my host file so that I don't have to remember the minikube IP. Usually I reach my service by https://app.dev/api/users/signup.

This is my gateway.config.yaml

http:
  port: 8080
apiEndpoints:
  auth:
    host: '*'
    path: '/api/users/*'
serviceEndpoints:
  authsrv:
    url: 'http://localhost:3000/'
policies:
  - basic-auth
  - cors
  - expression
  - key-auth
  - log
  - oauth2
  - proxy
  - rate-limit
pipelines:
  auth:
    apiEndpoints:
      - auth
    policies:
      - proxy:
          - action:
              serviceEndpoint: authsrv 
              changeOrigin: true

The apiEnpoints is for configuring the route that you call while the serviceEndpoints are what is called by the gateway so the internal IP of the microservice. I think that this is the issue I have no idea what the actual host is or how the gateway can get this information. When I used an ingress-nginx I never had to specify the host of the microservice. Because every time you boot up its different right so I don't understand what I have to do here. Any advice? Sadly express gateway has no docs of how to set it up with kubernetes the docs just say that its possible ): Here is the rest of my config:my-service-depl.yaml (simple NodeJS express app)

apiVersion: apps/v1
kind: Deployment
metadata:
  name: auth-depl
spec:
  replicas: 1
  selector:
    matchLabels:
      app: auth
  template:
    metadata:
      labels:
        app: auth
    spec:
      containers:
        - name: auth
          image: henryfoster/auth
---
apiVersion: v1
kind: Service
metadata:
  name: auth-srv
spec:
  selector:
    app: auth
  ports:
    - name: auth
      protocol: TCP
      port: 3000
      targetPort: 3000

ingress-srv.yaml

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: ingress
spec:
  backend:
    serviceName: gateway
    servicePort: 8080
gateway-depl.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: gateway
spec:
  selector:
    matchLabels:
      app: gateway
  replicas: 1
  template:
    metadata:
      labels:
        app: gateway
    spec:
      containers:
        - name: gateway
          image: henryfoster/gateway
          env:
            - name: LOG_LEVEL
              value: info
---
apiVersion: v1
kind: Service
metadata:
  name: gateway
spec:
  ports:
    - name: http
      protocol: TCP
      port: 8080
      targetPort: 8080
  selector:
    app: gateway
  type: ClusterIP

express-gateway: Dockerfile

FROM expressgateway/express-gateway
COPY ./config/ /var/lib/eg/
-- nanobot
api-gateway
docker
express-gateway
kubernetes
microservices

1 Answer

2/1/2021

Now I understand. Inside Kubernetes the service-name is the domain for its IP so to call the service inside kubernetes I have to use the service-name in this case: auth-srv. instead of:

serviceEndpoints:
  authsrv:
    url: 'http://localhost:3000/'

use service-name as host:

serviceEndpoints:
  authsrv:
    url: 'http://auth-srv:3000/'
-- nanobot
Source: StackOverflow