【问题标题】:How k8s knows the target port of a process inside a Pod?k8s 如何知道 Pod 内进程的目标端口?
【发布时间】:2021-01-05 11:37:43
【问题描述】:

假设我们有一个 Node 应用程序在 Docker 容器中运行并侦听端口 3000。我们希望公开此应用程序以在浏览器中访问,也在端口 3000 中访问。所以我们像这样进行端口转发:

docker run -p <port>:<targetPort> my-image // for example: 3000:3000

所以 docker 知道要监听哪个端口以及容器内的哪个进程来转发网络。

但是在k8s的NodePort服务中,提供NodePort服务端口和Pod的目标端口就够了,但不提供Pod内部的目标端口,所以我们有随机的外部端口,30,000-32,000(大约)监听外部流量,转发到 NodePort 服务的端口,然后转发到 Pod 的目标端口,但是.. 嘿,我们没有提到 Pod 内部的目标端口。 p>

那么 Pod 对象是如何知道将流量转发给它内部的哪个进程的呢?我们通常假设我们在一个 Pod 中只有一个容器,但如果我们有多个呢?

另请注意,在 Docker 中公开图像的示例中 - 如果我们不提及端口转发,则整个展览将不起作用,因此无法通过浏览器(在容器外)访问它。..

【问题讨论】:

    标签: docker kubernetes portforwarding kubernetes-pod


    【解决方案1】:

    pod 规范中的containerPort 只是信息性的,非强制性的。提到不会使 pod 内的应用程序在该端口上侦听。通常,您将在源代码或 dockerfile 中指定应用程序应侦听的端口。服务中的targetPort 需要与该端口匹配。例如,将流量转发到运行在 pod 内的 nginx 容器的服务的 targetPort 应该是 80,因为 nginx 进程侦听端口 80。

    service 中的 targetPort` 通知 kubernetes 服务在 pod 内运行的容器的哪个端口将流量转发到。

    如果一个 pod 有多个容器监听不同的端口,您可以在服务中指定多个 targetPort,如下所示。

    apiVersion: v1
    kind: Service
    metadata:
      name: service-name
    spec:
      ports:
      - name: http
        port: 80
        targetPort: 80
      - name: https
        port: 443
        targetPort: 443
      - name: something
        port: 6001
        targetPort: 6001
      selector:
        app: app-label
      type: NodePort
    

    【讨论】:

      【解决方案2】:

      kubernetes 中没有“Pod 内的目标端口”这样的东西。至少它不能在 Docker 中工作。在 docker 中,您可以运行多个容器,这些容器可以通过 localhost 公开和访问。 Docker 在 localhost 上打开并将流量转发到容器。否则您将如何访问容器。

      k8s 的工作方式不同,所以忘记 docker(不要认为如果它们被称为相同,那么它们必须工作相同)。 k8s 中的每个 pod 都有自己的 IP 地址可以访问,不需要你从 docker 知道的 port:targetport 格式。

      所以回答你的问题:

      那么 Pod 对象是如何知道将流量转发给它内部的哪个进程的呢?

      在 k8s 中,进程可以通过从内部和外部打开的端口访问。 pod 级别没有端口转换。

      那么k8s服务对象中service的port和targetPort是怎么关联的呢? Service 在 Pod 副本前充当负载均衡器,并持有静态 IP 地址。因此,在考虑服务时,请将其视为负载均衡器,因为这是它的主要功能。

      NodePort 类型的服务中有 3 个字段:

      port       - a port on which service(loadbalancer) is serving traffic.
      targetPort - a port that is opened by the process in pod (where to forward the trafic).
      nodePort   - a port that is open on every node.
      

      不指定targetPort时,k8s假设port和targetPort相同。


      我们通常假设我们在一个 Pod 中只有一个容器,但如果我们有多个呢?

      如果一个 pod 中有多个容器,所有这些容器共享同一个网络接口,因此如果一个容器已经打开,例如80 端口,其他试图打开 80 端口的 pod 将无法做到。

      k8s docs你可以阅读:

      每个 Pod 都有自己的 IP 地址。这意味着您不需要在 Pod 之间显式创建链接,并且几乎不需要处理将容器端口映射到主机端口的问题。这创建了一个干净、向后兼容的模型,从端口分配、命名、服务发现、负载平衡、应用程序配置和迁移的角度来看,Pod 可以被视为虚拟机或物理主机。

      总而言之,认为一个 pod 是一个虚拟机,当您打开一个端口时,它可以从外部自动访问,并且 pod 中的每个容器都与该虚拟机上的一个进程没有什么不同,因此您不能同时运行多个进程在打开相同端口的 VM 上。

      【讨论】:

        猜你喜欢
        • 2018-05-05
        • 1970-01-01
        • 1970-01-01
        • 2019-01-20
        • 1970-01-01
        • 1970-01-01
        • 2015-03-29
        • 2022-01-13
        • 1970-01-01
        相关资源
        最近更新 更多