【问题标题】:Why Do I Need a NodePort in My Local Kubernetes Cluster?为什么我的本地 Kubernetes 集群中需要一个 NodePort?
【发布时间】:2021-07-18 22:20:38
【问题描述】:

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

鉴于此 Dockerfile:

from node:lts-slim
RUN mkdir /code
COPY package.json /code/
WORKDIR /code
RUN npm install
COPY server.js /code/
EXPOSE 3000 
CMD ["node", "server.js"]

...这个部署:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-deployment
spec:
  replicas: 2
  selector:
    matchLabels:
      app: web-pod
  template:
    metadata:
      labels:
        app: web-pod
    spec:
      containers:
      - name: web
        image: kahunacohen/hello-k8s
        ports:
        - containerPort: 3000
          protocol: TCP

还有这项服务:

apiVersion: v1
kind: Service
metadata:
  name: web-service
spec:
  type: NodePort
  selector:
    app: web-pod
  ports:
    - port: 80
      targetPort: 3000
      protocol: TCP
      name: http

我的理解是:

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

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

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

【问题讨论】:

    标签: kubernetes


    【解决方案1】:

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

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

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

    Pod 规范中的containerPort: 不是严格要求的(但如果你给它name: http,那么你可以让服务指定targetPort: http,而无需知道具体的端口号)。 Dockerfile 中的EXPOSE 在这个序列中几乎没有任何意义。

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

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

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

    【讨论】:

    • 这是一个出色而清晰的答案。谢谢。
    猜你喜欢
    • 2020-09-11
    • 2021-06-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-26
    • 1970-01-01
    相关资源
    最近更新 更多