在Kubernetes中如何解析端口名称

huangapple go评论58阅读模式
英文:

How port names are resolved in kubernetes

问题

这里有一个可工作的Kubernetes配置,其中在Pod和Service中都使用了相同的端口名称。以下是Pod的配置部分:

ports:
- containerPort: 8000
  name: app-port
  protocol: TCP

以下是Service的配置部分:

ports:
- name: app-port
  nodePort: 32000
  port: 8000
  protocol: TCP
  targetPort: app-port
type: NodePort

app-port 这个名称是如何解析的?

英文:

There's a working k8s configuration which uses the same port name in a pod and in a service. Here's a config part of the pod:

ports:
- containerPort: 8000
  name: app-port
  protocol: TCP

Here's a config part of the service:

  ports:
  - name: app-port
    nodePort: 32000
    port: 8000
    protocol: TCP
    targetPort: app-port
  type: NodePort

How is the name app-port resolved?

答案1

得分: 2

创建Service时,它会与在Service spec.selector 中定义的标签选择器所选的Pod相关联。

当对Service发出请求时,控制平面会检索其spec.ports[*].targetPort的值:

  • 如果它不存在,则使用spec.ports[*].port字段的值来转发流量到Pods。
  • 如果它存在且为数字,则使用targetPort的值来转发流量到Pods。
  • 如果它是一个字符串,则控制平面会在Pod的spec.ports[*].name中查找与名称匹配的端口,并将具有匹配名称的端口用作目标端口。

以下是Kubernetes中相关的代码片段:

// FindPort函数用于查找给定Pod和portName的容器端口。
// 如果targetPort是一个数字,则使用它。
// 如果targetPort是一个字符串,则在目标Pod的所有容器的所有命名端口中查找该字符串。
// 如果找不到匹配项,则返回错误。
func FindPort(pod *v1.Pod, svcPort *v1.ServicePort) (int, error) {
    portName := svcPort.TargetPort
    switch portName.Type {
    case intstr.String:
        name := portName.StrVal
        for _, container := range pod.Spec.Containers {
            for _, port := range container.Ports {
                if port.Name == name && port.Protocol == svcPort.Protocol {
                    return int(port.ContainerPort), nil
                }
            }
        }
    case intstr.Int:
        return portName.IntValue(), nil
    }

    return 0, fmt.Errorf("no suitable port for manifest: %s", pod.UID)
}

来源

英文:

When you create the Service, it is associated with Pods selected by the label selector defined in the Service spec.selector.

When a request is made to the Service, the Control Plane retrieves its spec.ports[*].targetPort value:

  • If it does not exist, the value of spec.ports[*].port field is used instead to forward traffic to the Pods.

  • If it does exist and it is a number, the targetPort value is used to forward traffic to the Pods.

  • If it is a string, the Control Plane looks up the port by name in spec.ports[*].name of the Pod, and uses the port with the matching name as the target port.

Here is the relevant piece of code in Kubernetes:

// FindPort locates the container port for the given pod and portName.  If the
// targetPort is a number, use that.  If the targetPort is a string, look that
// string up in all named ports in all containers in the target pod.  If no
// match is found, fail.
func FindPort(pod *v1.Pod, svcPort *v1.ServicePort) (int, error) {
	portName := svcPort.TargetPort
	switch portName.Type {
	case intstr.String:
		name := portName.StrVal
		for _, container := range pod.Spec.Containers {
			for _, port := range container.Ports {
				if port.Name == name && port.Protocol == svcPort.Protocol {
					return int(port.ContainerPort), nil
				}
			}
		}
	case intstr.Int:
		return portName.IntValue(), nil
	}

	return 0, fmt.Errorf("no suitable port for manifest: %s", pod.UID)
}

source

答案2

得分: 1

基本上,您将使用端口号来引用目标端口。但是,您可以为 pod 配置中提到的每个端口赋予一个名称,并在服务中使用此名称来引用指定的端口。通过这种方式,您的服务将知道它需要考虑来自 pod 的哪个端口。

回答您的问题,您在pod 中创建的端口名称仅属于 pod 配置。它可以用作获取 pod 的端口号的引用。但在您的服务中,您正在创建一个新的端口名称属性,该属性仅属于服务。服务中的 targetPort 将仅考虑在服务中创建的 portname 属性中的端口号,而不是来自 pod 的端口号。

同样,Kubernetes 知道它需要考虑服务中创建的端口名称来确定服务目标端口号,而不是来自pod

基本上,Kubernetes 使用 DNS 来确定所有这些内容。有关更多信息,您可以参考以下链接:link1 link2

英文:

Basically you will refer to the target port with the port number. But, you can give a name to each port mentioned in the pod configuration and use this name in the service to refer to the specified port. By this your service will be aware of which port it needs to consider from the pod.

To answer your question, the port name which you created in the pod belongs only to the pod configuration. It can be used as a reference to get the portnumber of a pod. But in your service you are creating a new portname attribute which only belongs to the service. The targetPort in service will only consider the port number from the portname attribute created in the service and not from the pod.

Likewise the kubernetes knows that it needs to consider the target port number for the service by the port name created in the service and not from the pod.

Basically k8's uses DNS to determine all this stuff. For more information you can refer to this link1 link2

huangapple
  • 本文由 发表于 2023年1月9日 13:05:28
  • 转载请务必保留本文链接:https://go.coder-hub.com/75053378.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定