<?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: NURUDEEN KAMILU</title>
    <description>The latest articles on DEV Community by NURUDEEN KAMILU (@nurudeen_kamilu).</description>
    <link>https://dev.to/nurudeen_kamilu</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%2F2655934%2F913a7831-6976-4bc5-bc4b-4c066e700f17.jpg</url>
      <title>DEV Community: NURUDEEN KAMILU</title>
      <link>https://dev.to/nurudeen_kamilu</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/nurudeen_kamilu"/>
    <language>en</language>
    <item>
      <title>OVN Kubernetes - What Makes It Different</title>
      <dc:creator>NURUDEEN KAMILU</dc:creator>
      <pubDate>Sun, 30 Nov 2025 00:13:08 +0000</pubDate>
      <link>https://dev.to/nurudeen_kamilu/ovn-kubernetes-what-makes-it-different-2dli</link>
      <guid>https://dev.to/nurudeen_kamilu/ovn-kubernetes-what-makes-it-different-2dli</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;As Kubernetes continues to dominate container orchestration, the networking layer has become increasingly critical to cluster performance and functionality. &lt;strong&gt;OVN-Kubernetes (Open Virtual Network for Kubernetes)&lt;/strong&gt; has emerged as a sophisticated Container Network Interface (CNI) plugin that leverages &lt;strong&gt;Open vSwitch (OVS)&lt;/strong&gt; and its control plane, OVN, to provide advanced networking capabilities. Recently accepted as a &lt;strong&gt;CNCF Sandbox project (late 2024)&lt;/strong&gt;, it is the default networking provider for Red Hat OpenShift and is widely adopted in telecommunications and high-performance computing environments due to its unique architectural choices. Understanding what sets OVN-Kubernetes apart from other CNI solutions is essential for architects and cluster operators making infrastructure decisions.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is OVN-Kubernetes?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;OVN-Kubernetes&lt;/strong&gt; is a &lt;strong&gt;CNI plugin&lt;/strong&gt; that implements Kubernetes networking using &lt;strong&gt;OVN (Open Virtual Network)&lt;/strong&gt;, which itself is built on top of &lt;strong&gt;Open vSwitch&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Open vSwitch&lt;/strong&gt; is a mature, production-grade virtual switch that has been used in datacenters and cloud environments for over a decade. Think of it as a software-based network switch that runs on Linux servers, capable of forwarding network packets between virtual machines, containers, and physical networks. OVS supports advanced networking features like VLANs, tunnelling protocols, and quality of service controls, essentially bringing enterprise switch capabilities to software-defined environments.&lt;/p&gt;

&lt;p&gt;OVN builds on top of OVS by adding a &lt;strong&gt;control plane&lt;/strong&gt; that manages the network configuration across multiple hosts. While OVS handles the actual packet forwarding (the "data plane"), OVN provides the intelligence to coordinate networking across an entire cluster (the "control plane"). This separation allows for sophisticated network topologies and centralized management while maintaining high performance for packet processing.&lt;/p&gt;

&lt;p&gt;The plugin implements all required Kubernetes networking features, including pod-to-pod communication, service networking, network policies, and ingress/egress traffic management. What distinguishes it is the underlying architecture that uses proven datacenter networking technology rather than simpler overlay approaches.&lt;/p&gt;

&lt;h2&gt;
  
  
  Core Architecture
&lt;/h2&gt;

&lt;p&gt;OVN-Kubernetes can be deployed in two modes: default mode with a centralized control plane, or interconnect mode with a distributed control plane architecture. The default mode is the traditional deployment, while interconnect mode distributes the databases across nodes for improved stability and scalability. Below, we'll focus on the default mode architecture, which is simpler to understand and widely deployed.&lt;/p&gt;

&lt;h4&gt;
  
  
  Default Mode OVN-Kubernetes Components
&lt;/h4&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%2F87vzjk63j8r819z1b7cr.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%2F87vzjk63j8r819z1b7cr.png" alt="Default Mode OVN-Kubernetes Components" width="800" height="919"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In default mode, OVN-Kubernetes operates through several key components:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;ovnkube-master:&lt;/strong&gt; The OVN-Kubernetes controller that watches the Kubernetes API server for network-relevant changes (pods, services, network policies) and translates these into OVN logical network configurations that are stored in the NBDB. It also manages pod subnet allocation to nodes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;OVN Northbound Database (NBDB):&lt;/strong&gt; Stores the logical elements created by ovnkube-master. This represents the desired state of the network. In default mode, the NBDB runs on control plane nodes using RAFT for high availability with 3 replicas.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;ovn-northd:&lt;/strong&gt; A native OVN component that acts as a translator, converting the logical network elements from the Northbound Database into logical flows that are stored in the Southbound Database.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;OVN Southbound Database (SBDB):&lt;/strong&gt; Contains the physical network mapping and flow programming instructions that translate logical network configurations into actual data plane rules. Like the NBDB, it runs on control plane nodes with 3 replicas in HA mode.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;ovn-controller:&lt;/strong&gt; Runs on each node and connects to the centralized SBDB. It converts the logical flows from SBDB into OpenFlow rules and programs the local OVS instance accordingly.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Open vSwitch (OVS):&lt;/strong&gt; The data plane that runs on every node and actually forwards packets according to the programmed flows.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Note on Interconnect Mode: For large-scale deployments or scenarios requiring maximum stability, OVN-Kubernetes also supports interconnect mode, where the OVN databases run locally on each node rather than centrally. This distributed architecture eliminates RAFT coordination overhead and isolates database failures to individual nodes, improving both scalability and stability. Each node becomes its own "zone" with local databases, though this comes with additional operational complexity.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Makes OVN-Kubernetes Different
&lt;/h2&gt;

