<p>I have a requirement to deploy an HTTP application in K8s with zero downtime. I also have a restriction of using a <strong>single pod (replica=1)</strong>. But the problem is when I did that some of the HTTP requests get 502 Bad gateway when I did some changes to the K8s pod.</p>

<p>I refer the following two issues <a href="https://github.com/kubernetes/ingress-nginx/issues/489" rel="nofollow noreferrer">[1]</a> <a href="https://github.com/kubernetes/ingress-nginx/issues/322" rel="nofollow noreferrer">[2]</a>, but those issues work fine when I have more than a single replica. For a single replica, NGINX ingress still has a slight downtime which is less than 1 millisecond.</p>

<p>The lifecycle spec and rolling updates spec of my deployment set as below according to the answers given by the above issues <a href="https://github.com/kubernetes/ingress-nginx/issues/489" rel="nofollow noreferrer">[1]</a> <a href="https://github.com/kubernetes/ingress-nginx/issues/322" rel="nofollow noreferrer">[2]</a>.</p>

<pre><code> spec:
  strategy:
    rollingUpdate:
      maxSurge: 2
      maxUnavailable: 0
    type: RollingUpdate
    ...
    spec:
        ....
        lifecycle:
          preStop:
            exec:
              command:
              - sleep
              - "30"
</code></pre>

<p>Note that I have config maps that mount to this deployment. I'm not sure that would affect this downtime or not.</p>

<p>Also, I refer to these two blogs <a href="https://blog.sebastian-daschner.com/entries/zero-downtime-updates-kubernetes" rel="nofollow noreferrer">[3]</a> <a href="http://rahmonov.me/posts/zero-downtime-deployment-with-kubernetes/" rel="nofollow noreferrer">[4]</a>, but they did not solve my problem too. But when I refer this blog <a href="http://rahmonov.me/posts/zero-downtime-deployment-with-kubernetes/" rel="nofollow noreferrer">[4]</a> it shows that K8s can achieve zero downtime even with a single replica. Unfortunately, in <a href="http://rahmonov.me/posts/zero-downtime-deployment-with-kubernetes/" rel="nofollow noreferrer">[4]</a> he did not use an ingress-nginx controller. </p>

<p>In brief, I wanted to know that, is it possible to achieve zero-downtime in ingress-nginx with a single replication of pod?</p>

<p>References</p>

<p><a href="https://github.com/kubernetes/ingress-nginx/issues/489" rel="nofollow noreferrer">1</a> <a href="https://github.com/kubernetes/ingress-nginx/issues/489" rel="nofollow noreferrer">https://github.com/kubernetes/ingress-nginx/issues/489</a></p>

<p><a href="https://github.com/kubernetes/ingress-nginx/issues/322" rel="nofollow noreferrer">2</a> <a href="https://github.com/kubernetes/ingress-nginx/issues/322" rel="nofollow noreferrer">https://github.com/kubernetes/ingress-nginx/issues/322</a></p>

<p><a href="https://blog.sebastian-daschner.com/entries/zero-downtime-updates-kubernetes" rel="nofollow noreferrer">3</a> <a href="https://blog.sebastian-daschner.com/entries/zero-downtime-updates-kubernetes" rel="nofollow noreferrer">https://blog.sebastian-daschner.com/entries/zero-downtime-updates-kubernetes</a></p>

<p><a href="http://rahmonov.me/posts/zero-downtime-deployment-with-kubernetes/" rel="nofollow noreferrer">4</a> <a href="http://rahmonov.me/posts/zero-downtime-deployment-with-kubernetes/" rel="nofollow noreferrer">http://rahmonov.me/posts/zero-downtime-deployment-with-kubernetes/</a></p>

<p>I suppose that your single-pod restriction is at runtime and not during the upgrade, otherwise, you can't achieve your goal.</p>
<p>My opinion is your rolling upgrade strategy is good, you can add a <a href="https://kubernetes.io/docs/tasks/run-application/configure-pdb/" rel="nofollow noreferrer">PodDistruptionBudget</a> to manage <a href="https://kubernetes.io/docs/concepts/workloads/pods/disruptions/" rel="nofollow noreferrer">disruptions</a> to be sure that at least 1 pod is available.</p>
<pre><code>apiVersion: policy/v1beta1
kind: PodDisruptionBudget
metadata:
  name: sample-pdb
spec:
  minAvailable: 1
  selector:
    matchLabels:
      &lt;your_app_label&gt;
</code></pre>
<p>Another very important thing is the <a href="https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/" rel="nofollow noreferrer">probes</a>, according to documentation:</p>
<blockquote>
<p>The kubelet uses liveness probes to know when to restart a Container. For example, liveness probes could catch a deadlock, where an application is running, but unable to make progress. Restarting a Container in such a state can help to make the application more available despite bugs.</p>
<p>The kubelet uses readiness probes to know when a Container is ready to start accepting traffic. A Pod is considered ready when all of its Containers are ready. One use of this signal is to control which Pods are used as backends for Services. When a Pod is not ready, it is removed from Service load balancers.</p>
</blockquote>
<p>You should set the liveness probe, but most of all the readiness probe, to return a success response only when your new pod is really ready to accept a new connection, otherwise k8s think that the new pod is up and the old pod will be destroyed before the new one can accept connections.</p>
