<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Lavell Burton</title>
    <description>The latest articles on DEV Community by Lavell Burton (@benjmainburton).</description>
    <link>https://dev.to/benjmainburton</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2934094%2Ffcecddcd-0a98-49a3-a3b8-40d34d3dfde4.jpg</url>
      <title>DEV Community: Lavell Burton</title>
      <link>https://dev.to/benjmainburton</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/benjmainburton"/>
    <language>en</language>
    <item>
      <title>A teacher in my DevOps course showed us Containers, and I fell in love this year. I have never worked in tech in my life and this will be my first year attempting to break in and I plan to grow specifically with Kubernetes. My Journey starts now.</title>
      <dc:creator>Lavell Burton</dc:creator>
      <pubDate>Thu, 01 May 2025 15:36:19 +0000</pubDate>
      <link>https://dev.to/benjmainburton/a-teacher-in-my-devops-course-showed-us-containers-and-i-fell-in-love-this-year-i-have-never-17jl</link>
      <guid>https://dev.to/benjmainburton/a-teacher-in-my-devops-course-showed-us-containers-and-i-fell-in-love-this-year-i-have-never-17jl</guid>
      <description>&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/aws-builders/securing-kubernetes-encrypting-data-at-rest-with-kubeadm-and-containerd-on-amazon-linux-2023-212o" class="crayons-story__hidden-navigation-link"&gt;Securing Kubernetes: Encrypting Data at Rest with kubeadm and containerd on Amazon Linux 2023&lt;/a&gt;


  &lt;div class="crayons-story__body crayons-story__body-full_post"&gt;
    &lt;div class="crayons-story__top"&gt;
      &lt;div class="crayons-story__meta"&gt;
        &lt;div class="crayons-story__author-pic"&gt;
          &lt;a class="crayons-logo crayons-logo--l" href="/aws-builders"&gt;
            &lt;img alt="AWS Community Builders  logo" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Forganization%2Fprofile_image%2F2794%2F88da75b6-aadd-4ea1-8083-ae2dfca8be94.png" class="crayons-logo__image"&gt;
          &lt;/a&gt;

          &lt;a href="/benjmainburton" class="crayons-avatar  crayons-avatar--s absolute -right-2 -bottom-2 border-solid border-2 border-base-inverted  "&gt;
            &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2934094%2Ffcecddcd-0a98-49a3-a3b8-40d34d3dfde4.jpg" alt="benjmainburton profile" class="crayons-avatar__image"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/benjmainburton" class="crayons-story__secondary fw-medium m:hidden"&gt;
              Lavell Burton
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                Lavell Burton
                
              
              &lt;div id="story-author-preview-content-2409000" class="profile-preview-card__content crayons-dropdown branded-7 p-4 pt-0"&gt;
                &lt;div class="gap-4 grid"&gt;
                  &lt;div class="-mt-4"&gt;
                    &lt;a href="/benjmainburton" class="flex"&gt;
                      &lt;span class="crayons-avatar crayons-avatar--xl mr-2 shrink-0"&gt;
                        &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2934094%2Ffcecddcd-0a98-49a3-a3b8-40d34d3dfde4.jpg" class="crayons-avatar__image" alt=""&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;Lavell Burton&lt;/span&gt;
                    &lt;/a&gt;
                  &lt;/div&gt;
                  &lt;div class="print-hidden"&gt;
                    
                      Follow
                    
                  &lt;/div&gt;
                  &lt;div class="author-preview-metadata-container"&gt;&lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;

            &lt;span&gt;
              &lt;span class="crayons-story__tertiary fw-normal"&gt; for &lt;/span&gt;&lt;a href="/aws-builders" class="crayons-story__secondary fw-medium"&gt;AWS Community Builders &lt;/a&gt;
            &lt;/span&gt;
          &lt;/div&gt;
          &lt;a href="https://dev.to/aws-builders/securing-kubernetes-encrypting-data-at-rest-with-kubeadm-and-containerd-on-amazon-linux-2023-212o" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;Apr 15 '25&lt;/time&gt;&lt;span class="time-ago-indicator-initial-placeholder"&gt;&lt;/span&gt;&lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;

    &lt;/div&gt;

    &lt;div class="crayons-story__indention"&gt;
      &lt;h2 class="crayons-story__title crayons-story__title-full_post"&gt;
        &lt;a href="https://dev.to/aws-builders/securing-kubernetes-encrypting-data-at-rest-with-kubeadm-and-containerd-on-amazon-linux-2023-212o" id="article-link-2409000"&gt;
          Securing Kubernetes: Encrypting Data at Rest with kubeadm and containerd on Amazon Linux 2023
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/kubernetes"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;kubernetes&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/kubeadm"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;kubeadm&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/docker"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;docker&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/linux"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;linux&lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="crayons-story__bottom"&gt;
        &lt;div class="crayons-story__details"&gt;
          &lt;a href="https://dev.to/aws-builders/securing-kubernetes-encrypting-data-at-rest-with-kubeadm-and-containerd-on-amazon-linux-2023-212o" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left"&gt;
            &lt;div class="multiple_reactions_aggregate"&gt;
              &lt;span class="multiple_reactions_icons_container"&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/fire-f60e7a582391810302117f987b22a8ef04a2fe0df7e3258a5f49332df1cec71e.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/sparkle-heart-5f9bee3767e18deb1bb725290cb151c25234768a0e9a2bd39370c382d02920cf.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
              &lt;/span&gt;
              &lt;span class="aggregate_reactions_counter"&gt;4&lt;span class="hidden s:inline"&gt; reactions&lt;/span&gt;&lt;/span&gt;
            &lt;/div&gt;
          &lt;/a&gt;
            &lt;a href="https://dev.to/aws-builders/securing-kubernetes-encrypting-data-at-rest-with-kubeadm-and-containerd-on-amazon-linux-2023-212o#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              Comments


              &lt;span class="hidden s:inline"&gt;Add Comment&lt;/span&gt;
            &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="crayons-story__save"&gt;
          &lt;small class="crayons-story__tertiary fs-xs mr-2"&gt;
            13 min read
          &lt;/small&gt;
            
              &lt;span class="bm-initial"&gt;
                

              &lt;/span&gt;
              &lt;span class="bm-success"&gt;
                

              &lt;/span&gt;
            
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;