&lt;p&gt;While plugins like Flannel focus on simplicity and Cilium focuses on eBPF-based software performance, OVN-Kubernetes differentiates itself through architectural flexibility and hardware integration.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Geneve Encapsulation with Flexible Routing Options:&lt;/strong&gt; OVN-Kubernetes defaults to &lt;strong&gt;Geneve&lt;/strong&gt; (Generic Network Virtualization Encapsulation) for pod-to-pod communication across nodes, rather than the more common VXLAN. Why Geneva? Geneve's extensible header can carry additional metadata for security labels and logical flow identification, while VXLAN's fixed header size limits this capability. What distinguishes OVN-Kubernetes is its flexibility - while Geneve overlay is the default, it can be configured for direct routing modes that eliminate encapsulation overhead when network topology permits, providing both overlay convenience and native routing performance options.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Hardware Offload Capabilities:&lt;/strong&gt; This is one of the primary reason users choose OVN-Kubernetes over Cilium or Calico for bare-metal clusters. Because it is built on OVS, OVN-Kubernetes can leverage OVS Hardware Offload. It can push packet processing down to the SmartNIC (Network Interface Card) or DPU (Data Processing Unit), such as NVIDIA BlueField. This frees the main CPU from processing network packets (saving CPU cycles for application workloads), and network latency drops to near wire speed. In comparison, Cilium uses eBPF to speed up processing in the OS kernel; OVN-Kubernetes can bypass the CPU entirely for established flows. This makes it particularly suitable for latency-sensitive workloads like real-time analytics and telecommunications applications where microseconds matter.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Hybrid and Multi-Network Support:&lt;/strong&gt; OVN-Kubernetes provides robust support for hybrid networking scenarios where pods need connectivity to both the cluster network and external networks. Through the integration with Multus CNI, it can attach multiple network interfaces to pods, enabling use cases like separating control plane and data plane traffic or connecting workloads directly to physical networks. This flexibility makes OVN-Kubernetes particularly suitable for network function virtualization (NFV) and telecommunications workloads that require direct hardware access or specific network topologies.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Integrated Load Balancing:&lt;/strong&gt; Rather than relying on kube-proxy for service load balancing, OVN-Kubernetes can implement service load balancing directly in OVS using OVN's native load balancer objects. This approach bypasses iptables or IPVS entirely, reducing the complexity of the networking stack and improving performance, particularly for clusters with a large number of services.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Advanced Egress Traffic Control:&lt;/strong&gt; OVN-Kubernetes provides sophisticated controls for traffic leaving the cluster through three key features:&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;EgressIP:&lt;/strong&gt; Allows you to assign a specific, static public IP to a namespace or pod for outbound traffic (crucial for connecting to legacy firewalls that whitelist IPs).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;EgressFirewall:&lt;/strong&gt; Allows admins to block a specific pod from accessing specific external websites or IP ranges. For example, this pod cannot talk to the public internet, only the corporate intranet.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;EgressQoS:&lt;/strong&gt; Applies &lt;strong&gt;DSCP (Differentiated Services Code Point)&lt;/strong&gt; markings to outbound traffic for quality-of-service handling by external network equipment Ovn-kubernetes. Useful when external routers need to prioritize certain traffic flows.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;OVN-Kubernetes represents a sophisticated approach to Kubernetes networking that brings datacenter-grade software-defined networking to container orchestration. Its architecture, based on OVN and OVS, provides advanced features, excellent scalability, and flexibility that simpler CNI plugins cannot match. The tradeoff is operational complexity and the need for specialized knowledge. Organizations should choose OVN-Kubernetes when they need its advanced features, are operating at scale, have existing OVS expertise, or require the multi-network and hardware offloading capabilities it provides.&lt;/p&gt;

&lt;h5&gt;
  
  
  References and Further Reading:
&lt;/h5&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/ovn-kubernetes/ovn-kubernetes" rel="noopener noreferrer"&gt;OVN-Kubernetes GitHub Repository&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://docs.ovn.org/en/latest/" rel="noopener noreferrer"&gt;OVN Architecture Documentation&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.openvswitch.org/" rel="noopener noreferrer"&gt;Open vSwitch Documentation&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://docs.redhat.com/en/documentation/openshift_container_platform/4.20/html/ovn-kubernetes_network_plugin/about-ovn-kubernetes" rel="noopener noreferrer"&gt;RedHat OpenShift OVN-Kubernetes Network Plugin&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://ovn-kubernetes.io/" rel="noopener noreferrer"&gt;OVN-Kubernetes Official Documentation&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://blog.russellbryant.net/post/2017/05/2017-05-30-ovn-geneve-vs-vxlan-does-it-matter/#:~:text=With%20Geneve%2C%20OVN%20will%20identify,advanced%20features%20in%20the%20future." rel="noopener noreferrer"&gt;Comparisons: Russell Bryant: "OVN – Geneve vs VXLAN, Does it Matter?"&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.cncf.io/projects/ovn-kubernetes/" rel="noopener noreferrer"&gt;CNCF Sandbox: OVN-Kubernetes acceptance into CNCF Sandbox (Late 2024 announcements).&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>kubernetes</category>
      <category>cloudnative</category>
      <category>linux</category>
      <category>network</category>
    </item>
    <item>
      <title>AWS Config vs Kubernetes Native Policy Engines: Who Governs What?</title>
      <dc:creator>NURUDEEN KAMILU</dc:creator>
      <pubDate>Mon, 05 May 2025 12:06:35 +0000</pubDate>
      <link>https://dev.to/nurudeen_kamilu/aws-config-vs-kubernetes-native-policy-engines-who-governs-what-5dga</link>
      <guid>https://dev.to/nurudeen_kamilu/aws-config-vs-kubernetes-native-policy-engines-who-governs-what-5dga</guid>
      <description>&lt;p&gt;In modern cloud-native environments, compliance, governance, and standardization are critical to ensuring security, operational efficiency, and regulatory adherence. As organizations adopt containerized infrastructure, enforcing consistent policies across platforms like &lt;strong&gt;Amazon EKS&lt;/strong&gt; (Kubernetes-based) and &lt;strong&gt;ECS&lt;/strong&gt; (serverless containers) becomes increasingly complex.&lt;/p&gt;

&lt;p&gt;At first glance, &lt;strong&gt;AWS Config&lt;/strong&gt; and &lt;strong&gt;Kubernetes-native policy engines&lt;/strong&gt; like &lt;strong&gt;OPA Gatekeeper&lt;/strong&gt; and &lt;strong&gt;Kyverno&lt;/strong&gt; may appear to serve the same function — enforcing rules and ensuring compliance in containerized workloads. But in reality, they operate at &lt;strong&gt;different layers&lt;/strong&gt;, solve &lt;strong&gt;distinct problems&lt;/strong&gt;, and &lt;strong&gt;target different scopes of governance&lt;/strong&gt;. AWS Config is designed for &lt;strong&gt;cloud-wide compliance&lt;/strong&gt; across AWS resources, whereas Kubernetes-native engines are focused on &lt;strong&gt;cluster-level policy enforcement&lt;/strong&gt; within the Kubernetes API lifecycle.&lt;/p&gt;

&lt;p&gt;In environments where workloads span EKS, ECS, and other AWS services, these tools must often coexist — not compete. This article dives into their differences, where they overlap, and most importantly: &lt;em&gt;who really governs what&lt;/em&gt; in a dynamic, multi-platform cloud environment.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is AWS Config?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://aws.amazon.com/config/" rel="noopener noreferrer"&gt;AWS Config&lt;/a&gt; is a service that continuously monitors and records AWS resource configurations and evaluates them against desired states. Think of it as a compliance engine: it tracks configuration changes and helps you answer questions like:&lt;br&gt;
&lt;em&gt;- Are my EKS clusters configured securely?&lt;/em&gt;&lt;br&gt;
&lt;em&gt;- Are ECS tasks using only approved IAM roles?&lt;/em&gt;&lt;br&gt;
&lt;em&gt;- Is anything exposed to the public internet unintentionally?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;In a cloud environment, AWS Config works by recording and capturing configuration changes in AWS resources using a Config Recorder. By applying &lt;a href="https://docs.aws.amazon.com/config/latest/developerguide/evaluate-config.html" rel="noopener noreferrer"&gt;AWS Config rules&lt;/a&gt; (either managed or custom lambda rules), it can automatically assess whether your resource configurations adhere to best practices and compliance standards. Finally, when noncompliant configurations are detected, AWS Config can initiate automatic remediation actions (if configured) using &lt;a href="https://docs.aws.amazon.com/systems-manager/latest/userguide/systems-manager-automation.html" rel="noopener noreferrer"&gt;AWS Systems Manager Automation documents&lt;/a&gt;, ensuring resources are promptly corrected to maintain compliance.&lt;/p&gt;

&lt;h3&gt;
  
  
  Using AWS Config with EKS and ECS
&lt;/h3&gt;

