<?xml version="1.0" encoding="utf-8" standalone="yes"?><?xml-stylesheet type="text/xsl" href="/index.xsl"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>./techtipsy</title><link>https://ounapuu.ee/tags/kubernetes/</link><description>Recent content on ./techtipsy, a blog written by Herman Õunapuu.</description><generator>Hugo -- gohugo.io</generator><language>en-GB</language><managingEditor>ihavesomethoughtsonyourblog@ounapuu.ee (Herman Õunapuu)</managingEditor><webMaster>ihavesomethoughtsonyourblog@ounapuu.ee (Herman Õunapuu)</webMaster><lastBuildDate>Tue, 01 Oct 2024 06:00:00 +0300</lastBuildDate><atom:link href="https://ounapuu.ee/tags/kubernetes/index.xml" rel="self" type="application/rss+xml"/><item><title>So you want to migrate to Kubernetes: observations from a software developer</title><link>https://ounapuu.ee/posts/2024/10/01/kubernetes/</link><pubDate>Tue, 01 Oct 2024 06:00:00 +0300</pubDate><author>ihavesomethoughtsonyourblog@ounapuu.ee (Herman Õunapuu)</author><guid>https://ounapuu.ee/posts/2024/10/01/kubernetes/</guid><description>I'm not an expert in Kubernetes, but I've been involved in migrating services to it. Here are my observations.</description><content:encoded><![CDATA[<img src="https://ounapuu.ee/posts/2024/10/01/kubernetes/media/cover_hu_3c4db4d1998319c4.jpg" width="1200" height="630" alt="So you want to migrate to Kubernetes: observations from a software developer" /><p>Kubernetes: everyone wants to do it, regardless of their scale and business objectives.<sup id="fnref:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup></p>
<p>Common justifications include better scalability, cost savings, standardization and being super modern and stuff. It&rsquo;s
the future!</p>
<p>In my personal experience, Kubernetes is far from the magical uptime machine that a lot of people think it is, and
migrating it to it comes with a lot of hidden costs and potential downtime.</p>
<p>I&rsquo;m not a Kubernetes expert, but I&rsquo;ve been involved in a few Kubernetes migration projects and I have
<em><strong>opinions.</strong></em> Here are all the learnings and observations that I&rsquo;ve personally witnessed.</p>
<h2 id="migrations-are-complex">
  <a class="heading-anchor" href="#migrations-are-complex">Migrations are complex<svg class="heading-anchor__icon" viewBox="0 0 24 24" width="0.75em" height="0.75em" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg></a>
</h2>
<p>For most companies, using Kubernetes will mean planning and executing a migration project.</p>
<p>Assumptions will be made, estimates communicated and then the work begins. 90% of the migration will likely go
relatively smoothly, but the last
10% will result in the migration project blowing past any initial estimates that you had.</p>
<p>There will always be those teams and services that require more time due to conflicting priorities or unexpected
technical nuances popping up during testing.</p>
<p>It&rsquo;s the long tail that gets you.</p>
<h2 id="kubernetes-is-complex">
  <a class="heading-anchor" href="#kubernetes-is-complex">Kubernetes is complex<svg class="heading-anchor__icon" viewBox="0 0 24 24" width="0.75em" height="0.75em" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg></a>