</description>
      <category>kubernetes</category>
      <category>kubeadm</category>
      <category>docker</category>
      <category>linux</category>
    </item>
    <item>
      <title>Securing Kubernetes: Encrypting Data at Rest with kubeadm and containerd on Amazon Linux 2023</title>
      <dc:creator>Lavell Burton</dc:creator>
      <pubDate>Tue, 15 Apr 2025 13:42:53 +0000</pubDate>
      <link>https://dev.to/aws-builders/securing-kubernetes-encrypting-data-at-rest-with-kubeadm-and-containerd-on-amazon-linux-2023-212o</link>
      <guid>https://dev.to/aws-builders/securing-kubernetes-encrypting-data-at-rest-with-kubeadm-and-containerd-on-amazon-linux-2023-212o</guid>
      <description>&lt;p&gt;&lt;strong&gt;Introduction&lt;/strong&gt;: This project documents the process of setting up a Kubernetes cluster using kubeadm on an Amazon Linux 2023 EC2 instance, from Docker to containerd as the container runtime as containerd is native so I found out half way through setting up. The project is about enabling Encryption at Rest for Kubernetes secrets. The journey includes installing necessary tools, configuring the cluster, addressing errors, and securing sensitive data. This write-up is intended for those looking to set up a secure Kubernetes cluster in a production-like environment while learning from the challenges encountered.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Project Overview&lt;/strong&gt;&lt;br&gt;
The goal of this project was to deploy a Kubernetes cluster on an Amazon Linux 2023 EC2 instance using kubeadm, with a focus on securing sensitive data by enabling Encryption at Rest for Kubernetes secrets. Initially, I started with Docker as the container runtime, but I learned that Docker’s integration with Kubernetes (via Dockershim) was deprecated since Kubernetes 1.24. so I switched to containerd, a more native and recommended runtime, and successfully set up a single-node cluster, installed Calico for networking, and enabled encryption for secrets stored in etcd.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Prerequisites&lt;/strong&gt;&lt;br&gt;
EC2 Instance: Amazon Linux 2023 AMI, t2.large instance type (2 vCPUs, 8 GiB RAM), with appropriate security groups (allow ports 6443, 10250, 179 for Calico, and SSH) and more . . .&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Access&lt;/strong&gt;: SSH key pair for accessing the EC2 instance.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tools&lt;/strong&gt;: Basic familiarity with Linux commands, systemd, and Kubernetes concepts.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1: Launch the EC2 Instance&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I began by launching an EC2 instance to set up my Kubernetes cluster. Initially, I used an Ubuntu 24.04 AMI, but I encountered issues that led me to switch to an Amazon Linux 2023 AMI, which I found more reliable for my setup.&lt;/p&gt;

