英文:
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)
}
答案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
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论