</h2>
<p>Kubernetes is so complex that most people point you towards managed Kubernetes clusters provided by the big cloud
providers
as a starting point.<sup id="fnref:2"><a href="#fn:2" class="footnote-ref" role="doc-noteref">2</a></sup> To me, this is the best indication that we&rsquo;ve lost the plot.</p>
<p>Kubernetes is an abstraction layer on an already complicated
stack, and <a href="https://www.joelonsoftware.com/2002/11/11/the-law-of-leaky-abstractions/">abstractions tend to leak</a> at the
most inconvenient time.</p>
<p>There is nothing wrong about running plain old virtual machines as container hosts and scaling them vertically. Load
balancers and containers
are a stable and reliable technology by now, and individual servers have made a big
leap in performance over the past decade.</p>
<p>You&rsquo;re going to have to know about the fundamentals of where your service is running either way, so you might as well
keep the stack simple, understandable and easily debuggable, avoiding all the extra complexity.</p>
<p>There is no shame in <a href="https://boringtechnology.club/">choosing boring technology.</a></p>
<p>Shout-out to all the madlads who run Kubernetes at home <em><strong>for fun.</strong></em> I respect the hustle.</p>
<h2 id="kubernetes-will-only-start-making-sense-at-scale">
  <a class="heading-anchor" href="#kubernetes-will-only-start-making-sense-at-scale">Kubernetes will only start making sense at scale<svg class="heading-anchor__icon" viewBox="0 0 24 24" width="0.75em" height="0.75em" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg></a>
</h2>
<p>If your company doesn&rsquo;t have a fully staffed platform team (6-8 full-time employees), then you probably don&rsquo;t need
Kubernetes.</p>
<p>If you do, then you can start considering it, but know that it won&rsquo;t magically solve every issue that you have in your
tech organization. Your time might be better spent on tackling <em>those</em> issues first.</p>
<p>Kubernetes is great if you want to standardize how your workloads run, and with additional tooling and setup you can
end up with a pretty neat system where developers can set up new services on their own and easily monitor them
using your observability stack (Grafana, Prometheus etc.).</p>
<p>This requires a lot of effort though, from both your platform team and developers. This effort will be unreasonably high
for small startups and organizations, and my guesstimate is that using Kubernetes will start making sense if you have
100+ developers in your tech organization.</p>
<p>If you&rsquo;re a small team that has a setup that works for you, then continue using it. You&rsquo;re doing great!</p>
<p>If you only need a few Kubernetes features, such as autoscaling, health checks and rolling deployments, then you can
probably find a simple solution that works on your existing stack.</p>
<p>If you&rsquo;re just starting up, then don&rsquo;t use Kubernetes. My recommendation is to start
with a stupid simple stack that you know really well and scale it up vertically for as long as possible. Once that setup
does not work for you, you will probably have enough money and people to do the Kubernetes migration. It&rsquo;s a good
problem to have!</p>
<h2 id="let-your-developers-learn-kubernetes-before-migrating-to-it">
  <a class="heading-anchor" href="#let-your-developers-learn-kubernetes-before-migrating-to-it">Let your developers learn Kubernetes before migrating to it<svg class="heading-anchor__icon" viewBox="0 0 24 24" width="0.75em" height="0.75em" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg></a>
</h2>
<p>If you skip this part, then expect a lot of questions, blocking issues, missed deadlines, hasty debugging, lost
productivity and multiple production outages.</p>
<p>When I first dealt with Kubernetes, I had no idea what I was doing. I barely got to search what was the difference
between pods and nodes, how to package applications into containers and what the hell an ingress was<sup id="fnref:3"><a href="#fn:3" class="footnote-ref" role="doc-noteref">3</a></sup>. There was no
formal training or opportunities to take a few days to play around with Kubernetes before rolling it out to production.
I had to make sure my other work commitments got done in parallel.</p>
<p>It <em><strong>sucked</strong></em>.</p>
<p>I eventually got better at working with Kubernetes, mainly as a result of learning from production outages. This is
also training, but much more expensive compared to simply giving developers the opportunity to learn and experiment
in a sandbox.</p>
<p>After doing most of <a href="https://github.com/indrekots/kubernetes-the-much-harder-way">&ldquo;Kubernetes The Much Harder Way&rdquo;</a>, I
have a
vague understanding of what I&rsquo;m doing, but if the Kubernetes cluster were to completely fall over in an unexpected way,
I would still have no idea on how to even approach fixing it, or how to make sure that the cluster is properly secured.</p>
<p>One day long Kubernetes workshop organized by the company can go a long way in helping everyone get up to speed.
Just organize one <em><strong>before</strong></em> the migration.</p>
<h2 id="your-overworked-developers-wont-like-it">
  <a class="heading-anchor" href="#your-overworked-developers-wont-like-it">Your overworked developers won&rsquo;t like it<svg class="heading-anchor__icon" viewBox="0 0 24 24" width="0.75em" height="0.75em" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg></a>
