StuffHappens
StuffHappens

Reputation: 6557

How port names are resolved in kubernetes

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?

Upvotes: 1

Views: 1562

Answers (2)

blakelead
blakelead

Reputation: 1890

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

Upvotes: 3

Dharani Dhar Golladasari
Dharani Dhar Golladasari

Reputation: 1012

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

Upvotes: 1

Related Questions