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?
CodePudding user response:
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.
The relevant piece of code in Kubernetes is this:
// 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)
}