&lt;p&gt;When operating Kubernetes or container workloads at scale, governance isn’t optional — it’s essential. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;In Amazon EKS&lt;/strong&gt;, AWS Config helps you track key components such as: EKS control plane logging, VPC settings and network exposure, encryption status for logs and secrets and IAM roles used by worker node groups. It can detect misconfigurations like:&lt;br&gt;
🚫 Publicly accessible EKS clusters&lt;br&gt;
⚠️ Disabled encryption for secrets stored in Kubernetes &lt;a href="https://etcd.io/" rel="noopener noreferrer"&gt;ETCD&lt;/a&gt;&lt;br&gt;
⚠️ Ensures EKS clusters are running on currently supported versions,&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;In Amazon ECS&lt;/strong&gt;, AWS Config can monitor task definitions, IAM roles attached to ECS tasks, changes to security groups and public IP assignments. It can enforce controls like:&lt;br&gt;
✅ Ensuring tasks use only approved IAM roles&lt;br&gt;
✅ Ensures Container Insights are enabled on ECS clusters for observability&lt;br&gt;
🚫 Verifies containers do not run with privileged access&lt;/p&gt;

&lt;h3&gt;
  
  
  AWS Config Rules and Conformance Packs
&lt;/h3&gt;

&lt;p&gt;AWS Config setup is incomplete without Config rules. Config rules are logic-based checks that evaluate whether your AWS resources comply with defined configurations. There are two types: &lt;strong&gt;Managed Rules&lt;/strong&gt; (prebuilt by AWS to address common compliance needs) and &lt;strong&gt;Custom Rules&lt;/strong&gt; (built using AWS Lambda functions). Each rule evaluates compliance in response to configuration changes or periodically, giving you real-time insight into your environment's configuration drift.&lt;/p&gt;

&lt;p&gt;Example Rules:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;ec2-instance-no-public-ip&lt;/code&gt;: Flags any instance launched with a public IP&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ec2-ebs-encryption-by-default&lt;/code&gt;: Checks if Amazon Elastic Block Store (EBS) encryption is enabled by default.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;restricted-ssh&lt;/code&gt;: Checks whether security groups that are in use disallow unrestricted incoming SSH traffic&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Rather than managing individual rules across multiple accounts, &lt;strong&gt;Conformance Packs&lt;/strong&gt; let you bundle together Config rules as a collection, making it easier to be applied in multiple accounts - think of it as &lt;strong&gt;policy-as-code&lt;/strong&gt; for cloud governance. AWS provides many prebuilt packs for EKS best practices, CIS Benchmarks, PCI-DSS, HIPAA, NIST compliance and general security hardening. You can find them on &lt;a href="https://github.com/awslabs/aws-config-rules/tree/master/aws-config-conformance-packs" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;. You can also customize your own packs, combining both managed and custom rules.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Conformance Packs Dashboard&lt;/strong&gt;&lt;br&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%2Fytdhcsvrsxtpl4x8zucg.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%2Fytdhcsvrsxtpl4x8zucg.png" alt="Conformance Packs Dashboard" width="800" height="725"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Rules Under Conformance Pack&lt;/strong&gt;&lt;br&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%2F6bj3934bxmwbvfdvikbw.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%2F6bj3934bxmwbvfdvikbw.png" alt="Rules Under Conformance Pack" width="800" height="345"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Kubernetes Native Policy Engines: Kyverno and OPA Gatekeeper
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Kubernetes Native Policy Engines&lt;/strong&gt; are tools that integrate directly with the Kubernetes API to enforce governance, security, and compliance rules using policies defined as code. They work by integrating with the &lt;a href="https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/#admission-control-phases" rel="noopener noreferrer"&gt;Kubernetes admission control process&lt;/a&gt;, allowing it to inspect, validate, mutate, or reject resource requests before they are applied to the cluster. They allow cluster administrators to define and enforce standards across workloads and infrastructure in a Kubernetes-native way. &lt;/p&gt;

&lt;p&gt;Here’s how it works in a simplified flow:&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%2Fv1l5putqzj01ozeudld7.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%2Fv1l5putqzj01ozeudld7.png" alt="native engine workflow" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The most common Kubernetes native policy engines are &lt;a href="https://kyverno.io/" rel="noopener noreferrer"&gt;Kyverno&lt;/a&gt; and &lt;a href="https://github.com/open-policy-agent/gatekeeper" rel="noopener noreferrer"&gt;OPA Gatekeeper&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Kyverno&lt;/strong&gt; is a Kubernetes-native, declarative policy engine designed specifically for Kubernetes. It enables writing policies using YAML, making it accessible to users without needing a new language. Kyverno supports resource validation, mutation, and generation, aligning well with Kubernetes patterns.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;OPA Gatekeeper&lt;/strong&gt; is a powerful policy engine that uses the &lt;a href="https://www.openpolicyagent.org/docs/latest/policy-language/" rel="noopener noreferrer"&gt;Rego language&lt;/a&gt; to define complex policies. Gatekeeper extends OPA to Kubernetes, offering admission control and audit capabilities for enforcing custom rules with broader control over Kubernetes objects.&lt;/p&gt;

&lt;p&gt;Use cases of Kubernetes policy engine in EKS include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Pod Security Policies: Restrict privilege escalation, enforce runAsNonRoot, and control host networking.&lt;/li&gt;
&lt;li&gt;Network Segmentation: Enforce network policies to control communication between pods or namespaces.&lt;/li&gt;
&lt;li&gt;RBAC Rules Enforcement: Prevent creation of overly permissive roles or bindings.&lt;/li&gt;
&lt;li&gt;Namespace Restrictions: Limit what resources can be created or configured in specific namespaces.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;#Kyverno policy enforcing resource limits in specific namespaces&lt;/span&gt;

