<p>I have a <code>webapp</code> running on Kubernetes on 2 pods.</p>

<p>I edit my deployment with a new image version, from <code>webapp:v1</code> to <code>webapp:v2</code>.</p>

<p>I figure an issue during the rolling out...</p>

<pre><code>podA is v2
podB is still v1

html is served from podA
with a &lt;link&gt; to styles.css

styles.css is served from podB
with v1 styles

=&gt; html v2 + css v1 = 💥
</code></pre>

<hr>

<p>How can I be guaranteed, that all subsequent requests will be served from the same pod, or a pod with the same version that the html served?</p>

abernier
<blockquote>
  <p>How can I be guaranteed, that all subsequent requests will be served from the same pod, or a pod with the same version that the html served?</p>
</blockquote>

<p>Even if you do this, you will still have problems. Especially if your app is a single-page application. Consider this:</p>

<ul>
<li>User enters your website, gets <code>index.html</code> v1 </li>
<li>You release webapp:v2. After a few minutes, all the pods are running v2.</li>
<li>The user still has the webapp opened, with <code>index.html</code> v1</li>
<li>The user navigates in the app. This needs to load <code>styles.css</code>. The user gets <code>styles.css</code> v2. Boom, you're mixing versions, fail.</li>
</ul>

<p>I've run into this issue in production, and it's a pain to solve. In my experience, the best solution is:</p>

<ul>
<li>Tag all the resources (css, js, imgs, etc) with a version suffix (eg <code>styles.css</code> -> <code>styles-v1.css</code>, or a hash of the file contents <code>styles-39cf1a0b.css</code>). Many tools such as webpack, gulp, etc can do this automatically.</li>
<li><code>index.html</code> is not tagged, but it does reference the other resources with the right tag.</li>
<li>When deploying, do not delete the resources for older versions, just merge them with the newest ones. Make sure clients that have an old <code>index.html</code> can still get them succesfully.</li>
<li>Delete old resources after a few versions, or better, after a period of time passes (maybe 1 week?).</li>
</ul>

<p>With this, the above scenario now works fine!</p>

<ul>
<li>User enters your website, gets <code>index.html</code> v1 </li>
<li>You release webapp:v2. This replaces <code>index.html</code>, but leaves all the js/css in place, adding new ones with the new version suffix.</li>
<li>The user still has the webapp opened, with <code>index.html</code> v1</li>
<li>The user navigates in the app. This needs to load <code>styles-v1.css</code>, which loads successfully and matches the index.html version. No version mixing = good!</li>
<li>Next time the user reloads the page, they get <code>index.html</code> v2, which points to the new <code>styles-v2.css</code>, etc. Still no version mixing!</li>
</ul>

<p>Doing this with kubernetes is a bit tricky, you need to make your image build process take the files from a few older images and include them inside the new image, which is a bit strange.</p>

<p>Another solution is to stop serving your html/css/js from a pod, and serve it from blob storage instead. (Amazon S3, Google Cloud Storage, etc). This way, a deployment is just copying all the files, which get merged with the old files, giving you the desired behavior.</p>
