Search code examples
kubernetesgoogle-kubernetes-enginekubernetes-podkubernetes-service

Service is incorrectly selecting Pod listening on some different port


I tried the Service definition example from here.

So, I created below Service:

apiVersion: v1
kind: Service
metadata:
  name: service-simple-service
spec:
  selector:
    app: MyApp
  ports:
    - protocol: TCP
      port: 80
      targetPort: 9376

And then to test the concept, I created below Pod:

apiVersion: v1
kind: Pod
metadata:
  name: service-simple-service-pod
  labels:
    app: MyApp
spec:
  containers:
  - name: service-simple-service-pod-container-1
    image: nginx:alpine
    ports:
      - containerPort: 9376

And I can see that a new Endpoint for this Pod is created, so all good till now, below is the output:

C:\Users>kubectl describe service/service-simple-service
Name:              service-simple-service
Namespace:         default
Labels:            <none>
Annotations:       <none>
Selector:          app=MyApp
Type:              ClusterIP
IP:                10.98.246.70
Port:              <unset>  80/TCP
TargetPort:        9376/TCP
Endpoints:         10.244.0.8:9376
Session Affinity:  None
Events:            <none>

Then to test negative concept, I created below Pod.

apiVersion: v1
kind: Pod
metadata:
  name: service-simple-service-pod-nouse
  labels:
    app: MyApp
spec:
  containers:
  - name: service-simple-service-pod-nouse-container-1
    image: nginx:alpine
    ports:
      - containerPort: 9378

But to my surprise this Pod was also picked:

C:\Users>kubectl describe service/service-simple-service
Name:              service-simple-service
Namespace:         default
Labels:            <none>
Annotations:       <none>
Selector:          app=MyApp
Type:              ClusterIP
IP:                10.98.246.70
Port:              <unset>  80/TCP
TargetPort:        9376/TCP
Endpoints:         10.244.0.10:9376,10.244.0.8:9376
Session Affinity:  None
Events:            <none>

My understanding of Service I created above was that Scheduler will look for any Pod having label as app: MyApp and running on port 9376, so my expectation was that since this Pod is running on port 9378 so it will not be picked up. So, my question is that why this "service-simple-service-pod-nouse" was picked up?

If someone says that my understanding was incorrect and Service only selects Pod based on Label, then my question is that since "service-simple-service-pod-nouse" Pod is listening on port 9378 then how "service-simple-service" Service can send traffic to this Pod?


Solution

  • Sevice will picked all the pods that are labeled as the label selector of that service. service-simple-service service will select all the pods that are labeled as MyApp because you tell in the service selector (app: MyApp). This is the common and expected behavior of label-selector, you can see the k8s official doc

    apiVersion: v1
    kind: Service
    metadata:
      name: service-simple-service
    spec:
      selector:
        app: MyApp
      ports:
        - protocol: TCP
          port: 80
          targetPort: 9376
    

    Update

    Basically, a service get the requests and then it serves the traffic to the pods (those are labeled as the service selector), when a service take a pod then it opens a endpoint for that pod, when traffic comes to the service it sends those traffics in one of it endpoints(which is basically going to a pod). And the container port is basically the port inside the pod where the container is running.