</h2>
<p>During my 8+ years as a software developer, there was a push for developers to be full stack and to embrace the
operational side. I don&rsquo;t have anything against that, developers should be responsible for what they deploy and observe
the behaviour of their services diligently.</p>
<p>However, I&rsquo;ve also learned that a good chunk of developers don&rsquo;t want to mess with the full stack and want to focus on
their area of responsibility, which may involve more product-focused work. Throw in some inefficient meetings,
absurdly high expectations from the business side, and the time and tolerance for handling anything else goes way down.</p>
<p>The cognitive capacity for the average developer is limited. If your developers are already on that limit, and you
decide that <strong><em>we need some Kubernetes</em></strong> and developers need to be responsible for their own deployments, then you need
to expect some resistance and contempt towards you.</p>
<p>Even before you get to the Kubernetes part, you may also have to make sure that developers know the fundamentals about
where their service runs and what amount of resource consumption is appropriate for their service. Turns
out that this is not a given, especially in a fast-growth environment where teams and ownerships change often.</p>
<p>Oh, and developers might get very angry with you as every
Kubernetes-related frustration will be attributed to your platform team, even if it&rsquo;s an issue they themselves caused.
It&rsquo;s not fair, but it&rsquo;s how it may play out.</p>
<h2 id="your-application-code-has-made-assumptions-about-the-platform-its-running-on">
  <a class="heading-anchor" href="#your-application-code-has-made-assumptions-about-the-platform-its-running-on">Your application code has made assumptions about the platform it&rsquo;s running on<svg class="heading-anchor__icon" viewBox="0 0 24 24" width="0.75em" height="0.75em" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg></a>
</h2>
<p>If you don&rsquo;t have expert knowledge about the service that you&rsquo;re about to migrate to Kubernetes, then you&rsquo;ll likely
miss any assumptions that have been made in the application code itself.</p>
<p>Most common one is the assumption that there exists only one instance of your service at any time. You can
lift-and-shift
it to Kubernetes <em>as-is</em>, but then you won&rsquo;t be taking advantage of any scalability benefits that Kubernetes offers, so
what&rsquo;s the point?</p>
<p>There was also a case where a service was relying on local storage for temporarily storing tasks that had to be
picked up later. This made perfect sense on a virtual machine, but on Kubernetes the storage on the pods
is ephemeral, and pods have a habit of restarting for all sorts of reasons. This issue went unnoticed for quite a while
and
only became known after someone familiar with the service asked about it.
Adding a <a href="https://kubernetes.io/docs/concepts/storage/persistent-volumes/">persistent volume</a>
fixed this issue.</p>
<p>Some libraries and solutions can also make assumptions about the number of instances that your service has, or the
internal IP addresses that point to your service being static and predictable. Kubernetes breaks all of those
assumptions.</p>
<h2 id="you-still-need-a-platform-team">
  <a class="heading-anchor" href="#you-still-need-a-platform-team">You still need a platform team<svg class="heading-anchor__icon" viewBox="0 0 24 24" width="0.75em" height="0.75em" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg></a>
