k8s 辨析 port、NodePort、targetPort、containerPort 区别

k8s 辨析 port、NodePort、targetPort、containerPort 区别

我的见解:

cluster 有 自己的ip和端口(port/nodePort)。
pod 也有自己的ip和端口(targetPort)。
pod中的多个container共享一套资源与环境。
那么container中暴露的端口(containerPort)与 pod 暴露的端口(targetPort)一致。
container使用的ip 与 pod 使用的ip一致。

转载来源: k8s 辨析 port、NodePort、targetPort、containerPort 区别

转载来源: https://stackoverflow.com/questions/63448062/difference-between-container-port-and-targetport-in-kubernetes

刚接触 k8s 涉及到端口到内容较多,容易混淆,这里整理如下:

目录

nodePort

nodePort 提供了集群外部客户端访问 Service 的一种方式,nodePort 提供了集群外部客户端访问 Service 的端口,通过 nodeIP:nodePort 提供了外部流量访问k8s集群中service的入口。

比如外部用户要访问k8s集群中的一个Web应用,那么我们可以配置对应service的type=NodePortnodePort=30001。其他用户就可以通过浏览器http://node:30001访问到该web服务。

而数据库等服务可能不需要被外界访问,只需被内部服务访问即可,那么我们就不必设置service的NodePort。

port

port是暴露在cluster ip上的端口,:port提供了集群内部客户端访问service的入口,即clusterIP:port

mysql容器暴露了3306端口(参考DockerFile),集群内其他容器通过33306端口访问mysql服务,但是外部流量不能访问mysql服务,因为mysql服务没有配置NodePort。对应的service.yaml如下:

apiVersion: v1
kind: Service
metadata:
  name: mysql-service
spec:
  ports:
  - port: 33306
    targetPort: 3306
  selector:
    name: mysql-pod

targetPort

targetPort是pod上的端口,从port/nodePort上来的数据,经过kube-proxy流入到后端pod的targetPort上,最后进入容器。

与制作容器时暴露的端口一致(使用DockerFile中的EXPOSE),例如官方的nginx(参考DockerFile)暴露80端口。 对应的service.yaml如下:

apiVersion: v1
kind: Service
metadata:
  name: nginx-service
spec:
  type: NodePort            // 配置NodePort,外部流量可访问k8s中的服务
  ports:
  - port: 30080             // 服务访问端口,集群内部访问的端口
    targetPort: 80          // pod控制器中定义的端口(应用访问的端口)
    nodePort: 30001         // NodePort,外部客户端访问的端口
  selector:
    name: nginx-pod

containerPort

containerPort是在pod控制器中定义的、pod中的容器需要暴露的端口。

例如,mysql 服务需要暴露 3306 端口,redis 暴露 6379 端口

apiVersion: v1
kind: ReplicationController
metadata:
  name: redis-master
  labels: 
    name: redis-master
spec:
  replicas: 1
  selector:
    name: redis-master
  template:
    metadata:
      labels:
        name: redis-master
    spec:
      containers:
      - name: master
        image: kubeguide/redis-master
        ports:
        - containerPort: 6379   # 此处定义暴露的端口

targetPort vs containerPort

In a nutshell: targetPort and containerPort basically refer to the same port (so if both are used they are expected to have the same value) but they are used in two different contexts and have entirely different purposes. 简而言之: targetPortcontainerPort 基本上指的是相同的端口(因此,如果两者都使用,则预计它们具有相同的值),但它们在两个不同的上下文中使用并且具有完全不同的目的。

They cannot be used interchangeably as both are part of the specification of two distinct kubernetes resources/objects: Service and Pod respectively. While the purpose of containerPort can be treated as purely informational, targetPort is required by the Service which exposes a set of Pods. 它们不能互换使用,因为两者都是两个不同 kubernetes 资源/对象规范的一部分:分别是 ServicePod 。虽然 containerPort 的目的可以被视为纯粹的信息性,但 Service 需要 targetPort 来公开一组 Pods

It’s important to understand that by declaring containerPort with the specific value in your Pod/Deployment specification you cannot make your Pod to expose this specific port e.g. if you declare in containerPort field that your nginx Pod exposes port 8080 instead of default 80, you still need to configure your nginx server in your container to listen on this port. 重要的是要理解,通过使用 Pod / Deployment 规范中的特定值声明 containerPort ,您无法使 Pod 公开此值特定端口,例如如果您在 containerPort 字段中声明您的 nginx Pod 公开端口 8080 而不是默认的 80 ,您仍然需要配置您的 nginx 服务器在您的容器中监听此端口。

Declaring containerPort in Pod specification is optional. Even without it your Service will know where to direct the request based on the info it has declared in its targetPort. 在 Pod 规范中声明 containerPort 是可选的。即使没有它,您的 Service 也会根据它在 targetPort 中声明的信息知道将请求定向到哪里。

It’s good to remember that it’s not required to declare targetPort in the Service definition. If you omit it, it defaults to the value you declared for port (which is the port of the Service itself). 请记住,不需要在 Service 定义中声明 targetPort 。如果省略它,它默认为您为 port 声明的值(这是 Service 本身的端口)。


ContainerPort in pod spec Pod 规范中的 ContainerPort

List of ports to expose from the container. Exposing a port here gives the system additional information about the network connections a container uses, but is primarily informational. Not specifying a port here DOES NOT prevent that port from being exposed 要从容器公开的端口列表。此处公开端口可为系统提供有关容器使用的网络连接的附加信息,但主要是提供信息。此处不指定端口并不能防止该端口被暴露

targetPort in service spec 服务规范中的 targetPort

Number or name of the port to access on the pods targeted by the service. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. If this is a string, it will be looked up as a named port in the target Pod’s container ports. 服务目标 Pod 上要访问的端口号或名称。数字必须在 1 到 65535 范围内。名称必须是 IANA_SVC_NAME。如果这是一个字符串,它将在目标 Pod 的容器端口中作为命名端口进行查找。 If this is not specified, the value of the ‘port’ field is used (an identity map). 如果未指定,则使用“端口”字段的值(身份映射)。

Hence targetPort in service needs to match the containerPort in pod spec because that’s how service knows which container port is destination to forward the traffic to. 因此,服务中的 targetPort 需要与 pod 规范中的 containerPort 相匹配,因为这就是服务如何知道哪个容器端口是将流量转发到的目的地。


containerPort is the port, which app inside the container can be reached on. containerPort 是容器内的应用程序可以访问的端口。

targetPort is the port, which is exposed in the cluster and the service connects the pod to other services or users. targetPort 是端口,在集群中公开,服务将 pod 连接到其他服务或用户。

参考文章

kubernetes中port、target port、node port的对比分析,以及kube-proxy代理 Kubernetes中的nodePort,targetPort,port的区别和意义


评论

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注