<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:googleplay="http://www.google.com/schemas/play-podcasts/1.0"><channel><title><![CDATA[Ife Ayelabola]]></title><description><![CDATA[A passionate engineer specialising in software engineering, cybersecurity, platform engineering, and containerisation using Docker and Kubernetes. I blend technology and creativity through both my work and my passion as a photographer.]]></description><link>https://blog.floormind.com</link><image><url>https://substackcdn.com/image/fetch/$s_!oAso!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5e0c3f8c-4422-4477-830e-0c60c4b0db27_1280x1280.png</url><title>Ife Ayelabola</title><link>https://blog.floormind.com</link></image><generator>Substack</generator><lastBuildDate>Tue, 21 Apr 2026 10:52:25 GMT</lastBuildDate><atom:link href="https://blog.floormind.com/feed" rel="self" type="application/rss+xml"/><copyright><![CDATA[Ife Ayelabola]]></copyright><language><![CDATA[en]]></language><webMaster><![CDATA[floormind@substack.com]]></webMaster><itunes:owner><itunes:email><![CDATA[floormind@substack.com]]></itunes:email><itunes:name><![CDATA[Ife Junior]]></itunes:name></itunes:owner><itunes:author><![CDATA[Ife Junior]]></itunes:author><googleplay:owner><![CDATA[floormind@substack.com]]></googleplay:owner><googleplay:email><![CDATA[floormind@substack.com]]></googleplay:email><googleplay:author><![CDATA[Ife Junior]]></googleplay:author><itunes:block><![CDATA[Yes]]></itunes:block><item><title><![CDATA[Migrating from the In-Tree AWS EBS Driver to the EBS CSI Driver in EKS]]></title><description><![CDATA[EKS Administation]]></description><link>https://blog.floormind.com/p/debugging-an-ebs-zonemismatch-error</link><guid isPermaLink="false">https://blog.floormind.com/p/debugging-an-ebs-zonemismatch-error</guid><dc:creator><![CDATA[Ife Junior]]></dc:creator><pubDate>Wed, 18 Mar 2026 14:03:16 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!ni4I!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F99972821-4042-4a58-990e-fd9f6ba083a3_651x342.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!ni4I!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F99972821-4042-4a58-990e-fd9f6ba083a3_651x342.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!ni4I!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F99972821-4042-4a58-990e-fd9f6ba083a3_651x342.jpeg 424w, https://substackcdn.com/image/fetch/$s_!ni4I!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F99972821-4042-4a58-990e-fd9f6ba083a3_651x342.jpeg 848w, https://substackcdn.com/image/fetch/$s_!ni4I!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F99972821-4042-4a58-990e-fd9f6ba083a3_651x342.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!ni4I!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F99972821-4042-4a58-990e-fd9f6ba083a3_651x342.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!ni4I!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F99972821-4042-4a58-990e-fd9f6ba083a3_651x342.jpeg" width="651" height="342" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/99972821-4042-4a58-990e-fd9f6ba083a3_651x342.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:342,&quot;width&quot;:651,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;csi | AWS Open Source Blog&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="csi | AWS Open Source Blog" title="csi | AWS Open Source Blog" srcset="https://substackcdn.com/image/fetch/$s_!ni4I!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F99972821-4042-4a58-990e-fd9f6ba083a3_651x342.jpeg 424w, https://substackcdn.com/image/fetch/$s_!ni4I!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F99972821-4042-4a58-990e-fd9f6ba083a3_651x342.jpeg 848w, https://substackcdn.com/image/fetch/$s_!ni4I!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F99972821-4042-4a58-990e-fd9f6ba083a3_651x342.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!ni4I!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F99972821-4042-4a58-990e-fd9f6ba083a3_651x342.jpeg 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>While doing some routine maintenance work on my EKS cluster recently, I ended up modernising part of my storage setup.</p><p>The cluster was already using the <strong>AWS EBS CSI driver</strong>, but it had originally been installed manually using <code>eksctl</code> rather than being managed through Terraform.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.floormind.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Ife Ayelabola is a reader-supported publication. To receive new posts and support my work, consider becoming a free or paid subscriber.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p>Because of that:</p><ul><li><p>The add-on wasn&#8217;t managed as infrastructure-as-code</p></li><li><p>The driver version was behind the recommended version for my Kubernetes release</p></li></ul><p>That led me to:</p><ol><li><p>Bring the <strong>AWS EBS CSI driver</strong> under Terraform management</p></li><li><p>Migrate Grafana&#8217;s persistent storage from the <strong>legacy in-tree EBS provisioner</strong> to the modern <strong>CSI driver</strong></p></li></ol><p>But this work didn&#8217;t start as a storage migration task.</p><p>It started with a scheduling issue.</p><div><hr></div><h1>The Problem That Triggered This Work</h1><p>While improving Grafana's scheduling in my EKS cluster, I ran into an issue regarding how <strong>stateful workloads interact with AWS EBS volumes</strong>.</p><p>I covered the scheduling side of this problem in more detail in a previous post about <strong>node affinity and zonal storage constraints in Kubernetes</strong>.</p><p>While investigating the issue further, I noticed that the Grafana volume had originally been provisioned using the <strong>legacy in-tree AWS EBS driver</strong>, rather than the modern <strong>AWS EBS CSI driver</strong>.</p><p>Since I was already reviewing the storage configuration, this became a good opportunity to migrate Grafana&#8217;s persistent storage to the CSI driver and bring the EBS CSI addon under Terraform management.</p><div><hr></div><h1>In-Tree vs CSI Storage Drivers</h1><p>While investigating the storage configuration, I noticed that the Grafana volume had originally been created using the <strong>legacy in-tree AWS EBS provisioner</strong>.</p><p>Older Kubernetes clusters relied on built-in storage plugins provided by the cloud provider.</p><p>For AWS EBS this meant the provisioner looked like this:</p><pre><code>kubernetes.io/aws-ebs</code></pre><p>These drivers have since been <strong>deprecated in favour of CSI drivers</strong>.</p><p>You can easily identify which driver a cluster is using by inspecting the <code>StorageClass</code>.</p><p>In my case, the existing storage class looked like this:</p><pre><code>apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: prometheus-stack-storageclass
provisioner: kubernetes.io/aws-ebs
reclaimPolicy: Retain
volumeBindingMode: WaitForFirstConsumer</code></pre><p>The important line here is the <strong>provisioner field</strong>, which shows the legacy in-tree driver:</p><pre><code>provisioner: kubernetes.io/aws-ebs</code></pre><p>Modern Kubernetes clusters instead use the <strong>AWS EBS CSI driver</strong>, which uses the following provisioner:</p><pre><code>ebs.csi.aws.com</code></pre><p>So the new storage class looks something like this:</p><pre><code>apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: ebs-csi-gp3
provisioner: ebs.csi.aws.com
parameters:
  type: gp3
  fsType: ext4
allowVolumeExpansion: true
reclaimPolicy: Retain
volumeBindingMode: WaitForFirstConsumer</code></pre><p>Since the Grafana volume had been provisioned using the <strong>in-tree driver</strong>, this became a good opportunity to migrate it to a <strong>CSI-backed storage class</strong>.</p><div><hr></div><h1>Managing the CSI Driver with Terraform</h1><p>During this work I also noticed that the <strong>AWS EBS CSI driver </strong>had originally been installed manually using<strong> </strong><code>eksctl</code>.</p><p>While that works perfectly fine, the rest of my infrastructure is managed using <strong>Terraform</strong>, so leaving the add-on outside of Terraform would eventually lead to configuration drift.</p><p>To bring the driver under infrastructure-as-code management, I first defined the add-on in Terraform:</p><pre><code>resource &#8220;aws_eks_addon&#8221; &#8220;aws_ebs_csi_driver&#8221; {
  cluster_name  = var.cluster_name
  addon_name    = &#8220;aws-ebs-csi-driver&#8221;
  addon_version = &#8220;v1.xx.x-eksbuild.x&#8221;

  service_account_role_arn = var.ebs_csi_driver_role_arn

  resolve_conflicts_on_create = &#8220;OVERWRITE&#8221;
  resolve_conflicts_on_update = &#8220;OVERWRITE&#8221;
}</code></pre><p>Since the add-on already existed in the cluster, the next step was to <strong>import it into Terraform state</strong> rather than recreate it.</p><p>This can be done using:</p><pre><code>terraform import aws_eks_addon.aws_ebs_csi_driver &lt;cluster-name&gt;:aws-ebs-csi-driver</code></pre><p>After importing the resource, Terraform was able to recognise the existing driver and manage it moving forward.</p><p>This means future upgrades to the CSI driver can now be handled alongside the rest of the cluster infrastructure through Terraform.</p><div><hr></div><h1>Backing Up Grafana Before Migration</h1><p>Grafana stores dashboards, plugin data and configuration on disk, so before migrating the volume, I created a snapshot of the existing EBS volume.</p><p>The snapshot was created at the <strong>AWS level first</strong>, which meant Kubernetes did not yet know about it.</p><p>To make the snapshot usable within Kubernetes, I needed to import it using Kubernetes snapshot resources.</p><div><hr></div><h1>Importing the AWS Snapshot into Kubernetes</h1><p>Since the snapshot already existed in AWS, I created a <code>VolumeSnapshotContent</code> resource referencing the AWS snapshot ID.</p><pre><code>apiVersion: snapshot.storage.k8s.io/v1
kind: VolumeSnapshotContent
metadata:
  name: grafana-snap-content
spec:
  deletionPolicy: Retain
  driver: ebs.csi.aws.com
  volumeSnapshotClassName: ebs-csi-snapclass
  source:
    snapshotHandle: snap-xxxxxxxx
  volumeSnapshotRef:
    name: grafana-snapshot
    namespace: prometheus</code></pre><p>This effectively <strong>imports the AWS snapshot into Kubernetes</strong>.</p><div><hr></div><h1>Creating the VolumeSnapshot</h1><p>Next I created the Kubernetes snapshot resource:</p><pre><code>apiVersion: snapshot.storage.k8s.io/v1
kind: VolumeSnapshot
metadata:
  name: grafana-snapshot
  namespace: prometheus
spec:
  volumeSnapshotClassName: ebs-csi-snapclass
  source:
    volumeSnapshotContentName: grafana-snap-content</code></pre><p>Once created, Kubernetes recognised the snapshot as a restore source.</p><p>I confirmed it was ready:</p><pre><code>kubectl get volumesnapshot -n prometheus</code></pre><p>Output:</p><pre><code>READYTOUSE   true</code></pre><div><hr></div><h1>Restoring the Snapshot Into a CSI Volume</h1><p>Once the snapshot was ready, I created a new PVC restoring the snapshot using the CSI storage class.</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;yaml&quot;,&quot;nodeId&quot;:&quot;c9b5407c-090e-450a-8678-a1fe1b58e7fd&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-yaml">apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: grafana-pvc-csi
  namespace: prometheus
spec:
  storageClassName: ebs-csi-gp3
  accessModes:
    - ReadWriteOnce
  volumeMode: Filesystem
  resources:
    requests:
      storage: 5Gi
  dataSource:
    name: grafana-snapshot
    kind: VolumeSnapshot
    apiGroup: snapshot.storage.k8s.io
    kmsKeyId: arn:aws:kms:eu-west-2:XXXXX:key/&lt;XXXXXX&gt;</code></pre></div><p>Kubernetes then provisioned a <strong>new EBS volume using the CSI driver</strong> and restored the snapshot contents.</p><div><hr></div><h1>Updating Grafana to Use the New Volume</h1><p>Grafana was deployed using the <code>kube-prometheus-stack</code> Helm chart.</p><p>I updated the Helm values so Grafana would use the restored claim:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;yaml&quot;,&quot;nodeId&quot;:&quot;f10ebca0-3ccc-4eb7-a797-291a12bd7b28&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-yaml">grafana:
  persistence:
    enabled: true
    existingClaim: grafana-pvc-csi</code></pre></div><p>After redeploying the chart, Grafana started successfully using the new CSI-backed volume.</p><p>All existing configuration was preserved, including dashboards and data sources.</p><div><hr></div><h1>Final Result</h1><p>After completing the work:</p><ul><li><p>The <strong>AWS EBS CSI driver is now managed through Terraform</strong></p></li><li><p>Grafana storage has been migrated from the <strong>in-tree AWS EBS provisioner to the CSI driver</strong></p></li><li><p>The monitoring stack now runs on a modern storage architecture</p></li><li><p>snapshots provide a safe rollback path for future changes</p></li></ul><div><hr></div><h1>Closing Thoughts</h1><p>This migration stemmed from a real operational issue.</p><p>A scheduling problem led me to review storage behaviour, which uncovered an outdated driver and an opportunity to modernise the cluster.</p><p>That kind of chain reaction is very common in platform engineering.</p><p>You start by fixing one issue, and if you take the opportunity, you leave the platform in a much better state than you found it.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.floormind.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Ife Ayelabola is a reader-supported publication. To receive new posts and support my work, consider becoming a free or paid subscriber.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item><item><title><![CDATA[Designing Stateful Workloads in EKS: Using Node Affinity to Avoid EBS ZoneMismatch Errors]]></title><description><![CDATA[EKS Admin]]></description><link>https://blog.floormind.com/p/designing-stateful-workloads-in-eks</link><guid isPermaLink="false">https://blog.floormind.com/p/designing-stateful-workloads-in-eks</guid><dc:creator><![CDATA[Ife Junior]]></dc:creator><pubDate>Mon, 16 Mar 2026 14:03:00 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!-tdR!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F090634e3-1f58-4671-bcee-16c620bebc3c_800x450.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!-tdR!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F090634e3-1f58-4671-bcee-16c620bebc3c_800x450.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!-tdR!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F090634e3-1f58-4671-bcee-16c620bebc3c_800x450.png 424w, https://substackcdn.com/image/fetch/$s_!-tdR!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F090634e3-1f58-4671-bcee-16c620bebc3c_800x450.png 848w, https://substackcdn.com/image/fetch/$s_!-tdR!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F090634e3-1f58-4671-bcee-16c620bebc3c_800x450.png 1272w, https://substackcdn.com/image/fetch/$s_!-tdR!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F090634e3-1f58-4671-bcee-16c620bebc3c_800x450.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!-tdR!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F090634e3-1f58-4671-bcee-16c620bebc3c_800x450.png" width="800" height="450" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/090634e3-1f58-4671-bcee-16c620bebc3c_800x450.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:450,&quot;width&quot;:800,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Understanding Kubernetes Node Affinity With Example&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Understanding Kubernetes Node Affinity With Example" title="Understanding Kubernetes Node Affinity With Example" srcset="https://substackcdn.com/image/fetch/$s_!-tdR!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F090634e3-1f58-4671-bcee-16c620bebc3c_800x450.png 424w, https://substackcdn.com/image/fetch/$s_!-tdR!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F090634e3-1f58-4671-bcee-16c620bebc3c_800x450.png 848w, https://substackcdn.com/image/fetch/$s_!-tdR!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F090634e3-1f58-4671-bcee-16c620bebc3c_800x450.png 1272w, https://substackcdn.com/image/fetch/$s_!-tdR!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F090634e3-1f58-4671-bcee-16c620bebc3c_800x450.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>While making some improvements to my EKS cluster recently, I revisited how Grafana was scheduled across nodes.</p><p>The cluster runs a mixture of <strong>on-demand and spot instances</strong>, which is a common cost optimisation strategy. However, workloads running on spot instances can disappear at any time when AWS reclaims the capacity.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.floormind.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Ife Ayelabola is a reader-supported publication. To receive new posts and support my work, consider becoming a free or paid subscriber.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p>Because of this, I wanted to improve how Grafana behaved when nodes were reclaimed and pods needed to be rescheduled.</p><p>During this work I ran into an issue that highlights an important design consideration when running <strong>stateful workloads in Kubernetes using AWS EBS volumes</strong>.</p><div><hr></div><h1>The Error That Exposed the Problem</h1><p>After Grafana restarted due to spot instance being reclaimed, the pod failed to start and remained pending.</p><p>Inspecting the pod events revealed the following:</p><pre><code>AttachVolume.Attach failed for volume &#8220;grafana&#8221; : rpc error: code = Internal desc =