&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;kyverno.io/v1&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ClusterPolicy&lt;/span&gt;
&lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;require-resource-limits&lt;/span&gt;
&lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;validationFailureAction&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;enforce&lt;/span&gt;
  &lt;span class="na"&gt;background&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
  &lt;span class="na"&gt;rules&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;validate-resources&lt;/span&gt;
      &lt;span class="na"&gt;match&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;resources&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;kinds&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;Pod&lt;/span&gt;
      &lt;span class="na"&gt;preconditions&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;all&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;{{request.object.metadata.namespace}}"&lt;/span&gt;
            &lt;span class="na"&gt;operator&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;In&lt;/span&gt;
            &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;default"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;production"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;staging"&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
      &lt;span class="na"&gt;validate&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Resource&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;limits&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;are&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;required&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;for&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;CPU&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;and&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;memory"&lt;/span&gt;
        &lt;span class="na"&gt;pattern&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;containers&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
              &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;resources&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
                  &lt;span class="na"&gt;limits&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
                    &lt;span class="na"&gt;memory&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;?*"&lt;/span&gt;
                    &lt;span class="na"&gt;cpu&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;?*"&lt;/span&gt;
                  &lt;span class="na"&gt;requests&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
                    &lt;span class="na"&gt;memory&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;?*"&lt;/span&gt;
                    &lt;span class="na"&gt;cpu&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;?*"&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  AWS Config vs Kyverno/OPA: The Governance Divide
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature/Concern&lt;/th&gt;
&lt;th&gt;AWS Config&lt;/th&gt;
&lt;th&gt;Kyverno/OPA&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Scope&lt;/td&gt;
&lt;td&gt;AWS infrastructure-wide&lt;/td&gt;
&lt;td&gt;Kubernetes-specific&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Real-time Admission Control&lt;/td&gt;
&lt;td&gt;❌ No (post-deployment)&lt;/td&gt;
&lt;td&gt;✅ Yes (admission control)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Mutation/Remediation&lt;/td&gt;
&lt;td&gt;✅ Yes (via SSM)&lt;/td&gt;
&lt;td&gt;✅ Yes (both can mutate resources)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Policy Language&lt;/td&gt;
&lt;td&gt;YAML, custom Lambda&lt;/td&gt;
&lt;td&gt;Rego (OPA) / YAML (Kyverno)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Visibility&lt;/td&gt;
&lt;td&gt;AWS Console, Security Hub&lt;/td&gt;
&lt;td&gt;K8s-native tools (kubectl, UI)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Learning Curve&lt;/td&gt;
&lt;td&gt;🔶 Moderate (AWS knowledge required)&lt;/td&gt;
&lt;td&gt;🔶 Moderate (K8s knowledge required)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cost Model&lt;/td&gt;
&lt;td&gt;💰 Pay per configuration item&lt;/td&gt;
&lt;td&gt;🆓 Open source / self-hosted&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Deployment Complexity&lt;/td&gt;
&lt;td&gt;🔄 Moderate (AWS setup)&lt;/td&gt;
&lt;td&gt;🔄 Moderate (K8s setup)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cross-Account Support&lt;/td&gt;
&lt;td&gt;✅ Yes (Organizations)&lt;/td&gt;
&lt;td&gt;❌ No (cluster-specific)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Audit History&lt;/td&gt;
&lt;td&gt;✅ Yes (Configuration Timeline)&lt;/td&gt;
&lt;td&gt;✅ Yes (PolicyReport CRDs)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Drift Detection&lt;/td&gt;
&lt;td&gt;✅ Yes (continuous recording)&lt;/td&gt;
&lt;td&gt;❌ No (admission time only)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Template Support&lt;/td&gt;
&lt;td&gt;✅ Yes (CloudFormation)&lt;/td&gt;
&lt;td&gt;✅ Yes (Helm charts)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Extensibility&lt;/td&gt;
&lt;td&gt;🔌 Lambda functions&lt;/td&gt;
&lt;td&gt;🔌 Webhooks and custom resources&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Performance Impact&lt;/td&gt;
&lt;td&gt;🔄 Minimal (out-of-band)&lt;/td&gt;
&lt;td&gt;⚠️ Can impact cluster if poorly configured&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Infrastructure as Code Support&lt;/td&gt;
&lt;td&gt;✅ Yes (CloudFormation, Terraform)&lt;/td&gt;
&lt;td&gt;✅ Yes (Kubernetes manifests)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  When to Use What? (AWS Config vs Kyverno/OPA)
&lt;/h3&gt;

&lt;p&gt;Use AWS Config for infrastructure-level governance and enforcing compliance across AWS services. For example, ensuring your EKS cluster is private and secure. Use Kyverno or OPA for runtime policies and workload-level enforcement inside Kubernetes, like allowing only signed container images to run. They complement each other and are best used together to ensure both infrastructure and workloads stay compliant and secure.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Cloud-native governance is multi-layered — no single tool covers it all. AWS Config provides cloud-wide compliance across AWS services, while Kubernetes-native policy engines like Kyverno and OPA Gatekeeper enforce fine-grained rules within clusters. These tools are complementary, not competing. Together, they enable both infrastructure-level and workload-level governance.&lt;/p&gt;

&lt;p&gt;Ultimately, this calls for a DevSecOps mindset — one that combines shift-left enforcement with continuous monitoring, ensuring security and compliance at every stage of the delivery pipeline.&lt;/p&gt;

&lt;h4&gt;
  
  
  References:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.aws.amazon.com/config/latest/developerguide/evaluate-config.html" rel="noopener noreferrer"&gt;https://docs.aws.amazon.com/config/latest/developerguide/evaluate-config.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.aws.amazon.com/config/latest/developerguide/setup-autoremediation.html" rel="noopener noreferrer"&gt;https://docs.aws.amazon.com/config/latest/developerguide/setup-autoremediation.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.aws.amazon.com/toolkit-for-vscode/latest/userguide/systems-manager-automation-docs.html" rel="noopener noreferrer"&gt;https://docs.aws.amazon.com/toolkit-for-vscode/latest/userguide/systems-manager-automation-docs.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/awslabs/aws-config-rules/tree/master/aws-config-conformance-packs" rel="noopener noreferrer"&gt;https://github.com/awslabs/aws-config-rules/tree/master/aws-config-conformance-packs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/#admission-control-phases" rel="noopener noreferrer"&gt;https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/#admission-control-phases&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://kyverno.io/docs/" rel="noopener noreferrer"&gt;https://kyverno.io/docs/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/open-policy-agent/gatekeeper" rel="noopener noreferrer"&gt;https://github.com/open-policy-agent/gatekeeper&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>devops</category>
      <category>kubernetes</category>
      <category>aws</category>
      <category>cloudcomputing</category>
    </item>
    <item>
      <title>Surviving Kubernetes Pod Evictions: Managing Resources, Priorities, and Stability</title>
      <dc:creator>NURUDEEN KAMILU</dc:creator>
      <pubDate>Sun, 16 Feb 2025 20:17:18 +0000</pubDate>
      <link>https://dev.to/nurudeen_kamilu/surviving-kubernetes-pod-evictions-managing-resources-priorities-and-stability-3jj1</link>
      <guid>https://dev.to/nurudeen_kamilu/surviving-kubernetes-pod-evictions-managing-resources-priorities-and-stability-3jj1</guid>
      <description>&lt;p&gt;Kubernetes is designed to orchestrate workloads efficiently across nodes, ensuring optimal resource utilization and workload reliability. However, when resource constraints arise, Kubernetes must make tough decisions—this is where pod eviction comes in. Understanding how Kubernetes evicts pods helps administrators optimize workload resilience and ensure high availability.&lt;/p&gt;

&lt;p&gt;In this article, we will explore Kubernetes pod eviction mechanisms, diving into node-pressure eviction, API-driven eviction, pod priorities, pod preemption, and Quality of Service (QoS) classes. We will also examine how these factors interact to maintain cluster stability.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Foundation: Quality of Service (QoS)
&lt;/h3&gt;

&lt;p&gt;At the heart of Kubernetes' eviction decisions lies the &lt;strong&gt;&lt;a href="https://kubernetes.io/docs/concepts/workloads/pods/pod-qos/" rel="noopener noreferrer"&gt;Quality of Service&lt;/a&gt;&lt;/strong&gt; (QoS) classification system. Every pod in Kubernetes is assigned one of three QoS classes:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Guaranteed&lt;/strong&gt;: A pod is assigned this QoS class if all of its containers have precisely defined resource (cpu and memory) requests and limits that are set equal to each other.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Burstable&lt;/strong&gt;: This is the middle class of QoS; these pods have defined memory or CPU requests or limits for at least one of their containers.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;BestEffort&lt;/strong&gt;: These pods have no resource requests or limits defined.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Evictions can occur for multiple reasons, including resource constraints (e.g., memory pressure) and administrative actions (e.g., API-initiated deletions). Kubernetes provides structured mechanisms to handle evictions gracefully. There are two main categories of pod eviction:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Node-pressure eviction&lt;/strong&gt;: Triggered automatically when a node experiences resource shortages.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;API-driven eviction&lt;/strong&gt;: Initiated by a user or an external controller via the Kubernetes API.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let’s break down these eviction types and the factors influencing them.&lt;/p&gt;

