为什么我的本地 Kubernetes 集群需要 NodePort?

Aar*_*ron 2 kubernetes

请原谅我对网络的相对无知,但我已经阅读了很多文档,但仍然无法理解这一点(可能是由于缺乏网络背景)。

\n

给定这个 Dockerfile:

\n
from node:lts-slim\nRUN mkdir /code\nCOPY package.json /code/\nWORKDIR /code\nRUN npm install\nCOPY server.js /code/\nEXPOSE 3000 \nCMD ["node", "server.js"]\n
Run Code Online (Sandbox Code Playgroud)\n

...此部署:

\n
from node:lts-slim\nRUN mkdir /code\nCOPY package.json /code/\nWORKDIR /code\nRUN npm install\nCOPY server.js /code/\nEXPOSE 3000 \nCMD ["node", "server.js"]\n
Run Code Online (Sandbox Code Playgroud)\n

和这项服务:

\n
apiVersion: v1\nkind: Service\nmetadata:\n  name: web-service\nspec:\n  type: NodePort\n  selector:\n    app: web-pod\n  ports:\n    - port: 80\n      targetPort: 3000\n      protocol: TCP\n      name: http\n
Run Code Online (Sandbox Code Playgroud)\n

我的理解是:

\n
    \n
  1. 我的容器中的应用程序在 3000 上将自身暴露给外界
  2. \n
  3. 我的部署 yaml 说“容器正在监听 3000”
  4. \n
  5. 我的服务说将 3000 内部映射到端口 80,这是默认端口,因此您不必将该端口添加到主机。
  6. \n
  7. 我使用 NodePort 类型是因为在 Docker Desktop 等本地集群上,它可以开箱即用,而不是 LoadBalancer。它在集群中的每个节点(pod?)上向外部开放一个随机端口(位于 30000\xe2\x80\x9332767 之间)。该节点端口是我从外部访问我的应用程序的方式。例如本地主机:30543。
  8. \n
\n

我的假设正确吗?我不清楚为什么我无法在 localhost:80 或仅 localhost 访问我的应用程序,如果该服务在容器端口和外部世界之间进行映射?服务中3000和80之间的映射有什么意义?

\n

简而言之,为什么我需要 NodePort?

\n

Dav*_*aze 5

有两个网络层,我们可以称之为“集群内部”和“集群外部”。Pod 和 Service 都有自己的 IP 地址,但这些仅位于集群内部。您需要 NodePort 将请求从集群外部转发到集群内部。

在“真正的”Kubernetes 集群中,您会发出请求......

  1. ...以http://any-kubernetes-node.example.com:31245/您期望物理系统具有的方式使用“正常”IP 地址,连接到 NodePort 端口,该端口转发...
  2. ...to http://web-service.default.svc.cluster.local:80/,具有集群内部 IP 地址和服务端口,它会查看它选择并转发的 Pod...
  3. ...to http://10.20.30.40:3000/,使用任何匹配 Pod 的集群内部 IP 地址和服务中的目标端口。

Pod 规范中的containerPort:并不是严格必需的(但如果您提供它,那么您可以在不知道特定端口号的情况下 name: http指定服务)。Dockerfile 中的内容在此序列中几乎没有任何意义。targetPort: httpEXPOSE

此顺序还为您提供了一些灵活性,无需知道事情在哪里运行。假设您有 100 个节点和 3 个 pod 副本;初始连接可以连接到任何节点,并且服务将转发到所有目标 pod,而您无需从调用者那里了解任何这些详细信息。

(为了完整起见,LoadBalancer 类型服务请求在集群外部创建负载均衡器;例如,AWS ELB。这会转发到任何集群节点,如上面的步骤 1 所示。如果您不在云环境中并且集群不知道如何自动创建外部负载均衡器,它与 NodePort 相同。)

如果我们将其简化为本地 Kubernetes 安装(Docker Desktop、minikube 等),唯一真正的区别是只有一个节点;底层基础设施仍然像多节点分布式集群一样构建。这些安装中访问服务的具体方式有所不同。在 Docker Desktop 中,从主机系统,您可以localhost在第一步中将其用作“正常”“外部”节点 IP 地址。