How to expose Flask App with Kubernetes Ingress?

7/28/2020

I have a simple python flask app named hwrequest. I can run it from PyCharm IDE and it works fine. I've dockerized this app using following Dockerfile

FROM python:3.8-alpine
LABEL maintainer="John Smith, john.smith@mycompany.com"
RUN apk update && apk add bash curl
COPY . /hwrequest
WORKDIR /hwrequest
RUN pip install -r app/requirements.txt
EXPOSE 5000
ENTRYPOINT ["python"]
CMD ["/hwrequest/app/app.py"]

I can exec -it into container and when I call successfully curl 127.0.0.1:5000 Now I'am trying to deploy this app to Kubernetes and expose it with Ingress.

This is my YAML files:

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: "hwrequest"
  name: "hwrequest"
spec:
  replicas: 1
  selector:
    matchLabels:
      app: "hwrequest"
  template:
    metadata:
      labels:
        app: "hwrequest"
    spec:
      containers:
      - name: "hwrequest"
        image: "myregistry.com/hwrequest:0.0.4"
        imagePullPolicy: Always
        ports:
        - containerPort: 5000
apiVersion: v1
kind: Service
metadata:
  name: "hwrequest"
  labels:
    app: "hwrequest"
spec:
  type: ClusterIP
  ports:
    - port: 5000
      targetPort: 5000
  selector:
    app: "hwrequest"
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: "hwrequest"
spec:
  rules:
  - http:
      paths:
      - backend:
          serviceName: "hwrequest"
          servicePort: 5000
    host: "hwrequest.mycompany.com"

When I call curl hwrequest.mycompany.com I get 502 Bad Gateway

What am I doing wrong?

-- Robert Grądzki
docker
flask
kubernetes
kubernetes-ingress
python

1 Answer

7/28/2020

Exposing any application on kubernetes using ingress is non trivial task and here are few things to look for

  1. Make sure that the application is listening on 0.0.0.0 instead of 127.0.0.1
  2. The curl request should have Host header i.e -H "Host: hwrequest.mycompany.com" because this is how ingress controller will know which rule to apply as per the rules defined in ingress resource.
  3. There need to a be an ingress controller such as nginx running in the cluster and the ingress controller pods need to be exposed via NodePort or LoadBalancer type service or can be deployed with hostNetwork: true
  4. You need to use NODEIP(kubernetes node) and NODEPORT in curl if NodePort service was used so it would look like curl http://<NODEIP>:NODEPORT -H "Host: hwrequest.mycompany.com".

If you used hostNetwork to expose nginx ingress controller pods then curl should be curl http://<NODEIP> -H "Host: hwrequest.mycompany.com"`

If you used LoadBalancer type service(works on cloud providers such as AWS,Azure,GCP) then curl should be curl http://<LOADBALANCERIP> -H "Host: hwrequest.mycompany.com"`

If you are just starting I would suggest to look at this guide on using nginx ingress on Minikube

-- Arghya Sadhu
Source: StackOverflow