Could not attach volume &#8220;vol-xxxxxxxxxxxx&#8221; to node &#8220;i-xxxxxxxxxxxx&#8221;:
could not attach volume &#8220;vol-xxxxxxxxxxxx&#8221; to node &#8220;i-xxxxxxxxxxxx&#8221;:
InvalidVolume.ZoneMismatch: The volume &#8216;vol-xxxxxxxxxxxx&#8217; is not in the same
availability zone as instance &#8216;i-xxxxxxxxxxxx&#8217;</code></pre><p>This can typically be seen with:</p><pre><code>kubectl describe pod prometheus-grafana-xxxxx -n prometheus</code></pre><p>or</p><pre><code>kubectl get events -n prometheus</code></pre><p>The key clue here is the message:</p><pre><code>InvalidVolume.ZoneMismatch</code></pre><p>This indicates that Kubernetes attempted to attach an EBS volume that exists in <strong>one availability zone</strong> to a node running in <strong>another availability zone</strong>.</p><p>Because my cluster spans multiple AZs, the scheduler had placed the replacement pod onto a node that could not attach the existing volume.</p><div><hr></div><h1>Understanding EBS Volume Attachments</h1><p>Another important aspect of EBS is how it attaches to nodes.</p><p>Unlike many network-attached storage systems, <strong>EBS does not support multi-node read/write access</strong>.</p><p>A typical EBS volume supports:</p><pre><code>ReadWriteOnce</code></pre><p>This means the volume can only be attached to <strong>one node at a time</strong>.</p><p>In contrast, traditional network storage solutions often support:</p><pre><code>ReadWriteMany</code></pre><p>where multiple nodes can mount the same volume simultaneously.</p><p>Because EBS behaves more like a <strong>block device attached to a single machine</strong>, Kubernetes must schedule the pod onto the node where the volume can attach.</p><p>This is why the AZ mismatch caused the workload to fail.</p><div><hr></div><h1>Why Not Use EFS Instead?</h1><p>One alternative would be <strong>Amazon EFS</strong>.</p><p>EFS behaves more like traditional network-attached storage and supports:</p><pre><code>ReadWriteMany</code></pre><p>meaning multiple pods across multiple nodes can mount the same filesystem simultaneously.</p><p>However there is a trade-off.</p><p>EFS is typically <strong>more expensive than EBS</strong> and has different performance characteristics.</p><p>Since Grafana only requires a <strong>single writer volume</strong>, using EBS remains the more cost-effective option for this workload.</p><p>So the architecture decision here was deliberate:</p><ul><li><p><strong>EBS for cost efficiency</strong></p></li><li><p><strong>single-attach storage</strong></p></li><li><p><strong>careful scheduling considerations</strong></p></li></ul><div><hr></div><h1>Designing Scheduling Rules for Stateful Workloads</h1><p>Given these constraints, we need to ensure Kubernetes schedules pods in a way that respects how the storage behaves.</p><p>Kubernetes provides several mechanisms for controlling where pods are placed:</p><ul><li><p>node selectors</p></li><li><p>node affinity</p></li><li><p>taints and tolerations</p></li><li><p>topology-aware scheduling</p></li></ul><p>For stateful workloads using EBS-backed volumes, it&#8217;s important to influence the scheduler so that pods are placed onto nodes that can successfully attach the volume.</p><div><hr></div><h1>Using Node Affinity</h1><p>Node affinity allows us to define rules about <strong>which nodes a pod should run on</strong>, based on node labels.</p><p>A simplified example looks like this:</p><pre><code>affinity:
  nodeAffinity:
    requiredDuringSchedulingIgnoredDuringExecution:
      nodeSelectorTerms:
        - matchExpressions:
            - key: topology.kubernetes.io/zone
              operator: In
              values:
                - eu-west-2a</code></pre><p>Breaking this down:</p><p><strong>requiredDuringScheduling</strong></p><p>The rule must be satisfied when Kubernetes schedules the pod.</p><p><strong>IgnoredDuringExecution</strong></p><p>If the rule stops being true later, the pod will not be evicted.</p><p>This allows us to guide the scheduler without forcing unnecessary restarts of running workloads.</p><div><hr></div><h1>The Bigger Architectural Lesson</h1><p>This issue highlights an important distinction in Kubernetes.</p><p>Stateless workloads can generally run anywhere in the cluster.</p><p>Stateful workloads, however, often have <strong>infrastructure constraints</strong> that influence where they can run.</p><p>When using EBS-backed storage, those constraints include:</p><ul><li><p>availability zones</p></li><li><p>single-node attachment</p></li><li><p>storage cost considerations</p></li></ul><p>Understanding these constraints helps design scheduling policies that prevent runtime failures like the <strong>ZoneMismatch error</strong>.</p><div><hr></div><h1>Closing Thoughts</h1><p>This issue surfaced while improving the resilience of Grafana in a cluster running spot instances.</p><p>What started as a simple scheduling tweak turned into a deeper look at how <strong>stateful workloads interact with cloud storage primitives</strong>.</p><p>These kinds of debugging exercises are valuable because they highlight how:</p><ul><li><p>Kubernetes scheduling</p></li><li><p>cloud infrastructure</p></li><li><p>and storage architecture</p></li></ul><p>all interact with each other.</p><p>In the next post, I&#8217;ll walk through how I migrated Grafana&#8217;s storage from the <strong>legacy in-tree AWS EBS driver to the modern EBS CSI driver</strong>, while safely preserving the existing data using Kubernetes volume snapshots.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.floormind.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Ife Ayelabola is a reader-supported publication. To receive new posts and support my work, consider becoming a free or paid subscriber.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item><item><title><![CDATA[When Kubernetes Upgrades Reveal Hidden Technical Debt: Fixing kube-proxy Version Skew in EKS]]></title><description><![CDATA[Recently I ran into an interesting issue while reviewing the upgrade readiness of one of my Amazon EKS clusters.]]></description><link>https://blog.floormind.com/p/when-kubernetes-upgrades-reveal-hidden</link><guid isPermaLink="false">https://blog.floormind.com/p/when-kubernetes-upgrades-reveal-hidden</guid><dc:creator><![CDATA[Ife Junior]]></dc:creator><pubDate>Tue, 10 Mar 2026 21:57:15 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!3NfR!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F92a4f4ef-54d1-4541-a398-569113f17b30_512x512.webp" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!3NfR!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F92a4f4ef-54d1-4541-a398-569113f17b30_512x512.webp" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!3NfR!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F92a4f4ef-54d1-4541-a398-569113f17b30_512x512.webp 424w, https://substackcdn.com/image/fetch/$s_!3NfR!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F92a4f4ef-54d1-4541-a398-569113f17b30_512x512.webp 848w, https://substackcdn.com/image/fetch/$s_!3NfR!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F92a4f4ef-54d1-4541-a398-569113f17b30_512x512.webp 1272w, https://substackcdn.com/image/fetch/$s_!3NfR!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F92a4f4ef-54d1-4541-a398-569113f17b30_512x512.webp 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!3NfR!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F92a4f4ef-54d1-4541-a398-569113f17b30_512x512.webp" width="512" height="512" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/92a4f4ef-54d1-4541-a398-569113f17b30_512x512.webp&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:512,&quot;width&quot;:512,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:66008,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/webp&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://blog.floormind.com/i/190556587?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F92a4f4ef-54d1-4541-a398-569113f17b30_512x512.webp&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!3NfR!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F92a4f4ef-54d1-4541-a398-569113f17b30_512x512.webp 424w, https://substackcdn.com/image/fetch/$s_!3NfR!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F92a4f4ef-54d1-4541-a398-569113f17b30_512x512.webp 848w, https://substackcdn.com/image/fetch/$s_!3NfR!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F92a4f4ef-54d1-4541-a398-569113f17b30_512x512.webp 1272w, https://substackcdn.com/image/fetch/$s_!3NfR!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F92a4f4ef-54d1-4541-a398-569113f17b30_512x512.webp 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Recently I ran into an interesting issue while reviewing the upgrade readiness of one of my Amazon EKS clusters.</p><p>What initially looked like a routine upgrade warning turned into a small investigation into:</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.floormind.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Ife Ayelabola is a reader-supported publication. To receive new posts and support my work, consider becoming a free or paid subscriber.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><ul><li><p>Kubernetes version skew policies</p></li><li><p>EKS managed vs self-managed add-ons</p></li><li><p>Terraform cluster provisioning</p></li><li><p>Cilium networking configuration</p></li></ul><p>In the end, the fix was simple &#8212; but the journey revealed something that often happens in long-running Kubernetes clusters: <strong>silent infrastructure drift</strong>.</p><p>This post walks through how I discovered the issue and how I resolved it.</p><div><hr></div><h1>The Warning</h1><p>While reviewing the <strong>EKS Upgrade Insights</strong> dashboard, I saw the following alert:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;bash&quot;,&quot;nodeId&quot;:&quot;fe5ed9a6-c1dd-4b6e-abcf-862de86e61db&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-bash">kube-proxy version skew
