无法通过 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主机上访问它,如下所示:
然后请求挂起,如果我尝试从我的工作站访问 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 部分)
您可能错误地配置了 Pod
和 Service
关系,但由于您没有 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: {}
我有一个简单的 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主机上访问它,如下所示:
然后请求挂起,如果我尝试从我的工作站访问 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 服务器侦听所有具有
的 IPapp.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 部分)
您可能错误地配置了 Pod
和 Service
关系,但由于您没有 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: {}