2

I'm learning Kubernetes over Minikube. My demo consists of a Flask API and a MySQL Database. I made all the .yaml files but something strange happens with services of the deployments...

I cannot communicate with the API externally (neither with Postman, Curl, browser...)

By "externally" I mean "from outside the cluster" (on the same machine, ex: from the browser, postman...)

This the Deployment+Service for the API:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: api-dip-api-deployment
  labels:
    app: api-dip-api
spec:
  replicas: 1
  selector:
    matchLabels:
      app: api-dip-api
  template:
    metadata:
      labels:
        app: api-dip-api
    spec:
      containers:
      - name: api-dip-api
        image: myregistry.com
        ports:
        - containerPort: 5000

        env:
        - name: DATABASE_USER
          valueFrom:
            secretKeyRef:
              name: api-secret
              key: api-db-user 

        - name: DATABASE_PASSWORD
          valueFrom:
            secretKeyRef:
              name: api-secret
              key: api-db-password
            
        - name: DATABASE_HOST
          valueFrom:
            configMapKeyRef:
              name: api-configmap
              key: api-database-url

        - name: DATABASE_NAME
          valueFrom:
            configMapKeyRef:
              name: api-configmap
              key: api-database-name

        - name: DATABASE_PORT
          valueFrom:
            configMapKeyRef:
              name: api-configmap
              key: api-database-port           
      
      imagePullSecrets:
      - name: regcred
--- 
apiVersion: v1
kind: Service
metadata: 
  name: api-service
spec: 
  selector:
    app: api-dip-api

  ports:
  - port: 5000 
    protocol: TCP
    targetPort: 5000
    nodePort: 30000

  type: LoadBalancer

Dockerfile API:

FROM python:latest

# create a dir for app
WORKDIR /app

# intall dependecies
COPY requirements.txt .
RUN pip install -r requirements.txt

# source code
COPY /app .

EXPOSE 5000
# run the application
CMD ["python", "main.py"]

Since i'm using Minikube the correct IP for the service is displayed with

minikube service <service_name>

I already tried looking the minikube context, as suggested in another post, but it shows like:

CURRENT   NAME       CLUSTER    AUTHINFO   NAMESPACE
*         minikube   minikube   minikube   default

so it should be ok.

I don't know what to try now... the ports are mapped correctly I think.

  • In the Flask application, what does the `app.run()` line look like? [Deploying a minimal flask app in docker - server connection issues](https://stackoverflow.com/questions/30323224/deploying-a-minimal-flask-app-in-docker-server-connection-issues) applies to both Docker and Kubernetes environments. – David Maze Jun 27 '21 at 11:19
  • 1
    @DavidMaze i wrote that line like this: app.run(host='0.0.0.0', port=5000) – ANTONELLO BARBONE Jun 27 '21 at 11:26
  • Can you check that your service have been able to found some endpoints? To do so, use the following command: `kubectl describe service | grep Endpoints` – Arnaud Develay Jun 28 '21 at 08:18
  • @ArnaudDevelay it prints out: "Endpoints: 172.17.0.4:5000" – ANTONELLO BARBONE Jun 28 '21 at 10:06
  • @ArnaudDevelay This is the first thing a tried. i used "minikube service to get the correct IP:30000 and if i try to go there i get "connection refused"... instead i should get the swagger webpage. Samething if a try to call the api endpoints from postman – ANTONELLO BARBONE Jun 28 '21 at 12:49
  • So we can say that manifests are correct and the pods are running. The command `kubectl get service` should display the external IP of your service. You can then access it with `http://:5000`. You can also use the nodeport: `http://:30000`. – Arnaud Develay Jun 28 '21 at 12:53
  • You can also try to connect from your cluster, with `kubectl run cmd --image=busybox -it --rm -- /bin/sh` and then run `wget -O- http://172.17.0.4:5000`. This will ensure that your service can be consumed correctly within your cluster. – Arnaud Develay Jun 28 '21 at 12:53
  • Last thing: it seems that you have to run this command `minikube tunnel` in another terminal to use your LoadBalancer service: https://minikube.sigs.k8s.io/docs/commands/tunnel/ and https://minikube.sigs.k8s.io/docs/handbook/accessing/#run-tunnel-in-a-separate-terminal – Arnaud Develay Jun 28 '21 at 13:07
  • @ArnaudDevelay by executing the WGET inside the cluster it works (that is a thing i already tried, and still works) i tried run minikube tunnel, but still nothing.. the swagger homepage does not appear. still connection refused – ANTONELLO BARBONE Jun 28 '21 at 13:19
  • Sorry, no more idea. I am just sure that your issue is related to minikube. It should work with either node-ip:30000 or service-ip:5000. – Arnaud Develay Jun 28 '21 at 13:37
  • @ArnaudDevelay don't worry i understand that is not easy at all. I tried also doing: "kubectl get service" and then use the EXTERNAL-IP provided (like in the guide you linked to me) both with port 30000 and 5000 and connection goes in timeout... – ANTONELLO BARBONE Jun 28 '21 at 14:02
  • What is your environment? Is minikube installed locally or on remote host? On which OS? Windows, Linux, macOS? –  Jul 01 '21 at 10:02
  • @PawełGrondal yes, take a look to the answer I just posted – ANTONELLO BARBONE Jul 01 '21 at 15:16

1 Answers1

2

I did not found any solution to my problem. I run Kubernetes with Minikube on Vmware Fusion on my Mac with BigSur.

I found out that the SAME EXACT deployment works on a machine with ubuntu installed, OR on a virtual machine made with VirtualBox.

Actually seems that this is a known issue:

  • TLDR; run `minikube tunnel` and then grab the external IP address and the port from `kubectl get svc`. Grab the port, not the nodePort. e.g. in the code provided in the question, something like `127.0.0.1:5000` – Hossein Shahsahebi Apr 12 '22 at 18:15