&lt;h3&gt;
  
  
  Node-Pressure Eviction: Automatic Resource Management
&lt;/h3&gt;

&lt;p&gt;When a node in the cluster experiences resource pressure—such as low memory or disk space availability—Kubernetes triggers &lt;strong&gt;node-pressure eviction&lt;/strong&gt;. This is a self-defense mechanism to prevent the node from becoming unresponsive or crashing. The &lt;a href="https://kubernetes.io/docs/concepts/architecture/#kubelet" rel="noopener noreferrer"&gt;kubelet&lt;/a&gt; monitors resource usage and, upon reaching critical thresholds, selects pods for eviction based on priority and QoS value.&lt;/p&gt;

&lt;h4&gt;
  
  
  Configuring Node-Pressure Eviction
&lt;/h4&gt;

&lt;p&gt;Node-pressure eviction can be configured by setting eviction thresholds in the kubelet configuration. Below is an example of how to configure eviction thresholds in the &lt;a href="https://kubernetes.io/docs/reference/config-api/kubelet-config.v1beta1/#kubelet-config-k8s-io-v1beta1-KubeletConfiguration" rel="noopener noreferrer"&gt;Kubelet configuration file&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;kubelet.config.k8s.io/v1beta1&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;KubeletConfiguration&lt;/span&gt;
&lt;span class="na"&gt;evictionHard&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;memory.available&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;500Mi"&lt;/span&gt;
  &lt;span class="na"&gt;nodefs.available&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;10%"&lt;/span&gt;
  &lt;span class="na"&gt;nodefs.inodesFree&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;5%"&lt;/span&gt;
  &lt;span class="na"&gt;imagefs.available&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;15%"&lt;/span&gt;
&lt;span class="na"&gt;evictionSoft&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;memory.available&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;1Gi"&lt;/span&gt;
  &lt;span class="na"&gt;nodefs.available&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;15%"&lt;/span&gt;
  &lt;span class="na"&gt;nodefs.inodesFree&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;10%"&lt;/span&gt;
  &lt;span class="na"&gt;imagefs.available&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;20%"&lt;/span&gt;
&lt;span class="na"&gt;evictionSoftGracePeriod&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;memory.available&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;1m30s"&lt;/span&gt;
  &lt;span class="na"&gt;nodefs.available&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;1m30s"&lt;/span&gt;
  &lt;span class="na"&gt;nodefs.inodesFree&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;1m30s"&lt;/span&gt;
  &lt;span class="na"&gt;imagefs.available&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;1m30s"&lt;/span&gt;
&lt;span class="na"&gt;evictionMaxPodGracePeriod&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;600&lt;/span&gt;
&lt;span class="na"&gt;evictionPressureTransitionPeriod&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;5m0s"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Key configuration components:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Hard Eviction Thresholds&lt;/strong&gt;: When these are breached, the kubelet will immediately start evicting pods&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Soft Eviction Thresholds&lt;/strong&gt;: Pods are evicted only if the threshold is exceeded for a specified grace period&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Grace Periods&lt;/strong&gt;: Define how long the kubelet should wait before starting eviction&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pressure Transition Period&lt;/strong&gt;: Defines how long a node condition must persist before triggering eviction under pressure condition&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The kubelet monitors these &lt;a href="https://kubernetes.io/docs/concepts/scheduling-eviction/node-pressure-eviction/#node-conditions" rel="noopener noreferrer"&gt;eviction signals&lt;/a&gt; for eviction decisions. &lt;/p&gt;

&lt;h4&gt;
  
  
  Factors Affecting Node-Pressure Eviction
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Quality of Service (QoS) Class:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Guaranteed: Highest priority—only evicted in extreme conditions.&lt;/li&gt;
&lt;li&gt;Burstable: Evicted after BestEffort pods but before Guaranteed pods.&lt;/li&gt;
&lt;li&gt;BestEffort: Lowest priority—first to be evicted.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Pod Priority and Preemption: Higher-priority pods are less likely to be evicted, while lower-priority pods are targeted first. Pod priority can be defined by creating a &lt;a href="https://kubernetes.io/docs/concepts/scheduling-eviction/pod-priority-preemption/#priorityclass" rel="noopener noreferrer"&gt;PriorityClass&lt;/a&gt; and specifying it in the pod specification (&lt;code&gt;priorityClassName&lt;/code&gt;).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Graceful Termination: The Kubelet allows evicted pods to terminate gracefully based on their configured &lt;a href="https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#pod-termination" rel="noopener noreferrer"&gt;&lt;code&gt;terminationGracePeriodSeconds&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  API-Driven Eviction: The Manual Override
&lt;/h3&gt;

&lt;p&gt;Unlike node-pressure evictions, which are automatic, &lt;strong&gt;API-driven evictions&lt;/strong&gt; occur when users or controllers explicitly request pod removal using the &lt;a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.32/#create-eviction-pod-v1-core" rel="noopener noreferrer"&gt;Eviction API&lt;/a&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  Use Cases for API-Driven Eviction
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Cluster Autoscaler&lt;/strong&gt;: Scales down nodes by evicting pods before removing the node.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Controllers (e.g., Deployment, ReplicaSet)&lt;/strong&gt;: May trigger evictions to manage rolling updates.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Administrative Actions&lt;/strong&gt;: Operators can manually evict pods to redistribute workloads.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;API-driven evictions respect &lt;a href="https://kubernetes.io/docs/concepts/workloads/pods/disruptions/#pod-disruption-budgets" rel="noopener noreferrer"&gt;pod disruption budgets&lt;/a&gt; (PDBs), ensuring that evictions do not impact availability beyond acceptable thresholds.&lt;/p&gt;

&lt;h3&gt;
  
  
  Pod Priority and Preemption: The Hierarchy of Importance
&lt;/h3&gt;

&lt;p&gt;Not all pods are created equal. Kubernetes allows users to assign priorities to pods, which influence eviction and scheduling decisions. Preemption priority determines which pods get evicted when a higher-priority pod needs to be scheduled. The &lt;a href="https://kubernetes.io/docs/concepts/scheduling-eviction/kube-scheduler/" rel="noopener noreferrer"&gt;Kubernetes scheduler&lt;/a&gt; evaluates available nodes and determines if preempting existing pods would create enough resources for the new pod. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Higher-priority pods preempt lower-priority ones&lt;/strong&gt; when no sufficient resources are available.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pods with the same priority are not preempted&lt;/strong&gt;; Kubernetes looks for lower-priority alternatives.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Preemption considers pod disruption budgets (PDBs)&lt;/strong&gt; to minimize service disruptions.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This ensures that critical workloads always have resources available.&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;Pod eviction in Kubernetes is a finely tuned process that balances resource availability, workload importance, and user-defined policies. By leveraging node-pressure eviction, API-driven eviction, pod priorities, pod preemption, and QoS classes, Kubernetes ensures that clusters remain stable and efficient, even under pressure. By understanding these mechanisms, you can optimize your workloads, ensure fair resource distribution, and prevent disruptions in your Kubernetes environments.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;So, the next time a pod is evicted, remember: it’s not a failure—it’s Kubernetes doing its job, mastering the art of letting go.&lt;/strong&gt;&lt;/p&gt;

&lt;h5&gt;
  
  
  References:
