Home > Software design >  Kubernetes: are ContainerPorts on a workload's spec *really* primarily informational?
Kubernetes: are ContainerPorts on a workload's spec *really* primarily informational?

Time:01-02

The k8s docs clearly state about containerPorts:

List of ports to expose from the container. Exposing a port here gives the system additional information about the network connections a container uses, but is primarily informational. Not specifying a port here DOES NOT prevent that port from being exposed. Any port which is listening on the default "0.0.0.0" address inside a container will be accessible from the network. Cannot be updated.

But what happens when I have the following containerPorts configuration inside a workload (let's say a Deployment):

    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
          - containerPort: 8089
            name: web

And in the Service exposing the workload I specify:

spec:
  ports:
  - name: http
    port: 8081
    protocol: TCP
    targetPort: webz <---- notice the misspelling 
  selector:
    app: nginx
  type: ClusterIP

The Service has no way to route the traffic to a targetPort=webz, because we've named our containerPort web.

What am I missing? If the Service won't indeed be able to route traffic to the workload, then I believe that calling this array "primarily informational" is a bit of an overstatement.

CodePudding user response:

If you only use a port number, they are purely informational and dont influence anything native to kubernetes.

# pod
image: nginx:1.14.2
ports:
  - containerPort: 8089

However, as you noticed, things change a bit if you use a name. Then you can reference to the port number by name.

# pod
image: nginx:1.14.2
ports:
  - containerPort: 8089
    name: web

As you noticed as well, if you want to reference this name and get a corresponding port number, the name must exist in the list of ports.

It is still informational in that it doesn't actually change the port the container is listening on. It has no impact on the container at all. However, the information, being an information, can be used.

You can think of them as variables. For example:

let web = 8000
let targetPort = web

Of course, we could also just write

let targetPort = 8080

And exactly the second case is also possible in Kubernetes

# service
spec:
  ports:
    - port: 8081
      targetPort: 8080
  selector:
    app: nginx

You can see that the port is directly used in the service, and by doing this, you could omit the port list from your pod spec completely.

As a side note, you have the same options between ingress and service, in that you can decide to use names or port numbers.

So ultimately, whether you name things, is up to you. If you decide to use names, then of course the names must match.

  • Related