I have an application that has two k8s deployments called onboarding-server
and frontend
onboarding-server is a node server and frontend is a react application that is built and deployed using Nginx.
Here is a snippet which is returned when I run kubectl get all
NAME READY STATUS RESTARTS AGE
pod/frontend-deployment-578f898ffb-cc7gc 1/1 Running 0 15s
pod/node-deployment-7f4754fdf5-fnmls 1/1 Running 0 7d10h
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/frontend-service LoadBalancer 10.100.200.64 10.167.198.105 80:31167/TCP 13d
service/node-service LoadBalancer 10.100.200.71 10.167.199.136 3200:32276/TCP 13d
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/frontend-deployment 1/1 1 1 5d12h
deployment.apps/node-deployment 1/1 1 1 7d10h
NAME DESIRED CURRENT READY AGE
replicaset.apps/frontend-deployment-578f898ffb 1 1 1 17s
replicaset.apps/node-deployment-7f4754fdf5 1 1 1 7d10h
And my nginx.conf
config looks something like this
upstream node-service{
server node-service;
}
server {
listen 80;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
try_files $uri $uri/ /index.html;
}
location = /api {
proxy_pass http://node-service;
}
error_page 404 /index.html;
location = / {
root /usr/share/nginx/html;
internal;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
Now I try to talk to my backend service from the frontend using this URL
/api/onboarding/v1/user/login
My understanding of Nginx is that when I request /api
it should redirect me to http://node-service/api/onboarding/v1/user/login
and hence should return the appropriate response. But what I get back is
Fetch failed loading: POST
http://192.168.5.21/api/onboarding/v1/user/login
How can I connect to node-service from Nginx?
EDIT 1 : One thing that I forgot to mention is that when I go inside the container using the exec
command I am able to get appropriate response using
curl http://192.168.5.21/api/onboarding/v1/user/login
In your FE you can deploy this config:
server {
listen 80;
location / {
include /etc/nginx/mime.types;
try_files $uri $uri/ /index.html;
}
location /be-svc/ {
proxy_pass "http://<be-svc>.<namespace>/";
}
}
After that your Dockerfile
can be something like this:
FROM nginx:1.14
COPY build /usr/share/nginx/html
RUN rm /etc/nginx/conf.d/default.conf
COPY config/nginx/sites-available/api.conf /etc/nginx/conf.d
And just put the ingress like usual in front of your FE service. Hope it helps!
For path-based routing in Kubernetes, I'll suggest you to take a look at Ingress. You can use Nginx Ingress for kubernetes in your case. You'll be able to map services based on path.
For Example,
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: demo-ingress
annotations: {
'kubernetes.io/ingress.class': nginx
}
spec:
rules:
- host: foo.bar.com
http:
paths:
- path: /foo
backend:
serviceName: demo-backend
servicePort: 80
Now, as you are using nginx as a reverse-proxy, you can expose your backend service as a Type NodePort and use the External IP of your backend service instead of using the service name-
location = /api {
proxy_pass http://external-ip:port;
}