我有一个简单的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主机上访问它,如下所示:
然后,请求挂起,如果我尝试从我的工作站访问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', () => ...
那可能是什么问题?
答案 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部分)
您极有可能错误地配置了Pod
和Service
关系,但是由于您没有发布PodSpec
,因此您描述的行为听起来要多得多就像明显的错误配置一样,我们将继续使用它,直到有相反的证据为止