【问题标题】:How to run echo server inside Kubernetes (with docker container) to communicate with it form other machines in local environment?如何在 Kubernetes(带有 docker 容器)内运行 echo 服务器以与本地环境中的其他机器进行通信?
【发布时间】:2021-02-10 23:10:12
【问题描述】:

我想要实现的是使用pythontornado运行最简单的回显服务器,代码在这里:

#!/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()

我想在运行在 kubernetes 的 Pod 中的 docker 中运行它。 我已经实现了,但只是部分实现了。我在本地网络中的物理机上运行 kubernetes 集群。为了运行集群,我使用了minikube。 这是我的配置文件,我用它们来运行 kubernetes DeploymentService

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

究竟是什么问题?我可以通过curl $NODE_IP:$NODE_PORT 向我的回显服务器发送请求并且我得到了响应,但我也希望能够做到curl localhost:$NODE_PORT 并且(对我来说至关重要)我必须能够做到curl $MY_LOCAL_MACHINE_IP:$NODE_PORT from同一本地网络中的其他机器。

有可能实现吗?我应该使用某种方式将我的本地 IP 和端口转发到节点的 ip 吗? 也许我不应该使用 ServiceType : NodePort 而我应该使用 LoadBalancer ? 也许minikube 是个问题,我应该使用不同的工具?

【问题讨论】:

  • Kubernetes 本质上是一个远程集群环境; NodePort 服务几乎永远不会是localhost 或本地系统。您通常会使用 DNS 名称配置负载均衡器(手动或使用 LoadBalancer 服务)并让客户端连接到该名称。
  • 好的,谢谢,我明白为什么在这种情况下我不能使用 NodePort。我将我的 ServiceType 更改为 LoadBalancer,现在我可以通过我的 loadBalancer 的外部 IP 与我的 echo 服务器通信,但我仍然只能从我的机器使用这个 IP(这与 minikube 集群),但我希望能够与这个 echo来自同一本地网络中其他计算机的服务器。我还应该做什么?
  • @Dariusz.O 这是可能的,但解决方案将取决于您使用的--driver 和操作系统。 Minikube 本身提供了一个“隔离层”(我的意思是在 LAN 上公开它)。请将您使用的操作系统和--driver 添加到您的问题中。您可以尝试在具有minikube 实例的主机上运行:kubectl port-forward svc/testApp-svc 5020:5020 --address 0.0.0.0。您还可以查看其他解决方案,例如kubeadmkubespraymicrok8s 等。

标签: kubernetes minikube


【解决方案1】:

Minikube 是一种工具,可在您的机器(PC、笔记本电脑、服务器等)上生成单节点 Kubernetes 集群以用于开发目的。

它使用不同的--drivers来运行Kubernetes(可以部署为bare-metaldockervirtualboxkvm等)。这允许与主机和其他设备隔离。 这也意味着此设置的网络部分存在差异。

谈到 Kubernetes 的网络部分,有很多内容需要介绍。我鼓励您查看官方文档:


由于使用了 driverOS 未知,因此很难确定确切的解决方案。 一些可以帮助您的建议:

  • 当您使用 Linux 发行版时,您可以选择使用驱动程序--none。它将使用Docker,但所有内容(如kubeapi-serveretcd 等容器)都将直接在您的主机上进行配置。这样你就可以运行:$ curl $MY_LOCAL_MACHINE_IP:$NODE_PORT)。使用--driver=docker,我提到的所有内容都将放入Docker 容器中。

附注!

--driver=none 有一些限制/问题(例如安全性降低)。您可以通过以下文档了解更多信息:

  • 作为一种解决方法/临时解决方案,您可以使用前面提到的(在您的主机上运行):

    • $ kubectl port-forward svc/testApp-svc 5020:5020 --address 0.0.0.0 - 此命令会将来自端口 5020 的请求直接转发到端口 Service: testApp-svc 上的 Service: testApp-svc
  • 对于其他驱动程序,例如 Virtualbox,您需要访问它的文档才能在 LAN 上公开您的 minikube 实例。


看到这部分问题:

(对我来说至关重要)我必须能够从同一本地网络中的其他机器执行 curl $MY_LOCAL_MACHINE_IP:$NODE_PORT。

补充一点,minikube 之外还有其他解决方案可以配置您的 Kubernetes 集群。它们之间存在一些差异,您需要选择最适合您要求的一种。 其中一些是:

附注!

要为LoadBalancer 类型的Service 分配IP addresses,您可以查看metallb(使用上述选项时)。


其他资源:

【讨论】:

    【解决方案2】:

    感谢您的详细回复。以后我会尝试你提到的其他解决方案。

    【讨论】:

    • 您好,很高兴您收到了您需要的信息。请考虑删除此答案,因为它没有回答发布的问题。取而代之的是,您可以 upvote/accept 回答您认为它对您有帮助的答案。没有义务这样做。
    猜你喜欢
    • 2017-06-25
    • 1970-01-01
    • 2019-09-06
    • 1970-01-01
    • 2018-04-21
    • 1970-01-01
    • 1970-01-01
    • 2019-08-07
    • 1970-01-01
    相关资源
    最近更新 更多