无法通过 MicroK8s 集群中的 Kubernetes NodePort 服务访问 Express.js 服务

Can't access an Express.js service via a Kubernetes NodePort service in a MicroK8s cluster

我有一个简单的 Express.js 服务器 Dockerized,当我 运行 它喜欢:

docker run -p 3000:3000 mytag:my-build-id

http://localhost:3000/ responds just fine and also if I use the LAN IP of my workstation like http://10.44.103.60:3000/

现在,如果我使用如下服务部署声明将其部署到 MicroK8s:

apiVersion: v1
kind: Service
metadata:
  creationTimestamp: null
  name: my-service
spec:
  type: NodePort
  ports:
  - name: "3000"
    port: 3000
    targetPort: 3000
status:
  loadBalancer: {}

和像这样的 pod 规范(更新 2019-11-05):

apiVersion: apps/v1
kind: Deployment
metadata:
  creationTimestamp: null
  name: my-service
spec:
  replicas: 1
  selector:
    matchLabels:
      name: my-service
  strategy: {}
  template:
    metadata:
      creationTimestamp: null
      labels:
        name: my-service
    spec:
      containers:
      - image: mytag:my-build-id
        name: my-service
        ports:
        - containerPort: 3000
        resources: {}
      restartPolicy: Always
status: {}

并通过kubectl get services获取暴露的NodePort为32750并尝试在MicroK8s主机上访问它,如下所示:

卷曲http://127.0.0.1:32750

然后请求挂起,如果我尝试从我的工作站访问 MicroK8s 主机的 LAN IP http://192.168.191.248:32750/ 然后请求立即被拒绝。

但是,如果我尝试使用

转发到 pod 中
kubectl port-forward my-service-5db955f57f-q869q 3000:3000

然后 http://localhost:3000/ 工作正常。

所以 pod 部署似乎工作正常,并且像 microbot-service 这样的示例服务在那个集群上工作得很好。

我已确保 Express.js 服务器侦听所有具有

的 IP
app.listen(port, '0.0.0.0', () =>  ...

那么可能是什么问题?

the LAN IP of the MicroK8s host from my workstation

这是您误解的核心来源;本地主机、127.0.0.1 和您机器的 LAN IP 与显然是虚拟机 运行 microk8s 的东西无关(它本来 无限 对实际有价值将该信息包含在您的问题中,而不是我们必须从一个隐藏的句子中推断出来)

I've made sure the Express.js server listens on all IPs with

根据您稍后报告的内容:

at http://192.168.191.248:32750/ then the request is immediately refused.

那么看起来您的快速服务器实际上并没有监听所有接口。这解释了为什么您可以成功地通过端口转发到 Pod(这会导致流量出现在 Pod 的本地主机上)但不能从 "outside" Pod

到达它

您还可以通过使用集群内的另一个 Pod curl 端口 3000 上的 Pod IP 来测试该理论(为了避开服务和 NodePort 部分)

您可能错误地配置了 PodService 关系,但由于您没有 post 您的 PodSpec 以及您的行为描述的声音更像是一种明显的错误配置,我们将继续这样做,直到我们有相反的证据

您需要为您的服务添加 selector。这将告诉 Kubernetes 如何找到您的部署。此外,您可以使用 nodePort 指定服务的端口号。这样做之后,您将能够卷曲您的 MicroK8s IP。

您的服务 YAML 应如下所示:

apiVersion: v1
kind: Service
metadata:
  creationTimestamp: null
  name: my-service
spec:
  type: NodePort
  ports:
  - name: http
    port: 80
    targetPort: 80
    nodePort: 30001
  selector: 
    name: my-service      
status:
  loadBalancer: {}