<p>Considering a very simple <strong>service.yaml</strong> file:</p>

<pre><code>kind: Service
apiVersion: v1
metadata:
  name: gateway-service
spec:
  type: NodePort
  selector:
    app: gateway-app
  ports:
  - name: gateway-service
    protocol: TCP
    port: 80
    targetPort: 8080
    nodePort: 30080
</code></pre>

<p>We know that service will route all the requests to the pods with this label <code>app=gateway-app</code> at port <code>8080</code> (a.k.a. <code>targetPort</code>). There is another <code>port</code> field in the service definition, which is <code>80</code> in this case here. What is this <code>port</code> used for? When should we use it? </p>

<p>From the documentation, there is also this line:</p>

<blockquote>
  <p>By default the <code>targetPort</code> will be set to the same value as the port field.</p>
  
  <p>Reference: <a href="https://kubernetes.io/docs/concepts/services-networking/service/" rel="noreferrer">https://kubernetes.io/docs/concepts/services-networking/service/</a></p>
</blockquote>

<p>In other words, when should we keep <code>targetPort</code> and <code>port</code> the same and when not?</p>

<p>In a <code>nodePort</code> service you can have 3 types of ports defined:</p>

<p><strong>TargetPort</strong>:</p>

<p>As you mentioned in your question, this is the corresponding port to your pod and essentially the <code>containerPort</code>s you have defined in your replica manifest. </p>

<p><strong>Port (servicePort)</strong>: </p>

<p>This defines the port that other local resources can refer to. Quoting from the Kubernetes docs: </p>

<blockquote>
  <p>this Service will be visible [locally] as .spec.clusterIP:spec.ports[*].port</p>
</blockquote>

<p>Meaning, this is not accessible publicly, however you can refer to your service port through other resources (within the cluster) with this port. An example is when you are creating an ingress for this service. In your ingress you will be required to present this port in the <code>servicePort</code> field:</p>

<pre><code>  ...
        backend:
          serviceName: test
          servicePort: 80
</code></pre>

<p><strong>NodePort</strong>: </p>

<p>This is the port on your node which publicly exposes your service. Again quoting from the docs:</p>

<blockquote>
  <p>this Service will be visible [publicly] as [NodeIP]:spec.ports[*].nodePort</p>
</blockquote>