Checks version of kube-proxy in cluster to see if upgrade would cause non compliance
with supported Kubernetes kube-proxy version skew policy.</code></pre></div><p>At first glance, this seemed minor. The cluster had been running perfectly fine.</p><p>But version skew warnings should always be investigated because they often indicate deeper compatibility issues.</p><div><hr></div><h1>Inspecting the kube-proxy Version</h1><p>To check the running version of kube-proxy in the cluster, I inspected the daemonset:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;bash&quot;,&quot;nodeId&quot;:&quot;65893438-5541-49ff-bd07-6fbe0b6b5728&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-bash">kubectl -n kube-system get ds kube-proxy \
-o jsonpath=&#8217;{.spec.template.spec.containers[0].image}&#8217;</code></pre></div><p>The result:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;bash&quot;,&quot;nodeId&quot;:&quot;e34857fd-204d-4da7-a230-019ac058f4ae&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-bash">602401143452.dkr.ecr.eu-west-2.amazonaws.com/eks/kube-proxy:v1.29.0-minimal-eksbuild.1</code></pre></div><p>The cluster control plane version was:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;bash&quot;,&quot;nodeId&quot;:&quot;57e3dd9b-0670-4c33-aad8-33a7fe2bd298&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-bash">1.35</code></pre></div><p>This immediately explained the warning.</p><p>Kubernetes enforces a <strong>version skew policy</strong> between control plane components and kube-proxy.</p><p>The rule is:</p><ul><li><p>kube-proxy <strong>must not be newer than the API server</strong></p></li><li><p>kube-proxy may be <strong>up to three minor versions older</strong></p></li></ul><p>In my case:</p><p>ComponentVersionControl Plane1.35kube-proxy1.29</p><p>That&#8217;s a <strong>six-version gap</strong>, well outside the supported window.</p><p>Even though the cluster was functioning, this configuration was technically unsupported.</p><div><hr></div><h1>Why Was kube-proxy So Old?</h1><p>The next question was obvious:</p><p><strong>Why hadn&#8217;t kube-proxy been upgraded automatically?</strong></p><p>To answer that, I checked whether kube-proxy was installed as an <strong>EKS managed add-on</strong>.</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;bash&quot;,&quot;nodeId&quot;:&quot;7f768581-8d61-4081-9a4f-470a343b6eb7&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-bash">aws eks describe-addon \
--cluster-name my-cluster \
--addon-name kube-proxy</code></pre></div><p>The result:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;bash&quot;,&quot;nodeId&quot;:&quot;fb475387-96fc-4136-a8e5-206f78bfce68&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-bash">ResourceNotFoundException: No addon: kube-proxy found in cluster</code></pre></div><p>That meant kube-proxy was <strong>not managed by EKS</strong>.</p><p>Instead, it was running as a <strong>self-managed Kubernetes daemonset</strong>.</p><p>This made sense once I remembered how the cluster had been created.</p><p>The cluster was originally provisioned via <strong>Terraform</strong>, and at the time I had not explicitly configured EKS add-ons.</p><p>When clusters are created outside the AWS console, the default components &#8212; such as:</p><ul><li><p>kube-proxy</p></li><li><p>CoreDNS</p></li><li><p>AWS VPC CNI</p></li></ul><p>may exist as <strong>self-managed components unless explicitly installed as managed add-ons</strong>.</p><div><hr></div><h1>A Complication: Cilium Networking</h1><p>This cluster also uses <strong>Cilium</strong> as the CNI instead of the default AWS VPC CNI.</p><p>Before modifying kube-proxy, I needed to confirm whether Cilium was operating in <strong>kube-proxy replacement mode</strong>.</p><p>If it was, kube-proxy would not be required at all.</p><p>Checking the Cilium configuration:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;bash&quot;,&quot;nodeId&quot;:&quot;0c6b3f01-8591-47b4-b242-3950d71992e4&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-bash">kubectl -n kube-system get cm cilium-config -o yaml | grep kubeProxyReplacement</code></pre></div><p>The command returned nothing.</p><p>I also confirmed the daemonset was actively running:</p><pre><code>kubectl -n kube-system get ds kube-proxy</code></pre><p>Result:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;bash&quot;,&quot;nodeId&quot;:&quot;08478e43-bf41-465e-8b53-b6d0341b0b34&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-bash">kube-proxy   6   6   6</code></pre></div><p>This confirmed that <strong>kube-proxy was still responsible for Kubernetes Service routing</strong>.</p><p>Cilium was providing networking and policy features, but <strong>not replacing kube-proxy</strong>.</p><div><hr></div><h1>The Solution: Migrating kube-proxy to an EKS Managed Add-on</h1><p>Since kube-proxy was self-managed and significantly outdated, the best solution was to migrate it to the <strong>EKS managed add-on system</strong>.</p><p>Managed add-ons provide several advantages:</p><ul><li><p>automatic compatibility with cluster versions</p></li><li><p>simplified upgrades</p></li><li><p>consistent lifecycle management</p></li><li><p>integration with EKS upgrade workflows</p></li></ul><p>Because the cluster itself is managed with Terraform, I chose to manage the add-on declaratively as well.</p><p>I added the following Terraform resource:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;bash&quot;,&quot;nodeId&quot;:&quot;98e822e3-50fc-49cd-a874-24b3c8aa3f5d&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-bash">resource &#8220;aws_eks_addon&#8221; &#8220;kube_proxy&#8221; {
  cluster_name                = aws_eks_cluster.eks_cluster.name
  addon_name                  = &#8220;kube-proxy&#8221;
  addon_version               = &#8220;v1.35.0-eksbuild.2&#8221;
  resolve_conflicts_on_create = &#8220;OVERWRITE&#8221;
  resolve_conflicts_on_update = &#8220;OVERWRITE&#8221;
}</code></pre></div><p>The <code>OVERWRITE</code> flag is important.</p><p>Because a self-managed daemonset already existed, this tells EKS to <strong>replace the existing configuration with the managed add-on</strong>.</p><div><hr></div><h1>Applying the Change</h1><p>After adding the resource, I ran:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;bash&quot;,&quot;nodeId&quot;:&quot;e02956fd-5fd3-4edc-bc3d-3c6ffe18d6f2&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-bash">terraform plan</code></pre></div><p>The output showed:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;bash&quot;,&quot;nodeId&quot;:&quot;2a3f0a7f-e111-46ef-b828-7d9b4096e081&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-bash">+ aws_eks_addon.kube_proxy will be created</code></pre></div><p>Importantly:</p><p><strong>The EKS cluster itself was not recreated.</strong></p><p>Add-ons are independent resources and can be installed or updated without affecting the control plane.</p><p>After applying the change, I verified the add-on status:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;bash&quot;,&quot;nodeId&quot;:&quot;714279a5-a2b3-4704-bc90-e3f24b98462a&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-bash">aws eks describe-addon \
--cluster-name my-cluster \
--addon-name kube-proxy</code></pre></div><p>Result:</p><pre><code>ACTIVE</code></pre><p>The kube-proxy daemonset was now running the correct version for Kubernetes 1.35.</p><div><hr></div><h1>Lessons Learned</h1><p>Even small upgrade warnings can reveal interesting platform insights.</p><p>Here are a few takeaways from this experience.</p><h3>Long-Running Clusters Accumulate Drift</h3><p>Clusters that have been running for years often contain components installed using older practices.</p><p>Without explicit lifecycle management, these components may quietly fall out of compliance.</p><div><hr></div><h3>EKS Managed Add-ons Reduce Operational Burden</h3><p>Moving critical components such as kube-proxy and CoreDNS to managed add-ons simplifies cluster maintenance and reduces upgrade risks.</p><div><hr></div><h3>Networking Choices Affect Upgrade Strategy</h3><p>Using alternative CNIs like Cilium introduces additional considerations.</p><p>Before modifying cluster components, it&#8217;s important to understand which parts of the networking stack are actually responsible for service routing.</p><div><hr></div><h3>Infrastructure as Code Should Include Add-ons</h3><p>If you are managing EKS with Terraform, it is worth managing <strong>add-ons explicitly</strong> as well.</p><p>This keeps the entire cluster lifecycle declarative and avoids surprises during upgrades.</p><div><hr></div><h1>Final Thoughts</h1><p>Kubernetes platforms evolve quickly, and clusters that were created with one set of assumptions can drift away from best practices over time.</p><p>This issue was ultimately straightforward to resolve, but it highlights how important it is to periodically review the underlying components of your cluster &#8212; not just the workloads running on top of it.</p><p>Sometimes a simple upgrade warning is actually an opportunity to improve the overall platform architecture.</p><div><hr></div><p>If you&#8217;re interested in <strong>platform engineering, Kubernetes infrastructure, and DevSecOps</strong>, I&#8217;ll be writing more posts about real-world problems like this as they arise.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.floormind.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Ife Ayelabola is a reader-supported publication. To receive new posts and support my work, consider becoming a free or paid subscriber.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item><item><title><![CDATA[Field Notes – A Test Shoot with Jemilia (Elite Models)]]></title><description><![CDATA[In this test shoot, I explored the captivating journey of Jemilia, one of Elite&#8217;s new faces.]]></description><link>https://blog.floormind.com/p/field-notes-a-test-shoot-with-jemilia</link><guid isPermaLink="false">https://blog.floormind.com/p/field-notes-a-test-shoot-with-jemilia</guid><dc:creator><![CDATA[Ife Junior]]></dc:creator><pubDate>Tue, 10 Jun 2025 07:00:55 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!1kAn!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcbb138fe-e922-42db-9233-70b5157a1cf9_3375x5062.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In this test shoot, I explored the captivating journey of Jemilia, one of Elite&#8217;s new faces. My theme centred around the concept of mature, structured styling that enhanced her presence and polished appearance and allowed her vibrant personality to radiate. I curated three unique outfits, each carefully thrifted, designed to evoke distinct moods and movements, adding depth to her story as I captured her essence through the lens.</p><p>The shoot was a mix of digital and film. I used the <strong>Pentax 67 medium format</strong> for softness and depth, alongside my <strong>Sony full-frame mirrorless</strong> for flexibility. Lighting was simple but intentional: a <strong>one-light setup using the Godox AD600 Pro</strong>, a <strong>parabolic softbox</strong>, and a <strong>40x60" reflector</strong> to shape and balance the light.</p><p>You will find 16 images and a BTS video from the shoot below. Let me know your thoughts&#8212;and if you are a stylist or makeup artist looking to collaborate on future shoots, do feel free to get in touch out.</p><div><hr></div><h3><strong>Look 1: Pinstripe Power</strong></h3><p>At first glance, I wanted to channel something grown-up and editorial. Jemilia wore a grey pinstripe oversized blazer and matching wide-leg trousers over a textured white blouse and a layered red top. The bold silhouette contrasted beautifully against the track setting&#8212;corporate meets playground rebellion.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!1kAn!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcbb138fe-e922-42db-9233-70b5157a1cf9_3375x5062.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!1kAn!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcbb138fe-e922-42db-9233-70b5157a1cf9_3375x5062.jpeg 424w, https://substackcdn.com/image/fetch/$s_!1kAn!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcbb138fe-e922-42db-9233-70b5157a1cf9_3375x5062.jpeg 848w, https://substackcdn.com/image/fetch/$s_!1kAn!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcbb138fe-e922-42db-9233-70b5157a1cf9_3375x5062.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!1kAn!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcbb138fe-e922-42db-9233-70b5157a1cf9_3375x5062.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!1kAn!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcbb138fe-e922-42db-9233-70b5157a1cf9_3375x5062.jpeg" width="1456" height="2184" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/cbb138fe-e922-42db-9233-70b5157a1cf9_3375x5062.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:2184,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:2548502,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://blog.floormind.com/i/165602277?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcbb138fe-e922-42db-9233-70b5157a1cf9_3375x5062.jpeg&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!1kAn!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcbb138fe-e922-42db-9233-70b5157a1cf9_3375x5062.jpeg 424w, https://substackcdn.com/image/fetch/$s_!1kAn!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcbb138fe-e922-42db-9233-70b5157a1cf9_3375x5062.jpeg 848w, https://substackcdn.com/image/fetch/$s_!1kAn!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcbb138fe-e922-42db-9233-70b5157a1cf9_3375x5062.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!1kAn!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcbb138fe-e922-42db-9233-70b5157a1cf9_3375x5062.jpeg 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!3EGQ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8d35323e-549d-45fc-a5b4-d39b260658ed_4000x6000.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!3EGQ!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8d35323e-549d-45fc-a5b4-d39b260658ed_4000x6000.jpeg 424w, https://substackcdn.com/image/fetch/$s_!3EGQ!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8d35323e-549d-45fc-a5b4-d39b260658ed_4000x6000.jpeg 848w, https://substackcdn.com/image/fetch/$s_!3EGQ!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8d35323e-549d-45fc-a5b4-d39b260658ed_4000x6000.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!3EGQ!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8d35323e-549d-45fc-a5b4-d39b260658ed_4000x6000.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!3EGQ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8d35323e-549d-45fc-a5b4-d39b260658ed_4000x6000.jpeg" width="1456" height="2184" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/8d35323e-549d-45fc-a5b4-d39b260658ed_4000x6000.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:2184,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:2292903,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://blog.floormind.com/i/165602277?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8d35323e-549d-45fc-a5b4-d39b260658ed_4000x6000.jpeg&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!3EGQ!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8d35323e-549d-45fc-a5b4-d39b260658ed_4000x6000.jpeg 424w, https://substackcdn.com/image/fetch/$s_!3EGQ!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8d35323e-549d-45fc-a5b4-d39b260658ed_4000x6000.jpeg 848w, https://substackcdn.com/image/fetch/$s_!3EGQ!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8d35323e-549d-45fc-a5b4-d39b260658ed_4000x6000.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!3EGQ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8d35323e-549d-45fc-a5b4-d39b260658ed_4000x6000.jpeg 1456w" sizes="100vw"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!DlPe!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb7b81acb-c713-499c-8173-bd594bc6c2db_4000x6000.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!DlPe!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb7b81acb-c713-499c-8173-bd594bc6c2db_4000x6000.jpeg 424w, https://substackcdn.com/image/fetch/$s_!DlPe!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb7b81acb-c713-499c-8173-bd594bc6c2db_4000x6000.jpeg 848w, https://substackcdn.com/image/fetch/$s_!DlPe!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb7b81acb-c713-499c-8173-bd594bc6c2db_4000x6000.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!DlPe!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb7b81acb-c713-499c-8173-bd594bc6c2db_4000x6000.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!DlPe!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb7b81acb-c713-499c-8173-bd594bc6c2db_4000x6000.jpeg" width="1456" height="2184" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b7b81acb-c713-499c-8173-bd594bc6c2db_4000x6000.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:2184,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:2235272,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://blog.floormind.com/i/165602277?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb7b81acb-c713-499c-8173-bd594bc6c2db_4000x6000.jpeg&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!DlPe!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb7b81acb-c713-499c-8173-bd594bc6c2db_4000x6000.jpeg 424w, https://substackcdn.com/image/fetch/$s_!DlPe!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb7b81acb-c713-499c-8173-bd594bc6c2db_4000x6000.jpeg 848w, https://substackcdn.com/image/fetch/$s_!DlPe!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb7b81acb-c713-499c-8173-bd594bc6c2db_4000x6000.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!DlPe!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb7b81acb-c713-499c-8173-bd594bc6c2db_4000x6000.jpeg 1456w" sizes="100vw"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!qf12!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4b3893d3-cf08-4c7b-a63a-84d7dba35e46_4000x6000.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!qf12!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4b3893d3-cf08-4c7b-a63a-84d7dba35e46_4000x6000.jpeg 424w, https://substackcdn.com/image/fetch/$s_!qf12!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4b3893d3-cf08-4c7b-a63a-84d7dba35e46_4000x6000.jpeg 848w, https://substackcdn.com/image/fetch/$s_!qf12!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4b3893d3-cf08-4c7b-a63a-84d7dba35e46_4000x6000.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!qf12!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4b3893d3-cf08-4c7b-a63a-84d7dba35e46_4000x6000.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!qf12!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4b3893d3-cf08-4c7b-a63a-84d7dba35e46_4000x6000.jpeg" width="1456" height="2184" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/4b3893d3-cf08-4c7b-a63a-84d7dba35e46_4000x6000.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:2184,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:2338540,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://blog.floormind.com/i/165602277?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4b3893d3-cf08-4c7b-a63a-84d7dba35e46_4000x6000.jpeg&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!qf12!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4b3893d3-cf08-4c7b-a63a-84d7dba35e46_4000x6000.jpeg 424w, https://substackcdn.com/image/fetch/$s_!qf12!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4b3893d3-cf08-4c7b-a63a-84d7dba35e46_4000x6000.jpeg 848w, https://substackcdn.com/image/fetch/$s_!qf12!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4b3893d3-cf08-4c7b-a63a-84d7dba35e46_4000x6000.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!qf12!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4b3893d3-cf08-4c7b-a63a-84d7dba35e46_4000x6000.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Ud0_!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2e7e9064-974b-48e8-821c-bed772539eba_4000x6000.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Ud0_!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2e7e9064-974b-48e8-821c-bed772539eba_4000x6000.jpeg 424w, https://substackcdn.com/image/fetch/$s_!Ud0_!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2e7e9064-974b-48e8-821c-bed772539eba_4000x6000.jpeg 848w, https://substackcdn.com/image/fetch/$s_!Ud0_!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2e7e9064-974b-48e8-821c-bed772539eba_4000x6000.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!Ud0_!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2e7e9064-974b-48e8-821c-bed772539eba_4000x6000.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Ud0_!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2e7e9064-974b-48e8-821c-bed772539eba_4000x6000.jpeg" width="1456" height="2184" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/2e7e9064-974b-48e8-821c-bed772539eba_4000x6000.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:2184,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:2783664,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://blog.floormind.com/i/165602277?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2e7e9064-974b-48e8-821c-bed772539eba_4000x6000.jpeg&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Ud0_!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2e7e9064-974b-48e8-821c-bed772539eba_4000x6000.jpeg 424w, https://substackcdn.com/image/fetch/$s_!Ud0_!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2e7e9064-974b-48e8-821c-bed772539eba_4000x6000.jpeg 848w, https://substackcdn.com/image/fetch/$s_!Ud0_!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2e7e9064-974b-48e8-821c-bed772539eba_4000x6000.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!Ud0_!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2e7e9064-974b-48e8-821c-bed772539eba_4000x6000.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><div class="image-gallery-embed" data-attrs="{&quot;gallery&quot;:{&quot;images&quot;:[{&quot;type&quot;:&quot;image/jpeg&quot;,&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/3cf3defc-3b3a-45c6-bca0-eb278ddd01f8_4000x6000.jpeg&quot;}],&quot;caption&quot;:&quot;First look &quot;,&quot;alt&quot;:&quot;Ife Ayelabola Nomadcoder Test shoot&quot;,&quot;staticGalleryImage&quot;:{&quot;type&quot;:&quot;image/jpeg&quot;,&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/3cf3defc-3b3a-45c6-bca0-eb278ddd01f8_4000x6000.jpeg&quot;}},&quot;isEditorNode&quot;:true}"></div><p></p><div><hr></div><h3><strong>Look 2: Utility Denim</strong></h3><p>The second look leaned more streetwear&#8212;oversized denim trousers with utility-style hardware, paired with a neutral shirt and a layered mesh top with pops of red. I liked the toughness of this look, softened by her natural poise. It grounded the set and gave it weight.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!9t-X!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1518828c-acb4-4b14-a001-2fec01acda81_3881x5821.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!9t-X!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1518828c-acb4-4b14-a001-2fec01acda81_3881x5821.jpeg 424w, https://substackcdn.com/image/fetch/$s_!9t-X!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1518828c-acb4-4b14-a001-2fec01acda81_3881x5821.jpeg 848w, https://substackcdn.com/image/fetch/$s_!9t-X!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1518828c-acb4-4b14-a001-2fec01acda81_3881x5821.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!9t-X!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1518828c-acb4-4b14-a001-2fec01acda81_3881x5821.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!9t-X!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1518828c-acb4-4b14-a001-2fec01acda81_3881x5821.jpeg" width="1456" height="2184" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/1518828c-acb4-4b14-a001-2fec01acda81_3881x5821.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:2184,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:2651367,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://blog.floormind.com/i/165602277?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1518828c-acb4-4b14-a001-2fec01acda81_3881x5821.jpeg&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!9t-X!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1518828c-acb4-4b14-a001-2fec01acda81_3881x5821.jpeg 424w, https://substackcdn.com/image/fetch/$s_!9t-X!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1518828c-acb4-4b14-a001-2fec01acda81_3881x5821.jpeg 848w, https://substackcdn.com/image/fetch/$s_!9t-X!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1518828c-acb4-4b14-a001-2fec01acda81_3881x5821.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!9t-X!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1518828c-acb4-4b14-a001-2fec01acda81_3881x5821.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!8mCO!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6acf6a04-71a7-40db-be4a-5e3084ec853c_4000x6000.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!8mCO!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6acf6a04-71a7-40db-be4a-5e3084ec853c_4000x6000.jpeg 424w, https://substackcdn.com/image/fetch/$s_!8mCO!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6acf6a04-71a7-40db-be4a-5e3084ec853c_4000x6000.jpeg 848w, https://substackcdn.com/image/fetch/$s_!8mCO!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6acf6a04-71a7-40db-be4a-5e3084ec853c_4000x6000.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!8mCO!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6acf6a04-71a7-40db-be4a-5e3084ec853c_4000x6000.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!8mCO!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6acf6a04-71a7-40db-be4a-5e3084ec853c_4000x6000.jpeg" width="1456" height="2184" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/6acf6a04-71a7-40db-be4a-5e3084ec853c_4000x6000.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:2184,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:2186571,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://blog.floormind.com/i/165602277?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6acf6a04-71a7-40db-be4a-5e3084ec853c_4000x6000.jpeg&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!8mCO!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6acf6a04-71a7-40db-be4a-5e3084ec853c_4000x6000.jpeg 424w, https://substackcdn.com/image/fetch/$s_!8mCO!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6acf6a04-71a7-40db-be4a-5e3084ec853c_4000x6000.jpeg 848w, https://substackcdn.com/image/fetch/$s_!8mCO!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6acf6a04-71a7-40db-be4a-5e3084ec853c_4000x6000.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!8mCO!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6acf6a04-71a7-40db-be4a-5e3084ec853c_4000x6000.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!aanv!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F05880f79-5b45-4d16-972d-0697354e086a_4000x6000.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!aanv!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F05880f79-5b45-4d16-972d-0697354e086a_4000x6000.jpeg 424w, https://substackcdn.com/image/fetch/$s_!aanv!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F05880f79-5b45-4d16-972d-0697354e086a_4000x6000.jpeg 848w, https://substackcdn.com/image/fetch/$s_!aanv!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F05880f79-5b45-4d16-972d-0697354e086a_4000x6000.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!aanv!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F05880f79-5b45-4d16-972d-0697354e086a_4000x6000.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!aanv!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F05880f79-5b45-4d16-972d-0697354e086a_4000x6000.jpeg" width="1456" height="2184" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/05880f79-5b45-4d16-972d-0697354e086a_4000x6000.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:2184,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:2399253,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://blog.floormind.com/i/165602277?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F05880f79-5b45-4d16-972d-0697354e086a_4000x6000.jpeg&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!aanv!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F05880f79-5b45-4d16-972d-0697354e086a_4000x6000.jpeg 424w, https://substackcdn.com/image/fetch/$s_!aanv!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F05880f79-5b45-4d16-972d-0697354e086a_4000x6000.jpeg 848w, https://substackcdn.com/image/fetch/$s_!aanv!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F05880f79-5b45-4d16-972d-0697354e086a_4000x6000.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!aanv!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F05880f79-5b45-4d16-972d-0697354e086a_4000x6000.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!lYog!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb345ad9e-53a6-4643-9f18-455e35244d0d_4000x6000.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!lYog!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb345ad9e-53a6-4643-9f18-455e35244d0d_4000x6000.jpeg 424w, https://substackcdn.com/image/fetch/$s_!lYog!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb345ad9e-53a6-4643-9f18-455e35244d0d_4000x6000.jpeg 848w, https://substackcdn.com/image/fetch/$s_!lYog!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb345ad9e-53a6-4643-9f18-455e35244d0d_4000x6000.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!lYog!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb345ad9e-53a6-4643-9f18-455e35244d0d_4000x6000.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!lYog!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb345ad9e-53a6-4643-9f18-455e35244d0d_4000x6000.jpeg" width="1456" height="2184" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b345ad9e-53a6-4643-9f18-455e35244d0d_4000x6000.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:2184,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:2839219,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://blog.floormind.com/i/165602277?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb345ad9e-53a6-4643-9f18-455e35244d0d_4000x6000.jpeg&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!lYog!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb345ad9e-53a6-4643-9f18-455e35244d0d_4000x6000.jpeg 424w, https://substackcdn.com/image/fetch/$s_!lYog!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb345ad9e-53a6-4643-9f18-455e35244d0d_4000x6000.jpeg 848w, https://substackcdn.com/image/fetch/$s_!lYog!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb345ad9e-53a6-4643-9f18-455e35244d0d_4000x6000.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!lYog!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb345ad9e-53a6-4643-9f18-455e35244d0d_4000x6000.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!CQjJ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F710b61bf-04f6-45b4-87c0-103f0cefb0c9_5902x4815.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!CQjJ!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F710b61bf-04f6-45b4-87c0-103f0cefb0c9_5902x4815.jpeg 424w, https://substackcdn.com/image/fetch/$s_!CQjJ!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F710b61bf-04f6-45b4-87c0-103f0cefb0c9_5902x4815.jpeg 848w, https://substackcdn.com/image/fetch/$s_!CQjJ!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F710b61bf-04f6-45b4-87c0-103f0cefb0c9_5902x4815.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!CQjJ!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F710b61bf-04f6-45b4-87c0-103f0cefb0c9_5902x4815.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!CQjJ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F710b61bf-04f6-45b4-87c0-103f0cefb0c9_5902x4815.jpeg" width="1456" height="1188" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/710b61bf-04f6-45b4-87c0-103f0cefb0c9_5902x4815.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1188,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:12926501,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://blog.floormind.com/i/165602277?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F710b61bf-04f6-45b4-87c0-103f0cefb0c9_5902x4815.jpeg&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!CQjJ!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F710b61bf-04f6-45b4-87c0-103f0cefb0c9_5902x4815.jpeg 424w, https://substackcdn.com/image/fetch/$s_!CQjJ!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F710b61bf-04f6-45b4-87c0-103f0cefb0c9_5902x4815.jpeg 848w, https://substackcdn.com/image/fetch/$s_!CQjJ!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F710b61bf-04f6-45b4-87c0-103f0cefb0c9_5902x4815.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!CQjJ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F710b61bf-04f6-45b4-87c0-103f0cefb0c9_5902x4815.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><div><hr></div><h3><strong>Look 3: Relaxed Structure</strong></h3><p>The final look was the simplest&#8212;an oversized cream shirt styled open over a crisp white shirt and wide black trousers. Paired with trainers, this outfit brought out her casual confidence. It felt like a quiet close to the day&#8212;light, breathable, self-assured.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!8EFV!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F275f8c7c-d3a7-4612-a0ec-4eb816306a98_4000x6000.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!8EFV!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F275f8c7c-d3a7-4612-a0ec-4eb816306a98_4000x6000.jpeg 424w, https://substackcdn.com/image/fetch/$s_!8EFV!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F275f8c7c-d3a7-4612-a0ec-4eb816306a98_4000x6000.jpeg 848w, https://substackcdn.com/image/fetch/$s_!8EFV!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F275f8c7c-d3a7-4612-a0ec-4eb816306a98_4000x6000.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!8EFV!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F275f8c7c-d3a7-4612-a0ec-4eb816306a98_4000x6000.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!8EFV!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F275f8c7c-d3a7-4612-a0ec-4eb816306a98_4000x6000.jpeg" width="1456" height="2184" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/275f8c7c-d3a7-4612-a0ec-4eb816306a98_4000x6000.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:2184,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1638982,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://blog.floormind.com/i/165602277?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F275f8c7c-d3a7-4612-a0ec-4eb816306a98_4000x6000.jpeg&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!8EFV!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F275f8c7c-d3a7-4612-a0ec-4eb816306a98_4000x6000.jpeg 424w, https://substackcdn.com/image/fetch/$s_!8EFV!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F275f8c7c-d3a7-4612-a0ec-4eb816306a98_4000x6000.jpeg 848w, https://substackcdn.com/image/fetch/$s_!8EFV!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F275f8c7c-d3a7-4612-a0ec-4eb816306a98_4000x6000.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!8EFV!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F275f8c7c-d3a7-4612-a0ec-4eb816306a98_4000x6000.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!bsOs!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9fcd6797-c815-45cf-9276-42365371daf2_4000x6000.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!bsOs!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9fcd6797-c815-45cf-9276-42365371daf2_4000x6000.jpeg 424w, https://substackcdn.com/image/fetch/$s_!bsOs!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9fcd6797-c815-45cf-9276-42365371daf2_4000x6000.jpeg 848w, https://substackcdn.com/image/fetch/$s_!bsOs!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9fcd6797-c815-45cf-9276-42365371daf2_4000x6000.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!bsOs!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9fcd6797-c815-45cf-9276-42365371daf2_4000x6000.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!bsOs!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9fcd6797-c815-45cf-9276-42365371daf2_4000x6000.jpeg" width="1456" height="2184" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/9fcd6797-c815-45cf-9276-42365371daf2_4000x6000.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:2184,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1473167,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://blog.floormind.com/i/165602277?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9fcd6797-c815-45cf-9276-42365371daf2_4000x6000.jpeg&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!bsOs!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9fcd6797-c815-45cf-9276-42365371daf2_4000x6000.jpeg 424w, https://substackcdn.com/image/fetch/$s_!bsOs!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9fcd6797-c815-45cf-9276-42365371daf2_4000x6000.jpeg 848w, https://substackcdn.com/image/fetch/$s_!bsOs!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9fcd6797-c815-45cf-9276-42365371daf2_4000x6000.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!bsOs!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9fcd6797-c815-45cf-9276-42365371daf2_4000x6000.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!DMGr!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6f3b1db6-8b94-4eaa-9f1a-0483f900670a_4000x6000.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!DMGr!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6f3b1db6-8b94-4eaa-9f1a-0483f900670a_4000x6000.jpeg 424w, https://substackcdn.com/image/fetch/$s_!DMGr!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6f3b1db6-8b94-4eaa-9f1a-0483f900670a_4000x6000.jpeg 848w, https://substackcdn.com/image/fetch/$s_!DMGr!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6f3b1db6-8b94-4eaa-9f1a-0483f900670a_4000x6000.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!DMGr!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6f3b1db6-8b94-4eaa-9f1a-0483f900670a_4000x6000.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!DMGr!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6f3b1db6-8b94-4eaa-9f1a-0483f900670a_4000x6000.jpeg" width="1456" height="2184" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/6f3b1db6-8b94-4eaa-9f1a-0483f900670a_4000x6000.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:2184,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:2156994,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://blog.floormind.com/i/165602277?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6f3b1db6-8b94-4eaa-9f1a-0483f900670a_4000x6000.jpeg&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!DMGr!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6f3b1db6-8b94-4eaa-9f1a-0483f900670a_4000x6000.jpeg 424w, https://substackcdn.com/image/fetch/$s_!DMGr!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6f3b1db6-8b94-4eaa-9f1a-0483f900670a_4000x6000.jpeg 848w, https://substackcdn.com/image/fetch/$s_!DMGr!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6f3b1db6-8b94-4eaa-9f1a-0483f900670a_4000x6000.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!DMGr!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6f3b1db6-8b94-4eaa-9f1a-0483f900670a_4000x6000.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Zf1B!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdc676989-1a78-4044-918d-e85bb365f443_4000x6000.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Zf1B!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdc676989-1a78-4044-918d-e85bb365f443_4000x6000.jpeg 424w, https://substackcdn.com/image/fetch/$s_!Zf1B!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdc676989-1a78-4044-918d-e85bb365f443_4000x6000.jpeg 848w, https://substackcdn.com/image/fetch/$s_!Zf1B!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdc676989-1a78-4044-918d-e85bb365f443_4000x6000.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!Zf1B!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdc676989-1a78-4044-918d-e85bb365f443_4000x6000.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Zf1B!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdc676989-1a78-4044-918d-e85bb365f443_4000x6000.jpeg" width="1456" height="2184" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/dc676989-1a78-4044-918d-e85bb365f443_4000x6000.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:2184,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:2545393,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://blog.floormind.com/i/165602277?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdc676989-1a78-4044-918d-e85bb365f443_4000x6000.jpeg&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Zf1B!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdc676989-1a78-4044-918d-e85bb365f443_4000x6000.jpeg 424w, https://substackcdn.com/image/fetch/$s_!Zf1B!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdc676989-1a78-4044-918d-e85bb365f443_4000x6000.jpeg 848w, https://substackcdn.com/image/fetch/$s_!Zf1B!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdc676989-1a78-4044-918d-e85bb365f443_4000x6000.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!Zf1B!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdc676989-1a78-4044-918d-e85bb365f443_4000x6000.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!WmJO!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F54503b76-f044-4d9a-adf5-33807721ab2b_3602x5403.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!WmJO!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F54503b76-f044-4d9a-adf5-33807721ab2b_3602x5403.jpeg 424w, https://substackcdn.com/image/fetch/$s_!WmJO!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F54503b76-f044-4d9a-adf5-33807721ab2b_3602x5403.jpeg 848w, https://substackcdn.com/image/fetch/$s_!WmJO!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F54503b76-f044-4d9a-adf5-33807721ab2b_3602x5403.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!WmJO!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F54503b76-f044-4d9a-adf5-33807721ab2b_3602x5403.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!WmJO!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F54503b76-f044-4d9a-adf5-33807721ab2b_3602x5403.jpeg" width="1456" height="2184" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/54503b76-f044-4d9a-adf5-33807721ab2b_3602x5403.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:2184,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:2298737,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://blog.floormind.com/i/165602277?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F54503b76-f044-4d9a-adf5-33807721ab2b_3602x5403.jpeg&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!WmJO!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F54503b76-f044-4d9a-adf5-33807721ab2b_3602x5403.jpeg 424w, https://substackcdn.com/image/fetch/$s_!WmJO!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F54503b76-f044-4d9a-adf5-33807721ab2b_3602x5403.jpeg 848w, https://substackcdn.com/image/fetch/$s_!WmJO!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F54503b76-f044-4d9a-adf5-33807721ab2b_3602x5403.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!WmJO!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F54503b76-f044-4d9a-adf5-33807721ab2b_3602x5403.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><div><hr></div><p>This shoot reminded me of how much joy there is in building from scratch&#8212;thrifting, layering, experimenting&#8212;and watching a look come to life on someone who carries it with ease. Jemilia brought patience, movement, and presence to each frame.</p><p><strong>Let me know your thoughts on the images. If you&#8217;re a stylist, makeup artist, or creative looking to collaborate, my inbox is open.</strong></p><p>&#8212;</p><p></p><div class="native-video-embed" data-component-name="VideoPlaceholder" data-attrs="{&quot;mediaUploadId&quot;:&quot;f0def548-503f-4872-bd5d-26bc746863dd&quot;,&quot;duration&quot;:null}"></div><p></p>]]></content:encoded></item><item><title><![CDATA[Reducing My EKS Costs: A Continuous Optimisation Journey]]></title><description><![CDATA[Strategies for Cost Efficiency Without Sacrificing Performance]]></description><link>https://blog.floormind.com/p/reducing-my-eks-costs-a-continuous</link><guid isPermaLink="false">https://blog.floormind.com/p/reducing-my-eks-costs-a-continuous</guid><dc:creator><![CDATA[Ife Junior]]></dc:creator><pubDate>Tue, 11 Feb 2025 17:48:57 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/dfe3d628-cac9-4c84-bc06-101ca779d037_1262x711.webp" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!jY9Z!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F31d46961-26eb-499e-8cc2-d981d5f5c651_1258x641.webp" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!jY9Z!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F31d46961-26eb-499e-8cc2-d981d5f5c651_1258x641.webp 424w, https://substackcdn.com/image/fetch/$s_!jY9Z!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F31d46961-26eb-499e-8cc2-d981d5f5c651_1258x641.webp 848w, https://substackcdn.com/image/fetch/$s_!jY9Z!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F31d46961-26eb-499e-8cc2-d981d5f5c651_1258x641.webp 1272w, https://substackcdn.com/image/fetch/$s_!jY9Z!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F31d46961-26eb-499e-8cc2-d981d5f5c651_1258x641.webp 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!jY9Z!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F31d46961-26eb-499e-8cc2-d981d5f5c651_1258x641.webp" width="1258" height="641" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/31d46961-26eb-499e-8cc2-d981d5f5c651_1258x641.webp&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:641,&quot;width&quot;:1258,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:65594,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/webp&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!jY9Z!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F31d46961-26eb-499e-8cc2-d981d5f5c651_1258x641.webp 424w, https://substackcdn.com/image/fetch/$s_!jY9Z!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F31d46961-26eb-499e-8cc2-d981d5f5c651_1258x641.webp 848w, https://substackcdn.com/image/fetch/$s_!jY9Z!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F31d46961-26eb-499e-8cc2-d981d5f5c651_1258x641.webp 1272w, https://substackcdn.com/image/fetch/$s_!jY9Z!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F31d46961-26eb-499e-8cc2-d981d5f5c651_1258x641.webp 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Achieving cost reduction while enhancing infrastructure is a testament to strategic decision-making and technical finesse. This accomplishment contributes to immediate cost savings and sets the stage for long-term success and sustainability in cloud operations.</p><p>Cost is always a hot topic when running Kubernetes in the cloud, especially for small businesses or teams with limited budgets. The challenge is to find the right balance between maintaining a reliable, scalable, and secure infrastructure and optimising costs.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.floormind.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Ife Ayelabola is a reader-supported publication. To receive new posts and support my work, consider becoming a free or paid subscriber.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p>This achievement demonstrated a keen understanding of needs by recognising the importance of cost efficiency without compromising reliability, scalability, and security. Cost savings were achieved through meticulous analysis and optimisation of a Kubernetes deployment on Amazon EKS. This showcases proficiency in managing cloud resources effectively, leveraging only what is necessary to meet personal and business objectives.</p><p>I recently reduced my EKS costs from $404 to $280 while maintaining the same infrastructure and adding two extra nodes. This demonstrates my ability to support scalability and flexibility, which are crucial for adapting to evolving business requirements and accommodating growth without incurring unnecessary expenses. While this is just a small win in the grand scheme of things, as the saying goes, a win is a win.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!eLyg!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2a6f1b53-3b18-49e4-9c94-d48bd0771a94_1277x1301.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!eLyg!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2a6f1b53-3b18-49e4-9c94-d48bd0771a94_1277x1301.jpeg 424w, https://substackcdn.com/image/fetch/$s_!eLyg!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2a6f1b53-3b18-49e4-9c94-d48bd0771a94_1277x1301.jpeg 848w, https://substackcdn.com/image/fetch/$s_!eLyg!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2a6f1b53-3b18-49e4-9c94-d48bd0771a94_1277x1301.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!eLyg!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2a6f1b53-3b18-49e4-9c94-d48bd0771a94_1277x1301.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!eLyg!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2a6f1b53-3b18-49e4-9c94-d48bd0771a94_1277x1301.jpeg" width="1277" height="1301" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/2a6f1b53-3b18-49e4-9c94-d48bd0771a94_1277x1301.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1301,&quot;width&quot;:1277,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:47789,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!eLyg!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2a6f1b53-3b18-49e4-9c94-d48bd0771a94_1277x1301.jpeg 424w, https://substackcdn.com/image/fetch/$s_!eLyg!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2a6f1b53-3b18-49e4-9c94-d48bd0771a94_1277x1301.jpeg 848w, https://substackcdn.com/image/fetch/$s_!eLyg!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2a6f1b53-3b18-49e4-9c94-d48bd0771a94_1277x1301.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!eLyg!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2a6f1b53-3b18-49e4-9c94-d48bd0771a94_1277x1301.jpeg 1456w" sizes="100vw"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!YLGi!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F02b9c39b-653c-456d-9fc0-cad1c031ac67_1298x1302.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!YLGi!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F02b9c39b-653c-456d-9fc0-cad1c031ac67_1298x1302.jpeg 424w, https://substackcdn.com/image/fetch/$s_!YLGi!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F02b9c39b-653c-456d-9fc0-cad1c031ac67_1298x1302.jpeg 848w, https://substackcdn.com/image/fetch/$s_!YLGi!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F02b9c39b-653c-456d-9fc0-cad1c031ac67_1298x1302.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!YLGi!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F02b9c39b-653c-456d-9fc0-cad1c031ac67_1298x1302.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!YLGi!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F02b9c39b-653c-456d-9fc0-cad1c031ac67_1298x1302.jpeg" width="1298" height="1302" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/02b9c39b-653c-456d-9fc0-cad1c031ac67_1298x1302.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1302,&quot;width&quot;:1298,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:49378,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!YLGi!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F02b9c39b-653c-456d-9fc0-cad1c031ac67_1298x1302.jpeg 424w, https://substackcdn.com/image/fetch/$s_!YLGi!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F02b9c39b-653c-456d-9fc0-cad1c031ac67_1298x1302.jpeg 848w, https://substackcdn.com/image/fetch/$s_!YLGi!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F02b9c39b-653c-456d-9fc0-cad1c031ac67_1298x1302.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!YLGi!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F02b9c39b-653c-456d-9fc0-cad1c031ac67_1298x1302.jpeg 1456w" sizes="100vw"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h2>Understanding AWS Cost Structure</h2><p>Before diving into how I reduced my EKS costs, it's essential to understand how AWS charges for its services and what factors impact the overall cost of running Kubernetes in the cloud. AWS pricing is based on multiple factors: compute, storage, and data transfer.</p><p>Here are some key cost-impacting elements in AWS:</p><ul><li><p><strong>Cross Availability Zone (AZ) Communication:</strong> Data transfers between different AZs within the same region incur costs. While redundancy across AZs is essential for high availability, it can increase expenses if not appropriately managed.</p></li><li><p><strong>Cross-Region Data Transfer:</strong> Moving data between AWS regions has higher costs than intra-region transfers, so optimising data flow where possible is crucial.</p></li><li><p><strong>Requests Leaving the Internal AWS Network:</strong> Any data egressing from AWS to the public internet incurs additional charges. These costs can add up quickly if your workloads interact with external APIs or serve external traffic.</p></li><li><p><strong>Storage and Persistent Volumes:</strong> Unused or over-provisioned storage, especially persistent volumes allocated to workloads, can lead to unnecessary charges.</p></li><li><p><strong>Idle and Underutilised Compute Resources:</strong> Running EC2 instances or Kubernetes nodes with low utilisation leads to wasted spending.</p></li></ul><p>By understanding these key cost components, I could identify optimisation areas that would most impact reducing my expenses.</p><h2>How I Reduced My EKS Costs</h2><p>The key to optimising any cloud infrastructure is visibility. You can&#8217;t fix what you don&#8217;t understand. I deployed an open-source cost-monitoring tool called Kubecost into my EKS cluster to better understand my Kubernetes-related expenses.</p><h3>Deploying Kubecost for Cost Visibility</h3><p>Kubecost is a tool that provides real-time cost monitoring for Kubernetes workloads. It breaks down expenses by namespace, pod, and service. Integrating Kubecost into my cluster allowed me to track my spending and identify savings opportunities.</p><ul><li><p>Once Kubecost was running, I started analysing my infrastructure costs over time. I discovered a few key areas where I was overspending:</p></li><li><p>Underutilised Nodes: Some nodes ran with low CPU and memory usage, meaning I was paying for resources I wasn&#8217;t fully utilising.</p></li><li><p>Inefficient Pod Scheduling: Certain workloads ran on more expensive instances when they could be distributed more efficiently.</p></li><li><p>EBS Volume Costs: I allocated persistent volumes that weren&#8217;t fully utilised.</p></li></ul><h2>The Optimisation Process</h2><p>Armed with the insights from Kubecost, I took the following steps to optimise my EKS setup:</p><ol><li><p><strong>Right-Sizing Nodes: </strong>I reassessed and optimised my instance types for my workloads instead of sticking with my previous node configurations. This allowed me to switch to a more cost-effective instance type without sacrificing performance.</p></li><li><p><strong>Bin Packing Workloads More Efficiently: </strong>I improved pod scheduling to use my nodes more efficiently by fine-tuning Kubernetes resource requests and limits. This allowed me to add two extra nodes while reducing my overall costs.</p></li><li><p><strong>Cleaning Up Unused Resources: </strong>Kubecost helped me identify idle volumes and resources accumulating unnecessary costs. By removing or resizing them, I reduced additional expenses.</p></li><li><p><strong>Spot Instances and Savings Plans:</strong> While I haven&#8217;t fully transitioned to spot instances yet, I started experimenting with them for non-critical workloads, which has led to further cost reductions.</p></li></ol><h2>Looking Ahead</h2><p>This achievement shows adeptness at navigating the complexities of Kubernetes and cloud infrastructure. Technical expertise has been instrumental in realising these improvements, from fine-tuning resource allocation to implementing cost-saving measures without compromising performance.</p><p>Treating this achievement as a win and celebrating it encourages continuous improvement. This mindset ensures that cost optimisation efforts remain prioritised, leading to further enhancements and efficiencies over time.</p><p>Moving forward, I plan to:</p><ul><li><p>Automate cost-monitoring alerts using Kubecost.</p></li><li><p>Experiment with spot instances for more workloads.</p></li><li><p>Explore additional cost-saving features like AWS Graviton-based instances.</p></li><li><p>Implement cluster auto-scaling more aggressively to match workload demand.</p></li></ul><p>Optimising costs while enhancing infrastructure showcases proficiency in balancing business objectives with technical knowledge. I enjoy tackling the challenge of maintaining a scalable and resilient Kubernetes setup while controlling costs.</p><p>This small win has already proven valuable, and I&#8217;m excited to see what further cost-saving measures I can implement in the coming months.</p><p><strong>What strategies have worked for you if you also work on Kubernetes cost optimisation? Let's discuss them!</strong></p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.floormind.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Ife Ayelabola is a reader-supported publication. To receive new posts and support my work, consider becoming a free or paid subscriber.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item><item><title><![CDATA[The Youthful Spirit of Tropical Paradise]]></title><description><![CDATA[A Photo Story]]></description><link>https://blog.floormind.com/p/the-youthful-spirit-of-tropical-paradise</link><guid isPermaLink="false">https://blog.floormind.com/p/the-youthful-spirit-of-tropical-paradise</guid><pubDate>Thu, 06 Feb 2025 18:02:14 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!Saej!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe6ad0d63-1f42-420e-bb7e-48ec2a0170c4_1667x2500.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In early 2024, I travelled to the Dominican Republic with my camera, eager to capture something beyond the postcard-perfect beaches and tourist-laden resorts. What I found was a familiar story&#8212;one that resonated deeply with my own past. In the vibrant streets and sunlit alleyways, I met children whose joy was infectious and whose resilience was palpable. Their laughter, play, and ability to create something out of nothing reminded me of my childhood in Lagos, Nigeria.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Saej!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe6ad0d63-1f42-420e-bb7e-48ec2a0170c4_1667x2500.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Saej!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe6ad0d63-1f42-420e-bb7e-48ec2a0170c4_1667x2500.jpeg 424w, https://substackcdn.com/image/fetch/$s_!Saej!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe6ad0d63-1f42-420e-bb7e-48ec2a0170c4_1667x2500.jpeg 848w, https://substackcdn.com/image/fetch/$s_!Saej!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe6ad0d63-1f42-420e-bb7e-48ec2a0170c4_1667x2500.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!Saej!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe6ad0d63-1f42-420e-bb7e-48ec2a0170c4_1667x2500.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Saej!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe6ad0d63-1f42-420e-bb7e-48ec2a0170c4_1667x2500.jpeg" width="1456" height="2184" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/e6ad0d63-1f42-420e-bb7e-48ec2a0170c4_1667x2500.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:2184,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:701688,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Saej!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe6ad0d63-1f42-420e-bb7e-48ec2a0170c4_1667x2500.jpeg 424w, https://substackcdn.com/image/fetch/$s_!Saej!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe6ad0d63-1f42-420e-bb7e-48ec2a0170c4_1667x2500.jpeg 848w, https://substackcdn.com/image/fetch/$s_!Saej!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe6ad0d63-1f42-420e-bb7e-48ec2a0170c4_1667x2500.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!Saej!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe6ad0d63-1f42-420e-bb7e-48ec2a0170c4_1667x2500.jpeg 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">The Youthful Spirit of Tropical Paradise (2024)</figcaption></figure></div><p>Although I was fortunate to come from a family that could provide me with the opportunities I needed, I also recognised the experience of living in an environment that wasn&#8217;t always advantageous. These are environments with limited resources, and opportunities are even scarcer, but we compensate for our material deficiencies with imagination, community, and the incredible energy of youthful joy. We transformed the streets into our playground, simple objects into toys, and every moment into a memory that would last a lifetime. Observing these children in the Dominican Republic, I recognised that same spirit&#8212;an unbreakable resilience that turns any place into a paradise, regardless of circumstances.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.floormind.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Ife Ayelabola is a reader-supported publication. To receive new posts and support my work, consider becoming a free or paid subscriber.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><div class="image-gallery-embed" data-attrs="{&quot;gallery&quot;:{&quot;images&quot;:[{&quot;type&quot;:&quot;image/jpeg&quot;,&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/64439317-524a-4a4d-8b70-941603c50e7a_1667x2500.jpeg&quot;},{&quot;type&quot;:&quot;image/jpeg&quot;,&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/7771ebb0-bda2-4184-b435-f679de3655c4_1667x2500.jpeg&quot;},{&quot;type&quot;:&quot;image/jpeg&quot;,&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/4f996edd-0ea6-4866-9702-044895239eea_1667x2500.jpeg&quot;},{&quot;type&quot;:&quot;image/jpeg&quot;,&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/9e7e1425-6b7b-4d50-b5e2-ed087451664b_1667x2500.jpeg&quot;}],&quot;caption&quot;:&quot;The Youthful Spirit of Tropical Paradise (2024)&quot;,&quot;alt&quot;:&quot;&quot;,&quot;staticGalleryImage&quot;:{&quot;type&quot;:&quot;image/png&quot;,&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/94390f89-f90b-45d5-b0de-03678f69a03a_1456x1456.png&quot;}},&quot;isEditorNode&quot;:true}"></div><p>I spent days photographing them, watching as they raced one another down the dusty roads of a beautiful tropical country, played games, and shared the kind of laughter that can only come from a pure and unburdened heart. They reminded me of my childhood friends back in Lagos&#8212;the way we would chase after each other in the rain and find adventure in the most mundane corners of our world.</p><p>What struck me most was their ability to find joy in a world that shapes them in so many ways. The Dominican Republic, like many places, is a land of contrasts&#8212;stunning landscapes, vibrant communities, and a spirit that shines through in its people. These children, much like the ones I grew up with, are not defined by circumstances but by their resilience, their energy, and their endless creativity. They embrace what surrounds them&#8212;the warmth of friendship, the excitement of discovery, and the simple pleasures that make childhood so full of life, turning even the ordinary into something extraordinary through their boundless imagination and endless creativity.</p><div class="image-gallery-embed" data-attrs="{&quot;gallery&quot;:{&quot;images&quot;:[{&quot;type&quot;:&quot;image/jpeg&quot;,&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/8123beee-4629-47a2-9796-23da812b1143_1667x2500.jpeg&quot;}],&quot;caption&quot;:&quot;The Youthful Spirit of Tropical Paradise (2024)&quot;,&quot;alt&quot;:&quot;&quot;,&quot;staticGalleryImage&quot;:{&quot;type&quot;:&quot;image/jpeg&quot;,&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/8123beee-4629-47a2-9796-23da812b1143_1667x2500.jpeg&quot;}},&quot;isEditorNode&quot;:true}"></div><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!MUmC!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fad7bf414-24d5-4a0d-8b01-d2c311408e84_1667x2500.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!MUmC!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fad7bf414-24d5-4a0d-8b01-d2c311408e84_1667x2500.jpeg 424w, https://substackcdn.com/image/fetch/$s_!MUmC!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fad7bf414-24d5-4a0d-8b01-d2c311408e84_1667x2500.jpeg 848w, https://substackcdn.com/image/fetch/$s_!MUmC!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fad7bf414-24d5-4a0d-8b01-d2c311408e84_1667x2500.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!MUmC!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fad7bf414-24d5-4a0d-8b01-d2c311408e84_1667x2500.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!MUmC!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fad7bf414-24d5-4a0d-8b01-d2c311408e84_1667x2500.jpeg" width="1456" height="2184" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/ad7bf414-24d5-4a0d-8b01-d2c311408e84_1667x2500.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:2184,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:344612,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!MUmC!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fad7bf414-24d5-4a0d-8b01-d2c311408e84_1667x2500.jpeg 424w, https://substackcdn.com/image/fetch/$s_!MUmC!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fad7bf414-24d5-4a0d-8b01-d2c311408e84_1667x2500.jpeg 848w, https://substackcdn.com/image/fetch/$s_!MUmC!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fad7bf414-24d5-4a0d-8b01-d2c311408e84_1667x2500.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!MUmC!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fad7bf414-24d5-4a0d-8b01-d2c311408e84_1667x2500.jpeg 1456w" sizes="100vw"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">The Youthful Spirit of Tropical Paradise (2024)</figcaption></figure></div><p>Photography has always been more than just a craft for me. It&#8217;s a way to tell stories that might otherwise go unnoticed and to capture emotions that words sometimes fail to articulate. This series, The Youthful Spirit of Tropical Paradise (2024), honours the universal spirit of youth&#8212;the ability to find happiness even in adversity and to create light in spaces where darkness might otherwise prevail. </p><p>Through these images, viewers see more than just the faces of these children&#8212;they witness the stories they tell. From the young girl having her hair done under the scorching sun to friends catching up on the school bus after a long day, these moments capture the essence of childhood. </p><div class="image-gallery-embed" data-attrs="{&quot;gallery&quot;:{&quot;images&quot;:[{&quot;type&quot;:&quot;image/jpeg&quot;,&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/d7c378ca-a5a0-45a0-9459-f4f5b5186348_1667x2500.jpeg&quot;}],&quot;caption&quot;:&quot;The Youthful Spirit of Tropical Paradise (2024)&quot;,&quot;alt&quot;:&quot;&quot;,&quot;staticGalleryImage&quot;:{&quot;type&quot;:&quot;image/jpeg&quot;,&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/d7c378ca-a5a0-45a0-9459-f4f5b5186348_1667x2500.jpeg&quot;}},&quot;isEditorNode&quot;:true}"></div><div class="image-gallery-embed" data-attrs="{&quot;gallery&quot;:{&quot;images&quot;:[{&quot;type&quot;:&quot;image/jpeg&quot;,&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/85974bab-bb49-49ad-a0aa-f2c522d811cf_1333x2000.jpeg&quot;},{&quot;type&quot;:&quot;image/jpeg&quot;,&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/73947f65-d05d-424c-bf28-071e4d03403c_1333x2000.jpeg&quot;},{&quot;type&quot;:&quot;image/jpeg&quot;,&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/08f2e764-57f3-4a58-bb7b-247eed4cb2d6_1333x2000.jpeg&quot;}],&quot;caption&quot;:&quot;The Youthful Spirit of Tropical Paradise (2024)&quot;,&quot;alt&quot;:&quot;&quot;,&quot;staticGalleryImage&quot;:{&quot;type&quot;:&quot;image/png&quot;,&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/8ff3529f-5096-43f2-9611-c4468e8cab81_1456x474.png&quot;}},&quot;isEditorNode&quot;:true}"></div><p>These stories speak of perseverance, the beauty of growing up in a paradise shaped by nature&#8217;s abundance, and the unbreakable joy that defines childhood, no matter where in the world you are. They reveal the quiet strength found in everyday moments&#8212;the laughter shared between friends, the determination in a child&#8217;s eyes as they chase their dreams, and the simple pleasures of playing beneath open skies. They remind us that childhood is a time of boundless wonder, where imagination flourishes, friendships deepen, and joy is discovered in life&#8217;s simplest moments. </p><p>Because, in the end, paradise isn&#8217;t just a place. It&#8217;s a feeling, a moment, a state of mind. And these children have mastered the art of living in it.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!E61j!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F533a1730-8da7-49a5-9ca8-e6c431fac9bf_1546x2500.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!E61j!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F533a1730-8da7-49a5-9ca8-e6c431fac9bf_1546x2500.jpeg 424w, https://substackcdn.com/image/fetch/$s_!E61j!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F533a1730-8da7-49a5-9ca8-e6c431fac9bf_1546x2500.jpeg 848w, https://substackcdn.com/image/fetch/$s_!E61j!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F533a1730-8da7-49a5-9ca8-e6c431fac9bf_1546x2500.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!E61j!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F533a1730-8da7-49a5-9ca8-e6c431fac9bf_1546x2500.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!E61j!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F533a1730-8da7-49a5-9ca8-e6c431fac9bf_1546x2500.jpeg" width="1456" height="2354" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/533a1730-8da7-49a5-9ca8-e6c431fac9bf_1546x2500.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:2354,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:396243,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!E61j!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F533a1730-8da7-49a5-9ca8-e6c431fac9bf_1546x2500.jpeg 424w, https://substackcdn.com/image/fetch/$s_!E61j!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F533a1730-8da7-49a5-9ca8-e6c431fac9bf_1546x2500.jpeg 848w, https://substackcdn.com/image/fetch/$s_!E61j!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F533a1730-8da7-49a5-9ca8-e6c431fac9bf_1546x2500.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!E61j!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F533a1730-8da7-49a5-9ca8-e6c431fac9bf_1546x2500.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">The Youthful Spirit of Tropical Paradise (2024)</figcaption></figure></div><p></p><p></p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.floormind.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Ife Ayelabola is a reader-supported publication. To receive new posts and support my work, consider becoming a free or paid subscriber.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item><item><title><![CDATA[Understanding Threat Modelling: ]]></title><description><![CDATA[A Critical Approach to Cybersecurity]]></description><link>https://blog.floormind.com/p/understanding-threat-modelling</link><guid isPermaLink="false">https://blog.floormind.com/p/understanding-threat-modelling</guid><dc:creator><![CDATA[Ife Junior]]></dc:creator><pubDate>Mon, 03 Feb 2025 07:15:19 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!23lN!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F436306d4-10cb-4fd4-9e08-7264691942c8_680x680.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!23lN!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F436306d4-10cb-4fd4-9e08-7264691942c8_680x680.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!23lN!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F436306d4-10cb-4fd4-9e08-7264691942c8_680x680.png 424w, https://substackcdn.com/image/fetch/$s_!23lN!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F436306d4-10cb-4fd4-9e08-7264691942c8_680x680.png 848w, https://substackcdn.com/image/fetch/$s_!23lN!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F436306d4-10cb-4fd4-9e08-7264691942c8_680x680.png 1272w, https://substackcdn.com/image/fetch/$s_!23lN!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F436306d4-10cb-4fd4-9e08-7264691942c8_680x680.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!23lN!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F436306d4-10cb-4fd4-9e08-7264691942c8_680x680.png" width="680" height="680" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/436306d4-10cb-4fd4-9e08-7264691942c8_680x680.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:680,&quot;width&quot;:680,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:36433,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!23lN!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F436306d4-10cb-4fd4-9e08-7264691942c8_680x680.png 424w, https://substackcdn.com/image/fetch/$s_!23lN!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F436306d4-10cb-4fd4-9e08-7264691942c8_680x680.png 848w, https://substackcdn.com/image/fetch/$s_!23lN!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F436306d4-10cb-4fd4-9e08-7264691942c8_680x680.png 1272w, https://substackcdn.com/image/fetch/$s_!23lN!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F436306d4-10cb-4fd4-9e08-7264691942c8_680x680.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>In an age of continually evolving cyber threats, anticipating and mitigating security risks is more crucial than ever. One of the most effective ways to achieve this is through threat modelling, a structured approach to identifying vulnerabilities, understanding potential attack vectors, and mitigating risks before they materialise into security incidents. Threat modelling is not just a technical exercise but a strategic process enabling organisations to secure their applications, systems, and infrastructure proactively.</p><p>At its core, threat modelling involves systematically evaluating how an application, system, or process might be attacked. This approach enables security professionals, developers, and architects to anticipate weaknesses and devise robust countermeasures before they can be exploited. Unlike traditional reactive security measures that address vulnerabilities after a breach, threat modelling is a proactive discipline that aims to strengthen defences from the outset.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.floormind.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Ife Ayelabola is a reader-supported publication. To receive new posts and support my work, consider becoming a free or paid subscriber.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><h3>The Foundation of Threat Modelling</h3><p>To understand threat modelling, it is essential to distinguish between key security concepts. A <strong>weakness</strong> is an inherent flaw in an application&#8217;s design or implementation that can be exploited if left unaddressed. A <strong>vulnerability</strong> manifests a weakness an attacker can leverage to compromise a system. Together, these elements form the foundation of security risks that must be mitigated.</p><p>An attack or security incident typically consists of three components:</p><ul><li><p><strong>The target</strong>, which represents a valuable asset, such as a database containing sensitive user information.</p></li><li><p><strong>The attack vector</strong> is the route through which an attacker gains access, such as an unprotected form on a website.</p></li><li><p><strong>The actor</strong>, the individual or entity executing the attack.</p></li></ul><p>The concept of an <strong>attack surface</strong> further broadens the discussion. It encapsulates all the potential entry points that an attacker can exploit, including physical elements like hardware, software components such as operating systems and applications, and network elements like open ports and firewall configurations.</p><h3>Assessing Risk: Likelihood and Impact</h3><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!vtQO!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F72ebdabf-366c-4312-8a99-338ab145a57b_1200x675.webp" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!vtQO!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F72ebdabf-366c-4312-8a99-338ab145a57b_1200x675.webp 424w, https://substackcdn.com/image/fetch/$s_!vtQO!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F72ebdabf-366c-4312-8a99-338ab145a57b_1200x675.webp 848w, https://substackcdn.com/image/fetch/$s_!vtQO!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F72ebdabf-366c-4312-8a99-338ab145a57b_1200x675.webp 1272w, https://substackcdn.com/image/fetch/$s_!vtQO!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F72ebdabf-366c-4312-8a99-338ab145a57b_1200x675.webp 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!vtQO!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F72ebdabf-366c-4312-8a99-338ab145a57b_1200x675.webp" width="1200" height="675" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/72ebdabf-366c-4312-8a99-338ab145a57b_1200x675.webp&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:675,&quot;width&quot;:1200,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:102230,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/webp&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!vtQO!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F72ebdabf-366c-4312-8a99-338ab145a57b_1200x675.webp 424w, https://substackcdn.com/image/fetch/$s_!vtQO!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F72ebdabf-366c-4312-8a99-338ab145a57b_1200x675.webp 848w, https://substackcdn.com/image/fetch/$s_!vtQO!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F72ebdabf-366c-4312-8a99-338ab145a57b_1200x675.webp 1272w, https://substackcdn.com/image/fetch/$s_!vtQO!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F72ebdabf-366c-4312-8a99-338ab145a57b_1200x675.webp 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Threat modelling is deeply rooted in risk assessment. Security teams evaluate risk based on two primary factors: <strong>likelihood</strong> and <strong>impact</strong>. Likelihood refers to the probability of a given threat occurring, while impact measures the severity of consequences should an attack be successful. Together, these elements define the overall risk:</p><blockquote><p>risk = impact * likelihood</p></blockquote><p>Understanding this equation helps prioritise security efforts, ensuring the most critical vulnerabilities are addressed first. Threat modelling allows organisations to move beyond vague security concerns and focus on concrete, actionable threats.</p><h3>The Value of Threat Modelling in Cybersecurity</h3><p>The importance of threat modelling cannot be overstated. By incorporating it into the development lifecycle, organisations gain significant advantages:</p><ul><li><p><strong>Proactive security</strong>: Anticipating threats before they materialise reduces the risk of security breaches.</p></li><li><p><strong>Efficiency in security responses</strong>: Preparedness leads to faster, more effective incident handling.</p></li><li><p><strong>Improved prioritisation</strong>: Resources can be allocated effectively by addressing the highest-impact threats first.</p></li><li><p><strong>Enhanced security awareness</strong>: Development teams gain a deeper understanding of security considerations, leading to more secure coding practices.</p></li></ul><h3>When and How to Conduct Threat Modelling</h3><p>Threat modelling is most effective when performed early in the development process. Ideally, it should begin in the requirement gathering and design phases, allowing security concerns to be addressed before they become deeply embedded in the system. However, continuous threat modelling throughout the software development lifecycle&#8212;particularly in Agile and DevOps environments&#8212;ensures that security remains a persistent focus.</p><p>There are various methodologies for implementing threat modelling, each with unique strengths. Some organisations adopt an <strong>asset-centric approach</strong>, securing critical assets like databases and servers. Others take an <strong>attacker-centric approach</strong>, attempting to think like a malicious actor to identify potential entry points and weaknesses. Another common strategy is the <strong>application-centric approach</strong>, where an application's architecture and data flows are mapped to assess security risks at each stage.</p><h3>Choosing the Right Methodology</h3><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!3nNg!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9413d2f1-fba4-4f63-b6fa-129a0aba5c19_643x360.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!3nNg!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9413d2f1-fba4-4f63-b6fa-129a0aba5c19_643x360.jpeg 424w, https://substackcdn.com/image/fetch/$s_!3nNg!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9413d2f1-fba4-4f63-b6fa-129a0aba5c19_643x360.jpeg 848w, https://substackcdn.com/image/fetch/$s_!3nNg!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9413d2f1-fba4-4f63-b6fa-129a0aba5c19_643x360.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!3nNg!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9413d2f1-fba4-4f63-b6fa-129a0aba5c19_643x360.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!3nNg!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9413d2f1-fba4-4f63-b6fa-129a0aba5c19_643x360.jpeg" width="643" height="360" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/9413d2f1-fba4-4f63-b6fa-129a0aba5c19_643x360.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:360,&quot;width&quot;:643,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:57086,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!3nNg!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9413d2f1-fba4-4f63-b6fa-129a0aba5c19_643x360.jpeg 424w, https://substackcdn.com/image/fetch/$s_!3nNg!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9413d2f1-fba4-4f63-b6fa-129a0aba5c19_643x360.jpeg 848w, https://substackcdn.com/image/fetch/$s_!3nNg!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9413d2f1-fba4-4f63-b6fa-129a0aba5c19_643x360.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!3nNg!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9413d2f1-fba4-4f63-b6fa-129a0aba5c19_643x360.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Selecting the right threat modelling methodology depends on several factors, including organisational maturity, security expertise, and business goals. Popular methodologies include:</p><ul><li><p><strong>PASTA (Process for Attack Simulation and Threat Analysis)</strong> is an iterative, business-driven approach emphasising dynamic threat landscapes.</p></li><li><p><strong>Microsoft Threat Modelling</strong>: A developer-friendly framework that integrates seamlessly into the software development lifecycle.</p></li><li><p><strong>OCTAVE (Operationally Critical Threat, Asset and Vulnerability Evaluation)</strong>: A risk-analysis framework for evaluating organisational security risks.</p></li><li><p><strong>TRIKE</strong>: An automated, asset-centric threat modelling tool for risk assessment.</p></li><li><p><strong>VAST (Visual Agile Simple Threat Modelling)</strong>: Tailored for Agile teams, enabling application and operational threat modelling in dynamic development environments.</p></li></ul><p>Each methodology offers unique advantages, and organisations must choose an approach that aligns with their security needs and workflows.</p><h3>The Threat Modelling Process in Action</h3><p>Regardless of the methodology chosen, the general process of threat modelling follows a structured series of steps:</p><ol><li><p><strong>Define the scope</strong>: Identify what assets and components are within the scope for analysis.</p></li><li><p><strong>Map the system architecture</strong>: Create data flow diagrams to visualise the system's architecture.</p></li><li><p><strong>Identify security risks</strong>: Assess potential threats, vulnerabilities, and attack vectors.</p></li><li><p><strong>Categorise threats</strong>: Use frameworks like STRIDE (Spoofing, Tampering, Repudiation, Information Disclosure, Denial of Service, and Elevation of Privilege) to classify threats.</p></li><li><p><strong>Prioritise risks</strong>: Rank threats based on their impact and likelihood.</p></li><li><p><strong>Implement countermeasures</strong>: Develop security controls to mitigate identified threats.</p></li><li><p><strong>Document and iterate</strong>: Maintain a continuous feedback loop to refine the security posture.</p></li></ol><h3>Conclusion</h3><p>Threat modelling is not a one-time task but an ongoing discipline that should be integrated into every software and system development stage. By identifying potential threats early, organisations can proactively strengthen their security defences, minimise risks, and build resilient applications.</p><p>Whether leveraging an asset, attacker, or application-centric approach, the key to effective threat modelling lies in systematic assessment, informed prioritisation, and continuous iteration. In today&#8217;s cyber landscape, organisations that invest in proactive security measures like threat modelling are best positioned to withstand evolving threats and safeguard their digital assets.</p><h4>References:</h4><p><a href="https://www.threatmodelingmanifesto.org/">Threat Modeling Manifesto</a></p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.floormind.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Ife Ayelabola is a reader-supported publication. To receive new posts and support my work, consider becoming a free or paid subscriber.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item><item><title><![CDATA[Logging Best Practices in Microservices and Kubernetes-Based Applications]]></title><description><![CDATA[A Comprehensive guide]]></description><link>https://blog.floormind.com/p/logging-best-practices-in-microservices</link><guid isPermaLink="false">https://blog.floormind.com/p/logging-best-practices-in-microservices</guid><dc:creator><![CDATA[Ife Junior]]></dc:creator><pubDate>Wed, 29 Jan 2025 18:55:54 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!9vu3!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8e22af9e-56b4-477b-bdcf-b5dd4e79fb52_1024x683.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!9vu3!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8e22af9e-56b4-477b-bdcf-b5dd4e79fb52_1024x683.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!9vu3!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8e22af9e-56b4-477b-bdcf-b5dd4e79fb52_1024x683.jpeg 424w, https://substackcdn.com/image/fetch/$s_!9vu3!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8e22af9e-56b4-477b-bdcf-b5dd4e79fb52_1024x683.jpeg 848w, https://substackcdn.com/image/fetch/$s_!9vu3!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8e22af9e-56b4-477b-bdcf-b5dd4e79fb52_1024x683.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!9vu3!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8e22af9e-56b4-477b-bdcf-b5dd4e79fb52_1024x683.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!9vu3!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8e22af9e-56b4-477b-bdcf-b5dd4e79fb52_1024x683.jpeg" width="1024" height="683" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/8e22af9e-56b4-477b-bdcf-b5dd4e79fb52_1024x683.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:683,&quot;width&quot;:1024,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:246493,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!9vu3!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8e22af9e-56b4-477b-bdcf-b5dd4e79fb52_1024x683.jpeg 424w, https://substackcdn.com/image/fetch/$s_!9vu3!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8e22af9e-56b4-477b-bdcf-b5dd4e79fb52_1024x683.jpeg 848w, https://substackcdn.com/image/fetch/$s_!9vu3!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8e22af9e-56b4-477b-bdcf-b5dd4e79fb52_1024x683.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!9vu3!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8e22af9e-56b4-477b-bdcf-b5dd4e79fb52_1024x683.jpeg 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>A few years ago, I wrote about logging best practices in traditional applications on my <a href="https://medium.com/@floormind/logging-some-good-practices-a2e2552087af">Medium</a> account. However, logging has also evolved as software architectures have shifted towards microservices and containerised environments like Kubernetes. The old strategies still apply but must be extended to work effectively in distributed dynamic systems.</p><p>This revised post explores effective logging practices in microservices and Kubernetes applications. It clarifies each concept, details successful implementation strategies, and highlights key takeaways.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.floormind.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><div><hr></div><h3>Structured Logging: Essential for Scalability and Security</h3><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!cIGm!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F89717f4a-dcd0-407f-a2c3-e304df10c5ce_800x450.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!cIGm!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F89717f4a-dcd0-407f-a2c3-e304df10c5ce_800x450.png 424w, https://substackcdn.com/image/fetch/$s_!cIGm!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F89717f4a-dcd0-407f-a2c3-e304df10c5ce_800x450.png 848w, https://substackcdn.com/image/fetch/$s_!cIGm!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F89717f4a-dcd0-407f-a2c3-e304df10c5ce_800x450.png 1272w, https://substackcdn.com/image/fetch/$s_!cIGm!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F89717f4a-dcd0-407f-a2c3-e304df10c5ce_800x450.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!cIGm!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F89717f4a-dcd0-407f-a2c3-e304df10c5ce_800x450.png" width="800" height="450" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/89717f4a-dcd0-407f-a2c3-e304df10c5ce_800x450.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:450,&quot;width&quot;:800,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:378956,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!cIGm!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F89717f4a-dcd0-407f-a2c3-e304df10c5ce_800x450.png 424w, https://substackcdn.com/image/fetch/$s_!cIGm!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F89717f4a-dcd0-407f-a2c3-e304df10c5ce_800x450.png 848w, https://substackcdn.com/image/fetch/$s_!cIGm!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F89717f4a-dcd0-407f-a2c3-e304df10c5ce_800x450.png 1272w, https://substackcdn.com/image/fetch/$s_!cIGm!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F89717f4a-dcd0-407f-a2c3-e304df10c5ce_800x450.png 1456w" sizes="100vw"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><h4>What is Structured Logging?</h4><p>Structured logging is a way of logging data in a predictable, machine-readable format, often JSON. In microservices, structured logging ensures logs are easily parsed, searchable, and consistently formatted across different services. However, logging should also be considered part of <strong>application security</strong>. For example, we audit infrastructure for security and compliance, and logging allows us to audit application events, trace back actions, and detect anomalies.</p><h4>Why Logging is a Security Protocol</h4><p>Logging isn&#8217;t just for debugging&#8212;it provides a historical record of system events, making it a crucial security component. By maintaining structured logs, organisations can:</p><ul><li><p>Detect <strong>tampering attempts</strong> or suspicious activities in real time.</p></li><li><p>Identify unauthorised access attempts and <strong>security breaches</strong>.</p></li><li><p>Ensure compliance with industry regulations like <strong>SOC 2, HIPAA, and GDPR</strong>.</p></li><li><p>Investigate incidents through <strong>forensic analysis</strong> when issues arise.</p></li><li><p>Mitigate <strong>repudiation attacks</strong>, where users deny performing specific actions by keeping immutable logs of all key events.</p></li></ul><h5>Log Privacy &amp; Data Anonymisation</h5><p>Logs should avoid storing sensitive user data to comply with regulations like GDPR and CCPA. Tokenisation and redaction can help prevent the exposure of personal data.</p><h6>Example: Instead of logging:</h6><pre><code><code>{ "email": "user@example.com", "creditCard": "4242424242424242" }</code></code></pre><h6>Use: </h6><pre><code><code>{ "email": "u***@example.com", "creditCard": "**** **** **** 4242" }</code></code></pre><h4>How to Implement Structured Logging Securely</h4><ul><li><p>Use JSON format for logs instead of unstructured text.</p></li><li><p>Ensure all logs contain key security-relevant fields such as timestamps, request origins, and user activity.</p></li><li><p>Implement <strong>role-based access control (RBAC)</strong> to restrict access to logs.</p></li><li><p>Encrypt logs <strong>both in transit and at rest</strong>.</p></li><li><p>Integrate logs with <strong>SIEM (Security Information and Event Management) solutions</strong> like Splunk or Datadog for proactive security monitoring.</p></li></ul><h4>What We Have</h4><ul><li><p>Logs should be machine-readable (JSON format is preferred) for log aggregators.</p></li><li><p>Easily searchable using tools like ELK, Loki, and Splunk.</p></li><li><p>Ensures <strong>compliance and security auditing</strong> by logging critical system events.</p></li><li><p>Allows efficient debugging in a distributed system.</p></li></ul><p>Example using Serilog in C#:</p><pre><code><code>Log.Information("User {UserId} performed an action at {Timestamp}", userId, DateTime.UtcNow);</code></code></pre><p>We can build a more resilient and auditable system by treating logging as a security mechanism rather than just a debugging tool.</p><div><hr></div><h3>Providing Context in Logs</h3><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!7rQu!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0dcbffaa-6a02-4ede-9f4a-d76bd0eaa300_1920x1080.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!7rQu!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0dcbffaa-6a02-4ede-9f4a-d76bd0eaa300_1920x1080.jpeg 424w, https://substackcdn.com/image/fetch/$s_!7rQu!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0dcbffaa-6a02-4ede-9f4a-d76bd0eaa300_1920x1080.jpeg 848w, https://substackcdn.com/image/fetch/$s_!7rQu!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0dcbffaa-6a02-4ede-9f4a-d76bd0eaa300_1920x1080.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!7rQu!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0dcbffaa-6a02-4ede-9f4a-d76bd0eaa300_1920x1080.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!7rQu!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0dcbffaa-6a02-4ede-9f4a-d76bd0eaa300_1920x1080.jpeg" width="1456" height="819" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/0dcbffaa-6a02-4ede-9f4a-d76bd0eaa300_1920x1080.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:819,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:64436,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!7rQu!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0dcbffaa-6a02-4ede-9f4a-d76bd0eaa300_1920x1080.jpeg 424w, https://substackcdn.com/image/fetch/$s_!7rQu!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0dcbffaa-6a02-4ede-9f4a-d76bd0eaa300_1920x1080.jpeg 848w, https://substackcdn.com/image/fetch/$s_!7rQu!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0dcbffaa-6a02-4ede-9f4a-d76bd0eaa300_1920x1080.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!7rQu!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0dcbffaa-6a02-4ede-9f4a-d76bd0eaa300_1920x1080.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><h4>What is Context in Logging?</h4><p>Context in logging refers to adding meaningful information to log entries to ensure that logs are easily understandable and traceable. It helps engineers and operators quickly determine <strong>what happened, where, and why</strong> when debugging or analysing system behaviour.</p><p>Context includes details such as:</p><ul><li><p>The <strong>application</strong> or service name.</p></li><li><p>The <strong>request ID</strong> or <strong>correlation ID</strong> for tracking.</p></li><li><p><strong>Timestamps</strong> to track when the event occurred.</p></li><li><p>The <strong>user or session ID</strong> (if applicable and security compliant).</p></li><li><p>The <strong>method or function</strong> that generated the log.</p></li></ul><p>However, while providing context, <strong>security must be a top priority</strong>&#8212;logs should never contain sensitive data such as passwords, or financial details.</p><h4>How to Implement Context in Logs</h4><ul><li><p>Include metadata such as <code>serviceName</code>, <code>requestId</code>, and <code>timestamp</code> in each log.</p></li><li><p>Use <strong>structured logging</strong> formats like JSON to standardise context across logs.</p></li><li><p>Leverage <strong>Correlation IDs</strong> to link logs across multiple services (see the section on Correlation IDs below).</p></li><li><p>Avoid logging sensitive information to comply with security best practices.</p></li></ul><p>Example structured log with context:</p><pre><code><code>{
  "timestamp": "2024-01-29T12:34:56Z",
  "service": "user-service",
  "level": "INFO",
  "message": "User logged in",
  "userId": "12345",
  "requestId": "abcd-efgh-ijkl"
}
</code></code></pre><p>Providing <strong>structured and contextual logs</strong> ensures that logs remain useful for current developers and future teams who may need to debug issues years later.</p><h4>What We Have</h4><ul><li><p>Contextual logs that provide <strong>clarity and traceability</strong>.</p></li><li><p>Use of <strong>structured formats</strong> like JSON to ensure uniformity.</p></li><li><p>Emphasis on <strong>avoiding sensitive data exposure</strong>.</p></li><li><p><strong>Correlation ID integration</strong> for tracking distributed requests.</p></li></ul><div><hr></div><h3><strong>What is a Correlation ID?</strong></h3><p>A Correlation ID is a unique identifier assigned to a request or transaction as it traverses multiple services in a distributed system. It connects all logs associated with that request, simplifying the tracing of user actions, debugging of issues, and analysis of system performance.</p><p>Why Correlation IDs Are Important?</p><ul><li><p>Enhances Traceability: Connects logs from various microservices that manage the same request.  </p></li><li><p>Improves Debugging: Aids engineers in tracking a request's journey through the system.  </p></li><li><p>Supports Performance Monitoring: Identifies bottlenecks in request processing. </p></li><li><p>Facilitates Business Intelligence: Aggregates logs to better understand user behaviour and transactions.</p></li></ul><h4>Example Use Case  </h4><p>A user starts a checkout request on an e-commerce site. This request activates calls to: </p><ol><li><p>Authentication Service (to verify user identity)  </p></li><li><p>Order Service (to create an order)  </p></li><li><p>Payment Service (to process payment)  </p></li><li><p>Inventory Service (to update stock)  </p></li></ol><p>By assigning a Correlation ID (e.g., correlationId: "xyz-123-abc"), logs from all these services can be connected, offering a comprehensive view of the request lifecycle.</p><div><hr></div><h3>Deciding Log Levels: Filtering Noise in a Microservices World</h3><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!h4uA!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F964112dc-879a-48f2-9a07-74637cceabcd_480x252.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!h4uA!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F964112dc-879a-48f2-9a07-74637cceabcd_480x252.jpeg 424w, https://substackcdn.com/image/fetch/$s_!h4uA!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F964112dc-879a-48f2-9a07-74637cceabcd_480x252.jpeg 848w, https://substackcdn.com/image/fetch/$s_!h4uA!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F964112dc-879a-48f2-9a07-74637cceabcd_480x252.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!h4uA!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F964112dc-879a-48f2-9a07-74637cceabcd_480x252.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!h4uA!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F964112dc-879a-48f2-9a07-74637cceabcd_480x252.jpeg" width="480" height="252" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/964112dc-879a-48f2-9a07-74637cceabcd_480x252.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:252,&quot;width&quot;:480,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:15867,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!h4uA!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F964112dc-879a-48f2-9a07-74637cceabcd_480x252.jpeg 424w, https://substackcdn.com/image/fetch/$s_!h4uA!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F964112dc-879a-48f2-9a07-74637cceabcd_480x252.jpeg 848w, https://substackcdn.com/image/fetch/$s_!h4uA!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F964112dc-879a-48f2-9a07-74637cceabcd_480x252.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!h4uA!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F964112dc-879a-48f2-9a07-74637cceabcd_480x252.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h4>What are Log Levels?</h4><p>Log levels categorise logs by severity, helping filter out unnecessary noise while surfacing critical issues. They define the importance of a log message and guide engineers in prioritising issues.</p><p><strong>Common Log Levels:</strong></p><ul><li><p><strong>DEBUG</strong>: Provides detailed information for diagnosing issues during development. It should not be used in production.</p></li><li><p><strong>INFO</strong>: General operational messages that indicate normal application behaviour.</p></li><li><p><strong>WARN</strong>: Indicates a potential issue that does not affect functionality but may require attention.</p></li><li><p><strong>ERROR</strong>: Captures failures in the application that need investigation but do not cause an immediate crash.</p></li><li><p><strong>FATAL</strong>: Represents critical failures that may bring down the application.</p></li></ul><h4>Why It&#8217;s Important to Standardise Log Levels</h4><p>Consistently using the correct log levels ensures that logs are meaningful and actionable. Teams should agree on how to classify logs to prevent overuse of <code>ERROR</code> or <code>INFO</code> messages where <code>WARN</code> would be more appropriate. This consistency helps:</p><ul><li><p>Enable effective log filtering to concentrate on genuine issues.</p></li><li><p>Enhance log analysis and debugging by minimising unnecessary noise.</p></li><li><p>Assist in prioritising fixes based on log severity.</p></li><li><p>Assist junior engineers in understanding log categorisation via code reviews.</p></li></ul><h4>How to Implement Log Levels Effectively</h4><ul><li><p>Define a standard <strong>log-level policy</strong> for the team.</p></li><li><p>Review log levels <strong>during code reviews</strong> to maintain consistency and educate junior developers.</p></li><li><p>Use <strong>dynamic log-level configurations</strong> to adjust verbosity in production without redeploying services.</p></li><li><p>Ensure logging platforms allow filtering based on log levels for targeted analysis.</p></li></ul><h4>What We Have</h4><ul><li><p>Clearly defined log levels for categorisation.</p></li><li><p>Use of dynamic log-level settings in Kubernetes via environment variables.</p></li><li><p>Encourage discussion on log levels during <strong>code reviews</strong>.</p></li></ul><div><hr></div><h4>Performance Considerations in Logging</h4><h5>Logging and Its Impact on Performance</h5><p>Although logging is essential, it can introduce performance overhead, particularly in high-throughput applications developed in C#, Java or any other language. Frequent and excessive logging can:</p><ul><li><p>Elevated CPU usage due to string formatting and file I/O operations.</p></li><li><p>Cause disk bloat if logs are not rotated and archived correctly.</p></li><li><p>Slow down the application when synchronous logging blocks execution.</p></li></ul><h5>How to Mitigate Performance Issues</h5><ul><li><p>Use Asynchronous Logging: Libraries like Serilog and NLog in C# support asynchronous logging to avoid blocking execution.</p></li><li><p>Batch Logging: Instead of writing logs immediately, accumulate and write them in batches to reduce I/O overhead.</p></li><li><p>Stream Logs to Kafka: By passing logs through a distributed streaming system like Apache Kafka, logs can be processed asynchronously in a scalable manner. Kafka ensures:</p><ul><li><p>Logs are distributed efficiently across consumers.</p></li><li><p>If an error occurs, processing can resume from the last offset.</p></li><li><p>Logs can be replayed if necessary.</p></li></ul></li><li><p>Implement Log Rotation: To retain logs efficiently, use log rotate or similar tools to archive and remove old logs, preventing disk space exhaustion.</p></li></ul><h5>Recommended Tools for Performance Optimisation</h5><ul><li><p>Serilog &amp; NLog: Support asynchronous logging and structured output.</p></li><li><p>Apache Kafka: Distributed log streaming and processing.</p></li><li><p>logrotate: Automates log rotation and cleanup to free disk space.</p></li></ul><h5>What We Have</h5><ul><li><p>Use of asynchronous logging to prevent performance bottlenecks.</p></li><li><p>Streaming logs to Kafka for distributed processing.</p></li><li><p>Log rotation to manage disk space efficiently.</p></li></ul><h5>Rate-Limiting and Log Sampling</h5><p>Rather than logging every request, only log a sample of non-critical messages, thereby reducing storage overhead.</p><h2>Improvements to Logging Practices: Alerts, Multi-Environment Strategies, and Business Intelligence</h2><p>Logging is not merely about capturing data; it&#8217;s about making it actionable. The improvements outlined below can enhance logging practices, rendering logs more valuable for monitoring, debugging, and business intelligence.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!3tR9!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F06dd487b-f96b-498e-a44e-16abea9d92c3_960x440.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!3tR9!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F06dd487b-f96b-498e-a44e-16abea9d92c3_960x440.jpeg 424w, https://substackcdn.com/image/fetch/$s_!3tR9!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F06dd487b-f96b-498e-a44e-16abea9d92c3_960x440.jpeg 848w, https://substackcdn.com/image/fetch/$s_!3tR9!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F06dd487b-f96b-498e-a44e-16abea9d92c3_960x440.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!3tR9!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F06dd487b-f96b-498e-a44e-16abea9d92c3_960x440.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!3tR9!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F06dd487b-f96b-498e-a44e-16abea9d92c3_960x440.jpeg" width="960" height="440" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/06dd487b-f96b-498e-a44e-16abea9d92c3_960x440.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:440,&quot;width&quot;:960,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:11706,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!3tR9!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F06dd487b-f96b-498e-a44e-16abea9d92c3_960x440.jpeg 424w, https://substackcdn.com/image/fetch/$s_!3tR9!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F06dd487b-f96b-498e-a44e-16abea9d92c3_960x440.jpeg 848w, https://substackcdn.com/image/fetch/$s_!3tR9!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F06dd487b-f96b-498e-a44e-16abea9d92c3_960x440.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!3tR9!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F06dd487b-f96b-498e-a44e-16abea9d92c3_960x440.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><div><hr></div><h3>Alerts &amp; Proactive Monitoring</h3><h4>What is Alert-Based Logging?</h4><p>Alert-based logging triggers real-time notifications for anomalies, allowing teams to respond proactively. Instead of manually sifting through logs, alerts highlight key issues automatically.</p><h4>How to Implement Alert-Based Logging</h4><ul><li><p><strong>Identify Essential Metrics: </strong>Pinpoint necessary logs, such as elevated error rates, unsuccessful transactions, or security violations.</p></li><li><p><strong>Establish Alert Notifications: </strong>Set up real-time notifications using log monitoring platforms like Grafana, Datadog, or Splunk.</p></li><li><p><strong>Connect with Communication Platforms: </strong>Set up alerts to inform teams through channels like Slack, PagerDuty, or Microsoft Teams.</p></li><li><p><strong>Optimise Alert Settings: </strong>Prevent alert fatigue by defining thresholds that guarantee only significant issues trigger notifications.</p></li></ul><h4>Example Alert Setup</h4><ul><li><p>Configure <strong>Grafana</strong> to send an alert when the error log count exceeds a predefined threshold:</p></li></ul><pre><code><code>alert:
  conditions:
    - type: threshold
      threshold: 100
      operator: gt
      field: "log_error_count"
  actions:
    - notify: slack_channel
      message: "A high error rate has been detected in the production logs!"