&lt;p&gt;Image Type: I used a Amazon Linux 2023 AMI (initially tried Ubuntu 24.04 AMI but switched due to compatibility and setup challenges).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm5e6y0pvt562n2v0jzho.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm5e6y0pvt562n2v0jzho.png" alt="Image description" width="800" height="338"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Instance Type: t2.large (2 vCPUs, 8GiB RAM), suitable for a small Kubernetes cluster.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpdhxpndppwlr22rpq88q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpdhxpndppwlr22rpq88q.png" alt="Image description" width="800" height="178"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Created Key Pair: Generated a key pair named my-key for SSH access.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzrbiclw84025vnxsjhk1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzrbiclw84025vnxsjhk1.png" alt="Image description" width="800" height="139"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fui7gy36hlth8n5oxgen1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fui7gy36hlth8n5oxgen1.png" alt="Image description" width="800" height="772"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Network Settings&lt;/strong&gt;:&lt;br&gt;
Security Group: Configured to allow inbound traffic on ports 22 (SSH), 6443 (Kubernetes API server), 10250 (kubelet), and 179 (Calico BGP for networking), 2379–2380 etcd Server Client API, 10250 Kubectl — Self, Control Plane, 10256 kube-proxy — Self, Load Balancers, 10257 kube-controller, 10259 kube-scheduler, 443 HTTPS, 8080, 80, 30000–32767 NodePort Services&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frf5zs903nvro7pz1esbb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frf5zs903nvro7pz1esbb.png" alt="Image description" width="800" height="335"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Subnet: Placed in a public subnet within my VPC (e.g., subnet-xxxxxxxx in us-east-1).&lt;/p&gt;

&lt;p&gt;I began by launching an EC2 instance using the Amazon Linux 2023 AMI. This can be done via the AWS Management Console or CLI. Here’s the CLI command I used:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;aws ec2 run-instances --image-id ami-0c55b159cbfafe1f0 --instance-type t2.large --key-name my-kube-key --security-group-ids sg-xxxxxxxx --subnet-id subnet-xxxxxxxx --region us-east-1&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;After launching, I connected to the instance:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;ssh -i my-kube-key.pem ec2-user@&amp;lt;ec2-public-ip&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The instance’s private IP (e.g., 172.xx.xx.x) was used for cluster configuration.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2: Initial Attempt with Docker (Later Switched to containerd)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I initially attempted to set up the cluster using Docker as the container runtime, with Ubuntu as it was familiar. Here are the steps I followed:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Install Docker&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;sudo yum update -y&lt;br&gt;
sudo yum install docker -y&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/install-docker.html?source=post_page-----611a4b8b6fcd---------------------------------------" rel="noopener noreferrer"&gt;Installing Docker to use with the AWS SAM CLI&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe1jxfsqqttl5h8arah9q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe1jxfsqqttl5h8arah9q.png" alt="Image description" width="800" height="406"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhfg8idn7p4hzg44c3hpx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhfg8idn7p4hzg44c3hpx.png" alt="Image description" width="800" height="408"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Start and Enable Docker&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;sudo systemctl start docker&lt;br&gt;
sudo systemctl enable docker&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Add ec2-user to Docker Group&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To avoid using sudo for Docker commands:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;sudo usermod -aG docker ec2-user&lt;br&gt;
exit  # Re-SSH to apply group changes&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0oy5n137n2yta4ck1wwq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0oy5n137n2yta4ck1wwq.png" alt="Image description" width="800" height="68"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Verify Docker Installation&lt;/p&gt;

&lt;p&gt;&lt;code&gt;docker run hello-world&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6h0vd34wysafjj3g8bgr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6h0vd34wysafjj3g8bgr.png" alt="Image description" width="800" height="532"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This confirmed Docker was working, but I later learned that Docker’s integration with Kubernetes (via Dockershim) was deprecated, which is why I switch to containerd.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fahdqskeepc8sxhp800cn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fahdqskeepc8sxhp800cn.png" alt="Image description" width="800" height="241"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 3: Switch to containerd&lt;/strong&gt;&lt;br&gt;
Since Docker’s support in Kubernetes is deprecated, I switched to containerd, a native container runtime recommended for Kubernetes I heard of it before, but I was just staying in my comfort zone. I installed specific versions of containerd, runc, and CNI plugins manually to ensure compatibility.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Install containerd v2.0.4&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;curl -LO https://github.com/containerd/containerd/releases/download/v2.0.4/containerd-2.0.4-linux-amd64.tar.gz&lt;br&gt;
sudo tar Cxzvf /usr/local containerd-2.0.4-linux-amd64.tar.gz&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxqlcpa4t65v9at48ihs1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxqlcpa4t65v9at48ihs1.png" alt="Image description" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/containerd/containerd/blob/main/docs/getting-started.md" rel="noopener noreferrer"&gt;Getting started with containerd&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Created the systemd Directory&lt;/p&gt;