</h2>
<p>I&rsquo;ve seen claims that using Kubernetes will mean that you&rsquo;ll need fewer people on your platform team, especially if you
use a managed Kubernetes offering.</p>
<p>The reality is that you still need someone to make sure that even a managed Kubernetes instance stays up and running.
This involves mundane work, such as making sure that updates are applied correctly without breaking every workload,
or making sure that additional tooling bolted on to your Kubernetes cluster doesn&rsquo;t wreck the services that are running
on it.</p>
<p>Before the migration, your platform team answered questions and requests from developers, and wrangled whatever
infrastructure you had running.</p>
<p>During the migration, your platform team will be answering questions and requests for both setups while also setting up
Kubernetes and related infrastructure-as-code solutions, and unless you brought in more people before the migration,
they&rsquo;ll be overworked.</p>
<p>After the migration, your platform team will still be answering questions and requests, maintaining whatever
infrastructure-as-code
solutions you put in place, and making sure that Kubernetes stays running, which seems to take about the same number
of people as before, if not more.</p>
<p>If you managed to avoid burning out any engineers during the migration, then that&rsquo;s great!</p>
<p>If you managed to reduce headcount <em>after</em> a Kubernetes migration and it did not bite you in the ass years after the
fact, then please do let me know.</p>
<h2 id="kubernetes-wont-fix-your-legacy-monolith">
  <a class="heading-anchor" href="#kubernetes-wont-fix-your-legacy-monolith">Kubernetes won&rsquo;t fix your legacy monolith<svg class="heading-anchor__icon" viewBox="0 0 24 24" width="0.75em" height="0.75em" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg></a>
</h2>
<p>Kubernetes works really well with small services that start up within seconds and use relatively few resources.</p>
<p>The start-up time of your monolith is probably measured in minutes, and it likes to use all the CPU cores and RAM that
you
give it.</p>
<p>It can still run on Kubernetes, but certain aspects, such as scaling up fast in response to a spike in load, won&rsquo;t work
due to the long start-up time, or due to existing Kubernetes nodes not being able to accommodate your monolith without
slowly starting up new nodes. By the time more instances of your service start up, that temporary increase in load
might have already passed. Your performance still sucks and your resource usage graphs look like a poorly maintained
saw.</p>
<p>Your platform team will also be unhappy with these types of services as these big resource-hungry monoliths tend to
require the use of bigger nodes, and they might even end up impacting neighboring pods if configured improperly.</p>
<p>If you have set up tooling to ship service logs from your pods to a centralized location, then you might also find
that your high-traffic monolith is logging so much that the tooling can&rsquo;t keep up, resulting in logs going missing.
The root cause can be something as basic
as <a href="https://vector.dev/docs/reference/configuration/sources/kubernetes_logs/#glob_minimum_cooldown_ms">a default configuration value not working out</a>
for your <em>thicc</em> monolith, but by the time you get to that discovery, you&rsquo;ll have wasted a good number of hours or days
of productive work time.</p>
<h2 id="kubernetes-wont-magically-fix-your-performance-issues">
  <a class="heading-anchor" href="#kubernetes-wont-magically-fix-your-performance-issues">Kubernetes won&rsquo;t magically fix your performance issues<svg class="heading-anchor__icon" viewBox="0 0 24 24" width="0.75em" height="0.75em" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg></a>
</h2>
<p>Autoscaling is one of the features that a lot of Kubernetes users like.</p>
<p>You&rsquo;re having lunch and your service got really popular all of a sudden? No problem, your properly configured
<a href="https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/">HorizontalPodAutoscaler</a> can take care of
it!</p>
<p>Autoscaling can save your butt, but it can also introduce additional issues.</p>
<p>For example, deploying a new version of your service can fail
because you have too many instances of the service running. Databases, such
as <a href="https://www.postgresql.org/">PostgreSQL</a>,
have a limited number of database connections available. Each instance of your service using up N database connections.
If you don&rsquo;t account for deployments or autoscaling scenarios, then the new instances
will fail to start up because they cannot establish new database connections. It&rsquo;s a good idea to have a few instances'
worth of database connections set aside as a buffer.</p>
<p>Unless you&rsquo;re actually limited by physical constraints, such as CPU time, memory and network bandwidth, then Kubernetes
is unlikely to fix any performance issues. You&rsquo;re better off profiling your application, network and database
performance first and making sure that your observability stack gives you enough information to troubleshoot
performance issues.</p>
<h2 id="kubernetes-is-not-a-magical-uptime-machine">
  <a class="heading-anchor" href="#kubernetes-is-not-a-magical-uptime-machine">Kubernetes is not a magical uptime machine<svg class="heading-anchor__icon" viewBox="0 0 24 24" width="0.75em" height="0.75em" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg></a>
