<p>I am using statefulset and I spin up multiple pods but they are not replica of each other. I want to set the hostname of the pods and passing these hostname as a env variable to all the pods so that they can communicate with each other.</p>

<p>I tried to use hostname under pod spec but hostname is never to set to specified hostname. However, it is set to hostname as podname-0.</p>

<pre><code># Source: testrep/templates/statefulset.yaml
apiVersion: apps/v1
kind: StatefulSet 
metadata:
  name: orbiting-butterfly-testrep
  labels:
    app.kubernetes.io/name: testrep
    helm.sh/chart: testrep-0.1.0
    app.kubernetes.io/instance: orbiting-butterfly
    app.kubernetes.io/managed-by: Tiller
spec:
  replicas: 1
  selector:
    matchLabels:
      app.kubernetes.io/name: testrep
      app.kubernetes.io/instance: orbiting-butterfly
  strategy:
    type: Recreate
  template:
    metadata:
      labels:
        app.kubernetes.io/name: testrep
        app.kubernetes.io/instance: orbiting-butterfly
    spec:
      nodeSelector:
          testol: ad3
       hostname: test1
       containers:
        - name: testrep
          image: "test/database:v1"
          imagePullPolicy: IfNotPresent
          env:
           - name: DB_HOSTS
             value: test1,test2,test3
</code></pre>

<ol>
<li>As per documentation:</li>
</ol>
<blockquote>
<p>StatefulSet is the workload API object used to manage stateful applications.</p>
</blockquote>
<blockquote>
<p>Manages the deployment and scaling of a set of Pods, and provides guarantees about the ordering and uniqueness of these Pods.</p>
</blockquote>
<p>StatefulSets are valuable for applications that require one or more of the following:</p>
<ul>
<li><strong>Stable, unique network identifiers</strong>.</li>
<li>Stable, persistent storage.</li>
<li>Ordered, graceful deployment and scaling.</li>
<li>Ordered, automated rolling updates.</li>
</ul>
<ol start="2">
<li>Statefulset <a href="https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#limitations" rel="nofollow noreferrer">Limitations</a>:</li>
</ol>
<blockquote>
<p>StatefulSets currently require a Headless Service to be responsible for the network identity of the Pods. You are responsible for creating this Service.</p>
</blockquote>
<ol start="2">
<li><a href="https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#pod-identity" rel="nofollow noreferrer">Pod Identity</a></li>
</ol>
<blockquote>
<p>StatefulSet Pods have a unique identity that is comprised of an ordinal, a stable network identity, and stable storage. The identity sticks to the Pod, regardless of which node it’s (re)scheduled on.
<strong>For a StatefulSet with N replicas, each Pod in the StatefulSet will be assigned an integer ordinal, from 0 up through N-1, that is unique over the Set</strong>.</p>
</blockquote>
<ol start="3">
<li><a href="https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#stable-network-id" rel="nofollow noreferrer">Stable Network ID</a></li>
</ol>
<blockquote>
<p>Each Pod in a StatefulSet derives its hostname from the name of the StatefulSet and the ordinal of the Pod. <strong>The pattern for the constructed hostname is $(statefulset name)-$(ordinal)</strong>. <strong>The example above will create three Pods named web-0,web-1,web-2</strong>. A StatefulSet can use a Headless Service to control the domain of its Pods. The domain managed by this Service takes the form: $(service name).$(namespace).svc.cluster.local, where “cluster.local” is the cluster domain. As each Pod is created, it gets a matching DNS subdomain, taking the form: $(podname).$(governing service domain), where the governing service is defined by the serviceName field on the StatefulSet.</p>
</blockquote>
<p><strong>Note</strong>:</p>
<p>You are responsible for creating the Headless Service responsible for the network identity of the pods.</p>
<p>So as described by <a href="https://stackoverflow.com/a/58669371/11207414">vjdhama</a> Please create your Statefulset with Headless Service.</p>
<p>You can find this example in the docs:</p>
<pre><code>apiVersion: v1
kind: Service
metadata:
 name: nginx
 labels:
   app: nginx
spec:
  ports:
  - port: 80
    name: web
  clusterIP: None
  selector:
    app: nginx


apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: web
spec:
  selector:
    matchLabels:
      app: nginx # has to match .spec.template.metadata.labels
  serviceName: &quot;nginx&quot; # has to match headless Service metadata.name
  replicas: 3 # by default is 1
  template:
    metadata:
      labels:
        app: nginx # has to match .spec.selector.matchLabels
    spec:
      terminationGracePeriodSeconds: 10
      containers:
      - name: nginx
        image: k8s.gcr.io/nginx-slim:0.8
        ports:
        - containerPort: 80
</code></pre>
<p>In this scenario Pod DNS and Pod Hostnames should be respectively:</p>
<pre><code>    Pod DNS
    web-{0..N-1}.nginx.default.svc.cluster.local
    
    Pod Hostname
    web-{0..N-1}


    NAME                                   READY   STATUS    RESTARTS   AGE     IP               
    pod/web-0                              1/1     Running   0          5m      192.168.148.78   
    pod/web-1                              1/1     Running   0          4m53s   192.168.148.79   
    pod/web-2                              1/1     Running   0          4m51s   192.168.148.80  
    
</code></pre>
<p>From the Pod perspective:</p>
<pre><code>   root@web-2:# nslookup nginx
   Server:      10.96.0.10
   Address: 10.96.0.10#53

   Name:    nginx.default.svc.cluster.local 
   Address: 192.168.148.80
   Name:    nginx.default.svc.cluster.local
   Address: 192.168.148.78
   Name:    nginx.default.svc.cluster.local
   Address: 192.168.148.79
</code></pre>
<p>So you can call each of the respective pods using the Pod DNS, like:</p>
<pre><code>web-0.nginx.default.svc.cluster.local
</code></pre>
<p><strong>Update:</strong></p>
<p>Exposing single pod from StatefulSet.</p>
<blockquote>
<h2>Pod Name Label</h2>
<p>When the StatefulSet controller creates a Pod, it adds a label, <code>statefulset.kubernetes.io/pod-name</code>, that is set to the name of the Pod. This label allows you to attach a Service to a specific Pod in the StatefulSet.</p>
</blockquote>
<p><a href="https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#pod-name-label" rel="nofollow noreferrer">https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#pod-name-label</a></p>
<p>You can find <a href="https://itnext.io/exposing-statefulsets-in-kubernetes-698730fb92a1" rel="nofollow noreferrer">here</a> tricky way.
Using described above advantages of Statefulset:</p>
<blockquote>
<p>The pattern for the constructed hostname is $(statefulset name)-$(ordinal). The example above will create three Pods named web-0,web-1,web-2.</p>
</blockquote>
<p>So as an example:</p>
<pre><code>apiVersion: v1
kind: Service
metadata:
  name: app-0
spec:
  type: LoadBalancer
  selector:
    statefulset.kubernetes.io/pod-name: web-0
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
</code></pre>
<p>Will do this for you.</p>
<p>Hope this help.</p>