&lt;p&gt;The /usr/local/lib/systemd/system directory didn’t exist, so I created it:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;sudo mkdir -p /usr/local/lib/systemd/system&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdcotty2w6wdtlbmrbrh2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdcotty2w6wdtlbmrbrh2.png" alt="Image description" width="800" height="46"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Installed containerd systemd Service&lt;/p&gt;

&lt;p&gt;&lt;code&gt;sudo curl -L https://raw.githubusercontent.com/containerd/containerd/main/containerd.service -o /usr/local/lib/systemd/system/containerd.service&lt;br&gt;
sudo systemctl daemon-reload&lt;br&gt;
sudo systemctl enable --now containerd&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://raw.githubusercontent.com/containerd/containerd/main/containerd.service" rel="noopener noreferrer"&gt;https://raw.githubusercontent.com/containerd/containerd/main/containerd.service&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Installed runc v1.2.6&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://github.com/opencontainers/runc/releases/tag/v1.2.6" rel="noopener noreferrer"&gt;runc&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;curl -LO https://github.com/opencontainers/runc/releases/download/v1.2.6/runc.amd64&lt;br&gt;
sudo install -m 755 runc.amd64 /usr/local/sbin/runc&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Install CNI Plugins v1.6.2&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;sudo mkdir -p /opt/cni/bin&lt;br&gt;
curl -LO https://github.com/containernetworking/plugins/releases/download/v1.6.2/cni-plugins-linux-amd64-v1.6.2.tgz&lt;br&gt;
sudo tar Cxzvf /opt/cni/bin cni-plugins-linux-amd64-v1.6.2.tgz&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/containernetworking/plugins/releases/tag/v1.6.2" rel="noopener noreferrer"&gt;container networking&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs5o261rixzfauid5m5ip.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs5o261rixzfauid5m5ip.png" alt="Image description" width="800" height="390"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 4: Installed Kubernetes Tools&lt;/strong&gt;&lt;br&gt;
I set up the Kubernetes repository for version 1.32 and installed kubeadm, kubelet, and kubectl.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Added Kubernetes Repositories (v1.32)&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;sudo tee /etc/yum.repos.d/kubernetes.repo &amp;lt;&amp;lt;EOF&lt;br&gt;
[kubernetes]&lt;br&gt;
name=Kubernetes&lt;br&gt;
baseurl=https://pkgs.k8s.io/core:/stable:/v1.32/rpm/&lt;br&gt;
enabled=1&lt;br&gt;
gpgcheck=1&lt;br&gt;
gpgkey=https://pkgs.k8s.io/core:/stable:/v1.32/rpm/repodata/repomd.xml.key&lt;br&gt;
EOF&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://kubernetes.io/docs/tasks/administer-cluster/kubeadm/change-package-repository/" rel="noopener noreferrer"&gt;Kubernetes Package Repository&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpl90pvj3fpc7dfwifczb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpl90pvj3fpc7dfwifczb.png" alt="Image description" width="800" height="304"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Install kubeadm, kubelet, and kubectl&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;sudo dnf install -y kubeadm kubelet kubectl&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm672g5553q2rsthxlayi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm672g5553q2rsthxlayi.png" alt="Image description" width="800" height="402"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Installed the versionlock Plugin (Optional, to Prevent Updates)&lt;/strong&gt;&lt;br&gt;
The versionlock plugin wasn’t available by default, so I installed it:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;sudo dnf install -y 'dnf-command(versionlock)'&lt;br&gt;
sudo dnf versionlock add kubeadm kubelet kubectl&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://docs.stg.fedoraproject.org/en-US/quick-docs/dnf/" rel="noopener noreferrer"&gt;dnf&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnei7gwkoakzfw6heocjz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnei7gwkoakzfw6heocjz.png" alt="Image description" width="800" height="300"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fld5toz1ow9e8bg710yff.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fld5toz1ow9e8bg710yff.png" alt="Image description" width="800" height="114"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: I initially considered preventing updates to ensure stability but learned that updates are important for security fixes, bug resolutions, and compatibility. In a production environment, controlled upgrades are recommended instead of locking versions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 5: Prepared the System for Kubernetes&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Kubernetes requires specific system settings to function properly like,&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Disabling Swap&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;sudo swapoff -a&lt;br&gt;
sudo sed -i '/ swap / s/^/#/' /etc/fstab&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl0du14r4zpl0a2bxslqj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl0du14r4zpl0a2bxslqj.png" alt="Image description" width="800" height="66"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Set SELinux to Permissive per documentation&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Kubernetes can have issues with SELinux in enforcing mode, so I set it to permissive:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;sudo setenforce 0&lt;br&gt;
sudo sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftlm7l5h9ce2ur50mrs2a.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftlm7l5h9ce2ur50mrs2a.png" alt="Image description" width="800" height="54"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/install-kubeadm/" rel="noopener noreferrer"&gt;install-kubeadm&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Enable IP Forwarding&lt;/strong&gt;&lt;br&gt;
I encountered a preflight error [ERROR FileContent — proc-sys-net-ipv4-ip_forward]. Kubernetes requires IP forwarding to be enabled:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;sudo sysctl -w net.ipv4.ip_forward=1&lt;br&gt;
sudo sh -c 'echo "net.ipv4.ip_forward=1" &amp;gt;&amp;gt; /etc/sysctl.conf'&lt;br&gt;
sudo sysctl -p&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;It was complaining about kubelet Service so I Enabled kubelet Service&lt;/p&gt;