</h2>
<p>It really isn&rsquo;t.</p>
<p>At some point, you will have downtime because of a Kubernetes configuration issue, taking down your whole service.</p>
<p>Sometimes you&rsquo;ll involve additional tooling to make working with Kubernetes easier. That can also horrifically backfire
due to <a href="/posts/2024/04/04/helm-rollbljat/">circumstances not under your control.</a></p>
<p>You&rsquo;ll probably have system-wide latency spikes because a critical service got its pods restarted one by one,
and the new pods need to warm up their caches again. This is especially true
for <a href="https://en.wikipedia.org/wiki/Java_virtual_machine">JVM</a>-based services.</p>
<p>Misconfigured tooling can wreak havoc on your Kubernetes cluster. It&rsquo;s not fun to troubleshoot why all your pods
suddenly disappeared, only to find out later that <a href="https://karpenter.sh/">Karpenter</a> went on a pod massacre.</p>
<h2 id="vertical-scaling-can-go-a-long-way">
  <a class="heading-anchor" href="#vertical-scaling-can-go-a-long-way">Vertical scaling can go a long way<svg class="heading-anchor__icon" viewBox="0 0 24 24" width="0.75em" height="0.75em" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg></a>
</h2>
<p>If your current stack has a load balancer and a few containers, and you&rsquo;re not doing anything too inefficient,
then you can probably scale up vertically for a very long time.</p>
<p>Servers have made a big leap in performance and capability, resulting in
machines with 128+ CPU cores, <em>terabytes</em> of fast memory and lots of room for adding ridiculously fast SSD-based
storage.</p>
<p>You can already take advantage of this using your favourite cloud provider by picking a higher-tiered VM. You&rsquo;ll still
be
paying the cloud tax, but it&rsquo;s going to be cheaper than a Kubernetes cluster, and your stack will remain simple, fast
and portable.</p>
<p>If you want to go even further, you can buy 2+ physical servers, find a suitable location to host them,
and take full advantage of modern hardware. At a certain scale, this will be much cheaper than <em>the cloud</em>,
even if you need to hire somebody to manage, maintain and replace them. Physical servers aren&rsquo;t scary, and you&rsquo;ll need
knowledgeable platform people working for you either way, so why not cut out the complexity and expense of the cloud?<sup id="fnref:4"><a href="#fn:4" class="footnote-ref" role="doc-noteref">4</a></sup></p>
<h2 id="conclusion">
  <a class="heading-anchor" href="#conclusion">Conclusion<svg class="heading-anchor__icon" viewBox="0 0 24 24" width="0.75em" height="0.75em" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg></a>
