Ports in the pod and not the same as in the deployment descriptor

11/18/2019

We have found that the ports defined in our daemonset deployment descriptor are not reflected in the running pods. The image we are using is NGINX, and we routed these host ports to 80 and 8080:

        ports:
        - containerPort: 80
          hostPort: 30003
        - containerPort: 8080
          hostPort: 30002

Nothing wrong there, and the deployment history shows those ports are active in the pod:

daemonset.extensions/nginx-licensed with revision #25
Pod Template:
  Containers:
   nginx-licensed:
    Image:  nginx-licensed:1.0.117
    Ports:  80/TCP, 8080/TCP
    Host Ports: 30003/TCP, 30002/TCP

We wanted to change the host port used, and to allow the infrastructure changes to be made gradually, we assigned both old and new host ports to the same container ports:

        ports:
        - name: new80
          containerPort: 80
          hostPort: 20003
        - name: old80
          containerPort: 80
          hostPort: 30003
        - name: new8080
          containerPort: 8080
          hostPort: 20002
        - name: old8080
          containerPort: 8080
          hostPort: 30002

At this point, 'kubectl apply' results in only the 2000x ports being active:

daemonset.extensions/nginx-licensed with revision #26
Pod Template:
  Containers:
   nginx-licensed:
    Image:  nginx-licensed:1.0.119
    Ports:  80/TCP, 8080/TCP
    Host Ports: 20003/TCP, 20002/TCP

Note that if we restarted the pods, all four ports become active:

daemonset.extensions/nginx-licensed with revision #1
Pod Template:
  Containers:
   nginx-licensed:
    Image:  nginx-licensed:1.0.119
    Ports:  80/TCP, 80/TCP, 8080/TCP, 8080/TCP
    Host Ports: 20003/TCP, 30003/TCP, 20002/TCP, 30002/TCP

However, if we don't restart the pods, and try to remove the 3000x pods, i.e. this:

        ports:
        - containerPort: 80
          hostPort: 20003
        - containerPort: 8080
          hostPort: 20002

We end up with no container ports! :

daemonset.extensions/nginx-licensed with revision #27
Pod Template:
  Containers:
   nginx-licensed:
    Image:  nginx-licensed:1.0.119
    Ports:  80/TCP, 8080/TCP
    Host Ports: 0/TCP, 0/TCP

Any ideas why that is, or what we've done wrong? We rolled back to the version with four ports defined (i.e. both 2000x and 3000x), and that's resulted in just the 2000x host ports active.

Does this look like a bug?

Thanks!

-- jdavis
kubernetes

1 Answer

11/26/2019

I reproduced your scenario on GKE and I have the same symptoms as you.

There is a way to achieve what you need and for that you need to patch your objects. You need to use the patch type merge-patch+json and as a patch you need to supply a complete/desired list of containerPort.

Firstly you need to export your yaml file and make the necessary changes:

$ kubectl get deployments <your-deployment> -o yaml --export > patch-file.yaml

After making the changes, patch it:

$ kubectl patch deployments <your-deployment> --type merge --patch "$(cat patch-file.yaml)"

After doing this, I have your desired state:

$ kubectl describe deployments nginx-deployment | grep -i ports
    Ports:        80/TCP, 80/TCP, 8080/TCP, 8080/TCP
    Host Ports:   20003/TCP, 30003/TCP, 20002/TCP, 30002/TCP

If you want to deep dive into how this is working in the background refer to documentation here and here.

-- mWatney
Source: StackOverflow