<p>I have a Kubernetes cluster with the following components(Nginx-ingress).
<a href="https://i.stack.imgur.com/pVzKw.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/pVzKw.png" alt="enter image description here" /></a></p>
<p>When I deploy a new version of the Tomcat, old ones will stick around for a while(for application reasons) maybe like 10 minutes then they will die. For a short period of time, some users will connect to the old pods and some will connect to new ones. Users who connect to V2 of tomcat need to get the new static assets meaning they need to connect to Apache v2. The problem is that even if I keep both versions of the apache around for the same amount of the time, how am I going to make sure users with the new version of tomcat connect to the new version of apache and users with the old version of tomcat connect to the old version of apache? I want apache pods to be stateless.</p>

<p>I think you should try the blue green deployment model.</p>
<blockquote>
<p>A blue/green deployment is a change management strategy for releasing software code. Blue/green deployments, which may also be referred to as A/B deployments require two identical hardware environments that are configured exactly the same way. While one environment is active and serving end users, the other environment remains idle.</p>
</blockquote>
<p>Container technology offers a stand-alone environment to run the desired service, which makes it super easy to create identical environments as required in the blue/green deployment. The loosely coupled Services - ReplicaSets, and the label/selector-based service routing in Kubernetes make it easy to switch between different backend environments. With these techniques, the blue/green deployments in Kubernetes can be done as follows:</p>
<ul>
<li>Before the deployment, the infrastructure is prepared like so:
<ul>
<li>Prepare the blue deployment and green deployment with TOMCAT_VERSION=7 and TARGET_ROLE set to blue or green respectively.</li>
</ul>
</li>
</ul>
<pre class="lang-yaml prettyprint-override"><code>apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: tomcat-deployment-${TARGET_ROLE}
spec:
  replicas: 2
  template:
    metadata:
      labels:
        app: tomcat
        role: ${TARGET_ROLE}
    spec:
      containers:
      - name: tomcat-container
        image: tomcat:${TOMCAT_VERSION}
        ports:
        - containerPort: 8080
        readinessProbe:
          httpGet:
            path: /
            port: 8080
</code></pre>
<p>Prepare the public service endpoint, which initially routes to one of the backend environments, say TARGET_ROLE=blue.</p>
<pre class="lang-yaml prettyprint-override"><code>kind: Service
apiVersion: v1
metadata:
  name: tomcat-service
  labels:
    app: tomcat
    role: ${TARGET_ROLE}
    env: prod
spec:
  type: LoadBalancer
  selector:
    app: tomcat
    role: ${TARGET_ROLE}
  ports:
    - port: 80
      targetPort: 8080
</code></pre>
<p>Optionally, prepare a test endpoint so that we can visit the backend environments for testing. They are similar to the public service endpoint, but they are intended to be accessed internally by the dev/ops team only.</p>
<pre class="lang-yaml prettyprint-override"><code>kind: Service
apiVersion: v1
metadata:
  name: tomcat-test-${TARGET_ROLE}
  labels:
    app: tomcat
    role: test-${TARGET_ROLE}
spec:
  type: LoadBalancer
  selector:
    app: tomcat
    role: ${TARGET_ROLE}
  ports:
    - port: 80
      targetPort: 8080
</code></pre>
<ul>
<li>Update the application in the inactive environment, say green environment. Set TARGET_ROLE=green and TOMCAT_VERSION=8 in the deployment config to update the green environment.</li>
<li>Test the deployment via the tomcat-test-green test endpoint to ensure the green environment is ready to serve client traffic.</li>
<li>Switch the frontend Service routing to the green environment by updating the Service config with TARGET_ROLE=green.</li>
<li>Run additional tests on the public endpoint to ensure it is working properly.</li>
<li>Now the blue environment is idle and we can:
<ul>
<li>leave it with the old application so that we can roll back if there's issue with the new application</li>
<li>update it to make it a hot backup of the active environment</li>
<li>reduce its replica count to save the occupied resources</li>
</ul>
</li>
</ul>
<p><a href="https://i.stack.imgur.com/48ho2.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/48ho2.png" alt="enter image description here" /></a></p>
<p>As compared to Rolling Update, the blue/green up* The public service is either routed to the old applications, or new applications, but never both at the same time.</p>
<ul>
<li>The time it takes for the new pods to be ready does not affect the public service quality, as the traffic will only be routed to the new pods when all of them are tested to be ready.</li>
<li>We can do comprehensive tests on the new environment before it serves any public traffic. Just keep in mind this is in production, and the tests should not pollute live application data.</li>
</ul>
<p><a href="https://kubernetes.io/blog/2018/04/30/zero-downtime-deployment-kubernetes-jenkins/" rel="nofollow noreferrer">References</a></p>
