2

What I want to achieve is to run the simplest echo server using python and tornado, code here:

#!/usr/bin/env python3
import tornado.ioloop
import tornado.web
from tornado.log import enable_pretty_logging

class MainHandler(tornado.web.RequestHandler):
    def get(self):
        self.write("Hello, world")

def make_app():
    return tornado.web.Application([
        (r"/", MainHandler),
    ])

if __name__ == "__main__":
    port = 8080
    print ("Starting up echo server at port %d" % port)
    enable_pretty_logging()
    app = make_app()
    app.listen(int(port))
    
    tornado.ioloop.IOLoop.current().start()

I want to run it inside docker that is running inside kubernetes's Pod. I already achieved it but only partly. I'm running kubernetes cluster on physical machine, which is in my local network. To run cluster I used minikube. Here are my configuration files, which I use to run kubernetes Deployment and Service:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: testApp
spec:
  replicas: 1
  selector:
    matchLabels:
      app: testApp
  template:
    metadata:
      labels:
        app: testApp
    spec:
      containers:
      - name: testApp-container
        image: testApp-docker:latest
        imagePullPolicy: Never
        command: ["python3"]
        args: ["-u", "echo_tornado.py"]

        ports:
        - containerPort: 5020
      restartPolicy: Always
apiVersion: v1
kind: Service
metadata:
  name: testApp-svc
  labels:
    app: testApp
spec:
  type: NodePort
  ports:
  - port: 5020
    targetPort: 5020
    nodePort: 5020
  selector:
    app: testApp

What is problem exactly ? I can sent request to my echo server by curl $NODE_IP:$NODE_PORT and I'm getting a response, but I also want to be able do curl localhost:$NODE_PORT and also (what is crucial for me) I must be able to do curl $MY_LOCAL_MACHINE_IP:$NODE_PORT from other machine inside same local network.

Is it possible to achieve it ? Should I use some kind of forwarding my local IP and port to node's ip ? Maybe I shouldn't use ServiceType : NodePort and I should use LoadBalancer ? Maybe minikube is a problem and I should use different tool ?

David Maze
  • 130,717
  • 29
  • 175
  • 215
AnDevi
  • 67
  • 7
  • 1
    Kubernetes is intrinsically a remote clustered environment; the NodePort service will almost never be `localhost` or the local system. You'd typically configure a load balancer (either manually or with a LoadBalancer service) with a DNS name and have clients connect to that. – David Maze Feb 03 '21 at 14:49
  • Ok, thanks I understand why I couldn't use NodePort in that case. I changed my ServiceType to LoadBalancer, now I can communicate with my echo server via my loadBalancer's external IP, but still I can use this IP only from my machine (this with minikube cluster), but I wish to be able to talk with this echo server from others machines in same local network. What else should I do ? – AnDevi Feb 03 '21 at 16:36
  • @Dariusz.O It's possible but the solution will depend on the `--driver` and OS you use. `Minikube` by itself provides an "isolation layer" (what I mean by that is exposing it on LAN). Please add the OS and `--driver` you use to your question. You can try to run on the host that is having `minikube` instance: `kubectl port-forward svc/testApp-svc 5020:5020 --address 0.0.0.0`. You can also look on other solutions like `kubeadm`, `kubespray`, `microk8s`, etc. – Dawid Kruk Feb 04 '21 at 12:49

1 Answers1

2

Minikube is a tool that spawn your single node Kubernetes cluster for development purposes on your machine (PC, Laptop, Server, etc.).

It uses different --drivers to run Kubernetes (it can be deployed as bare-metal, in docker, in virtualbox, in kvm, etc.). This allows for isolation from host and other devices. It also means that there are differences when it comes to the networking part of this setup.

There is a lot to cover when it comes to the networking part of Kubernetes. I encourage you to check the official docs:


As the driver used and the OS is unknown it could be hard to pinpoint the exact solution. Some of the pointers that could help you:

  • When you are using Linux distribution you can opt to use driver --none. It will use Docker but everything (containers like kubeapi-server, etcd, etc.) will be provisioned directly on your host. By that you could run: $ curl $MY_LOCAL_MACHINE_IP:$NODE_PORT). With --driver=docker everything I mentioned will be put in a Docker container.

A side note!

--driver=none have some limitations/issues (for example decreased security). You can read more about it by following this documentation:

  • As a workaround/temporary solution you can use previously mentioned (run on your host):

    • $ kubectl port-forward svc/testApp-svc 5020:5020 --address 0.0.0.0 - this command will forward requests coming to your machine on port 5020 directly to the Service: testApp-svc on port 5020.
  • With other driver like for example Virtualbox you will need to reach the documentation of it for ability to expose your minikube instance on the LAN.


Seeing this part of the question:

(what is crucial for me) I must be able to do curl $MY_LOCAL_MACHINE_IP:$NODE_PORT from other machine inside same local network.

It could beneficiary to add that there are other solution outside of minikube that could provision your Kubernetes cluster. There are some differences between them and you would need to chose the one that suits your requirements the most. Some of them are:

A side note!

For assigning the IP addresses for a LoadBalancer type of Service you could look on metallb (when using above options).


Additional resources:

Dawid Kruk
  • 8,982
  • 2
  • 22
  • 45