&lt;/h5&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://kubernetes.io/docs/concepts/scheduling-eviction/scheduling-framework/" rel="noopener noreferrer"&gt;Kubernetes Scheduling Framework&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.toPod%20Quality%20of%20Service%20(QoS)%20Classes"&gt;Pod Quality of Service (QoS) Classes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://kubernetes.io/docs/concepts/scheduling-eviction/pod-priority-preemption/" rel="noopener noreferrer"&gt;Pod Priority and Preemption&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://kubernetes.io/docs/concepts/scheduling-eviction/kube-scheduler/" rel="noopener noreferrer"&gt;Kube-Scheduler&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://kubernetes.io/docs/concepts/scheduling-eviction/node-pressure-eviction/" rel="noopener noreferrer"&gt;Node-Pressure Eviction&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://kubernetes.io/docs/concepts/scheduling-eviction/api-eviction/" rel="noopener noreferrer"&gt;API-Driven Eviction&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>kubernetes</category>
      <category>cloudnative</category>
      <category>devops</category>
      <category>cloudcomputing</category>
    </item>
    <item>
      <title>Understanding Node Problem Detector in Kubernetes: Beyond Default Node Conditions</title>
      <dc:creator>NURUDEEN KAMILU</dc:creator>
      <pubDate>Mon, 13 Jan 2025 22:34:03 +0000</pubDate>
      <link>https://dev.to/nurudeen_kamilu/understanding-node-problem-detector-in-kubernetes-beyond-default-node-conditions-1d1h</link>
      <guid>https://dev.to/nurudeen_kamilu/understanding-node-problem-detector-in-kubernetes-beyond-default-node-conditions-1d1h</guid>
      <description>&lt;h2&gt;
  
  
  Introducton
&lt;/h2&gt;

&lt;p&gt;In Kubernetes, monitoring node health is crucial for maintaining a reliable cluster. While Kubernetes provides built-in node conditions, these basic health checks might not be sufficient for production environments. This is where Node Problem Detector (NPD) comes in, extending the default monitoring capabilities with rich system-level problem detection.&lt;/p&gt;

&lt;p&gt;This article delves into the features and benefits of NPD, showing how it extends beyond the default Kubernetes node healthy monitoring to proactively detect and address potential node issues.&lt;/p&gt;

&lt;h2&gt;
  
  
  Default Kubernetes Node Conditions
&lt;/h2&gt;

&lt;p&gt;By default, Kubernetes nodes come with several &lt;a href="https://kubernetes.io/docs/reference/node/node-status/#condition" rel="noopener noreferrer"&gt;built-in conditions&lt;/a&gt; that provide basic health information about the nodes in the cluster. &lt;/p&gt;

&lt;p&gt;These conditions are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Ready&lt;/strong&gt;: Is the node healthy and able to schedule pods?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;MemoryPressure&lt;/strong&gt;: Is the node running low on memory?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;DiskPressure&lt;/strong&gt;: Are disk space or I/O operations causing problems?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;PIDPressure&lt;/strong&gt;: Is the node overloaded with too many processes?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;NetworkUnavailable&lt;/strong&gt;: Are network configurations causing connectivity issues?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each condition is represented by status indicators that describe the current health or operational state of a node. There are three possible statuses:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;True&lt;/strong&gt;: The condition is currently happening. For instance, if &lt;strong&gt;MemoryPressure&lt;/strong&gt; is &lt;strong&gt;True&lt;/strong&gt;, it means the node is experiencing memory pressure at the moment.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;False&lt;/strong&gt;: The condition is not happening. For example, if &lt;strong&gt;DiskPressure&lt;/strong&gt; is &lt;strong&gt;False&lt;/strong&gt;, the node has sufficient disk space and no I/O issues.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Unknown&lt;/strong&gt;: The system cannot determine the status of the condition, often due to a lack of communication or incomplete data from the node.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These conditions can be viewed using the command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl describe node &amp;lt;node-name&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command will return each node condition along with its respective status.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Conditions:
  Type             Status  LastHeartbeatTime                 LastTransitionTime                Reason                       Message
  ----             ------  -----------------                 ------------------                ------                       -------
  MemoryPressure   False   Mon, 13 Jan 2025 21:19:43 +0100   Sun, 01 Dec 2024 01:03:13 +0100   KubeletHasSufficientMemory   kubelet has sufficient memory available
  DiskPressure     False   Mon, 13 Jan 2025 21:19:43 +0100   Sun, 01 Dec 2024 01:03:13 +0100   KubeletHasNoDiskPressure     kubelet has no disk pressure
  PIDPressure      False   Mon, 13 Jan 2025 21:19:43 +0100   Sun, 01 Dec 2024 01:03:13 +0100   KubeletHasSufficientPID      kubelet has sufficient PID available
  Ready            True    Mon, 13 Jan 2025 21:19:43 +0100   Sun, 01 Dec 2024 01:03:33 +0100   KubeletReady                 kubelet is posting ready status
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Based on these statuses, Kubernetes adds the necessary &lt;a href="https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/#taint-nodes-by-condition" rel="noopener noreferrer"&gt;taints&lt;/a&gt; that match the condition affecting the node. While these default conditions offer a quick glimpse into a node’s health, they may miss deeper, system-level issues. This is where Node Problem Detector steps in to fill the gap.&lt;/p&gt;

&lt;h2&gt;
  
  
  Node Problem Detector: Enhanced Node Monitoring
&lt;/h2&gt;

&lt;p&gt;Node Problem Detector extends Kubernetes' native node monitoring capabilities by detecting and reporting various system-level issues. It runs as a daemon on the node, detects node problems, and reports them to the apiserver.&lt;/p&gt;

&lt;h3&gt;
  
  
  How Node Problem Detector Works
&lt;/h3&gt;

&lt;p&gt;The problem daemon is the core component that monitors and detects node problems. Its function is to identify and report specific node problems to the node problem detector. NPD supports several types of problem daemons:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;SystemLogMonitor&lt;/strong&gt;: Watches system logs (journald, syslog, etc) for predefined patterns and reports problems and metrics accordingly. The types of node conditions reported by this daemon are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;KernelDeadlock&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ReadonlyFilesystem&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;FrequentDockerRestart&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;FrequentKubeletRestart&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;FrequentContainerdRestart&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;CustomPluginMonitor&lt;/strong&gt;: Executes custom scripts for specific problem detection. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;HealthChecker&lt;/strong&gt;: Performs periodic health checks. The types of node conditions reported by this daemon are &lt;strong&gt;KubeletUnhealthy&lt;/strong&gt; and &lt;strong&gt;ContainerRuntimeUnhealthy&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Upon detection of problems, NPD makes the problem visible to the Kubernetes management stack through the apiserver. Problems are reported as &lt;strong&gt;NodeCondition&lt;/strong&gt; (if it is a permanent problem that will make the node unavailable for pod scheduling) or &lt;strong&gt;Event&lt;/strong&gt; (if it is a temporary problem that has limited impact).&lt;/p&gt;

&lt;h3&gt;
  
  
  Deploying Node Problem Detector
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Method 1: Using Helm
&lt;/h4&gt;

&lt;p&gt;NPD can be deployed using the official &lt;a href="https://github.com/deliveryhero/helm-charts/tree/master/stable/node-problem-detector" rel="noopener noreferrer"&gt;Node Problem Detector Helm chart&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;helm repo add deliveryhero https://charts.deliveryhero.io/
helm &lt;span class="nb"&gt;install &lt;/span&gt;node-problem-detector deliveryhero/node-problem-detector &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--namespace&lt;/span&gt; kube-system
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Method 2: As a System Service
&lt;/h4&gt;

