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.