k8s如何知道Pod内部进程的目标端口?

问题描述

假设我们有一个运行在Docker容器中并在端口3000上监听的Node应用程序。我们希望将此应用程序公开以在浏览器(也可以在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内的目标端口 。>

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

还请注意,在Docker中公开图像的示例中-如果我们不提及端口转发,则整个博览会将无法正常工作,因此无法通过浏览器(容器外部)进行访问。.

解决方法

广告连播规范中的

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

服务中的

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

如果吊舱中有多个容器在不同的端口上侦听,则可以在服务中指定多个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
,

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

k8s的工作原理不同,所以请忘了docker(不要以为它们的名称相同,所以它们必须相同)。 k8s中的每个Pod都有可以访问的自己的IP地址,不需要使用您从docker知道的格式的port:targetport。

所以回答您的问题:

那么Pod对象如何知道向其内部的哪个进程转发流量?

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

那么,服务的端口和k8s服务对象中的targetPort有何关系? 服务充当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会假定端口和targetPort相同。


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

如果一个容器中有多个容器,则所有这些容器共享同一网络接口,因此,如果一个容器已经打开,例如端口80,尝试打开端口80的其他Pod将无法执行此操作。

k8s docs中,您可以阅读:

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

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