<p>In my GKE Kubernetes cluster, I have 2 node <strong>pools</strong>; one with regular nodes and the other with pre-emptible nodes. I'd like some of the pods to be on pre-emptible nodes so I can save costs while I have at least 1 pod on a regular non-pre-emptible node to reduce the risk of downtime.</p>
<p>I'm aware of using <code>podAntiAffinity</code> to encourage pods to be scheduled on different nodes, but is there a way to have k8s schedule pods for a single deployment across both <strong>pools</strong>?</p>

<p>Yes 💡! You can use <a href="https://kubernetes.io/docs/concepts/workloads/pods/pod-topology-spread-constraints/" rel="nofollow noreferrer"><code>Pod Topology Spread Constraints</code></a>, based on a label 🏷️ key on your nodes. For example, the label could be <code>type</code> and the values could be <code>regular</code> and <code>preemptible</code>. Then you can have something like this:</p>
<pre class="lang-yaml prettyprint-override"><code>kind: Pod
apiVersion: v1
metadata:
  name: mypod
  labels:
    foo: bar
spec:
  topologySpreadConstraints:
  - maxSkew: 1
    topologyKey: type
    whenUnsatisfiable: DoNotSchedule
    labelSelector:
      matchLabels:
        foo: bar
  containers:
  - name: app
    image: myimage
</code></pre>
<p>You can also identify a <code>maxSkew</code> which means the maximum differentiation of a number of pods that one label value (node type) can have.</p>
<p>You can also combine multiple 'Pod Topology Spread Constraints' and also together with PodAffinity/AntiAffinity and NodeAffinity. All depending on what best fits your use case.</p>
<p>Note: This feature is alpha in 1.16 and beta in 1.18. Beta features are enabled by default but with alpha features, you need an <a href="https://cloud.google.com/kubernetes-engine/docs/how-to/creating-an-alpha-cluster" rel="nofollow noreferrer">alpha cluster</a> in GKE.</p>
<p>☮️✌️</p>