&lt;p&gt;&lt;code&gt;sudo systemctl enable kubelet.service&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 6: Initialized the Control Plane&lt;/strong&gt;&lt;br&gt;
I initialized the Kubernetes control plane using kubeadm. Initially, I ran into a preflight warning [WARNING FileExisting-tc] because the tc command (from iproute) wasn’t in the default path, even though it was installed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fixed the tc Path&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;[WARNING FileExisting-tc]: tc not found in system path&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4n7sm25d7g9nwui93sx0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4n7sm25d7g9nwui93sx0.png" alt="Image description" width="800" height="110"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;sudo yum install iproute&lt;br&gt;
which tc&lt;br&gt;
export PATH=$PATH:/sbin&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwtd1kdxn85uquyj979ie.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwtd1kdxn85uquyj979ie.png" alt="Image description" width="800" height="182"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;sudo PATH=$PATH:/sbin kubeadm init --apiserver-advertise-address=172.31.26.7 --pod-network-cidr=192.168.0.0/16&lt;br&gt;
sudo systemctl enabled kubelet.service&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4cv4e395sbeuox2f4bwo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4cv4e395sbeuox2f4bwo.png" alt="Image description" width="800" height="306"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The init command above succeeded, initializing the control plane with Kubernetes v1.32.3.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 7: Set Up kubeconfig&lt;/strong&gt;&lt;br&gt;
To interact with the cluster using kubectl, I set up the kubeconfig file:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;mkdir -p $HOME/.kube&lt;br&gt;
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config&lt;br&gt;
sudo chown $(id -u):$(id -g) $HOME/.kube/config&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F06q75v0wqk13ean5ock2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F06q75v0wqk13ean5ock2.png" alt="Image description" width="800" height="52"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 8: Installed Calico for Pod Networking&lt;/strong&gt;&lt;br&gt;
Kubernetes requires a CNI plugin for pod-to-pod networking. I chose Calico because it matched my — pod-network-cidr=192.168.0.0/16 and integrates well with AWS:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;kubectl apply -f https://raw.githubusercontent.com/projectcalico/calico/v3.26.4/manifests/calico.yaml&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://docs.tigera.io/calico/latest/getting-started/kubernetes/quickstart" rel="noopener noreferrer"&gt;calico getting-started&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx0z6qly8kjpnd8asfjpn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx0z6qly8kjpnd8asfjpn.png" alt="Image description" width="800" height="341"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;I verified the cluster was operational:&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;kubectl get pods -n kube-system&lt;br&gt;
kubectl get nodes&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff2gaoll3dsg8v66wmpwd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff2gaoll3dsg8v66wmpwd.png" alt="Image description" width="800" height="155"&gt;&lt;/a&gt;&lt;br&gt;
Had to wait for the start didnt get that screenshot — oversight&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 9: Install etcd Client for Verification&lt;/strong&gt;&lt;br&gt;
To verify encryption later, I needed the etcdctl client. I installed it manually:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Download and Extracted etcd v3.5.21&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;curl -LO https://github.com/etcd-io/etcd/releases/download/v3.5.21/etcd-v3.5.21-linux-amd64.tar.gz&lt;br&gt;
tar xzf etcd-v3.5.21-linux-amd64.tar.gz&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Move etcdctl to PATH&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;sudo mv etcd-v3.5.21-linux-amd64/etcdctl /usr/local/bin/&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Verified Installation&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;etcdctl version&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: I didn’t need to run an external etcd server because kubeadm deploys etcd as a pod (etcd-) in the kube-system namespace. However, I initially installed etcd manually and tried to configure it, which led to errors (e.g., unsupported — etcd-endpoints flag). I resolved this by letting kubeadm manage etcd.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 10: Enabled Encryption at Rest&lt;/strong&gt;&lt;br&gt;
The main goal was to enable Encryption at Rest for Kubernetes secrets, which are stored in etcd. By default, secrets are stored unencrypted (base64-encoded but readable), posing a security risk.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Verify etcd Pod&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;kubectl get pods -n kube-system&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5mcmdt5a4ti9ycst13t7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5mcmdt5a4ti9ycst13t7.png" alt="Image description" width="800" height="155"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This showed the etcd-ip-172–31–90–174 pod running.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Check for etcd Certificates&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;ls /etc/kubernetes/pki/etcd&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fynws6spldb384n5beu2t.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fynws6spldb384n5beu2t.png" alt="Image description" width="800" height="109"&gt;&lt;/a&gt;&lt;br&gt;
This confirmed the presence of ca.crt, server.crt, and server.key.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Check Current Secret State (Unencrypted)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I created a test secret:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;kubectl create secret generic my-secret-1 --from-literal=key1=topsecret&lt;br&gt;
kubectl get secrets&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://kubernetes.io/docs/reference/kubectl/generated/kubectl_create/kubectl_create_secret_generic/" rel="noopener noreferrer"&gt;kubectl create secret&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fget20heorcmsnenecifi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fget20heorcmsnenecifi.png" alt="Image description" width="800" height="485"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmvp8yl7ugc4rfktizx9g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmvp8yl7ugc4rfktizx9g.png" alt="Image description" width="800" height="51"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I checked its state in etcd:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;ETCDCTL_API=3 etcdctl \&lt;br&gt;
   --cacert=/etc/kubernetes/pki/etcd/ca.crt \&lt;br&gt;
   --cert=/etc/kubernetes/pki/etcd/server.crt \&lt;br&gt;
   --key=/etc/kubernetes/pki/etcd/server.key \&lt;br&gt;
   get /registry/secrets/default/my-secret-1 | hexdump -C&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://kubernetes.io/docs/tasks/administer-cluster/configure-upgrade-etcd/" rel="noopener noreferrer"&gt;Operating etcd clusters for Kubernetes&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3cqvnthlxdduikjlcw0p.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3cqvnthlxdduikjlcw0p.png" alt="Image description" width="800" height="185"&gt;&lt;/a&gt;&lt;br&gt;