</code></code></pre><h4>Benefits of Alert-Based Logging</h4><ul><li><p><strong>Faster Incident Response</strong>: Detect and fix issues before they escalate.</p></li><li><p><strong>Automated Monitoring</strong>: Reduce manual log searches.</p></li><li><p><strong>Improved Reliability</strong>: Maintain system health by proactively addressing problems.</p></li></ul><div><hr></div><h3>2. Multi-Environment Logging Strategies</h3><h4>What is Multi-Environment Logging?</h4><h5><strong>Over logging ??</strong></h5><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!5uft!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8c98bb11-4c3b-4fe0-b36a-5657b1ec4bbd_640x427.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!5uft!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8c98bb11-4c3b-4fe0-b36a-5657b1ec4bbd_640x427.jpeg 424w, https://substackcdn.com/image/fetch/$s_!5uft!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8c98bb11-4c3b-4fe0-b36a-5657b1ec4bbd_640x427.jpeg 848w, https://substackcdn.com/image/fetch/$s_!5uft!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8c98bb11-4c3b-4fe0-b36a-5657b1ec4bbd_640x427.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!5uft!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8c98bb11-4c3b-4fe0-b36a-5657b1ec4bbd_640x427.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!5uft!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8c98bb11-4c3b-4fe0-b36a-5657b1ec4bbd_640x427.jpeg" width="640" height="427" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/8c98bb11-4c3b-4fe0-b36a-5657b1ec4bbd_640x427.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:427,&quot;width&quot;:640,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:81381,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!5uft!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8c98bb11-4c3b-4fe0-b36a-5657b1ec4bbd_640x427.jpeg 424w, https://substackcdn.com/image/fetch/$s_!5uft!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8c98bb11-4c3b-4fe0-b36a-5657b1ec4bbd_640x427.jpeg 848w, https://substackcdn.com/image/fetch/$s_!5uft!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8c98bb11-4c3b-4fe0-b36a-5657b1ec4bbd_640x427.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!5uft!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8c98bb11-4c3b-4fe0-b36a-5657b1ec4bbd_640x427.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><p>Different environments (development, staging, production) necessitate distinct logging strategies. Excessive logging in production may lead to performance issues, whereas insufficient logging in development can hinder debugging efforts.</p><p>We may not require the same logging level in the development environments as in the production environment. This will help us reduce noise, improve performance, or save costs. </p><h4>How to Implement Multi-Environment Logging</h4><ul><li><p><strong>Set Environment-Specific Log Levels</strong>: Configure different log levels for each environment.</p></li><li><p><strong>Use Configuration Management</strong>: Store logging configurations in environment variables or configuration files.</p></li><li><p><strong>Filter Logs by Environment</strong>: Use log aggregation tools to separate logs by environment.</p></li></ul><h4>Example Multi-Environment Log Configuration in C#</h4><pre><code><code>{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Development": "Debug",
      "Production": "Warning"
    }
  }
}
</code></code></pre><h4>Benefits of Multi-Environment Logging</h4><ul><li><p><strong>Improved Debugging in Development: </strong>Enhanced logging allows developers to pinpoint problems more effectively.</p></li><li><p><strong>Enhanced Production Efficiency: </strong>Minimizing excessive logs conserves resources.</p></li><li><p><strong>Distinct Log Separation: </strong>Simplifies the identification of various environments in log management systems.</p></li></ul><div><hr></div><h3>3. Logs as a Business Intelligence Tool</h3><h4>What is Business Intelligence Logging?</h4><p>A <strong>business intelligence log entry </strong>is a log record that documents information pertinent to company operations, user engagement, system efficiency, and feature usage. These logs enable organisations to derive valuable insights for informed decision-making, analytics, and optimisation.</p><h4>How to Implement Business Intelligence Logging</h4><ul><li><p><strong>Record Essential Business Events: </strong>Document occurrences like API response times, user interactions, and feature usage.</p></li><li><p><strong>Focus on operational and user behaviour trends</strong> rather than just debugging.</p></li><li><p><strong>Consolidate and Analyse Logs: </strong>Utilise platforms such as BigQuery, Snowflake, or AWS Athena to derive insights from structured logs.</p></li><li><p><strong>Design Dashboards: </strong>Develop live visualisations in Grafana or Kibana to monitor critical metrics.</p></li></ul><h4>Example Business Intelligence Log Entry</h4><pre><code><code>{
  "event": "APIResponseTime",
  "endpoint": "/checkout",
  "latency_ms": 250,
  "timestamp": "2024-01-29T12:35:00Z"
}
</code></code></pre><h4>Benefits of Business Intelligence Logging</h4><ul><li><p><strong>Improve User Experience</strong>: Identify slow endpoints and optimise performance.</p></li><li><p><strong>Feature Adoption Tracking</strong>: Understand which features users engage with most.</p></li><li><p><strong>Data-Driven Decisions</strong>: Use logs to inform product development and operational improvements.</p></li></ul><div><hr></div><h3>Wrapping Up: The Modern Approach to Logging</h3><p>Logging in microservices and Kubernetes requires a structured, security-focused, and performance-optimised approach. Following these best practices can enhance debugging, security, and observability.</p><p>Your logs, with structured logging, correlation IDs, and observability tools, will help you debug and improve system reliability and security.</p><p>Organisations can extract more value from their logs by integrating alerts and monitoring, multi-environment logging, and business intelligence practices. Logging isn&#8217;t just about capturing data&#8212;it&#8217;s about using it to <strong>proactively</strong> manage applications, optimise performance, and drive business decisions.</p><p>Happy blogging!</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.floormind.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item><item><title><![CDATA[How to Safely Upgrade a Kubernetes Node: ]]></title><description><![CDATA[A Step-by-Step Guide]]></description><link>https://blog.floormind.com/p/how-to-safely-upgrade-a-kubernetes</link><guid isPermaLink="false">https://blog.floormind.com/p/how-to-safely-upgrade-a-kubernetes</guid><dc:creator><![CDATA[Ife Junior]]></dc:creator><pubDate>Tue, 19 Nov 2024 19:53:30 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!kSQD!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fadfdab23-c3a5-45cd-adc2-bea8acd19755_1050x1019.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!kSQD!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fadfdab23-c3a5-45cd-adc2-bea8acd19755_1050x1019.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!kSQD!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fadfdab23-c3a5-45cd-adc2-bea8acd19755_1050x1019.png 424w, https://substackcdn.com/image/fetch/$s_!kSQD!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fadfdab23-c3a5-45cd-adc2-bea8acd19755_1050x1019.png 848w, https://substackcdn.com/image/fetch/$s_!kSQD!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fadfdab23-c3a5-45cd-adc2-bea8acd19755_1050x1019.png 1272w, https://substackcdn.com/image/fetch/$s_!kSQD!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fadfdab23-c3a5-45cd-adc2-bea8acd19755_1050x1019.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!kSQD!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fadfdab23-c3a5-45cd-adc2-bea8acd19755_1050x1019.png" width="1050" height="1019" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/adfdab23-c3a5-45cd-adc2-bea8acd19755_1050x1019.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1019,&quot;width&quot;:1050,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;So, You Want to DIY Kubernetes Upgrade? | Codementor&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="So, You Want to DIY Kubernetes Upgrade? | Codementor" title="So, You Want to DIY Kubernetes Upgrade? | Codementor" srcset="https://substackcdn.com/image/fetch/$s_!kSQD!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fadfdab23-c3a5-45cd-adc2-bea8acd19755_1050x1019.png 424w, https://substackcdn.com/image/fetch/$s_!kSQD!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fadfdab23-c3a5-45cd-adc2-bea8acd19755_1050x1019.png 848w, https://substackcdn.com/image/fetch/$s_!kSQD!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fadfdab23-c3a5-45cd-adc2-bea8acd19755_1050x1019.png 1272w, https://substackcdn.com/image/fetch/$s_!kSQD!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fadfdab23-c3a5-45cd-adc2-bea8acd19755_1050x1019.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Upgrading Kubernetes nodes is a critical task that ensures your cluster remains secure, performant, and compatible with the latest features. However, it can feel like walking a tightrope&#8212;especially in production environments where downtime isn&#8217;t an option. In this guide, I&#8217;ll walk you through the step-by-step process to upgrade a Kubernetes node while minimising risks and ensuring your workloads remain unaffected.</p><div><hr></div><h2><strong>Why Upgrade Kubernetes Nodes?</strong></h2><p>Kubernetes updates bring essential improvements in security, bug fixes, and new features. Upgrading nodes ensures your cluster:</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.floormind.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><ul><li><p>Adheres to compatibility policies (version skew).</p></li><li><p>Maintains security compliance.</p></li><li><p>Performs optimally under new workloads.</p></li></ul><p>That said, let&#8217;s get into the practical steps.</p><div><hr></div><h2><strong>Step 1: SSH Into the Node</strong></h2><p>The first step is to log into the target node where the upgrade will take place. Use your preferred method:</p><pre><code>ssh user@&lt;node-ip&gt;</code></pre><div><hr></div><h2><strong>Step 2: Validate Cluster Health Before Starting</strong></h2><p>Before upgrading, ensure that the cluster is in a healthy state to avoid exacerbating any existing issues.</p><pre><code>kubectl get nodes kubectl get pods -A kubectl get events -A</code></pre><p>Look for <code>NotReady</code> nodes, failing Pods, or unusual events before proceeding.</p><div><hr></div><h2><strong>Step 3: Drain the Node</strong></h2><p>To safely upgrade the node, workloads running on it must be evicted and rescheduled to other nodes. This prevents disruptions during the upgrade.</p><ol><li><p><strong>Mark the Node as Unschedulable</strong>: Prevent new workloads from being scheduled:</p></li></ol><pre><code>kubectl cordon &lt;node-name&gt;</code></pre><ol><li><p><strong>Evict Workloads</strong>: Drain all running Pods (except DaemonSets and static Pods):</p></li></ol><pre><code>kubectl drain &lt;node-name&gt; --ignore-daemonsets --delete-emptydir-data</code></pre><blockquote><p><strong>Note</strong>: Pods using <code>emptyDir</code> volumes will lose their data.</p></blockquote><div><hr></div><h2><strong>Step 4: Backup Cluster State</strong></h2><p>Take a backup of your cluster state to prevent data loss in case of failure. This is particularly important for clusters using <code>etcd</code>.</p><pre><code>ETCDCTL_API=3 etcdctl snapshot save backup.db --endpoints=&lt;etcd-endpoint&gt; --cacert=&lt;ca-file&gt; --cert=&lt;cert-file&gt; --key=&lt;key-file&gt;</code></pre><p>Adjust the command for your environment as needed.</p><div><hr></div><h2><strong>Step 5: Check Current Versions</strong></h2><p>Before upgrading, note the current versions of <code>kubeadm</code>, <code>kubelet</code>, and <code>kubectl</code> on the node:</p><pre><code>kubectl version kubelet --version kubeadm version</code></pre><p>This helps ensure a seamless upgrade process by comparing against available updates.</p><div><hr></div><h2><strong>Step 6: Validate the Upgrade Plan</strong></h2><p>Run the following command to validate the <code>kubeadm</code> upgrade plan and ensure compatibility:</p><pre><code>kubeadm upgrade plan</code></pre><p>This step provides details about the available versions and any potential conflicts.</p><div><hr></div><h2><strong>Step 7: Upgrade Using </strong><code>kubeadm</code></h2><p>Run the following command to upgrade the node&#8217;s Kubernetes components:</p><pre><code>kubeadm upgrade node</code></pre><p>If the version matches the control plane, Kubernetes skips the upgrade process for that node.</p><div><hr></div><h2><strong>Step 8: Update Package Repositories</strong></h2><p>Ensure your package manager&#8217;s repositories are up-to-date so you can fetch the latest Kubernetes packages:</p><pre><code>sudo apt update</code></pre><div><hr></div><h2><strong>Step 9: Check Latest Version Numbers</strong></h2><p>To verify the latest available versions of <code>kubeadm</code>, <code>kubectl</code>, and <code>kubelet</code>, use:</p><pre><code>apt show kubeadm -a | grep Version 
apt show kubectl -a | grep Version 
apt show kubelet -a | grep Version</code></pre><div><hr></div><h2><strong>Step 10: Install the Latest Version</strong></h2><p>Install the updated versions of Kubernetes components:</p><pre><code>sudo apt install -y kubelet=&lt;version&gt; kubectl=&lt;version&gt; kubeadm=&lt;version&gt;</code></pre><div><hr></div><h2><strong>Step 11: Verify the Upgrade</strong></h2><p>After installation, confirm that the components are running the correct versions:</p><pre><code>kubectl version kubelet --version kubeadm version</code></pre><div><hr></div><h2><strong>Step 12: Restart Critical Pods (Optional)</strong></h2><p>After restarting <code>kubelet</code>, ensure critical system Pods like <code>kube-proxy</code> or CNI (network plugins) are running correctly.</p><pre><code>kubectl get pods -n kube-system</code></pre><p>Look for any Pods in <code>CrashLoopBackOff</code> or <code>Pending</code> states and restart them if necessary:</p><pre><code>kubectl delete pod &lt;pod-name&gt; -n kube-system</code></pre><div><hr></div><h2><strong>Step 13: Restart the </strong><code>kubelet</code><strong> Service</strong></h2><p>Restart the <code>kubelet</code> service to apply the updates:</p><pre><code>sudo systemctl restart kubelet</code></pre><div><hr></div><h2><strong>Step 14: Rejoin the Node (if Necessary)</strong></h2><p>If the node fails to join the cluster automatically, you can rejoin it manually:</p><ol><li><p><strong>On the Control Plane</strong>: Create a token and retrieve the join command:</p></li></ol><pre><code>kubeadm token create --print-join-command</code></pre><ol><li><p><strong>On the Worker Node</strong>: Run the provided join command:</p></li></ol><pre><code>kubeadm join &lt;control-plane-ip&gt;:6443 --token &lt;token&gt; --discovery-token-ca-cert-hash &lt;hash&gt;</code></pre><ol><li><p>Restart the <code>kubelet</code> service:</p></li></ol><pre><code>sudo systemctl restart kubelet</code></pre><div><hr></div><h2><strong>Step 15: Uncordon the Node</strong></h2><p>Once the upgrade is complete, allow the node to schedule workloads again:</p><pre><code>kubectl uncordon &lt;node-name&gt;</code></pre><div><hr></div><h2><strong>Step 16: Verify Node Health</strong></h2><p>Ensure the node has successfully rejoined the cluster and is ready to accept workloads:</p><pre><code>kubectl get nodes</code></pre><p>Check the status of the node&#8212;it should show as <code>Ready</code>.</p><div><hr></div><h2><strong>Key Notes to Remember</strong></h2><ul><li><p>Always follow Kubernetes Version Skew Policies to ensure compatibility between the control plane and nodes.</p></li><li><p>Draining nodes is critical to maintaining workload availability during upgrades.</p></li><li><p>Keep an eye on resource usage after the upgrade to confirm stability.</p></li></ul><div><hr></div><p>Upgrading Kubernetes nodes can feel daunting, but by following these steps, you can execute the process confidently and safely. Keeping your cluster up-to-date ensures security, reliability, and the ability to leverage the latest Kubernetes features.</p><div><hr></div><p><strong>Did this guide help you? Share your thoughts or questions in the comments below!</strong></p><p>Subscribe to this Substack for more Kubernetes and DevOps tips delivered straight to your inbox.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.floormind.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item><item><title><![CDATA[Setting Up a Self-Managed Kubernetes Cluster: A Step-by-Step Guide]]></title><description><![CDATA[This is for a non HA cluster.]]></description><link>https://blog.floormind.com/p/setting-up-a-self-managed-kubernetes</link><guid isPermaLink="false">https://blog.floormind.com/p/setting-up-a-self-managed-kubernetes</guid><dc:creator><![CDATA[Ife Junior]]></dc:creator><pubDate>Mon, 04 Nov 2024 16:10:18 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!qfD_!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F61f8ce67-99c0-4af5-ad95-81825187fe9c_1621x1321.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div><hr></div><p>As Kubernetes continues to dominate the landscape of container orchestration, many developers and system administrators are opting for self-managed clusters to gain complete control over their infrastructure. In this guide, I&#8217;ll walk you through the steps required to set up a self-managed Kubernetes cluster using <code>kubeadm</code>.</p><p>By the end of this tutorial, you&#8217;ll have a functional Kubernetes cluster ready to handle workloads. Let&#8217;s dive in!</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.floormind.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!qfD_!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F61f8ce67-99c0-4af5-ad95-81825187fe9c_1621x1321.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!qfD_!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F61f8ce67-99c0-4af5-ad95-81825187fe9c_1621x1321.jpeg 424w, https://substackcdn.com/image/fetch/$s_!qfD_!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F61f8ce67-99c0-4af5-ad95-81825187fe9c_1621x1321.jpeg 848w, https://substackcdn.com/image/fetch/$s_!qfD_!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F61f8ce67-99c0-4af5-ad95-81825187fe9c_1621x1321.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!qfD_!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F61f8ce67-99c0-4af5-ad95-81825187fe9c_1621x1321.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!qfD_!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F61f8ce67-99c0-4af5-ad95-81825187fe9c_1621x1321.jpeg" width="1456" height="1187" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/61f8ce67-99c0-4af5-ad95-81825187fe9c_1621x1321.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1187,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:26434,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!qfD_!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F61f8ce67-99c0-4af5-ad95-81825187fe9c_1621x1321.jpeg 424w, https://substackcdn.com/image/fetch/$s_!qfD_!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F61f8ce67-99c0-4af5-ad95-81825187fe9c_1621x1321.jpeg 848w, https://substackcdn.com/image/fetch/$s_!qfD_!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F61f8ce67-99c0-4af5-ad95-81825187fe9c_1621x1321.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!qfD_!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F61f8ce67-99c0-4af5-ad95-81825187fe9c_1621x1321.jpeg 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><div><hr></div><h3>&#128221; Prerequisites</h3><p>Before beginning, ensure that you have:</p><ul><li><p><strong>An Odd Number of Servers:</strong> For failure tolerance, Kubernetes clusters work best with an odd number of servers. This setup allows for a simple quorum, following the formula <code>(N-1)/2</code> to determine the number of tolerated failures. For a minimal setup, you can start with <strong>1 master node</strong> (or control plane node) and <strong>2 worker nodes</strong>.</p></li><li><p><strong>Ubuntu 20.04</strong> or a similar Linux distribution on your nodes.</p></li><li><p>At least <strong>2 CPUs and 2 GB of RAM</strong> on each node (one control plane node and at least one worker node).</p></li><li><p>The control plane node should have at least <strong>20 GB </strong>of storage while the worker nodes should have at least <strong>10 GB</strong> of storage.</p></li><li><p>A reliable network connection</p></li><li><p>Root access or a user with sudo privileges during set up.</p></li></ul><div><hr></div><h3>Step 1: Prepare the Environment</h3><blockquote><p><em><strong>Note:</strong> Repeat <strong>Step 1</strong> on both the control plane (master) node and each worker node. This will ensure all nodes are prepared with the necessary dependencies.</em></p></blockquote><h3>Update System&nbsp;Packages</h3><p>Before installing Kubernetes components, let&#8217;s make sure your system packages are up to date. Run:</p><pre><code>sudo apt update &amp;&amp; sudo apt upgrade -y</code></pre><h3>Add Kubernetes Package Repository</h3><ol><li><p><strong>Download the Kubernetes GPG key:</strong></p></li></ol><pre><code>sudo curl -fsSLo /usr/share/keyrings/kubernetes-archive-keyring.gpg https://packages.cloud.google.com/apt/doc/apt-key.gpg</code></pre><ol><li><p><strong>Add the Kubernetes apt repository:</strong></p></li></ol><pre><code>echo "deb [signed-by=/usr/share/keyrings/kubernetes-archive-keyring.gpg] https://apt.kubernetes.io/ kubernetes-xenial main" | sudo tee /etc/apt/sources.list.d/kubernetes.list</code></pre><ol><li><p><strong>Update package lists:</strong></p></li></ol><pre><code>sudo apt update</code></pre><p>For more details, refer to the <a href="https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/install-kubeadm/">Kubernetes Installation Guide</a>.</p><div><hr></div><h3>Step 2: Install Kubernetes Tools</h3><blockquote><p><em><strong>Note:</strong> The first part of this step, where we install </em><code>kubeadm</code><em>, </em><code>kubelet</code><em>, and </em><code>kubectl</code><em>, should also be repeated on each worker node. These tools are required on both the control plane and worker nodes.</em></p></blockquote><h3>Install <code>kubeadm</code>, <code>kubelet</code>, and&nbsp;<code>kubectl</code></h3><p>These tools are essential for managing the Kubernetes cluster:</p><pre><code>sudo apt install -y kubeadm kubelet kubectl</code></pre><h3>Install Container Runtime (containerd)</h3><p>Kubernetes requires a container runtime like <code>containerd</code> to run containers. Install it with:</p><pre><code>sudo apt update &amp;&amp; sudo apt install -y containerd</code></pre><h3>Configure CGroups for <code>containerd</code> and&nbsp;<code>kubelet</code></h3><p>Control groups, or <strong>cgroups</strong>, are a Linux kernel feature that manage and allocate system resources such as CPU, memory, disk I/O, and network bandwidth for groups of processes. In the context of Kubernetes, cgroups play a crucial role in ensuring that containers are efficiently managed and isolated. Here&#8217;s what cgroups do:</p><ol><li><p><strong>Resource Allocation and Limiting</strong>:<br>Cgroups allow Kubernetes to set limits and requests on the amount of CPU and memory a container can use. For example, you can restrict a container to use a maximum of 512 MB of memory or a limited percentage of CPU resources. This prevents any single container from consuming all resources on the node.</p></li><li><p><strong>Resource Isolation</strong>:<br>By isolating resources, cgroups ensure that containers and their processes run independently without interfering with each other. If one container crashes or spikes in resource usage, cgroups help prevent it from impacting other containers.</p></li><li><p><strong>Resource Monitoring</strong>:<br>Cgroups provide visibility into resource usage, allowing Kubernetes to monitor the CPU and memory consumption of containers and make decisions based on this data (like scaling or scheduling).</p></li><li><p><strong>Resource Prioritization</strong>:<br>Cgroups can be used to prioritize resources for certain containers over others, ensuring critical services receive the resources they need, even under high load.</p></li></ol><p>Overall, cgroups help Kubernetes enforce resource limits, maintain stability, and optimize performance, which is essential for managing containerized applications in a multi-tenant environment.</p><p>Kubernetes components need to use consistent cgroup drivers. There are two main CGroup drivers, which are:</p><ol><li><p><code>systemd</code><strong> cgroup driver</strong></p></li></ol><ul><li><p><strong>Description:</strong> This driver uses <code>systemd</code> as the cgroup manager, which is the default init system on most modern Linux distributions (like Ubuntu and CentOS).</p></li><li><p><strong>Usage:</strong> Preferred for Kubernetes clusters as it aligns with the native Linux <code>systemd</code> init system, leading to better compatibility and stability in resource management.</p></li></ul><ol><li><p><code>cgroupfs</code><strong> cgroup driver</strong></p></li></ol><ul><li><p><strong>Description:</strong> This driver uses <code>cgroupfs</code> as the cgroup manager, which directly manages cgroups within the filesystem.</p></li><li><p><strong>Usage:</strong> Often used with container runtimes like Docker but may lead to issues in Kubernetes because it can conflict with <code>systemd</code>. It&#8217;s generally recommended to switch to <code>systemd</code> for Kubernetes clusters, especially in production environments.</p></li></ul><p><strong>Note:</strong> Consistency between the cgroup driver used by <code>kubelet</code> and the container runtime (such as <code>containerd</code> or Docker) is essential for stable cluster operations. Using the <code>systemd</code> driver is typically recommended for production environments.</p><p>Let&#8217;s set them to use <code>systemd</code>&nbsp;. With this being the default, all we have to do is verify that the current init system is using systemd, if so then we do not need to do anything.&nbsp;</p><ol><li><p>Check the current init system by running:</p></li></ol><pre><code>ps -p 1</code></pre><ol><li><p>Create the configuration path for <code>containerd</code>:</p></li></ol><pre><code>sudo mkdir -p /etc/containerd</code></pre><ol><li><p>Generate the default <code>containerd</code> config:</p></li></ol><pre><code>sudo containerd config default | sudo tee /etc/containerd/config.toml</code></pre><ol><li><p>Edit the config to set <code>SystemdCgroup</code> to <code>true</code>:</p></li></ol><pre><code>sudo sed -i 's/SystemdCgroup = false/SystemdCgroup = true/' /etc/containerd/config.toml</code></pre><ol><li><p>Verify the setting:</p></li></ol><pre><code>cat /etc/containerd/config.toml | grep -i SystemdCgroup -B 50</code></pre><ol><li><p>Restart <code>containerd</code>:</p></li></ol><pre><code>sudo systemctl restart containerd</code></pre><h3>Set the <code>kubelet</code> Cgroup Driver to <code>cgroupfs (Optional)</code></h3><p>This section can be skipped if you are using the default <code>systemd</code> driver. The whole point is to make sure we keep the container runtime and the kubelet using the same driver.&nbsp;</p><h4>1. Set the <code>kubelet</code> Cgroup Driver to&nbsp;<code>cgroupfs</code></h4><ol><li><p><strong>Edit the kubelet configuration file</strong>, typically located at <code>/var/lib/kubelet/config.yaml</code>:</p></li></ol><pre><code>sudo nano /var/lib/kubelet/config.yaml</code></pre><ol><li><p><strong>Find the </strong><code>cgroupDriver</code><strong> setting</strong> and set it to <code>cgroupfs</code>:</p></li></ol><pre><code>cgroupDriver: cgroupfs</code></pre><ol><li><p><strong>Save and close</strong> the file.</p></li><li><p><strong>Restart </strong><code>kubelet</code> to apply the changes:</p></li></ol><pre><code>sudo systemctl restart kubelet</code></pre><p>If the <code>kubelet</code> configuration file doesn&#8217;t already exist, you can also specify the cgroup driver directly by adding the <code>--cgroup-driver=cgroupfs</code> flag in the <code>kubelet</code> service configuration file (typically at <code>/etc/systemd/system/kubelet.service.d/10-kubeadm.conf</code>), then restart the <code>kubelet</code> service.</p><h4>2. Set the Container Runtime Cgroup Driver to&nbsp;<code>cgroupfs</code></h4><h4>For <code>containerd</code></h4><ol><li><p><strong>Edit the </strong><code>containerd</code><strong> configuration file</strong> located at <code>/etc/containerd/config.toml</code>:</p></li></ol><pre><code>sudo nano /etc/containerd/config.toml</code></pre><ol><li><p><strong>Locate the </strong><code>SystemdCgroup</code><strong> option</strong> under the <code>[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]</code> section, and set it to <code>false</code>:</p></li></ol><pre><code>[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]   SystemdCgroup = false</code></pre><ol><li><p><strong>Save and close</strong> the file.</p></li><li><p><strong>Restart </strong><code>containerd</code> to apply the changes:</p></li></ol><pre><code>sudo systemctl restart containerd</code></pre><ul><li><p>For Docker</p></li></ul><ol><li><p><strong>Create or edit the Docker daemon configuration file</strong> located at <code>/etc/docker/daemon.json</code>:</p></li></ol><pre><code>sudo nano /etc/docker/daemon.json</code></pre><ol><li><p><strong>Set the cgroup driver to </strong><code>cgroupfs</code> in the JSON configuration:</p></li></ol><pre><code>{   "exec-opts": ["native.cgroupdriver=cgroupfs"] }</code></pre><ol><li><p><strong>Save and close</strong> the file.</p></li><li><p><strong>Restart Docker</strong> to apply the changes:</p></li></ol><pre><code>sudo systemctl restart docker</code></pre><p>For more details, refer to the <a href="https://kubernetes.io/docs/setup/production-environment/container-runtimes/#containerd">Container Runtime Configuration</a> in Kubernetes documentation.</p><div><hr></div><h3>Step 3: Initialize the Control Plane&nbsp;Node</h3><h3>Disable Swap</h3><p>Kubernetes requires swap to be turned off, the reason is Kubernetes manages memory resources for containers and relies on accurate memory allocation and usage data. If swap is enabled, it can interfere with Kubernetes&#8217; ability to monitor and control resource usage accurately. This can lead to unexpected behavior, where containers exceed memory limits or become unstable, which affects overall cluster stability.</p><pre><code>sudo swapoff -a
sudo sed -i '/ swap / s/^/#/' /etc/fstab</code></pre><h3>Enable IP Forwarding</h3><p>IP forwarding is a feature in the Linux kernel that allows the server to forward network packets from one network interface to another. By default, many Linux distributions disable IP forwarding, which means the system will not route packets between network interfaces.</p><p>To ensure network traffic flows correctly between different network interfaces, IP forwarding is essential in Kubernetes. This will enable pod-to-pod communication between nodes.</p><h3>Why IP Forwarding is Needed in Kubernetes</h3><ol><li><p><strong>Pod-to-Pod Communication Across Nodes:</strong></p></li></ol><ul><li><p>Kubernetes creates a virtual network where each pod can communicate with other pods, even if they&#8217;re on different nodes. For this to work, IP packets need to be routed between different interfaces (e.g., between the pod network interface and the node&#8217;s main network interface).</p></li><li><p>Enabling IP forwarding allows each node to forward packets between these interfaces, facilitating cross-node communication in the cluster.</p></li></ul><ol><li><p><strong>Service and Network Routing:</strong></p></li></ol><ul><li><p>Kubernetes uses various service types (like ClusterIP, NodePort, and LoadBalancer) to expose applications to internal and external traffic.</p></li><li><p>With IP forwarding enabled, packets can be routed to their destination service or pod IP, even if that IP is on a different node within the cluster. This is crucial for Kubernetes networking components, such as kube-proxy, to correctly handle traffic routing.</p></li></ul><ol><li><p><strong>Network Plugins and CNI (Container Network Interface):</strong></p></li></ol><ul><li><p>Many CNI plugins (like Flannel, Calico, and Weave) rely on IP forwarding to handle the complex routing required for networking in a multi-node cluster.</p></li><li><p>Enabling IP forwarding ensures that the network plugins can set up and manage pod networking, allowing pods to communicate seamlessly across the cluster.</p></li></ul><p>Enable IP forwarding to allow packets to be routed between different network interfaces:</p><pre><code>#permanently change it
echo "net.ipv4.ip_forward = 1" | sudo tee -a /etc/sysctl.conf 

