Answers: <p>The difficulties we encountered with a single pod rolling update are already explained here:</p>
  <p><a href="https://stackoverflow.com/questions/46369100/kubernetes-rolling-update-killing-off-old-pod-without-bringing-up-new-one">https://stackoverflow.com/questions/46369100/kubernetes-rolling-update-killing-off-old-pod-without-bringing-up-new-one</a></p>
  <p>The solution to us was multifaceted.  First, we needed to set <code>MaxUnavailable = 0</code> and <code>MaxSurge=2</code>.  We then needed to setup a persistent volume claim, so that the pods could share disk.  If each pod has its own disk, then the pods would just hang, as the second pod is never &quot;available&quot; to take over.</p>
  
Answers: CC BY-SA 4.0
Answers: 2021-03-03T14:26:32.437Z
Answers: 2021-03-03T14:26:32.437Z
Answers: Adam Hughes
Answers: <blockquote>
  <p>Is there anyway to configure K8s to actually bring up a new pod, direct new traffic to it, and only then shutdown the old pod?</p>
  </blockquote>
  <p>This is the default behavior. <a href="https://kubernetes.io/docs/concepts/workloads/controllers/deployment/#max-surge" rel="nofollow noreferrer">MaxSurge</a> is number of <em>additional</em> pods that runs during upgrade.</p>
  <p>What you also have to check is how the load balancer is handling traffic, does it have capability to detect that you have deployed a new Pod, e.g. is it Kubernetes aware? See <a href="https://cloud.google.com/kubernetes-engine/docs/how-to/container-native-load-balancing" rel="nofollow noreferrer">Container native load balancing on Google Cloud</a>, it looks like you should have a <code>ReadinessProbe</code> on your <code>Deployment</code>.</p>
  <blockquote>
  <p>Actually I realized what's happening is that the pod is getting traffic routed to it before the app is actually completely ready.</p>
  </blockquote>
  <p>This is the default behavior, if you define a <a href="https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/" rel="nofollow noreferrer">ReadinessProbe</a> for your <code>Deployment</code>. As you write, you can also add a <code>StartupProbe</code> but the <code>ReadinessProbe</code> is most important.</p>
  
Answers: CC BY-SA 4.0
Answers: 2021-02-23T18:22:23.553Z
Answers: Ah awesome.  Let me try it out!  Thank you for pointing me in the right direction.  I'll accept the answer after I see if that solves it, and digest the other link you've sent me...
Answers: Adam Hughes
Answers: CC BY-SA 4.0
Answers: 2021-02-27T00:00:11.510Z
Answers: Please see updated question if still interestd - maxsurge was not the issue
Answers: Adam Hughes
Answers: CC BY-SA 4.0
Answers: 2021-02-27T06:41:27.847Z
Answers: I have updated, but I had already answered that you need a ReadinessProbe - so no really change.
Answers: Jonas
Answers: CC BY-SA 4.0
Answers: 2021-02-28T15:55:49.370Z
Answers: Ok thanks - sorry I didn't pay close enough attention!
Answers: Adam Hughes
Answers: CC BY-SA 4.0
Answers: 2021-02-23T18:06:46.813Z
Answers: 2021-02-27T06:39:00.120Z
Answers: 2021-02-27T06:39:00.120Z
Answers: Jonas
Answers: <p>I would suggest you go with ReadinessProbe. So, with this, your application can say that &quot;I am ready to receive the traffic&quot; then the current running pod is ready to be terminated.</p>
  <p>Note that it is different to LivenessProbe where it means &quot;I am alive&quot;, &quot;but not yet ready to serve the traffic&quot;.</p>
  
Answers: CC BY-SA 4.0
Answers: 2023-10-30T13:58:06.597Z
Answers: 2023-10-30T13:58:06.597Z
Answers: Justin Nguyen
Body: <p>I've inherited an app with K8s services with the following config</p>
  <pre><code>spec:
    ...
    replicas: 1
    strategy:
      rollingUpdate:
        maxSurge: 1
        maxUnavailable: 1
      type: RollingUpdate
  </code></pre>
  <p>For most of these light-weight services, we run a single instance of a pod on GCP.  We're expanding into blue-green deploys for some services, but the majority are still run this way.</p>
  <p>When we update the GCR image to a new version, the service becomes temporarily unavailable (maybe 10-30 seconds).  I'm assuming this is because K8s is killing the old pod while it brings up the new pod.  Is there anyway to configure K8s to actually bring up a new pod, direct new traffic to it, and only then shutdown the old pod?  This would seemingly allow for a deployment with no downtime, and not rely on having two pods running all the time (saving cost).  All docs I can find typically start with N pods so they don't have this issue...</p>
  <hr />
  <h2>UPDATE</h2>
  <p>So the issue is not related to maxsurge (changing it had no effect).  Actually I realized what's happening is that the pod is getting traffic routed to it before the app is actually completely ready.  These are spring apps, so they take like 30 seconds to start, and the service disruption we're seeing is occurring in the 30s window while the app is booting and the pod has already sent traffic to it.  So I guess what I really am after is as follows</p>
  <p><strong>how can k8s be configured to bring up a second pod, wait until it passes startup probe/healthcheck, and only then have the first pod route traffic to it and self-terminate?</strong></p>
  