Here the secret is unencrypted&lt;/p&gt;

&lt;p&gt;The output showed the secret in plaintext (base64-decodable), confirming it was unencrypted.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Check if Encryption Is Enabled&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I checked the API server configuration:&lt;br&gt;
&lt;code&gt;ps -aux | grep kube-api | grep encryption-provider-config&lt;br&gt;
cat /etc/kubernetes/manifests/kube-apiserver.yaml&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;No — encryption-provider-config flag was present, indicating encryption wasn’t enabled.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Create Encryption Configuration&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I chose the aescbc provider for simplicity, though stronger options like kms v2 are recommended for production. I generated a key:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;head -c 32 /dev/urandom | base64&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;I created an encryption configuration file (enc.yaml):&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsxm99kkm7llszwaveu8x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsxm99kkm7llszwaveu8x.png" alt="Image description" width="694" height="48"&gt;&lt;/a&gt;&lt;br&gt;
Created a file for the secret per documentation&lt;/p&gt;

&lt;p&gt;`cat &amp;lt;&amp;lt;EOF | tee enc.yaml&lt;br&gt;
apiVersion: apiserver.config.k8s.io/v1&lt;br&gt;
kind: EncryptionConfiguration&lt;br&gt;
resources:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;resources:

&lt;ul&gt;
&lt;li&gt;secrets
providers:&lt;/li&gt;
&lt;li&gt;aescbc:
  keys:
    - name: key1
      secret: &lt;/li&gt;
&lt;li&gt;identity: {}
EOF`&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fico0d4cgfzxjlacpuyft.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fico0d4cgfzxjlacpuyft.png" alt="Image description" width="800" height="968"&gt;&lt;/a&gt;&lt;br&gt;
the key here is not the format its a code from the command | head -c 32 /dev/urandom | base64 I replaced it with the correct key&lt;/p&gt;

