<p>Assuming I have a Kubernetes Deployment object with the <code>Recreate</code> strategy and I update the Deployment with a new container image version. Kubernetes will:</p>
<ol>
<li>scale down/kill the existing Pods of the Deployment,</li>
<li>create the new Pods,</li>
<li>which will pull the new container images</li>
<li>so the new containers can finally run.</li>
</ol>
<p>Of course, the <code>Recreate</code> strategy is exepected to cause a downtime between steps 1 and 4, where no Pod is actually running. However, step 3 can take a lot of time if the container images in question are or the container registry connection is slow, or both. In a test setup (Azure Kubernetes Services pulling a Windows container image from Docker Hub), I see it taking 5 minutes and more, which makes for a really long downtime.</p>
<p>So, what is a good option to reduce that downtime? Can I somehow get Kubernetes to pull the new images before killing the Pods in step 1 above? (Note that the solution should work with Windows containers, which are notoriously large, in case that is relevant.)</p>
<p>On the Internet, I have found <a href="https://codefresh.io/kubernetes-tutorial/single-use-daemonset-pattern-pre-pulling-images-kubernetes/" rel="nofollow noreferrer">this Codefresh article using a DaemonSet and Docker in Docker</a>, but I guess <a href="https://kubernetes.io/blog/2020/12/02/dont-panic-kubernetes-and-docker/#so-why-the-confusion-and-what-is-everyone-freaking-out-about" rel="nofollow noreferrer">Docker in Docker is no longer compatible with containerd</a>.</p>
<p>I've also found <a href="https://stackoverflow.com/a/59588935/62838">this StackOverflow answer</a> that suggests using an Azure Container Registry with Project Teleport, but that is in private preview and doesn't support Windows containers yet. Also, it's specific to Azure Kubernetes Services, and I'm looking for a more general solution.</p>
<p>Surely, this is a common problem that has a &quot;standard&quot; answer?</p>
<p><strong>Update 2021-12-21:</strong> Because I've got a corresponding answer, I'll clarify that I cannot easily change the deployment strategy. The application in question does not support running Pods of different versions at the same time because it uses a database that needs to be migrated to the corresponding application version, without forwards or backwards compatibility.</p>

<p>Via <a href="https://www.reddit.com/r/kubernetes/comments/oeruh9/can_kubernetes_prepull_and_cache_images/" rel="nofollow noreferrer">https://www.reddit.com/r/kubernetes/comments/oeruh9/can_kubernetes_prepull_and_cache_images/</a>, I've found these ideas:</p>
<ul>
<li>Implement a DaemonSet that runs a &quot;sleep&quot; loop on all the images I need.</li>
<li>Use <a href="http://github.com/mattmoor/warm-image" rel="nofollow noreferrer">http://github.com/mattmoor/warm-image</a>, which has no Windows support.</li>
<li>Use <a href="https://github.com/ContainerSolutions/ImageWolf" rel="nofollow noreferrer">https://github.com/ContainerSolutions/ImageWolf</a>, which says, &quot;ImageWolf is currently alpha software and intended as a PoC - please don't run it in production!&quot;</li>
<li>Use <a href="https://github.com/uber/kraken" rel="nofollow noreferrer">https://github.com/uber/kraken</a>, which seems to be a registry, not a pre-pulling solution.</li>
<li>Use <a href="https://github.com/dragonflyoss/Dragonfly" rel="nofollow noreferrer">https://github.com/dragonflyoss/Dragonfly</a> (now <a href="https://github.com/dragonflyoss/Dragonfly2" rel="nofollow noreferrer">https://github.com/dragonflyoss/Dragonfly2</a>), which also seems to do somethings completely different.</li>
<li>Use <a href="https://github.com/senthilrch/kube-fledged" rel="nofollow noreferrer">https://github.com/senthilrch/kube-fledged</a>, which looks exactly right and more mature than the others, but <a href="https://github.com/senthilrch/kube-fledged/issues/118" rel="nofollow noreferrer">has no Windows support</a>.</li>
<li>Use <a href="https://github.com/dcherman/image-cache-daemon" rel="nofollow noreferrer">https://github.com/dcherman/image-cache-daemon</a>, which <a href="https://hub.docker.com/r/exiges/image-cache-daemon/tags" rel="nofollow noreferrer">has no Windows support</a>.</li>
<li>Use <a href="https://goharbor.io/blog/harbor-2.1/" rel="nofollow noreferrer">https://goharbor.io/blog/harbor-2.1/</a>, which also seems to be a registry, not a pre-pulling solution.</li>
<li>Use <a href="https://openkruise.io/docs/user-manuals/imagepulljob/" rel="nofollow noreferrer">https://openkruise.io/docs/user-manuals/imagepulljob/</a>, which also looks right, but a) OpenKruise is huge and I'm not sure I want to install this just to preload images, and b) it seems <a href="https://hub.docker.com/r/openkruise/kruise-manager/tags" rel="nofollow noreferrer">it has no Windows support</a>.</li>
</ul>
<p>So, it seems I have to implement this on my own, with a DaemonSet. I still hope someone can provide a better answer than this one 🙂 .</p>