&lt;p&gt;For environments without DaemonSet support, NPD can run as a system service. To achieve this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Download the Node Problem Detector binaries.&lt;/li&gt;
&lt;li&gt;Create a systemd service file.&lt;/li&gt;
&lt;li&gt;Enable the service using systemd commands.&lt;/li&gt;
&lt;li&gt;Start the Node Problem Detector service.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Customizing Node Problem Detector
&lt;/h3&gt;

&lt;p&gt;One of NPD’s standout features is its ability to adapt to your specific needs. By leveraging the &lt;em&gt;CustomPluginMonitor problem daemon&lt;/em&gt;, you can define custom node conditions and rules to monitor exactly what matters most to your workloads.&lt;/p&gt;

&lt;h4&gt;
  
  
  1. Adding Custom Conditions and Detection Rules
&lt;/h4&gt;

&lt;p&gt;This example demonstrates a custom-plugin JSON file. This file defines custom condition and rules that enable NPD to identify problems based on specific patterns.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"plugin"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"custom"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"pluginConfig"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"invoke_interval"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"30s"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"timeout"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"5s"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"max_output_length"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"concurrency"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"enable_message_change_based_condition_update"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"source"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ntp-custom-plugin-monitor"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"metricsReporting"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"conditions"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"NTPProblem"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"reason"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"NTPIsUp"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"message"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ntp service is up"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"rules"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"temporary"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"reason"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"NTPIsDown"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"path"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"./config/plugin/check_ntp.sh"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"timeout"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"3s"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"permanent"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"condition"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"NTPProblem"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"reason"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"NTPIsDown"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"path"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"./config/plugin/check_ntp.sh"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"timeout"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"3s"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  2. Writing Custom Plugin Script
&lt;/h4&gt;

&lt;p&gt;The custom plugin script is the executable that performs the actual health checks. The output of the script must align with the patterns defined in the JSON file to trigger corresponding node conditions.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;

&lt;span class="nb"&gt;readonly &lt;/span&gt;&lt;span class="nv"&gt;OK&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;0
&lt;span class="nb"&gt;readonly &lt;/span&gt;&lt;span class="nv"&gt;NONOK&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;1
&lt;span class="nb"&gt;readonly &lt;/span&gt;&lt;span class="nv"&gt;UNKNOWN&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;2

&lt;span class="nb"&gt;readonly &lt;/span&gt;&lt;span class="nv"&gt;SERVICE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'ntp.service'&lt;/span&gt;

&lt;span class="c"&gt;# Check systemd cmd present&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt; &lt;span class="nb"&gt;command&lt;/span&gt; &lt;span class="nt"&gt;-v&lt;/span&gt; systemctl &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;/dev/null&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
  &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Could not find 'systemctl' - require systemd"&lt;/span&gt;
  &lt;span class="nb"&gt;exit&lt;/span&gt; &lt;span class="nv"&gt;$UNKNOWN&lt;/span&gt;
&lt;span class="k"&gt;fi&lt;/span&gt;

&lt;span class="c"&gt;# Return success if service active (i.e. running)&lt;/span&gt;
&lt;span class="k"&gt;if &lt;/span&gt;systemctl &lt;span class="nt"&gt;-q&lt;/span&gt; is-active &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$SERVICE&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
  &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$SERVICE&lt;/span&gt;&lt;span class="s2"&gt; is running"&lt;/span&gt;
  &lt;span class="nb"&gt;exit&lt;/span&gt; &lt;span class="nv"&gt;$OK&lt;/span&gt;
&lt;span class="k"&gt;else&lt;/span&gt;
  &lt;span class="c"&gt;# Does not differentiate stopped/failed service from non-existent&lt;/span&gt;
  &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$SERVICE&lt;/span&gt;&lt;span class="s2"&gt; is not running"&lt;/span&gt;
  &lt;span class="nb"&gt;exit&lt;/span&gt; &lt;span class="nv"&gt;$NONOK&lt;/span&gt;
&lt;span class="k"&gt;fi&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Node Problem Detector is more than just a monitoring tool — it’s a safety net for your Kubernetes clusters. By expanding beyond default node conditions and offering unparalleled customization, NPD equips you to tackle challenges head-on, ensuring high availability and smooth operations.&lt;/p&gt;

&lt;p&gt;Embrace NPD and take a proactive approach to node monitoring in your Kubernetes journey!&lt;/p&gt;

&lt;h4&gt;
  
  
  References and Further Reading
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/kubernetes/node-problem-detector/tree/master" rel="noopener noreferrer"&gt;Node Problem Detector GitHub Repository&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/deliveryhero/helm-charts/tree/master/stable/node-problem-detector" rel="noopener noreferrer"&gt;Helm Chart for NPD&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://kubernetes.io/docs/concepts/architecture/nodes/" rel="noopener noreferrer"&gt;Kubernetes Documentation: Nodes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/" rel="noopener noreferrer"&gt;Kubernetes Documentation: Taints and Tolerations&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>kubernetes</category>
      <category>cloudnative</category>
      <category>linux</category>
      <category>cloudcomputing</category>
    </item>
    <item>
      <title>Key Lessons and Mistakes from Setting Up EKS Clusters</title>
      <dc:creator>NURUDEEN KAMILU</dc:creator>
      <pubDate>Sat, 04 Jan 2025 15:30:06 +0000</pubDate>
      <link>https://dev.to/nurudeen_kamilu/key-lessons-and-mistakes-from-setting-up-eks-clusters-34a3</link>
      <guid>https://dev.to/nurudeen_kamilu/key-lessons-and-mistakes-from-setting-up-eks-clusters-34a3</guid>
      <description>&lt;p&gt;Setting up an Amazon Elastic Kubernetes Service (EKS) cluster is a common task for cloud-native organizations, but it’s not without its challenges. Many professionals, from cloud engineers to Kubernetes experts, have faced various obstacles during their EKS setup journey. These challenges often lead to important lessons and insights. Below are some of the most common mistakes encountered by teams when setting up EKS clusters, along with the key takeaways learned from those experiences.&lt;/p&gt;