&lt;p&gt;&lt;a href="https://kubernetes.io/docs/tasks/administer-cluster/encrypt-data/" rel="noopener noreferrer"&gt;Encrypting Confidential Data at Rest&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Move Configuration File&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;sudo mkdir -p /etc/kubernetes/enc&lt;br&gt;
sudo mv enc.yaml /etc/kubernetes/enc&lt;br&gt;
sudo ls /etc/kubernetes/enc&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Foh2f45n46d22l0a2jqvk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Foh2f45n46d22l0a2jqvk.png" alt="Image description" width="800" height="69"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj9ie4hkmzyvcl8eesiab.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj9ie4hkmzyvcl8eesiab.png" alt="Image description" width="800" height="46"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa3h9huotvbdgyenpcj93.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa3h9huotvbdgyenpcj93.png" alt="Image description" width="800" height="81"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Update kube-apiserver Manifest&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I edited the API server manifest to enable encryption:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;sudo vi /etc/kubernetes/manifests/kube-apiserver.yaml&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftyby2yjvouccigosfpzv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftyby2yjvouccigosfpzv.png" alt="Image description" width="800" height="742"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Added the following:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Under spec.containers[0].command:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;- --encryption-provider-config=/etc/kubernetes/enc/enc.yaml&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg10c6ok4bf1l4uw4m3p5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg10c6ok4bf1l4uw4m3p5.png" alt="Image description" width="800" height="787"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Under spec.containers[0].volumeMounts:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;- name: enc&lt;br&gt;
  mountPath: /etc/kubernetes/enc&lt;br&gt;
  readOnly: true&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1e9ysaazl9viiwh04a1o.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1e9ysaazl9viiwh04a1o.png" alt="Image description" width="800" height="1277"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Under spec.volumes:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;- name: enc&lt;br&gt;
  hostPath:&lt;br&gt;
    path: /etc/kubernetes/enc&lt;br&gt;
    type: DirectoryOrCreate&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy40h691n8j76kir7kcd9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy40h691n8j76kir7kcd9.png" alt="Image description" width="800" height="1101"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The API server pod automatically restarted after saving the changes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Verify Encryption&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I created a new secret:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;kubectl create secret generic my-secret-2 --from-literal=key2=topsecret&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://kubernetes.io/docs/reference/kubectl/generated/kubectl_create/kubectl_create_secret_generic/" rel="noopener noreferrer"&gt;kubectl create secret generic&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd094ubfm2sxp5lnorvu8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd094ubfm2sxp5lnorvu8.png" alt="Image description" width="800" height="43"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Checked its state in etcd:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;ETCDCTL_API=3 etcdctl \&lt;br&gt;
   --cacert=/etc/kubernetes/pki/etcd/ca.crt \&lt;br&gt;
   --cert=/etc/kubernetes/pki/etcd/server.crt \&lt;br&gt;
   --key=/etc/kubernetes/pki/etcd/server.key \&lt;br&gt;
   get /registry/secrets/default/my-secret-2 | hexdump -C&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjyn9ir6jc4c0clh7noa8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjyn9ir6jc4c0clh7noa8.png" alt="Image description" width="800" height="516"&gt;&lt;/a&gt;&lt;br&gt;
The secret is encrytped as you cant see the word topsecret in the bottom of the right like secret 1&lt;/p&gt;

