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/
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/'