<p>I've deployed few services and found one service to be behaving differently to others. I configured it to listen on 8090 port (which maps to 8443 internally), but the request works only if I send on port 8080. Here's my yaml file for the service (stripped down to essentials) and there is a deployment which encapsulates the service and container</p>
<pre><code>apiVersion: v1
kind: Service
metadata:
  name: uisvc
  namespace: default
  labels:
    helm.sh/chart: foo-1
    app.kubernetes.io/name: foo
    app.kubernetes.io/instance: rb-foo
spec:
  clusterIP: None
  ports:
    - name: http
      port: 8090
      targetPort: 8080
  selector:
    app.kubernetes.io/component: uisvc
</code></pre>
<p>After installing the helm, when I run <code>kubectl get svc</code>, I get the following output</p>
<pre><code>fooaccess       ClusterIP   None         &lt;none&gt;        8888/TCP   119m
fooset          ClusterIP   None         &lt;none&gt;        8080/TCP   119m
foobus          ClusterIP   None         &lt;none&gt;        6379/TCP   119m
uisvc           ClusterIP   None         &lt;none&gt;        8090/TCP   119m
</code></pre>
<p>However, when I ssh into one of the other running containers and issue a curl request on 8090, I get &quot;Connection refused&quot;. If I curl to &quot;http://uisvc:8080&quot;, then I am getting the right response. The container is running a spring boot application which by default listens on 8080. The only explanation I could come up with is somehow the port/targetPort is being ignored in this config and other pods are directly reaching the spring service inside.</p>
<p>Is this behaviour correct? Why is it not listening on 8090? How should I make it work this way?</p>
<p>Edit: Output for <code>kubectl describe svc uisvc</code></p>
<pre><code>Name:              uisvc
Namespace:         default
Labels:            app.kubernetes.io/instance=foo-rba
                   app.kubernetes.io/managed-by=Helm
                   app.kubernetes.io/name=rba
                   helm.sh/chart=rba-1
Annotations:       meta.helm.sh/release-name: foo
                   meta.helm.sh/release-namespace: default
Selector:          app.kubernetes.io/component=uisvc
Type:              ClusterIP
IP:                None
Port:              http  8090/TCP
TargetPort:        8080/TCP
Endpoints:         172.17.0.8:8080
Session Affinity:  None
Events:            &lt;none&gt;
</code></pre>

<p>This is expected behavior since you used <code>headless service</code>.</p>
<p>Headless Services are used for service discovery mechanism so instead of returning single <code>DNS A records</code>, the <code>DNS server</code> will return multiple <code>A records</code> for your service each pointing to the IP of an individual pods that backs the service. So you do simple <code>DNS A records</code> lookup and get the IP of all of the pods that are part of the service.</p>
<p>Since <code>headless service</code> doesn't create <code>iptables</code> rules but creates <code>dns records</code> instead, you can interact directly with your pod instead of a proxy. So If you resolve <code>&lt;servicename:port&gt;</code> you will get <code>&lt;podN_IP:port&gt;</code> and then your connection will go to the pod directly. As long as all of this is in the same namespace you don`t have resolve it by full dns name.</p>
<p>With several pods, DNS will give you all of them and just put in the random order (or in RR order). The order depends on the DNS server implementation and settings.</p>
<p>For more reading please visit:</p>
<ul>
<li><a href="https://kubernetes.io/docs/concepts/services-networking/service/#headless-services" rel="nofollow noreferrer">Services-netowrking/headless-services</a></li>
<li><a href="https://stackoverflow.com/questions/54488280/how-do-i-get-individual-pod-hostnames-in-a-deployment-registered-and-looked-up-i/56778273#56778273">This stack questions with great answer explaining how headless services work</a></li>
</ul>
