kubernetesdeploymenthorizontal-scaling

Is a Kubernetes StatefulSet the right answer if all we need is a consistent identifier for each Pod in a group of identical Pods?


We are looking at a Kubernetes scenario that requires us to maintain N pods for a given Deployment (let's assume for simplicitly that N is static and N = 3). Currently we are using a Deployment and a ReplicaSet for this.

Within each pod, is there any way (through environment variable injection or similar) for us to get a unique identifier that shows which pod that pod is (i.e. "1", "2", "3" or similar... the exact format is unimportant).

What is especially important (because of the system these pods connect to) is that if pod "2" dies, the replacement pod also reports its identifier as "2", not as something new, e.g. "4"... in other words, the set of identifiers does not change over time unless the size of the set is increased / decreased. Currently we are using the pod name, but that is not stable in this way; the pod name is new and unique every time.

Is this what a StatefulSet is for? The documentation seems to focus in particular on storage volumes, but this is not a priority for us. How would we actually obtain the unique and stable ID inside the container in code?


Solution

  • Yes, Statefulset is the way to go if the pods need to have their identity defined in some way.

    Here is the quote from a relevant section from the docs:

    Like a Deployment, a StatefulSet manages Pods that are based on an identical container spec. Unlike a Deployment, a StatefulSet maintains a sticky identity for each of their Pods. These pods are created from the same spec, but are not interchangeable: each has a persistent identifier that it maintains across any rescheduling.

    So, if you have a Statefulset object named myapp with 3 replicas then the pods will be named as myapp-0, myapp-1 and myapp-2.

    Further, if any of the pods die say myapp-1 then the new pod created as the replacement of that will again be myapp-1.

    You can expose the pod name to the containers via environment variables through Downward API and use it inside the scripts:

    env:
      - name: MY_POD_NAME
          valueFrom:
            fieldRef:
              fieldPath: metadata.name
    

    A relevant note that I missed to mention is that with Statefulsets the pods are brought up one by one unlike Deployments. So, for the above example myapp, myapp-1 will only get started after myapp-0 is ready.