Comments: CC BY-SA 4.0
Comments: 2021-02-25T03:49:33.007Z
Comments: Hi Adam! Could you please replace the screenshot with a code snippet? This will make it easier to find this question.
Comments: Bruce Becker
Tags: <kubernetes><gcp>
Title: Can we do zero-downtime kubernetes deployment with a single pod?
UserDisplayName: Adam Hughes
ThreadText: # Can we do zero-downtime kubernetes deployment with a single pod?
  
  (Asked by: username_0 on 2021-02-23)
  
  I've inherited an app with K8s services with the following config
  
  ```
  spec:
    ...
    replicas: 1
    strategy:
      rollingUpdate:
        maxSurge: 1
        maxUnavailable: 1
      type: RollingUpdate
  
  ```
  
  For most of these light-weight services, we run a single instance of a pod on GCP. We're expanding into blue-green deploys for some services, but the majority are still run this way.
  
  When we update the GCR image to a new version, the service becomes temporarily unavailable (maybe 10-30 seconds). I'm assuming this is because K8s is killing the old pod while it brings up the new pod. Is there anyway to configure K8s to actually bring up a new pod, direct new traffic to it, and only then shutdown the old pod? This would seemingly allow for a deployment with no downtime, and not rely on having two pods running all the time (saving cost). All docs I can find typically start with N pods so they don't have this issue...
  
  ---
  
  ## UPDATE
  
  So the issue is not related to maxsurge (changing it had no effect). Actually I realized what's happening is that the pod is getting traffic routed to it before the app is actually completely ready. These are spring apps, so they take like 30 seconds to start, and the service disruption we're seeing is occurring in the 30s window while the app is booting and the pod has already sent traffic to it. So I guess what I really am after is as follows
  
  **how can k8s be configured to bring up a second pod, wait until it passes startup probe/healthcheck, and only then have the first pod route traffic to it and self-terminate?**
  
  **Tags:** kubernetes, gcp
  
  > **Comments:**
  > **username_1**: Hi username_0! Could you please replace the screenshot with a code snippet? This will make it easier to find this question.  
  
  ---
  
  ## 3 answers
  
  ### Answer by username_0 on 2021-03-03. Score: 0 | Accepted answer
  
  The difficulties we encountered with a single pod rolling update are already explained here:
  
  <https://stackoverflow.com/questions/46369100/kubernetes-rolling-update-killing-off-old-pod-without-bringing-up-new-one>
  
  The solution to us was multifaceted. First, we needed to set `MaxUnavailable = 0` and `MaxSurge=2`. We then needed to setup a persistent volume claim, so that the pods could share disk. If each pod has its own disk, then the pods would just hang, as the second pod is never "available" to take over.
  
  
  ---
  
  ### Answer by username_2 on 2021-02-23. Score: 5
  
  > Is there anyway to configure K8s to actually bring up a new pod, direct new traffic to it, and only then shutdown the old pod?
  
  This is the default behavior. [MaxSurge](https://kubernetes.io/docs/concepts/workloads/controllers/deployment/#max-surge) is number of *additional* pods that runs during upgrade.
  
  What you also have to check is how the load balancer is handling traffic, does it have capability to detect that you have deployed a new Pod, e.g. is it Kubernetes aware? See [Container native load balancing on Google Cloud](https://cloud.google.com/kubernetes-engine/docs/how-to/container-native-load-balancing), it looks like you should have a `ReadinessProbe` on your `Deployment`.
  
  > Actually I realized what's happening is that the pod is getting traffic routed to it before the app is actually completely ready.
  
  This is the default behavior, if you define a [ReadinessProbe](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/) for your `Deployment`. As you write, you can also add a `StartupProbe` but the `ReadinessProbe` is most important.
  
  > **Comments:**
  > **username_0**: Ah awesome.  Let me try it out!  Thank you for pointing me in the right direction.  I'll accept the answer after I see if that solves it, and digest the other link you've sent me...  
  > **username_0**: Please see updated question if still interestd - maxsurge was not the issue  
  > **username_2**: I have updated, but I had already answered that you need a ReadinessProbe - so no really change.  
  > **username_0**: Ok thanks - sorry I didn't pay close enough attention!  
  
  ---
  
  ### Answer by username_3 on 2023-10-30. Score: 0
  
  I would suggest you go with ReadinessProbe. So, with this, your application can say that "I am ready to receive the traffic" then the current running pod is ready to be terminated.
  
  Note that it is different to LivenessProbe where it means "I am alive", "but not yet ready to serve the traffic".
  
  
  ---
  
  