Below is my Nodejs microservices pattern:
// api.ts
import { Router } from 'express';
const router = Router();
router.get(':id', ...doSomething);
router.post(':id', ...doSomething);
export default router;
// index.ts
import * as Express from 'express';
import API from './api.js';
basePath = process.env.basePath; // usually is project name
const app = Express();
// handle external call
app.use(basePath, API) // wish to remove this line
// handle internal call from microservices
app.use(API) // preferred to be like this
...continue
Below is my kubeDeploy file inherit from colleague
apiVersion: apps/v1
kind: Deployment
metadata:
name: $CI_PROJECT_NAME
namespace: $KUBE_NAMESPACE
spec:
replicas: 1
selector:
matchLabels:
app: $CI_PROJECT_NAME
template:
metadata:
labels:
app: $CI_PROJECT_NAME
spec:
imagePullSecrets:
- name: gitlabcred
containers:
- image: registry.gitlab.com/$GROUP_NAME/$CI_PROJECT_NAME:$CI_BUILD_REF_NAME
imagePullPolicy: Always
name: $CI_PROJECT_NAME
ports:
- containerPort: $PORT
env:
- name: basePath
value: "$URL_PATH"
resources: $KUBE_RESOURCES
livenessProbe: $KUBE_LIVENESS
---
apiVersion: v1
kind: Service
metadata:
name: $CI_PROJECT_NAME
namespace: $KUBE_NAMESPACE
spec:
ports:
- port: $PORT
protocol: TCP
name: http
selector:
app: $CI_PROJECT_NAME
sessionAffinity: ClientIP
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: $CI_PROJECT_NAME
namespace: $KUBE_NAMESPACE
annotations:
kubernetes.io/ingress.class: "nginx"
spec:
rules:
- host: $KUBE_DNS_NAME
http:
paths:
- path: /$URL_PATH
backend:
serviceName: $CI_PROJECT_NAME
servicePort: $PORT
- http:
paths:
- backend:
serviceName: $CI_PROJECT_NAME
servicePort: $PORT
Above code and settings work fine in both internal and external call like below:
http://publicUrl.com/projectA/someId // external call, microservice receive request.path as "/projectA/someId"
http://publicUrl.com/projectB/someId // external call, microservice receive request.path as "/projectB/someId"
http://projectA/someId // internal call, microservice receive request.path as "/someId"
http://projectB/someId // internal call, microservice receive request.path as "/someId"
I wish to remove "app.use(basePath, API)" from my microservice to make it environment independant.
Is the anyway I can change my kubeDeploy to make it change the path I received inside my microservice from an external call to become "/someId"?
Update: Below is latest kubeDeploy updated by devops
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: $CI_PROJECT_NAME
namespace: $KUBE_NAMESPACE
annotations:
kubernetes.io/ingress.class: "nginx"
nginx.ingress.kubernetes.io/rewrite-target: /$2
spec:
rules:
- host: $KUBE_DNS_NAME
http:
paths:
- path: /$URL_PATH(/|$)(.*)
backend:
serviceName: $CI_PROJECT_NAME
servicePort: $PORT
- http:
paths:
- backend:
serviceName: $CI_PROJECT_NAME
servicePort: $PORT
I tried above but I don't understand it become a redirect from browser side. Example: I when open http://publicUrl.com/projectA/help on my browser, somehow the url turn become http://publicUrl.com/help on browser address bar which it show "default backend - 404" due to Ingress unable to find a match path.
You can use the rewrite annotations, but keep in mind these are a custom extension of the nginx controller and are not portable to all other implementations.
From their example:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$2
name: rewrite
namespace: default
spec:
rules:
- host: rewrite.bar.com
http:
paths:
- backend:
serviceName: http-svc
servicePort: 80
path: /something(/|$)(.*)