<p>I am building a application in k8s where I want the replicas of deployments/statefulsets to scale as per the number of nodes added.</p>
<p>Initially deployment should come up with 1 replicas when 1st node is created and grow as we add more worker/master nodes to it and once max is achieved, it should stop growing. I am using local storage and I dont want statefulsets getting scheduled in a single node.</p>
<p>Assume I have a deployment where I expect 2 repicas to run. Only one should come when 1st node is launched. Finally when I have a 3 node master, It should have 2 replicas running in 2 nodes.</p>
<p>Is there anyway, I can achieve this. TIA</p>

yog raj
<p>There are various options.</p>
<h3>DaemonSet</h3>
<p>If you want exactly one replica of your app on every worker node, you can use a <a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.19/#daemonset-v1-apps" rel="nofollow noreferrer">DaemonSet</a> (although I guess you want to have only up to certain number of replicas, so in this case, this isn't a solution for your use case).</p>
<h3>Pod anti-affinty</h3>
<p>You can define a <a href="https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#inter-pod-affinity-and-anti-affinity" rel="nofollow noreferrer">Pod anti-affinity</a> for the Pods of your Deployment with a <code>requiredDuringSchedulingIgnoredDuringExecution</code> type and a <code>topologyKey</code> referring to a label that's different on each node. In this way, no two Pods of your Deployment will be scheduled to the same node.</p>
<p>For example, if you define three replicas in your Deployment, and there are only two worker nodes available, then two replicas will be scheduled on these two worker nodes and the third replica will remain pending until a third worker node is created, in which case it will be scheduled to this node.</p>
<h3>Operator</h3>
<p>The most flexible solution is creating an <a href="https://kubernetes.io/docs/concepts/extend-kubernetes/operator/" rel="nofollow noreferrer">operator</a>. In this case, you create a new <a href="https://kubernetes.io/docs/concepts/extend-kubernetes/api-extension/custom-resources/" rel="nofollow noreferrer">custom resource</a> which encodes your desired deployment behaviour (e.g. the desired maximum number of replicas). You do this by defining a custom resource definition (CRD). You then create an operator which is an application that interacts with the Kubernetes API and enforces this behaviour.</p>
<p>At runtime, this may then look as follows:</p>
<ul>
<li>You create an instance of your custom resource → the operator becomes active, checks the declared number of replicas in the custom resource, checks the number of available worker nodes, and creates the appropriate number of replicas.</li>
<li>You add an additional node to the cluster → the operator becomes active, checks if there are any pending replicas in the instances of your custom resource, and if so, schedules one of them to the new node.</li>
<li>You remove a node from the cluster → the operator becomes active and makes sure the replicas on the removed node are not scheduled to another node but just become pending until a new node is created.</li>
</ul>
<p>You can extend this logic in any way you want, since you can implement any logic you want in an operator.</p>