</h2>
<p>Kubernetes is a perfectly good option to go with, but only at the right level of organizational size and maturity.
Unless you&rsquo;re at that level, you really don&rsquo;t need to worry about using it.</p>
<div class="footnotes" role="doc-endnotes">
<hr>
<ol>
<li id="fn:1">
<p>right after they&rsquo;re done implementing &ldquo;AI&rdquo; and LLM-s on a completely unsuitable use case.&#160;<a href="#fnref:1" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
<li id="fn:2">
<p>the only thing worse than managed Kubernetes is a poorly managed self-hosted one.&#160;<a href="#fnref:2" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
<li id="fn:3">
<p>turns out that it&rsquo;s a fancy name for a reverse proxy. You know, like <code>nginx</code>.&#160;<a href="#fnref:3" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
<li id="fn:4">
<p>there are benefits to using the cloud, but just like Kubernetes, cloud services have a narrow set of circumstances
where their use is appropriate.&#160;<a href="#fnref:4" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
</ol>
</div>
]]></content:encoded></item><item><title>How to take down production with a single Helm command</title><link>https://ounapuu.ee/posts/2024/04/04/helm-rollbljat/</link><pubDate>Thu, 04 Apr 2024 07:00:00 +0300</pubDate><author>ihavesomethoughtsonyourblog@ounapuu.ee (Herman Õunapuu)</author><guid>https://ounapuu.ee/posts/2024/04/04/helm-rollbljat/</guid><description>Incident? No, I prefer to call it a 'premature deprecation event'.</description><content:encoded><![CDATA[<img src="https://ounapuu.ee/posts/2024/04/04/helm-rollbljat/media/cover_hu_65f5793490f23546.jpg" width="1200" height="630" alt="How to take down production with a single Helm command" /><p>You&rsquo;re Cletus Kubernetus: a software developer, and a proud Fedora Linux
user.<sup id="fnref:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup></p>
<p>You know Kubernetes, especially after the time you migrated some services to it.</p>
<p><a href="https://www.youtube.com/watch?v=ia8Q51ouA_s&amp;pp=ygUGa3JhemFt">Everything is calm.</a></p>
<p>Your pods are running. Your service is up. Business as usual.</p>
<p>You release some minor changes to production. Everything is still working.
Great!</p>
<p>But then you receive a message from a colleague. Oh no, something has gone wrong
with a particular piece of
functionality!</p>
<p>No worries. You&rsquo;re using Helm. You can roll this change back safely. You ask
your colleague. &ldquo;Oh yeah, <code>helm rollback</code>
should work.&rdquo;</p>
<p><code>helm rollback</code> it is.</p>
<p>Cool, cool, new pod is starting up. Seems like it is indeed working.</p>
<p><strong>Wait, where did all the pods go?</strong></p>
<p>After a hectic troubleshooting session with the team, you redeploy the service
and start investigating. A colleague
uses the staging environment to do a <code>helm rollback</code> and it works as expected,
the previous version of the service
is successfully deployed.</p>
<p>You investigate logs. The <code>helm rollback</code> call worked as expected, and then it
began deleting every entity related to the
deployment. Pods, secrets, ingresses, <em>everything</em> related to the service was
gone, and your name was present on each
deletion.</p>
<p>The troubleshooting was on standby for a few days since you had no further leads
and had to get other work
done. But you couldn&rsquo;t really move on from this issue mentally, could you?</p>
<p>One day you continue the investigation by opening the Helm GitHub repository,
looking at the open issues and throwing in some
keywords that might be relevant, such as &ldquo;rollback&rdquo;.</p>
<p><a href="https://github.com/helm/helm/issues/12681">What the fuck.</a></p>
<p>It wasn&rsquo;t an issue with Helm, or the way you ran it. Apparently the version of
Helm packaged in Fedora Linux included
a patch that introduced this issue. You then use the staging environment to
reproduce the issue. Everything was gone, again, but this time in a safer
environment.</p>
<p>You promptly run <code>dnf remove -y helm</code>.</p>
<p>After this and
the <a href="https://openwall.com/lists/oss-security/2024/03/29/4">xz backdoor</a>, the
idea of living in the
countryside and learning beekeeping doesn&rsquo;t sound <em>that</em> bad, does it?</p>
<div class="footnotes" role="doc-endnotes">
<hr>
<ol>
<li id="fn:1">
<p>Credit for that name goes to my colleagues, I wish I was that funny.&#160;<a href="#fnref:1" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
</ol>
</div>
]]></content:encoded></item><item><title>Strangling your service with a Kubernetes misconfiguration</title><link>https://ounapuu.ee/posts/2022/04/18/strangling-your-service-with-kubernetes/</link><pubDate>Mon, 18 Apr 2022 06:00:00 +0300</pubDate><author>ihavesomethoughtsonyourblog@ounapuu.ee (Herman Õunapuu)</author><guid>https://ounapuu.ee/posts/2022/04/18/strangling-your-service-with-kubernetes/</guid><description>Short story about a fun and simple way to shoot yourself in the foot, Kubernetes style.</description><content:encoded><![CDATA[<img src="https://ounapuu.ee/media/cover_hu_4fe4cf2661554252.jpg" width="1200" height="630" alt="Strangling your service with a Kubernetes misconfiguration" /><p>This is a quick story about a fun discovery that I made a while ago.</p>
<p><em>For legal reasons, all of this is made up and no such service ever existed.</em></p>









