<p>I want rollback deployment for my pods. I'm updating my pod using <code>set Image</code> in a CI environment. When I set maxUnavailable on Deployment/web file to 1, I get downtime. but when I set maxUnavailable to 0, The pods doesnot get replaced and container / app is not restarted. </p>

<p>Also I Have a single Node in Kubernetes cluster and Here's its info </p>

<pre><code>    Allocated resources:
      (Total limits may be over 100 percent, i.e., overcommitted.)
      CPU Requests  CPU Limits  Memory Requests  Memory Limits
      ------------  ----------  ---------------  -------------
      881m (93%)    396m (42%)  909712Ki (33%)   1524112Ki (56%)
    Events:         &lt;none&gt;
</code></pre>

<p>Here's the complete YAML file. I do have readiness Probe set. </p>

<pre><code>            apiVersion: extensions/v1beta1
            kind: Deployment
            metadata:
              annotations:
                deployment.kubernetes.io/revision: "10"
                kompose.cmd: C:\ProgramData\chocolatey\lib\kubernetes-kompose\tools\kompose.exe
                  convert
                kompose.version: 1.14.0 (fa706f2)
                kubectl.kubernetes.io/last-applied-configuration: |
                  {"apiVersion":"extensions/v1beta1","kind":"Deployment","metadata":{"annotations":{"kompose.cmd":"C:\\ProgramData\\chocolatey\\lib\\kubernetes-kompose\\tools\\kompose.exe convert","kompose.version":"1.14.0 (fa706f2)"},"creationTimestamp":null,"labels":{"io.kompose.service":"dev-web"},"name":"dev-web","namespace":"default"},"spec":{"replicas":1,"strategy":{},"template":{"metadata":{"labels":{"io.kompose.service":"dev-web"}},"spec":{"containers":[{"env":[{"name":"JWT_KEY","value":"ABCD"},{"name":"PORT","value":"2000"},{"name":"GOOGLE_APPLICATION_CREDENTIALS","value":"serviceaccount/quick-pay.json"},{"name":"mongoCon","value":"mongodb://quickpayadmin:quickpay1234@ds121343.mlab.com:21343/quick-pay-db"},{"name":"PGHost","value":"173.255.206.177"},{"name":"PGUser","value":"postgres"},{"name":"PGDatabase","value":"quickpay"},{"name":"PGPassword","value":"z33shan"},{"name":"PGPort","value":"5432"}],"image":"gcr.io/quick-pay-208307/quickpay-dev-node:latest","imagePullPolicy":"Always","name":"dev-web-container","ports":[{"containerPort":2000}],"readinessProbe":{"failureThreshold":3,"httpGet":{"path":"/","port":2000,"scheme":"HTTP"},"initialDelaySeconds":5,"periodSeconds":5,"successThreshold":1,"timeoutSeconds":1},"resources":{"requests":{"cpu":"20m"}}}]}}}}
              creationTimestamp: 2018-12-24T12:13:48Z
              generation: 12
              labels:
                io.kompose.service: dev-web
              name: dev-web
              namespace: default
              resourceVersion: "9631122"
              selfLink: /apis/extensions/v1beta1/namespaces/default/deployments/web
              uid: 5e66f7b3-0775-11e9-9653-42010a80019d
            spec:
              progressDeadlineSeconds: 600
              replicas: 2
              revisionHistoryLimit: 10
              selector:
                matchLabels:
                  io.kompose.service: web
              strategy:
                rollingUpdate:
                  maxSurge: 1
                  maxUnavailable: 0
                type: RollingUpdate
              template:
                metadata:
                  creationTimestamp: null
                  labels:
                    io.kompose.service: web
                spec:
                  containers:
                  - env:
                    - name: PORT
                      value: "2000"

                    image: gcr.io/myimagepath/web-node
                    imagePullPolicy: Always
                    name: web-container
                    ports:
                    - containerPort: 2000
                      protocol: TCP
                    readinessProbe:
                      failureThreshold: 10
                      httpGet:
                        path: /
                        port: 2000
                        scheme: HTTP
                      initialDelaySeconds: 10
                      periodSeconds: 10
                      successThreshold: 1
                      timeoutSeconds: 10
                    resources:
                      requests:
                        cpu: 10m
                    terminationMessagePath: /dev/termination-log
                    terminationMessagePolicy: File
                  dnsPolicy: ClusterFirst
                  restartPolicy: Always
                  schedulerName: default-scheduler
                  securityContext: {}
                  terminationGracePeriodSeconds: 30
            status:
              availableReplicas: 2
              conditions:
              - lastTransitionTime: 2019-01-03T05:49:46Z
                lastUpdateTime: 2019-01-03T05:49:46Z
                message: Deployment has minimum availability.
                reason: MinimumReplicasAvailable
                status: "True"
                type: Available
              - lastTransitionTime: 2018-12-24T12:13:48Z
                lastUpdateTime: 2019-01-03T06:04:24Z
                message: ReplicaSet "dev-web-7bd498fc74" has successfully progressed.
                reason: NewReplicaSetAvailable
                status: "True"
                type: Progressing
              observedGeneration: 12
              readyReplicas: 2
              replicas: 2
              updatedReplicas: 2
</code></pre>

<p>I've tried with 1 replica and it still doesnot work. </p>

<p>In first scenario, Kubernetes deletes one pod (<code>maxUnavailable: 1</code>) and started the pod with new image and waits for ~110 seconds(based on your readiness probe) to check if new pod is able to serve request. New pod isn't able to serve requests but the pod is in running state and hence it delete the second old pod and started it with new image and again second pod waits for the readiness probe to complete. This is the reason there is some time in between where both the containers are not ready to serve request and hence the downtime.</p>
<p>In second scenario, where you have <code>maxUnavailable:0</code>, Kubernetes first brings up the pod with new image and it isn't able to serve the request in ~110 seconds(based on your readiness probe) and hence it times out and deletes the new pod with new image. Same happens with the second pod. Hence both your pod do not get updated</p>
<p>So the reason is that you are not giving enough time to your application to come up and start serving requests. You can increase the value of <code>failureThreshold</code> in your readiness probe and <code>maxUnavailable: 0</code>, it will work.</p>