&lt;h3&gt;
  
  
  Mistake #1: Underestimating Networking Complexity
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Lesson Learned:&lt;/strong&gt; Planning the network architecture for EKS clusters is more complex than it initially appears. One of the most common mistakes is underestimating the intricacies of VPC setup, subnet design, and IP address management.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Issue:&lt;/strong&gt; Many teams started with smaller CIDR blocks for pod IP addresses, only to face IP exhaustion &lt;a href="https://github.com/aws/amazon-vpc-cni-k8s/issues/2846" rel="noopener noreferrer"&gt;issues&lt;/a&gt; as their cluster scaled. This forced them to rework their network design, leading to downtime and wasted effort.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Takeaway:&lt;/strong&gt; Ensure that larger CIDR blocks (e.g., /16) are allocated from the beginning. This provides enough IP space for pods and reduces the risk of IP address exhaustion as the cluster grows. A thorough network planning phase is essential before launching any workloads. Additionally, AWS provides the following options for managing IP address allocation more effectively: &lt;a href="https://docs.aws.amazon.com/eks/latest/userguide/cni-increase-ip-addresses-procedure.html" rel="noopener noreferrer"&gt;Increasing IP Addresses for EKS Pods&lt;/a&gt; - if you're running out of IP addresses for your pods in a VPC, you can follow the procedure for increasing IP addresses, as outlined in AWS documentation and &lt;a href="https://docs.aws.amazon.com/eks/latest/userguide/cni-custom-network-tutorial.html" rel="noopener noreferrer"&gt;Using a Custom Networking Setup&lt;/a&gt; - for more advanced network configurations, you can implement custom networking to better control pod IP allocation.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Mistake #2: Over-Provisioning Resources
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Lesson Learned:&lt;/strong&gt; It’s easy to assume that &lt;strong&gt;more resources are better&lt;/strong&gt;, especially when setting up the first EKS cluster. However, many teams faced &lt;strong&gt;underutilized resources&lt;/strong&gt; that unnecessarily drove up costs.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Issue:&lt;/strong&gt; Early configurations often led to &lt;strong&gt;over-provisioned EC2 instances&lt;/strong&gt;. While the extra capacity seemed prudent, it resulted in significant inefficiencies and higher costs than necessary.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Takeaway:&lt;/strong&gt; &lt;strong&gt;Right-sizing EC2 instances&lt;/strong&gt; based on actual workload requirements is crucial. By carefully monitoring resource usage and adjusting instance types to fit the needs of specific workloads, teams can optimize both performance and cost-efficiency.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Mistake #3: Failing to Automate Infrastructure Setup
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Lesson Learned:&lt;/strong&gt; Manual cluster setup may work for small-scale environments but doesn’t scale well in production or larger setups.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Issue:&lt;/strong&gt; Teams that started with manual configurations found themselves struggling to maintain consistency across multiple environments, leading to errors and delays during updates.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Takeaway:&lt;/strong&gt; Implementing Infrastructure as Code (IaC) through tools like &lt;a href="https://registry.terraform.io/modules/terraform-aws-modules/eks/aws/latest" rel="noopener noreferrer"&gt;Terraform&lt;/a&gt; or &lt;a href="https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-eks-cluster.html" rel="noopener noreferrer"&gt;AWS CloudFormation&lt;/a&gt; is essential for automating cluster creation and management. IaC ensures that clusters are easily reproducible, version-controlled, and aligned with best practices across environments. Additionally, leveraging CI/CD pipelines can significantly streamline the process, making infrastructure setup and deployment more efficient. CI/CD pipelines (such as GitHub Actions) for eks setup can be integrated with IaC to automate not just the deployment of applications but also the provisioning and configuration of your EKS cluster. This ensures that changes are tested, validated, and applied in a consistent manner across environments without manual intervention.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Mistake #4: Underestimating the Upgrade Process
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Lesson Learned:&lt;/strong&gt; Kubernetes upgrades can be tricky, and the process can introduce breaking changes if not managed carefully. Teams often underestimated the complexity of upgrading EKS clusters and suffered downtime or service interruptions as a result.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Issue:&lt;/strong&gt; Teams initially skipped upgrade testing, pushing Kubernetes version updates directly to production. This resulted in compatibility issues and disruptions in the production environment.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Takeaway:&lt;/strong&gt; Always test upgrades in a staging environment before applying them to production. Key steps include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Check EKS Release Notes: Review the &lt;a href="https://docs.aws.amazon.com/eks/latest/userguide/kubernetes-versions-standard.html" rel="noopener noreferrer"&gt;EKS release notes&lt;/a&gt; to understand version compatibility and potential breaking changes.&lt;/li&gt;
&lt;li&gt;Use the EKS Upgrade Checklist: Follow the upgrade &lt;a href="https://docs.aws.amazon.com/eks/latest/userguide/update-cluster.html" rel="noopener noreferrer"&gt;checklist&lt;/a&gt; in the EKS documentation to ensure all critical steps are covered.&lt;/li&gt;
&lt;li&gt;Simplify Data Plane Upgrades: Use &lt;a href="https://docs.aws.amazon.com/eks/latest/userguide/managed-node-groups.html" rel="noopener noreferrer"&gt;Managed Node Groups&lt;/a&gt; for automated rolling updates or &lt;a href="https://karpenter.sh/" rel="noopener noreferrer"&gt;Karpenter&lt;/a&gt; for dynamic node provisioning, making node upgrades easier and less error-prone.&lt;/li&gt;
&lt;li&gt;Backup and Rollback Plan: Always have a backup and rollback plan in case the upgrade doesn’t go as expected.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;
  
  
  Mistake #5: Neglecting Security from the Start
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Lesson Learned:&lt;/strong&gt; Security needs to be an integral part of the setup process, not an afterthought. Many teams initially deployed their clusters without properly considering access controls or data protection.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Issue:&lt;/strong&gt; Teams often used overly permissive IAM roles and Kubernetes RBAC settings, leading to unnecessary exposure and potential vulnerabilities. Additionally, sensitive data was sometimes stored insecurely, increasing the risk of breaches.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Takeaway:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Limit Permissions: Adopt a least privilege approach for both IAM roles and Kubernetes RBAC. Avoid granting developers cluster-admin permissions. Instead, use tools like &lt;a href="https://rbac-manager.docs.fairwinds.com/#join-the-fairwinds-open-source-community" rel="noopener noreferrer"&gt;RBAC Manager&lt;/a&gt; to enforce namespace-specific permissions, ensuring developers have access only to what they need.&lt;/li&gt;
&lt;li&gt;Protect the API Endpoint: Restrict public access to the EKS API endpoint and configure proper authentication and authorization components to prevent unauthorized users from interacting with the cluster.&lt;/li&gt;
&lt;li&gt;Secure Sensitive Data: Use secure storage solutions such as &lt;a href="https://external-secrets.io/v0.4.4/api-externalsecret/" rel="noopener noreferrer"&gt;external secrets&lt;/a&gt; to manage sensitive data, avoiding hardcoding credentials or secrets.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;
  
  
  Mistake #6: Overlooking Cost Optimization Opportunities
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Lesson Learned:&lt;/strong&gt; Managing EKS costs efficiently requires a proactive approach. Many teams failed to fully leverage cost-saving tools, leading to unnecessary expenses.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Issue:&lt;/strong&gt; Teams often overlooked EC2 Spot Instances for non-production workloads and configured autoscaling inefficiently, resulting in over-provisioned clusters and higher costs.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Takeaway:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Leverage EC2 Spot Instances: Use Spot Instances for workloads that can tolerate interruptions to reduce compute costs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Karpenter: A Game-Changer:&lt;/strong&gt; Karpenter dynamically provisions and scales nodes based on real-time demand. Unlike traditional autoscalers, it selects the most cost-effective EC2 instances, consolidates workloads efficiently, and reduces waste. This results in significant savings while maintaining performance.&lt;/li&gt;
&lt;li&gt;Optimize Autoscaling: Combine Karpenter with cluster autoscaling and horizontal pod autoscaling to dynamically adjust resources based on workload demands. &lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Setting up an EKS cluster is a journey filled with learning opportunities. Through careful planning, automation, and security, organizations can mitigate the risks of missteps that many have encountered. By taking note of these lessons and strategies, teams can avoid common mistakes and build scalable, secure, and cost-effective Kubernetes environments. While the road may not be without its challenges, the lessons learned from others’ experiences can help guide the way toward a more efficient and reliable EKS deployment.&lt;/p&gt;

</description>
      <category>kubernetes</category>
      <category>aws</category>
      <category>devops</category>
      <category>cloudnative</category>
    </item>
  </channel>
</rss>
