When exposing a service via ingress inginx on kubernetes, the only http response code upon requesting something is 200.
The web app is basically a form that uploads images, stores them somewhere, and responds with the according to code (e.g. bad request, or created with the URI location in the header). It expects a Request with multipart/form-data on an API address as following: "http://{anyAddress}/api/images?directory={whereToStore}?processing={someProcessingTags}"
The web app works as expected locally and as a single container on docker.
So when the service is accessed via ingress, it first responds with the form as expected. You can specify settings and an image to upload. Upon sending the Request the file is correctly uploaded to the web app and processed, the web app then sends the expected 201 created, but the response that gets back to the browser is always 200 OK. I have no idea why.
This is on a docker for desktop + kubernetes server that runs locally.
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: nginx-ingress
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/rewrite-target: /
nginx.ingress.kubernetes.io/proxy-body-size: 25m
spec:
rules:
- http:
paths:
- path: /image-upload
backend:
serviceName: image-upload-service
servicePort: http
---
apiVersion: v1
kind: Service
metadata:
name: image-upload-service
spec:
type: LoadBalancer
selector:
run: image-upload
ports:
- name: http
port: 80
targetPort: api
protocol: TCP
- name: https
port: 443
targetPort: api
protocol: TCP
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: image-upload-cluster
labels:
run: image-upload
spec:
selector:
matchLabels:
run: image-upload
replicas: 2
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 25%
maxSurge: 0
template:
metadata:
labels:
run: image-upload
spec:
volumes:
- name: shared-volume
hostPath:
path: /exports
containers:
- name: image-upload
image: calyxa/image-service
imagePullPolicy: IfNotPresent
volumeMounts:
- mountPath: /exports
name: shared-volume
resources:
requests:
cpu: 10m
ports:
- containerPort: 3000
name: api
readinessProbe:
httpGet:
path: /
port: 3000
initialDelaySeconds: 5
periodSeconds: 5
successThreshold: 1
I expect upon sending a Request with an image file to get a Response with an according to status code, that is 400 bad request or 201 created (with a location in the header).
The Response is always 200 OK, even when the web app crashes because of the Request.
If the web app itself is not running (because it crashed, for instance), I get a 503 service unavailable, as expected.
Jesus, I tried to make this work all day and found the solution after posting my question. So, in order to pass around parameters in api calls (in the http address) one does need to make the ingress rewrite-target rule like so:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: nginx-ingress
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/rewrite-target: /$1
nginx.ingress.kubernetes.io/proxy-body-size: 25m
#nginx.ingress.kubernetes.io/ingress.class: public
spec:
rules:
- http:
paths:
- path: /image-upload/?(.*)
backend:
serviceName: image-upload-service
servicePort: http
with the interesting parts being
rewrite-target: /$1
and
path: /image-upload/?(.*)
hope this helps someone else. cheers!