#to temporarily change it
sudo sysctl -w net.ipv4.ip_forward=1 </code></pre><p>Or&nbsp;</p><pre><code>cat &lt;&lt;EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1
net.bridge.bridge-nf-call-ip6tables = 1
EOF
sudo sysctl --system</code></pre><h3>Initialize the Kubernetes Cluster</h3><p>Let&#8217;s initialize the cluster on the control plane node. Replace <code>&lt;control-plane-ip&gt;</code> with the actual IP of your control plane node:</p><pre><code>sudo kubeadm init --apiserver-advertise-address=&lt;control-plane-ip&gt; --pod-network-cidr="10.244.0.0/16" --upload-certs</code></pre><p>Refer to the <a href="https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/create-cluster-kubeadm/">kubeadm Cluster Setup Guide</a> for more details.</p><h3>Configure <code>kubectl</code> for Cluster&nbsp;Access</h3><p>Now, let&#8217;s set up <code>kubectl</code> so you can manage the cluster:</p><pre><code>mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config</code></pre><div><hr></div><h3>Step 4: Install Pod Network&nbsp;(CNI)</h3><h3>Install Flannel (Example&nbsp;CNI)</h3><p>Kubernetes requires a container network interface (CNI) for pod-to-pod communication. Here, we&#8217;ll use Flannel. If you encounter issues with pods not running due to <code>br_netfilter</code>, load the module with:</p><pre><code>sudo modprobe overlay | bridge #depending on the module being used.
sudo modprobe br_netfilter</code></pre><h3>Download and Configure Flannel</h3><p>Kubernetes needs a Container Network Interface (CNI) for pod-to-pod communication. We&#8217;ll use Flannel as our CNI. Follow these steps to download and configure it:</p><ol><li><p><strong>Download the Flannel YAML configuration file</strong> and save it as <code>kube-flannel.yml</code>:</p></li></ol><pre><code>curl -LO https://raw.githubusercontent.com/flannel-io/flannel/v0.20.2/Documentation/kube-flannel.yml</code></pre><ol><li><p><strong>Edit the Flannel Configuration:</strong></p></li></ol><ul><li><p>Open the <code>kube-flannel.yml</code> file using a text editor:</p></li></ul><pre><code>cd kube-flannel.yml</code></pre><ul><li><p>Locate the <code>args</code> section within the <code>kube-flannel</code> container definition. It should look like this:</p></li></ul><pre><code>args:   
- --ip-masq   
- --kube-subnet-mgr</code></pre><ul><li><p>Add an additional argument to specify the network interface:</p></li></ul><pre><code>args:   
- --ip-masq   
- --kube-subnet-mgr   
- --iface=eth0</code></pre><ul><li><p>Adding <code>--iface=eth0</code> ensures Flannel uses the correct network interface for pod communication.</p></li></ul><ol><li><p><strong>Save and exit</strong> the file.</p></li><li><p><strong>Deploy Flannel</strong>:</p></li></ol><pre><code>kubectl apply -f kube-flannel.yaml</code></pre><p>For more about Flannel configuration, refer to the <a href="https://github.com/flannel-io/flannel">Flannel Documentation</a>.</p><div><hr></div><h3>Step 5: Verify Control Plane&nbsp;Status</h3><p>Run the following command to check if the control plane node is ready:</p><pre><code>kubectl get nodes</code></pre><p>You should see the control plane node in a &#8220;Ready&#8221; state if everything is set up correctly.</p><div><hr></div><h3>Step 6: Join Worker Nodes to the&nbsp;Cluster</h3><h3>Set Unique Hostnames for Worker&nbsp;Nodes</h3><p>Each worker node should have a unique hostname. Set it with:</p><pre><code>sudo hostnamectl set-hostname &lt;worker-node-name&gt;</code></pre><h3>Join Worker&nbsp;Nodes</h3><p>After initializing the control plane, <code>kubeadm</code> generates a command to join worker nodes. It will look similar to this:</p><pre><code>kubeadm join &lt;control-plane-ip&gt;:6443 --token &lt;token&gt; --discovery-token-ca-cert-hash &lt;hash&gt;</code></pre><p>Run the command on each worker node.</p><p>Refer to the <a href="https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/create-cluster-kubeadm/#more-information">Adding Nodes with kubeadm</a> for more information.</p><h3>Troubleshoot Common&nbsp;Issues</h3><p>If you encounter errors related to unsupported fields in the <code>kubeadm</code> config file, such as <code>caCertificateValidityPeriod</code> or <code>certificateValidityPeriod</code>, open the config file:</p><pre><code>sudo nano &lt;your-kubeadm-config-file&gt;.yaml</code></pre><p>Remove the unsupported fields if using <code>v1beta3</code>.</p><div><hr></div><h3>&#129514; Step 7: Run Kubernetes End-to-End (E2E)&nbsp;Tests</h3><p>Kubernetes provides a set of E2E tests to ensure that all cluster components are working together as expected. These tests are especially useful for validating your setup, troubleshooting issues, and ensuring the cluster meets expected performance and reliability standards.</p><h3>Prerequisites for E2E&nbsp;Tests</h3><ol><li><p><strong>Install </strong><code>kubectl</code><strong> and have access to your Kubernetes cluster.</strong></p></li><li><p><strong>Make sure the </strong><code>kubeconfig</code><strong> file</strong> is correctly configured, so <code>kubectl</code> can interact with your cluster:</p></li></ol><pre><code>export KUBECONFIG=$HOME/.kube/config</code></pre><ol><li><p><strong><a href="https://golang.org/doc/install">Install Go</a> (if it&#8217;s not already installed)</strong>:<br>Kubernetes E2E tests require Go, as they are implemented in Go code.</p></li><li><p><strong>Clone the Kubernetes Repository</strong>:<br>The E2E test scripts are included in the Kubernetes GitHub repository.</p></li></ol><pre><code>git clone https://github.com/kubernetes/kubernetes.git cd kubernetes</code></pre><h3>Running Basic E2E&nbsp;Tests</h3><p>Kubernetes includes a variety of E2E tests, from simple checks to complex scenarios. Follow these steps to run a basic test suite.</p><ol><li><p><strong>Build the E2E Test Binary</strong>:</p></li></ol><pre><code>make WHAT=test/e2e/e2e.test</code></pre><ol><li><p><strong>Run the E2E Test Suite</strong>:</p></li><li><p>The following command will run the E2E test suite against your cluster. Replace <code>&lt;your-cluster-ip&gt;</code> with your actual API server IP.</p></li></ol><pre><code>./_output/local/bin/linux/amd64/e2e.test --host=https://&lt;your-cluster-ip&gt;:6443</code></pre><p><strong>3. Specify tests to run</strong> by using the <code>--ginkgo.focus</code> flag if you want to run specific tests. For example, to run only the tests focused on pod creation, use:</p><pre><code>./_output/local/bin/linux/amd64/e2e.test --ginkgo.focus="\[sig-scheduling\] Pod should"</code></pre><p><strong>4. Viewing Test Results</strong>:</p><p>The E2E tests will output results to the console, indicating success or failure for each test.</p><ul><li><p>You can also export logs to a file:</p></li></ul><pre><code>./_output/local/bin/linux/amd64/e2e.test --host=https://&lt;your-cluster-ip&gt;:6443 &gt; e2e_test_results.log</code></pre><h3>Running Tests with Sonobuoy (Alternative Method)</h3><p><a href="https://sonobuoy.io/">Sonobuoy</a> is a diagnostic tool designed to run Kubernetes conformance tests and can simplify the process of running E2E tests across different Kubernetes clusters.</p><ol><li><p><strong>Download Sonobuoy</strong>: Download <a href="https://sonobuoy.io/">Sonobuoy</a>:</p></li></ol><pre><code>curl -L https://github.com/vmware-tanzu/sonobuoy/releases/latest/download/sonobuoy_$(uname -s)_$(uname -m).tar.gz | tar xvz sudo mv sonobuoy /usr/local/bin</code></pre><ol><li><p><strong>Run Sonobuoy Tests</strong>:</p></li><li><p>Run Sonobuoy to start the conformance test suite:</p></li></ol><pre><code>sonobuoy run</code></pre><ul><li><p>Check the test status:</p></li></ul><pre><code>sonobuoy status</code></pre><ol><li><p><strong>Retrieve and View Results</strong>:</p></li><li><p>When tests are complete, download the results:</p></li></ol><pre><code>sonobuoy retrieve .</code></pre><ul><li><p>Extract the tarball:</p></li></ul><pre><code>tar -xf *.tar.gz</code></pre><ul><li><p>Results will be stored in a set of JSON files, providing detailed insights into which tests passed or failed.</p></li></ul><h3>Additional Testing&nbsp;Tips</h3><ul><li><p><strong>Run Tests on a Dedicated Test Cluster</strong>: Running E2E tests can place a significant load on the cluster, so it&#8217;s advisable to run them in a testing or staging environment.</p></li><li><p><strong>Customize Test Runs</strong>: For large clusters, it might be useful to limit test scope by using tags like <code>--ginkgo.focus</code> or <code>--ginkgo.skip</code> to focus on specific test types.</p></li><li><p><strong>Regular Testing</strong>: For production-grade clusters, consider integrating E2E tests into a CI/CD pipeline to monitor cluster health continuously.</p></li></ul><p>More on E2E testing is available in the [Kubernetes E2E Testing Guide](<a href="https://github.com/kubernetes/community/blob/master/contributors/devel/sig-testing/e2e-tests">https://github.com/kubernetes/community/blob/master/contributors/devel/sig-testing/e2e-tests</a>)</p><div><hr></div><h3>&#127881; Wrapping&nbsp;Up</h3><p>Congratulations! You&#8217;ve successfully set up a self-managed Kubernetes cluster. From here, you can deploy applications, set up monitoring, and explore Kubernetes&#8217; powerful orchestration capabilities.</p><p>For more complex configurations, like high availability clusters, consider diving deeper into the Kubernetes documentation.</p><div><hr></div><p>Happy Clustering!  </p><p> </p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.floormind.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item></channel></rss>