<p>I am working to get an existing application consisting of a bunch of stateless, scalable microservices (and of course also a few stateful ones serving as backends) running on Docker Swarm and Kubernetes. Changing the code of the application is mostly out of the question, so I have to make some existing mechanisms that we have for, e.g., service discovery, work in the Swarm and K8s contexts.</p>

<p>One thing that helped me a lot with getting things up and running with Docker Swarm was the template feature of Swarm's "service create" command (<a href="https://docs.docker.com/engine/reference/commandline/service_create/#create-services-using-templates" rel="nofollow noreferrer">https://docs.docker.com/engine/reference/commandline/service_create/#create-services-using-templates</a>), where I can do something like</p>

<pre><code>-e my_env_var=foo{{.Task.Slot}}
</code></pre>

<p>Inside each container that is part of my Swarm service, this will set the env var my_env_var to a value of the form fooX, where "X" is the container's "slot number".
To grasp what a slot number is, consider a service with N instances (i.e., scale=N). Each container occupies one slot, and the slots are numbered from 1 to N. </p>

<p>That way, I can get a ID inside my container that is unique among all currently alive containers of my service, but at the same time, it is NOT totally random. If I scale a service from, e.g., 1 to 5, the five containers in my service will get the slots 1, 2, 3, 4, and 5.
If I scale it down to, e.g., 3, two containers will be stopped (e.g., 2 and 4, leaving me with 1, 3, and 5). But if I scale it up again to 5, the slot numbers will (in general) again be 1 to 5 (and even if they were, e.g., 2-6, that is still better than being totally random).</p>

<p>This has proven to be very useful for Swarm-enabling my application and I am desperately looking for something similar in K8s (in particular in the context of K8s deployments, which I am using for our stateless microservices as they seem to be the most suitable K8s concept).
I found the possibility to pass the pod name into the container with</p>

<pre><code>    env:
    - name: metadata_name
      valueFrom:
        fieldRef:
          fieldPath: metadata.name
</code></pre>

<p>Alas, the name of a container is 
a) rather lengthy
b) random (i.e., scaling down and up will NOT reuse names), 
e.g. the pods of a deployment named foo-deployment will be named something like</p>

<p>foo-deployment-64db944b84-bwrxx</p>

<p>foo-deployment-64db944b84-5jf7c</p>

<p>etc.
So as far as I understand, the last five characters are guaranteed by K8s to be unique among all active pods of a deployment, but they are NOT reused (rare collisions nonwithstanding) when scaling up and down.</p>

<p>Is there any mechanism that corresponds to Swarm's "slot" concept?</p>

<p>Regards
PalatinateJ</p>

<p>11 Months late, but here is the solution:</p>

<p>To get stable container (pod) names within K8S you <em>must</em> use a <code>StatefulSet</code>. <code>StatefulSets</code> are designed for applications that must maintain state, however, if you aren't using K8S volumes for state (keeping them ephemeral) you can use <code>StatefulSets</code> without an issue. There is a simple process of converting your <code>Deployment</code> to a <code>StatefulSet</code>:</p>

<ol>
<li>Change your <code>apiVersion:</code> to <code>apps/v1</code></li>
<li>Change the <code>kind:</code> to <code>StatefulSet</code></li>
<li>Under <code>spec:</code> add the <code>selector:</code> tag. This tag will contain everything you use to select the appropriate service. <strong>In addition</strong> you must ensure that any items you have under <code>spec:template:metadata:labels</code> match those under <code>spec:selector:matchLabels</code> (This will make more sense in the provided example)</li>
<li>If you have any sort of update strategy, called <code>strategy</code> in a <code>Deployment</code>, change this to <code>updateStrategy</code>. For future reference, if you do not update this, you will end up with both a <code>StatefulSet</code> and a <code>ReplicaSet</code> being deployed as K8S is trying to fill the <code>strategy</code> and your <code>StatefulSet</code> requirements. </li>
</ol>

<p>After applying these changes, you will have your <code>StatefulSet</code> deployed. How do we get task slots from this? The hostname.</p>

<p>Since K8S is maintaining stable pod names, you will have names such as:</p>

<pre><code>pod/mypod-0                             1/1     Running   0          10m
pod/mypod-1                             1/1     Running   0          9m
</code></pre>

<p>when running <code>kubetctl</code>. After that, it is a simple matter of parsing the number out of your pod name.</p>

<p>Below is the YAML for a <code>StatefulSet</code>:</p>

<pre><code>apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: myStatefulSetName
  labels:
    app: SomeLabel1
    label2: SomeLabel2
spec:
  replicas: 100
  selector:
    matchLabels:
        app: SomeLabel1
        label2: SomeLabel2
  updateStrategy:
    type: RollingUpdate
  template:
    metadata:
      labels:
        app: SomeLabel1
        label2: SomeLabel2
    spec:
      containers:
      - name: myPodName
        image: myPod:latest
        imagePullPolicy: Always
        ports:
        - name: myPodPort
          containerPort: 8080
</code></pre>

<p>The differences become apparent on a equivalent <code>Deployment</code>:</p>

<pre><code>apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: myDeploymentName
  labels:
    app: SomeLabel1
    label2: SomeLabel2
spec:
  replicas: 100
  strategy:
    type: RollingUpdate
  template:
    metadata:
      labels:
        app: SomeLabel1
        label2: SomeLabel2
    spec:
      containers:
      - name: myPodName
        image: myPod:latest
        imagePullPolicy: Always
        ports:
        - name: myPodPort
          containerPort: 8080
</code></pre>
