<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Kubernetes on Charlie Chiang's blog</title><link>https://charlie0129.github.io/blog/tags/kubernetes/</link><description>Recent content in Kubernetes on Charlie Chiang's blog</description><generator>Hugo -- gohugo.io</generator><language>en</language><lastBuildDate>Thu, 15 Aug 2024 14:54:00 +0800</lastBuildDate><atom:link href="https://charlie0129.github.io/blog/tags/kubernetes/index.xml" rel="self" type="application/rss+xml"/><item><title>What happens when your Kubernetes master has low memory or slow disk?</title><link>https://charlie0129.github.io/blog/p/what-happens-when-k8s-master-have-low-memory-or-slow-disk/</link><pubDate>Thu, 15 Aug 2024 14:54:00 +0800</pubDate><guid>https://charlie0129.github.io/blog/p/what-happens-when-k8s-master-have-low-memory-or-slow-disk/</guid><description>&lt;h2 id="background">Background
&lt;/h2>&lt;p>We want to test some sandbox application on our new cluster. My colleague reported that the performance is not as expected and wanted me to take a look.&lt;/p>
&lt;p>The sandbox application works like this: it starts a python container, runs some scripts, and exits. They executes scripts provided by the user, so the cluster is expected to create and destroy a lot of containers in a short period of time.&lt;/p>
&lt;h2 id="assumptions">Assumptions
&lt;/h2>&lt;p>Considering the characteristics of the application, the bottleneck could be the following:&lt;/p>
&lt;ul>
&lt;li>CPU/Memory of the worker nodes, or the container runtime&lt;/li>
&lt;li>Performance of the master node (apiserver, etcd, and etc)&lt;/li>
&lt;/ul>
&lt;p>Since we have relatively beefy worker nodes, each with 2*Xeon Platinum 8353v (72C144T) and 512GB of memory, the bottleneck is likely the master node (8C 16GB memory).&lt;/p>
&lt;p>Let&amp;rsquo;s verify this assumption.&lt;/p>
&lt;h2 id="observations">Observations
&lt;/h2>&lt;p>I ran k6 to load test the cluster.&lt;/p>
&lt;p>Pods started to pending&amp;hellip;&lt;/p>
&lt;p>&lt;img src="https://charlie0129.github.io/blog/p/what-happens-when-k8s-master-have-low-memory-or-slow-disk/images/pending-pods.png"
width="324"
height="514"
srcset="https://charlie0129.github.io/blog/p/what-happens-when-k8s-master-have-low-memory-or-slow-disk/images/pending-pods_hu_e0659d193f6ba0c7.webp 324w, https://charlie0129.github.io/blog/p/what-happens-when-k8s-master-have-low-memory-or-slow-disk/images/pending-pods_hu_ba8aa5c4b632e40c.jpg 324w"
loading="lazy"
alt="Pending Pods"
class="gallery-image"
data-flex-grow="63"
data-flex-basis="151px"
>
&lt;/p>
&lt;p>Hmm, it smelled like a etcd issue (the newly-created Pods is not able to be written to the database). I looked at the etcd dashboard. Sure enough, db backend is having some trouble writing the files.&lt;/p>
&lt;p>&lt;img src="https://charlie0129.github.io/blog/p/what-happens-when-k8s-master-have-low-memory-or-slow-disk/images/etcd-metrics.png"
width="2618"
height="1066"
srcset="https://charlie0129.github.io/blog/p/what-happens-when-k8s-master-have-low-memory-or-slow-disk/images/etcd-metrics_hu_80d6d18cafca0ce4.webp 480w, https://charlie0129.github.io/blog/p/what-happens-when-k8s-master-have-low-memory-or-slow-disk/images/etcd-metrics_hu_c269990831e72efd.jpg 480w, https://charlie0129.github.io/blog/p/what-happens-when-k8s-master-have-low-memory-or-slow-disk/images/etcd-metrics_hu_91c5ccc92849dc2c.webp 1024w, https://charlie0129.github.io/blog/p/what-happens-when-k8s-master-have-low-memory-or-slow-disk/images/etcd-metrics_hu_cf32d92f25ea41c1.jpg 1024w, https://charlie0129.github.io/blog/p/what-happens-when-k8s-master-have-low-memory-or-slow-disk/images/etcd-metrics_hu_9127fd9de5aa228a.webp 1536w, https://charlie0129.github.io/blog/p/what-happens-when-k8s-master-have-low-memory-or-slow-disk/images/etcd-metrics_hu_a0885a5cfc438bd8.jpg 1536w, https://charlie0129.github.io/blog/p/what-happens-when-k8s-master-have-low-memory-or-slow-disk/images/etcd-metrics_hu_8c1d60c12d405fae.webp 2048w, https://charlie0129.github.io/blog/p/what-happens-when-k8s-master-have-low-memory-or-slow-disk/images/etcd-metrics_hu_cad034763199ee91.jpg 2048w, https://charlie0129.github.io/blog/p/what-happens-when-k8s-master-have-low-memory-or-slow-disk/images/etcd-metrics_hu_7189bf7d1cc6fc48.webp 2560w, https://charlie0129.github.io/blog/p/what-happens-when-k8s-master-have-low-memory-or-slow-disk/images/etcd-metrics_hu_8085901669bce26f.jpg 2560w, https://charlie0129.github.io/blog/p/what-happens-when-k8s-master-have-low-memory-or-slow-disk/images/etcd-metrics_hu_ef9cffa4f1c7ec0d.webp 2618w, https://charlie0129.github.io/blog/p/what-happens-when-k8s-master-have-low-memory-or-slow-disk/images/etcd-metrics_hu_b63db6228ee138a1.jpg 2618w"
loading="lazy"
alt="etcd metrics"
class="gallery-image"
data-flex-grow="245"
data-flex-basis="589px"
>
&lt;/p>
&lt;p>I grabed the the disk stats: the disks on the master node is almost fully utilized! A better disk (SSD) is really needed.&lt;/p>
&lt;p>&lt;img src="https://charlie0129.github.io/blog/p/what-happens-when-k8s-master-have-low-memory-or-slow-disk/images/disk-io-time.png"
width="2624"
height="1324"
srcset="https://charlie0129.github.io/blog/p/what-happens-when-k8s-master-have-low-memory-or-slow-disk/images/disk-io-time_hu_896f8b53e1d20b40.webp 480w, https://charlie0129.github.io/blog/p/what-happens-when-k8s-master-have-low-memory-or-slow-disk/images/disk-io-time_hu_852332f2a2d80d7b.jpg 480w, https://charlie0129.github.io/blog/p/what-happens-when-k8s-master-have-low-memory-or-slow-disk/images/disk-io-time_hu_ea8ef60e62c81adf.webp 1024w, https://charlie0129.github.io/blog/p/what-happens-when-k8s-master-have-low-memory-or-slow-disk/images/disk-io-time_hu_e06faae575985720.jpg 1024w, https://charlie0129.github.io/blog/p/what-happens-when-k8s-master-have-low-memory-or-slow-disk/images/disk-io-time_hu_f42b0df92f42c16.webp 1536w, https://charlie0129.github.io/blog/p/what-happens-when-k8s-master-have-low-memory-or-slow-disk/images/disk-io-time_hu_77e90f88e10b09b2.jpg 1536w, https://charlie0129.github.io/blog/p/what-happens-when-k8s-master-have-low-memory-or-slow-disk/images/disk-io-time_hu_f3ce497608a58da8.webp 2048w, https://charlie0129.github.io/blog/p/what-happens-when-k8s-master-have-low-memory-or-slow-disk/images/disk-io-time_hu_11e03a19ecaada22.jpg 2048w, https://charlie0129.github.io/blog/p/what-happens-when-k8s-master-have-low-memory-or-slow-disk/images/disk-io-time_hu_75ecda59dd5360c7.webp 2560w, https://charlie0129.github.io/blog/p/what-happens-when-k8s-master-have-low-memory-or-slow-disk/images/disk-io-time_hu_afdd7e0c319c18b.jpg 2560w, https://charlie0129.github.io/blog/p/what-happens-when-k8s-master-have-low-memory-or-slow-disk/images/disk-io-time_hu_14566d795e0e6d8a.webp 2624w, https://charlie0129.github.io/blog/p/what-happens-when-k8s-master-have-low-memory-or-slow-disk/images/disk-io-time_hu_cc392e1e774a24d8.jpg 2624w"
loading="lazy"
alt="Disk IO time"
class="gallery-image"
data-flex-grow="198"
data-flex-basis="475px"
>
&lt;/p>
&lt;p>&lt;img src="https://charlie0129.github.io/blog/p/what-happens-when-k8s-master-have-low-memory-or-slow-disk/images/iostat.png"
width="1280"
height="185"
srcset="https://charlie0129.github.io/blog/p/what-happens-when-k8s-master-have-low-memory-or-slow-disk/images/iostat_hu_2d5369d4b44180a7.webp 480w, https://charlie0129.github.io/blog/p/what-happens-when-k8s-master-have-low-memory-or-slow-disk/images/iostat_hu_35ff1e9fe8b6ee07.jpg 480w, https://charlie0129.github.io/blog/p/what-happens-when-k8s-master-have-low-memory-or-slow-disk/images/iostat_hu_a384d1e2ec522a4b.webp 1024w, https://charlie0129.github.io/blog/p/what-happens-when-k8s-master-have-low-memory-or-slow-disk/images/iostat_hu_3fff69ee7108264.jpg 1024w, https://charlie0129.github.io/blog/p/what-happens-when-k8s-master-have-low-memory-or-slow-disk/images/iostat_hu_a395520b5f31a537.webp 1280w, https://charlie0129.github.io/blog/p/what-happens-when-k8s-master-have-low-memory-or-slow-disk/images/iostat_hu_4a88be4cca2c1c44.jpg 1280w"
loading="lazy"
alt="iostat"
class="gallery-image"
data-flex-grow="691"
data-flex-basis="1660px"
>
&lt;/p>
&lt;h2 id="side-note">Side note
&lt;/h2>&lt;p>We also experienced unexpected issue when I applied a cilium config, the whole cluster goes down (Thanks god. This is not a production cluster, or this will be a total disaster). At first, I assumed the cilium config that I written is wrong and I reverted, hoping the cluster will be fixed. Nope, all nodes are down. However, some interesting behavior is noticed: all worker nodes are in a ready - notready loop.&lt;/p>
&lt;p>Upon further investigation, I noticed the apiserver is constantly being OOM killed.&lt;/p>
&lt;p>&lt;img src="https://charlie0129.github.io/blog/p/what-happens-when-k8s-master-have-low-memory-or-slow-disk/images/apiserver-oomkilled.jpg"
width="1038"
height="232"
srcset="https://charlie0129.github.io/blog/p/what-happens-when-k8s-master-have-low-memory-or-slow-disk/images/apiserver-oomkilled_hu_e91b0622f442775d.webp 480w, https://charlie0129.github.io/blog/p/what-happens-when-k8s-master-have-low-memory-or-slow-disk/images/apiserver-oomkilled_hu_80c2e6f8dbe3044c.jpg 480w, https://charlie0129.github.io/blog/p/what-happens-when-k8s-master-have-low-memory-or-slow-disk/images/apiserver-oomkilled_hu_1f54d78c59f2929.webp 1024w, https://charlie0129.github.io/blog/p/what-happens-when-k8s-master-have-low-memory-or-slow-disk/images/apiserver-oomkilled_hu_f65127f002ff7e84.jpg 1024w, https://charlie0129.github.io/blog/p/what-happens-when-k8s-master-have-low-memory-or-slow-disk/images/apiserver-oomkilled_hu_c90160b6ead6e703.webp 1038w, https://charlie0129.github.io/blog/p/what-happens-when-k8s-master-have-low-memory-or-slow-disk/images/apiserver-oomkilled_hu_e43b58e01016429a.jpg 1038w"
loading="lazy"
alt="apiserver OOM killed"
class="gallery-image"
data-flex-grow="447"
data-flex-basis="1073px"
>
&lt;/p>
&lt;p>The apiserver is using more memory than the node has.&lt;/p>
&lt;p>&lt;img src="https://charlie0129.github.io/blog/p/what-happens-when-k8s-master-have-low-memory-or-slow-disk/images/apiserver-ram-usage.jpg"
width="426"
height="454"
srcset="https://charlie0129.github.io/blog/p/what-happens-when-k8s-master-have-low-memory-or-slow-disk/images/apiserver-ram-usage_hu_a36ad326df17beb3.webp 426w, https://charlie0129.github.io/blog/p/what-happens-when-k8s-master-have-low-memory-or-slow-disk/images/apiserver-ram-usage_hu_d3fe3e00e88e29b4.jpg 426w"
loading="lazy"
alt="apiserver RAM usage"
class="gallery-image"
data-flex-grow="93"
data-flex-basis="225px"
>
&lt;/p>
&lt;p>It seems something is hitting the apiserver really hard. Under normal circumstances, I will go to the master node to look at the apiserver logs. However, the master node is down (because OOM) and I cannot ssh into it.&lt;/p>
&lt;p>The cluster is stuck in such a loop:&lt;/p>
&lt;ol>
&lt;li>Worker nodes are all starting (cilium starting) and pulling/changed config through apiserver&lt;/li>
&lt;li>apiserver on the master node OOM&amp;rsquo;ed because of bursts of requests&lt;/li>
&lt;li>the apiserver is OOM killed&lt;/li>
&lt;li>worker node cannot report status to the apiserver&lt;/li>
&lt;li>worker node is marked as not ready; cilium pods are terminated because of nodes are not ready&lt;/li>
&lt;li>go to step 1&lt;/li>
&lt;/ol>
&lt;p>Since the cluster cannot properly start in such a scenario, I have to use some dirty fix to start the cluster: just after the apiserver is started, and before the apiserver eats all memory, such that the master node is still alive, quickly SSH into the master node and kill the apiserver process. By doing this a few times, we can span the burst of requests over a longer period of time, avoiding overloading the apiserver (causing it to be killed).&lt;/p>
&lt;h2 id="solution">Solution
&lt;/h2>&lt;p>The solution is simple: replace the master nodes with faster ones (much more memory, NVME SSDs).&lt;/p></description></item></channel></rss>