kuberneteskubernetes-service

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?


Solution

  • 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:

    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