Difference between targetPort and port in Kubernetes Service definition
if container listens on port 9376, then targetPort: 9376
if a service listens on port 80, then port: 80
Then service ports config looks like below
ports:
- protocol: TCP
port: 80
targetPort: 9376
Finally, request received to the service’s port, and forwarded on the targetPort of the pod.
In nutshell
nodeport:
Listens for external request on all worker nodes on nodeip:nodeport
and forwards the request to port.
ClusterIP:
Request comes through ingress and points to service name and port.
port:
Internal cluster service port for container and listens for incoming request from the nodeport and forwards to targetPort.
targetPort:
Receives the request from port and forwards to container pod(port) where it's listening. Even if you don't specify this will get by default assigned the same port numbers as port.
So the traffic flows Ingress-->Service-->Endpoint(Basically has POD IP)-->POD
It helps me to think of things from the perspective of the service.
nodePort
: The port on the node where external traffic will come in onport
: The port of this servicetargetPort
The target port on the pod(s) to forward traffic to
Traffic comes in on nodePort
, forwards to port
on the service which then routes to targetPort
on the pod(s).
It's worth emphasizing that nodePort
is for external traffic. Other pods in the cluster that may need to access the service will just use port
, not nodePort
as it's internal only access to the service.
Also worth noting that if targetPort
is not set, it will default to the same value as port
. E.g. 80:80
for service port 80
targeting container port 80
.
Service: This directs the traffic to a pod.
TargetPort: This is the actual port on which your application is running inside the container.
Port: Some times your application inside container serves different services on a different port.
Example: The actual application can run 8080
and health checks for this application can run on 8089
port of the container.
So if you hit the service without port it doesn't know to which port of the container it should redirect the request. Service needs to have a mapping so that it can hit the specific port of the container.
kind: Service
apiVersion: v1
metadata:
name: my-service
spec:
selector:
app: MyApp
ports:
- name: http
nodePort: 30475
port: 8089
protocol: TCP
targetPort: 8080
- name: metrics
nodePort: 31261
port: 5555
protocol: TCP
targetPort: 5555
- name: health
nodePort: 30013
port: 8443
protocol: TCP
targetPort: 8085
if you hit the my-service:8089
the traffic is routed to 8080
of the container(targetPort). Similarly, if you hit my-service:8443
then it is redirected to 8085
of the container(targetPort). But this myservice:8089
is internal to the kubernetes cluster and can be used when one application wants to communicate with another application. So to hit the service from outside the cluster someone needs to expose the port on the host machine on which kubernetes is running
so that the traffic is redirected to a port of the container. This is node port
(port exposed on the host machine).
From the above example, you can hit the service from outside the cluster(Postman or any rest-client) by host_ip:nodePort
Say your host machine ip is 10.10.20.20
you can hit the http, metrics, health services by 10.10.20.20:30475
, 10.10.20.20:31261
, 10.10.20.20:30013
.
Edits: Edited as per Raedwald comment.