&lt;p&gt;The output showed encrypted data (starting with k8s:enc:aescbc:v1:), confirming encryption was enabled. The original secret (my-secret-1) remained unencrypted because encryption only applies to new or updated secrets.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Encrypt Existing Secrets&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To encrypt all existing secrets:&lt;br&gt;
&lt;code&gt;kubectl get secrets --all-namespaces -o json | kubectl replace -f -&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This is getting the secrets and replacing them with them same json file, basically updating the objects with the same data so now everything is locked down and encrypted.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/" rel="noopener noreferrer"&gt;Namespaces&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgtckv386351y56uypbet.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgtckv386351y56uypbet.png" alt="Image description" width="800" height="80"&gt;&lt;/a&gt;&lt;br&gt;
The command that ensured all secrets will be encrypted moving forward&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fax2gz4dmcxmdn9wx0beb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fax2gz4dmcxmdn9wx0beb.png" alt="Image description" width="800" height="418"&gt;&lt;/a&gt;&lt;br&gt;
After the command was ran both secrets were updated and encrypted secret 1 &amp;amp; secret 2&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs3abp3asxfmxfmll1b2f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs3abp3asxfmxfmll1b2f.png" alt="Image description" width="800" height="101"&gt;&lt;/a&gt;&lt;br&gt;
Kube-api file showing the line we added in the manifest&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6qb4anahlr6cncffnvi4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6qb4anahlr6cncffnvi4.png" alt="Image description" width="800" height="97"&gt;&lt;/a&gt;&lt;br&gt;
used grep to highlight the exact line that was used to encrypt&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 11: Joining Worker Nodes&lt;/strong&gt;&lt;br&gt;
To scale the cluster, I prepared a worker node by installing containerd, kubeadm, and kubelet (same steps as the master, minus kubectl). I joined the worker node using the kubeadm join command provided by kubeadm init:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;sudo kubeadm join 172.31.26.7:6443 --token nitoam.ttnbcuhbc55kr5y6 --discovery-token-ca-cert-hash sha256:b75a4cde2e40f5b18dcb441908bedfeacecd397b6a397ecdbb78c7c2f5df0d67&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://kubernetes.io/docs/reference/setup-tools/kubeadm/kubeadm-join/" rel="noopener noreferrer"&gt;kubeadm-join&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffjxo8x2hhaz6e17c59qz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffjxo8x2hhaz6e17c59qz.png" alt="Image description" width="800" height="271"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Challenges and Lessons Learned&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Docker Deprecation:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I started with Docker but learned about its deprecation in Kubernetes Half way into the project&lt;/li&gt;
&lt;li&gt;Switching to containerd was cleaner and aligned with Kubernetes best practices.&lt;/li&gt;
&lt;li&gt;Lesson: Always check Kubernetes documentation for supported runtimes, especially with newer versions.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Preflight Errors:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Encountered errors like [ERROR FileContent — proc-sys-net-ipv4-ip_forward] and [WARNING FileExisting-tc]. These required enabling IP forwarding and adjusting the PATH for tc.&lt;/li&gt;
&lt;li&gt;Lesson: Kubernetes preflight checks are strict; ensure all system requirements (swap, SELinux, IP forwarding) are met.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;External etcd Configuration:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I initially tried to use an external etcd instance but faced errors (e.g., unsupported — etcd-endpoints flag). I resolved this by letting kubeadm manage etcd and using a configuration file (kubeadm-config.yaml) when needed.&lt;/li&gt;
&lt;li&gt;Lesson: For single-node setups, kubeadm’s default etcd is simpler; external etcd is better for high-availability clusters.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Encryption Providers:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I used aescbc for simplicity, but learned that kms v2 is stronger and recommended for production due to its envelope encryption and key rotation support.&lt;/li&gt;
&lt;li&gt;Lesson: Choose encryption providers based on security needs; kms v2 is ideal for production with a key management service.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Best Practices for Production&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;High Availability: Use 3+ control plane nodes with an external load balancer and a separate etcd cluster (3+ nodes).&lt;/li&gt;
&lt;li&gt;Encryption: Use kms v2 for stronger encryption and key rotation.&lt;/li&gt;
&lt;li&gt;Security Groups: Ensure EC2 security groups allow necessary ports (e.g., 6443 for API server, 179 for Calico).&lt;/li&gt;
&lt;li&gt;Updates: Avoid locking package versions (versionlock); instead, plan controlled upgrades for security and compatibility.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Other Issues&lt;/strong&gt;: I installed Docker, but by default kubeadm and kubelet no longer natively use Docker As of Kubernetes v1.24+, Docker is not the default runtime — it uses containerd (or CRI-O).&lt;br&gt;
And I only installed Docker but not the Docker shim (cri-dockerd), kubelet cannot talk to Docker directly anymore. That’s why kubelet was up, but the pods were dead.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;error: failed to create secret Post "https://172.31.90.174:6443/...": dial tcp 172.31.90.174:6443: connect: connection refused&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;error: failed to create secret Post "http://localhost:8080/...": dial tcp 127.0.0.1:8080: connect: connection refused&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This meant my kubectl couldn’t talk to the Kubernetes API server — it was basically refusing the connection. The node wasn’t properly connected to the control plane (master). Even though I ran kubeadm join, the node was probably still be initializing, or something broke during setup either way Containerd fixed everything for me.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In this project I successfully deployed a Kubernetes cluster on Amazon Linux 2023 using kubeadm and containerd, with Calico for networking and Encryption at Rest enabled for secrets. The journey involved overcoming challenges like runtime deprecation, preflight errors, and etcd configuration, providing valuable lessons for setting up secure Kubernetes clusters. By encrypting secrets in etcd, I ensured sensitive data was protected, achieving the primary goal of enhancing cluster security.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Connect with me on my Socials:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1w6qdhbbbl5rhjfan952.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1w6qdhbbbl5rhjfan952.png" alt="Image description" width="800" height="451"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.linkedin.com/in/benjaminlburton/" rel="noopener noreferrer"&gt;linkedin&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/benjaminBurton" rel="noopener noreferrer"&gt;Github&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/@lavellburton" rel="noopener noreferrer"&gt;YouTube&lt;/a&gt;&lt;/p&gt;

</description>
      <category>kubernetes</category>
      <category>kubeadm</category>
      <category>docker</category>
      <category>linux</category>
    </item>
  </channel>
</rss>
