<p>I want to scale an application with workers.<br>
There could be 1 worker or 100, and I want to scale them seamlessly.<br>
The idea is using replica set. However due to domain-specific reasons, the appropriate way to scale them is for each worker to know its: ID and the total number of workers.</p>

<p>For example, in case I have 3 workers, I'd have this:  </p>

<pre><code>id:0, num_workers:3
id:1, num_workers:3
id:2, num_workers:3
</code></pre>

<p>Is there a way of using kubernetes to do so?<br>
I pass this information in command line arguments to the app, and I assume it would be fine having it in environment variables too.</p>

<p>It's ok on size changes for all workers to be killed and new ones spawned. </p>

<p>Before giving the kubernetes-specific answer, I wanted to point out that it seems like the problem is trying to push cluster-coordination down into the app, which is almost by definition harder than using a distributed system primitive designed for that task. For example, if every new worker identifies themselves in <a href="https://github.com/coreos/etcd#readme" rel="nofollow noreferrer">etcd</a>, then they can <a href="https://github.com/coreos/etcd/blob/v3.2.11/Documentation/learning/api.md#watch-streams" rel="nofollow noreferrer">watch keys</a> to detect changes, meaning no one needs to destroy a running application just to update its list of peers, their contact information, their capacity, current workload, whatever interesting information you would enjoy having while building a distributed worker system.</p>

<p>But, on with the show:</p>

<hr>

<p>If you want stable identifiers, then <a href="https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/" rel="nofollow noreferrer">StatefulSets</a> is the modern answer to that. Whether that is an <em>exact</em> fit for your situation depends on whether (for your problem domain) <code>id:0</code> being "rebooted" still counts as <code>id:0</code> or the fact that it has stopped and started now disqualifies it from being <code>id:0</code>.</p>

<p>The running list of cluster size is tricky. If you are willing to be flexible in the launch mechanism, then you can have a <a href="https://github.com/mattn/etcdenv#readme" rel="nofollow noreferrer">pre-launch binary</a> populate the environment right before spawning the actual worker (that example is for reading from etcd directly, but the same principle holds for interacting with the kubernetes API, then launching).</p>

<p>You could do that same trick in a more static manner by having an <a href="https://kubernetes.io/docs/concepts/workloads/pods/init-containers/" rel="nofollow noreferrer">initContainer</a> write the current state of affairs to a file, which the app would then read in. Or, due to all Pod containers sharing networking, the app could contact a "sidecar" container on <code>localhost</code> to obtain that information via an API.</p>

<p>So far so good, except for the</p>

<blockquote>
  <p>on size changes for all workers to be killed and new one spawned</p>
</blockquote>

<p>The best answer I have for that requirement is that if the app must know its peers at launch time, then I am pretty sure you have left the realm of "scale $foo --replicas=5" and entered into the "destroy the peers and start all afresh" realm, with <code>kubectl delete pods -l some-label=of-my-pods</code>; which is, thankfully, what <a href="https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#on-delete" rel="nofollow noreferrer">updateStrategy: type: OnDelete</a> does, when combined with the <code>delete pods</code> command.</p>