<figure class="center">
  <a href="/posts/2022/04/18/strangling-your-service-with-kubernetes/media/thisisfine.jpg">
    <img src="/posts/2022/04/18/strangling-your-service-with-kubernetes/media/thisisfine_hu_6b59c5482301b18f.webp"
     width="1280"
     height="606"
     loading="lazy"
     decoding="async"
     alt="Accurate representation of the state of affairs in the project, circa 2019.">

  </a>
  <figcaption class="center">Accurate representation of the state of affairs in the project, circa 2019.</figcaption>
</figure>

<p>Once upon a time, we had this Java service that handled all the backend
work that you&rsquo;d expect to occur for a product with a web interface. The
service wasn&rsquo;t the newest thing on the block and had seen dozens of developers
work on it over many years.</p>
<p>At one point, it was moved to a Kubernetes cluster. That meant configuring all
the bits and pieces. In YAML, of course.</p>
<p>A couple of years ago I joined the project and started work on it. Things were
constantly on fire, so the fact that the service took anywhere from 5 to 15
minutes to deploy to the staging environment wasn&rsquo;t something I focused on.
After pushing a commit, the team either took a coffee break, went to play some
table tennis or started work on something else while the pipeline did its job.</p>
<p>It didn&rsquo;t help that running the service locally was hand-waved away as something
that was too impractical to do by people who had been in the project longer than
me, so the team simply relied on local tests and checking the staging
environment after they pushed a change.</p>
<p>A year or so later, I had enough. The project wasn&rsquo;t also constantly on fire,
only occasionally, so I decided to take the time to dig into our CI pipeline
configuration to see what is causing the pipeline to be so slow. My
investigation lead to Kubernetes configuration, specifically the part
where resource limits were configured. For whatever reason, I found that the
service was allowed an absurdly low CPU allocation, measured in millicores.</p>
<p>I increased the limit to something sensible, such as 1 full CPU core. The result?
The startup time of each pod took 30-40 seconds now, resulting in deployments that
took 2 to 3 minutes max. This is an insane improvement over the old deployments
that took up to 15 minutes regularly.</p>









<figure class="center">
  <a href="/posts/2022/04/18/strangling-your-service-with-kubernetes/media/artistsrendition.jpg">
    <img src="/posts/2022/04/18/strangling-your-service-with-kubernetes/media/artistsrendition_hu_a7c3f2044b7deb79.webp"
     width="1054"
     height="510"
     loading="lazy"
     decoding="async"
     alt="Artists rendition of the CPU usage patterns that the service exhibited, before and after the fix.">

  </a>
  <figcaption class="center">Artists rendition of the CPU usage patterns that the service exhibited, before and after the fix.</figcaption>
</figure>

<p>To go even faster. I tweaked the <code>maxSurge</code> property of the rolling update deployment
strategy to start up more new pods in parallel, further shortening the time that
it took to deploy the service. The only thing I had to keep in mind was the
number of database connections afforded to each pod and the maximum number of
connections offered by the database. Start up too many pods in parallel, and
you&rsquo;ll find that your deployment fails due to the service exhausting the
available database connections.</p>
<p>Some time later I learned the reason behind such a CPU resource limit configuration.
Apparently it&rsquo;s a good practice to set your resource limits based on the average
load that your service exhibits after it has properly started up. It does make
sense, especially if you don&rsquo;t want to have your Kubernetes nodes sit idle due to
inefficient resource usage.</p>
<p>This example case shows that it&rsquo;s a trade-off that you&rsquo;ll have to take into
consideration, especially if your service starts up quite slowly and not in
mere seconds.</p>
<p>At the time of writing this post, the tweaked configuration is still up and
running in production.</p>
]]></content:encoded></item></channel></rss>