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

时间:2019-11-04 17:51:05

标签: docker express kubernetes microk8s

我有一个简单的Dockerized Express.js服务器,运行时就像这样:

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

http://localhost:3000/响应很好,而且如果我使用工作站的LAN IP(如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/ 那么该请求将立即被拒绝。

但是,如果我尝试使用

kubectl port-forward my-service-5db955f57f-q869q 3000:3000

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

因此,pod部署似乎运行良好,例如微型机器人服务之类的示例服务在该群集上也运行良好。

我确保Express.js服务器使用

侦听所有IP。
app.listen(port, '0.0.0.0', () =>  ...

那可能是什么问题?

2 个答案:

答案 0 :(得分:2)

您需要向服务中添加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: {}

答案 1 :(得分:1)

  

我的工作站上的MicroK8s主机的LAN IP

这是您误会的根源;本地主机127.0.0.1和您计算机的LAN IP与运行microk8s的虚拟机显然无关(实际上,将这些信息包含在您的问题中,具有无限的价值,而不是我们必须从一个埋藏的句子中推断出来)

  

我确保Express.js服务器使用

侦听所有IP。

根据您以后的报告:

  

http://192.168.191.248:32750/处,请求立即被拒绝。

那么,看来您的Express服务器实际上并未在所有接口上进行侦听。这就解释了为什么您可以成功地将端口移植到Pod中(这导致流量出现在Pod的本地主机上),却无法从Pod的“外部”到达它。

您还可以通过在群集中使用另一个Pod来curl在端口3000上的Pod IP来测试该理论(以避开Service以及NodePort部分)

您极有可能错误地配置了PodService关系,但是由于您没有发布PodSpec,因此您描述的行为听起来要多得多就像明显的错误配置一样,我们将继续使用它,直到有相反的证据为止