<p>How can I speedup the rollout of new images in Kubernetes?</p>
<p>Currently, we have an automated build job that modifies a yaml file to point to a new revision and then runs <code>kubectl apply</code> on it.</p>
<p>It works, but it takes long delays (up to 20 minutes PER POD) before all pods with the previous revision are replaced with the latest.</p>
<p>Also, the deployment is configured for 3 replicas. We see one pod at a time is started with the new revision. (Is this the Kubernetes &quot;surge&quot; ?) But that is too slow, I would rather kill all 3 pods and have 3 new ones with the new image.</p>

<p>Jonas and SYN are right but I would like to expand this topic with some additional info and examples.</p>
<p>You have two types of strategies to choose from when specifying the way of updating your deployments:</p>
<ul>
<li><p><a href="https://kubernetes.io/docs/concepts/workloads/controllers/deployment/#recreate-deployment" rel="nofollow noreferrer">Recreate Deployment</a>: All existing Pods are killed before new ones are created.</p>
</li>
<li><p><a href="https://kubernetes.io/docs/concepts/workloads/controllers/deployment/#rolling-update-deployment" rel="nofollow noreferrer">Rolling Update Deployment</a>: The Deployment updates Pods in a rolling update fashion.</p>
</li>
</ul>
<p>The default and more recommended one is the <code>.spec.strategy.type==RollingUpdate</code>. See the examples below:</p>
<pre><code>spec:
  replicas: 3
  strategy:
   type: RollingUpdate
   rollingUpdate:
     maxSurge: 1
     maxUnavailable: 0
</code></pre>
<p>In this example there would be one additional Pod (<code>maxSurge: 1</code>) above the desired number of 3, and the number of available Pods cannot go lower than that number (<code>maxUnavailable: 0</code>).</p>
<p>Choosing this config, the Kubernetes will spin up an additional Pod, then stop an “old” one. If there’s another Node available to deploy this Pod, the system will be able to handle the same workload during deployment. If not, the Pod will be deployed on an already used Node at the cost of resources from other Pods hosted on the same Node.</p>
<p>You can also try something like this:</p>
<pre><code>spec:
  replicas: 3
  strategy:
   type: RollingUpdate
   rollingUpdate:
     maxSurge: 0
     maxUnavailable: 1
</code></pre>
<p>With the example above there would be no additional Pods (<code>maxSurge: 0</code>) and only a single Pod at a time would be unavailable (<code>maxUnavailable: 1</code>).</p>
<p>In this case, Kubernetes will first stop a Pod before starting up a new one. The advantage of that is that the infrastructure doesn’t need to scale up but the maximum workload will be less.</p>
<p>If you chose to use the percentage values for <code>maxSurge</code> and <code>maxUnavailable</code> you need to remember that:</p>
<ul>
<li><p><code>maxSurge</code> - the absolute number is calculated from the percentage by <strong>rounding up</strong></p>
</li>
<li><p><code>maxUnavailable</code> - the absolute number is calculated from percentage by <strong>rounding down</strong></p>
</li>
</ul>
<p>With the <code>RollingUpdate</code> defined correctly you also have to make sure your  applications provide endpoints to be queried by Kubernetes that return the app’s status. Below it's a <code>/greeting</code> endpoint, that returns an HTTP 200 status when it’s ready to handle requests, and HTTP 500 when it’s not:</p>
<pre><code>readinessProbe:
  httpGet:
    path: /greeting
    port: 8080
  initialDelaySeconds: 5
  periodSeconds: 5
  successThreshold: 1
  timeoutSeconds: 1
</code></pre>
<ul>
<li><p><code>initialDelaySeconds</code> - Time (in seconds) before the first check for readiness is done.</p>
</li>
<li><p><code>periodSeconds</code> - Time (in seconds) between two readiness checks after the first one.</p>
</li>
<li><p><code>successThreshold</code> - Minimum consecutive successes for the probe to be considered successful after having failed. Defaults to 1. Must be 1 for liveness. Minimum value is 1.</p>
</li>
<li><p><code>timeoutSeconds</code> - Number of seconds after which the probe times out. Defaults to 1 second. Minimum value is 1.</p>
</li>
</ul>
<p>More on the topic of liveness/readiness probes can be found <a href="https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/" rel="nofollow noreferrer">here</a>.</p>
