<?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: Romulo Franca</title>
    <description>The latest articles on DEV Community by Romulo Franca (@romulofrancas).</description>
    <link>https://dev.to/romulofrancas</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%2F592677%2F001853e9-d866-49cc-a87d-1dd46bef3b66.jpg</url>
      <title>DEV Community: Romulo Franca</title>
      <link>https://dev.to/romulofrancas</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/romulofrancas"/>
    <language>en</language>
    <item>
      <title>Terraform vs. Pulumi vs. Crossplane: Choosing the Right IaC Tool for Your Internal Developer Platform 🚀</title>
      <dc:creator>Romulo Franca</dc:creator>
      <pubDate>Tue, 25 Feb 2025 16:26:10 +0000</pubDate>
      <link>https://dev.to/romulofrancas/terraform-vs-pulumi-vs-crossplane-choosing-the-right-iac-tool-for-your-internal-developer-3a95</link>
      <guid>https://dev.to/romulofrancas/terraform-vs-pulumi-vs-crossplane-choosing-the-right-iac-tool-for-your-internal-developer-3a95</guid>
      <description>&lt;p&gt;Infrastructure as Code (IaC) is at the heart of modern platform engineering, enabling teams to define, provision, and manage infrastructure in a repeatable and scalable way. When building an &lt;strong&gt;Internal Developer Platform (IDP)&lt;/strong&gt;—a self-service system that abstracts infrastructure complexities for developers—choosing the right IaC tool can make or break your platform's success.&lt;/p&gt;

&lt;p&gt;So, should you use &lt;strong&gt;Terraform&lt;/strong&gt;, &lt;strong&gt;Pulumi&lt;/strong&gt;, or &lt;strong&gt;Crossplane&lt;/strong&gt; to power your IDP? Let's break it down. 🕵️‍♂️&lt;/p&gt;




&lt;h2&gt;
  
  
  🏆 The Contenders: Terraform, Pulumi, and Crossplane
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;1️⃣ Terraform: The Industry Standard for IaC&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Terraform, by HashiCorp, is the granddaddy of declarative IaC. It uses &lt;strong&gt;HCL (HashiCorp Configuration Language)&lt;/strong&gt; and is loved for its &lt;strong&gt;mature ecosystem&lt;/strong&gt;, &lt;strong&gt;large provider support&lt;/strong&gt;, and &lt;strong&gt;battle-tested reliability&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pros:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Huge &lt;strong&gt;community support&lt;/strong&gt; and ecosystem 🌎&lt;/li&gt;
&lt;li&gt;Mature, stable, and widely adopted ✅&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;State management&lt;/strong&gt; with Terraform Cloud &amp;amp; backend options&lt;/li&gt;
&lt;li&gt;Supports a vast number of providers (AWS, GCP, Azure, Kubernetes, etc.)&lt;/li&gt;
&lt;li&gt;Well-suited for infrastructure teams managing shared resources&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Cons:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Declarative-only&lt;/strong&gt;—not great for complex logic 🔄&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;State management overhead&lt;/strong&gt; can be a pain&lt;/li&gt;
&lt;li&gt;Writing &lt;strong&gt;HCL&lt;/strong&gt; can feel restrictive for developers used to imperative programming&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;2️⃣ Pulumi: IaC for Devs Who Love Code&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Pulumi takes a &lt;strong&gt;code-first&lt;/strong&gt; approach to IaC, allowing you to use programming languages like &lt;strong&gt;TypeScript, Python, Go, and C#&lt;/strong&gt; instead of a declarative language.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pros:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Leverages real programming languages&lt;/strong&gt; for infrastructure 💻&lt;/li&gt;
&lt;li&gt;Easier for developers to adopt (especially in an IDP setting)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No state file management&lt;/strong&gt; (defaults to backend storage like AWS S3)&lt;/li&gt;
&lt;li&gt;Great support for Kubernetes and cloud-native workloads&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Cons:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Smaller ecosystem&lt;/strong&gt; compared to Terraform&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Less mature&lt;/strong&gt; than Terraform, with a smaller community&lt;/li&gt;
&lt;li&gt;Requires &lt;strong&gt;learning a new API&lt;/strong&gt; even in familiar languages&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;3️⃣ Crossplane: The Kubernetes-Native IaC Solution&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Crossplane is a &lt;strong&gt;cloud-native control plane&lt;/strong&gt; that extends Kubernetes to manage infrastructure &lt;strong&gt;using Kubernetes Custom Resource Definitions (CRDs)&lt;/strong&gt;. It brings &lt;strong&gt;GitOps-style infrastructure management&lt;/strong&gt; to the table.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pros:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Full Kubernetes integration&lt;/strong&gt;—your infra is managed like any other K8s resource 📦&lt;/li&gt;
&lt;li&gt;Eliminates the need for external state management&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Policy-driven&lt;/strong&gt; infrastructure provisioning 🛡️&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Multi-cloud support&lt;/strong&gt; with a single API surface&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Cons:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Requires &lt;strong&gt;deep Kubernetes knowledge&lt;/strong&gt;—not ideal for non-K8s users 🚧&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Smaller ecosystem&lt;/strong&gt; compared to Terraform&lt;/li&gt;
&lt;li&gt;Can be overkill if your IDP doesn’t revolve around Kubernetes&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🔥 Terraform vs. Pulumi vs. Crossplane: Which One Wins for IDPs? 🏁
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;🚀 Developer Experience (DX)&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Pulumi wins&lt;/strong&gt; for developers who want a familiar coding experience.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Terraform is okay&lt;/strong&gt;, but HCL can feel clunky.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Crossplane is K8s-centric&lt;/strong&gt;, which may or may not fit your developers' needs.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;⚙️ Integration with Kubernetes&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Crossplane dominates&lt;/strong&gt; here—it’s built around Kubernetes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Terraform and Pulumi&lt;/strong&gt; can integrate with Kubernetes but require extra work.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;📦 Multi-Cloud &amp;amp; Multi-Provider Support&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Terraform has the most providers&lt;/strong&gt; (AWS, GCP, Azure, Kubernetes, etc.).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pulumi supports many of the same providers&lt;/strong&gt; but has a smaller ecosystem.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Crossplane is great for cloud-native multi-cloud&lt;/strong&gt; but lacks the breadth of Terraform.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;🔄 State Management &amp;amp; GitOps&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Crossplane handles state natively with Kubernetes&lt;/strong&gt; (no need for an external state store!).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pulumi has backend storage options&lt;/strong&gt; and doesn’t require state management.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Terraform requires state management&lt;/strong&gt; (Terraform Cloud, S3, Consul, etc.).&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;🏗️ Best Fit for Internal Developer Platforms&lt;/strong&gt;
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;Terraform&lt;/th&gt;
&lt;th&gt;Pulumi&lt;/th&gt;
&lt;th&gt;Crossplane&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Best for Ops Teams&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Best for Dev Teams&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Best for K8s Users&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Maturity &amp;amp; Stability&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;🔸&lt;/td&gt;
&lt;td&gt;🔸&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;GitOps Friendly&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;🔸&lt;/td&gt;
&lt;td&gt;🔸&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Use Terraform if:&lt;/strong&gt; You need a &lt;strong&gt;stable, widely adopted&lt;/strong&gt; solution for traditional infra provisioning.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use Pulumi if:&lt;/strong&gt; You want an &lt;strong&gt;IDP that feels more natural for developers&lt;/strong&gt; and supports multi-cloud.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use Crossplane if:&lt;/strong&gt; Your IDP is &lt;strong&gt;deeply Kubernetes-native&lt;/strong&gt; and you want full &lt;strong&gt;GitOps integration&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🎯 Final Verdict: Choose Based on Your IDP Needs
&lt;/h2&gt;

&lt;p&gt;There’s no &lt;strong&gt;one-size-fits-all&lt;/strong&gt; solution. The right tool depends on how your &lt;strong&gt;IDP is structured&lt;/strong&gt; and who will be managing infrastructure:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;For Ops-driven teams →&lt;/strong&gt; Terraform&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;For Developer-friendly experience →&lt;/strong&gt; Pulumi&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;For Kubernetes-native GitOps setups →&lt;/strong&gt; Crossplane&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you’re building an IDP, consider mixing &lt;strong&gt;Terraform for infrastructure provisioning&lt;/strong&gt; and &lt;strong&gt;Crossplane for Kubernetes resource management&lt;/strong&gt;. Or, if your developers love coding, &lt;strong&gt;Pulumi can bridge the gap&lt;/strong&gt; between infra and app dev teams.&lt;/p&gt;

&lt;h3&gt;
  
  
  🚀 Next Steps
&lt;/h3&gt;

&lt;p&gt;✅ Try out each tool in a &lt;strong&gt;proof-of-concept&lt;/strong&gt; for your IDP.&lt;br&gt;
✅ Consider &lt;strong&gt;hybrid approaches&lt;/strong&gt;—many teams use &lt;strong&gt;Terraform + Crossplane&lt;/strong&gt; or &lt;strong&gt;Pulumi + Terraform&lt;/strong&gt;.&lt;br&gt;
✅ &lt;strong&gt;Embrace automation and GitOps&lt;/strong&gt; to make infra changes seamless.&lt;/p&gt;

&lt;p&gt;Which tool are you using for your IDP? Let me know in the comments! 🛠️💬&lt;/p&gt;

</description>
      <category>terraform</category>
      <category>pulumi</category>
      <category>crossplane</category>
      <category>cloud</category>
    </item>
    <item>
      <title>Kubernetes Security: Protecting Your Cluster Like Fort Knox 🔐</title>
      <dc:creator>Romulo Franca</dc:creator>
      <pubDate>Tue, 18 Feb 2025 14:02:36 +0000</pubDate>
      <link>https://dev.to/romulofrancas/kubernetes-security-protecting-your-cluster-like-fort-knox-23ci</link>
      <guid>https://dev.to/romulofrancas/kubernetes-security-protecting-your-cluster-like-fort-knox-23ci</guid>
      <description>&lt;h2&gt;
  
  
  The Story: Why I Believe Security is the Foundation of Infrastructure 🏰
&lt;/h2&gt;

&lt;p&gt;I've always believed that security should be the foundation of any infrastructure. Think of it like building a house—you wouldn’t install a fancy entertainment system before making sure the doors have locks, right? Yet, I’ve seen so many Kubernetes clusters deployed with the equivalent of an “Open House” sign for hackers. &lt;/p&gt;

&lt;p&gt;Misconfigurations in Kubernetes security are more common than most people think. Unauthorized workloads, exposed API servers, leaked credentials, and privilege escalation attempts are just a few examples of incidents that can put an entire infrastructure at risk. Without the right security measures, attackers can exploit these vulnerabilities to deploy their own pods, access sensitive data, or disrupt services. &lt;/p&gt;

&lt;p&gt;That was the wake-up call: security isn’t an afterthought; it’s the &lt;strong&gt;cornerstone&lt;/strong&gt; of a resilient Kubernetes architecture. And if you don’t prioritize security from day one, you’re playing with fire.🔥&lt;/p&gt;

&lt;h2&gt;
  
  
  Understanding the Kubernetes Threat Landscape 🕵️‍♂️
&lt;/h2&gt;

&lt;p&gt;Before we dive into tools, let’s break down the security risks in Kubernetes:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Misconfigured RBAC (Role-Based Access Control)&lt;/strong&gt; – Giving too many privileges to users, service accounts, or applications can lead to unauthorized access.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Exposed Kubernetes API Server&lt;/strong&gt; – If your API server is accessible from the internet without proper controls, expect a visit from malicious actors.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Container Image Vulnerabilities&lt;/strong&gt; – Pulling images from untrusted sources or using outdated ones can introduce security flaws.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Runtime Threats&lt;/strong&gt; – Attackers exploiting running containers to escalate privileges or access sensitive data.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Lack of Network Policies&lt;/strong&gt; – Without defined network policies, pods can talk to each other freely—hello, lateral movement attacks! 🏃💨&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Unrestricted Host Privileges&lt;/strong&gt; – Running containers as root or allowing privileged escalation is asking for trouble.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Essential Kubernetes Security Tools 🛠️
&lt;/h2&gt;

&lt;p&gt;Now that we know what we’re up against, let’s talk about the tools that can turn your cluster into an impenetrable fortress.&lt;/p&gt;

&lt;h3&gt;
  
  
  1️⃣ Kubernetes Native Security Controls 🚀
&lt;/h3&gt;

&lt;p&gt;Before installing fancy security tools, Kubernetes itself has built-in features to enhance security:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;RBAC (Role-Based Access Control):&lt;/strong&gt; Define fine-grained permissions for users and services.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Network Policies:&lt;/strong&gt; Restrict pod-to-pod communication to limit attack surfaces.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pod Security Admission (PSA):&lt;/strong&gt; Enforce security standards like preventing privileged containers.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Audit Logs:&lt;/strong&gt; Monitor API calls and detect suspicious activity.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2️⃣ Image Scanning &amp;amp; Supply Chain Security 🔎
&lt;/h3&gt;

&lt;p&gt;To avoid shipping vulnerabilities, use these tools:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Trivy&lt;/strong&gt; (by Aqua Security) – Scans container images, code, and repositories for vulnerabilities.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Grype&lt;/strong&gt; (by Anchore) – Another powerful CLI vulnerability scanner.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sigstore / Cosign&lt;/strong&gt; – Verifies and signs container images to ensure integrity.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3️⃣ Runtime Security &amp;amp; Intrusion Detection 🛡️
&lt;/h3&gt;

&lt;p&gt;Detect and prevent threats in running containers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Falco&lt;/strong&gt; (by Sysdig) – Real-time security monitoring for Kubernetes workloads.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sysdig Secure&lt;/strong&gt; – Threat detection and forensic analysis for runtime security.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tetragon&lt;/strong&gt; (by Cilium) – eBPF-powered security observability and runtime enforcement.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  4️⃣ Network Security &amp;amp; Zero Trust 🔒
&lt;/h3&gt;

&lt;p&gt;Control traffic and prevent unauthorized access:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Cilium&lt;/strong&gt; – Advanced eBPF-based networking and security enforcement.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Calico&lt;/strong&gt; – Implements network policies to control pod communications.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Istio&lt;/strong&gt; – Service mesh with built-in security, including mutual TLS and traffic control.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  5️⃣ Secrets Management 🔑
&lt;/h3&gt;

&lt;p&gt;Avoid hardcoding secrets inside your cluster:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;External Secrets Operator&lt;/strong&gt; – Securely inject secrets from AWS Secrets Manager, HashiCorp Vault, or other providers.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sealed Secrets&lt;/strong&gt; (by Bitnami) – Encrypt Kubernetes secrets so they can be safely stored in Git.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Vault (by HashiCorp)&lt;/strong&gt; – Centralized secret management with fine-grained access control.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  6️⃣ Compliance &amp;amp; Policy Enforcement 📜
&lt;/h3&gt;

&lt;p&gt;Ensure your Kubernetes workloads comply with security standards:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Kyverno&lt;/strong&gt; – Kubernetes-native policy engine for governance and security enforcement.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;OPA (Open Policy Agent)&lt;/strong&gt; – Define security policies as code.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Kube-bench&lt;/strong&gt; – Checks your cluster’s compliance with the CIS Kubernetes Benchmark.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Best Practices to Keep Your Cluster Secure 🔥
&lt;/h2&gt;

&lt;h3&gt;
  
  
  ✅ Implement Least Privilege Access
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Don’t give admin privileges unless absolutely necessary.&lt;/li&gt;
&lt;li&gt;Restrict service account permissions to only what they need.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  ✅ Keep Kubernetes and Dependencies Up to Date
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Running an outdated Kubernetes version? Fix it ASAP.&lt;/li&gt;
&lt;li&gt;Regularly update container images and dependencies.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  ✅ Use Network Policies
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Restrict which pods can talk to each other.&lt;/li&gt;
&lt;li&gt;Deny all traffic by default and allow only necessary communication.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  ✅ Monitor and Audit Everything
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Enable Kubernetes audit logs.&lt;/li&gt;
&lt;li&gt;Use Prometheus and Grafana for observability.&lt;/li&gt;
&lt;li&gt;Set up alerts with Falco or Sysdig Secure.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Wrapping Up: Security is a Mindset 🧠
&lt;/h2&gt;

&lt;p&gt;Security isn’t a one-time setup—it’s an ongoing process. Whether you’re deploying a new app or tweaking configurations, &lt;strong&gt;always&lt;/strong&gt; ask yourself, “How could this be exploited?” Thinking like an attacker will help you design a more resilient system. 💪&lt;/p&gt;

&lt;p&gt;So, do yourself (and your SRE team) a favor: lock down your Kubernetes cluster before someone else does. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Your turn!&lt;/strong&gt; Which security tools do you use in your Kubernetes setup? Share your experiences in the comments! 🚀&lt;/p&gt;

</description>
      <category>devsecops</category>
      <category>devops</category>
      <category>kubernetes</category>
      <category>security</category>
    </item>
    <item>
      <title>Unlock the Future: Build Your Own Private "ChatGPT" in 30 Minutes with Kubernetes, Ollama, and NVIDIA 🤖</title>
      <dc:creator>Romulo Franca</dc:creator>
      <pubDate>Tue, 11 Feb 2025 17:23:23 +0000</pubDate>
      <link>https://dev.to/romulofrancas/unlock-the-future-build-your-own-private-chatgpt-in-30-minutes-with-kubernetes-ollama-and-1npp</link>
      <guid>https://dev.to/romulofrancas/unlock-the-future-build-your-own-private-chatgpt-in-30-minutes-with-kubernetes-ollama-and-1npp</guid>
      <description>&lt;p&gt;Imagine running ChatGPT-style AI &lt;strong&gt;entirely on your own hardware&lt;/strong&gt;—no cloud lock-in, no API limits, no privacy risks. Just &lt;strong&gt;pure, high-performance AI&lt;/strong&gt; under your control.  &lt;/p&gt;

&lt;p&gt;Big Tech doesn’t want you to know this, but &lt;strong&gt;you don’t need OpenAI or cloud GPUs&lt;/strong&gt; to build your own AI chatbot. With &lt;strong&gt;Kubernetes (K3s), NVIDIA GPUs, and Ollama&lt;/strong&gt;, you can deploy a &lt;strong&gt;private, lightning-fast ChatGPT alternative&lt;/strong&gt; in &lt;strong&gt;under 30 minutes&lt;/strong&gt;.  &lt;/p&gt;

&lt;p&gt;This guide is perfect for:&lt;br&gt;&lt;br&gt;
✅ &lt;strong&gt;Developers &amp;amp; enterprises&lt;/strong&gt; wanting &lt;strong&gt;full control over their AI&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
✅ &lt;strong&gt;Security-conscious teams&lt;/strong&gt; keeping AI &lt;strong&gt;inside their private networks&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
✅ &lt;strong&gt;Tinkerers &amp;amp; AI enthusiasts&lt;/strong&gt; looking to &lt;strong&gt;run custom LLMs&lt;/strong&gt; on bare metal  &lt;/p&gt;

&lt;p&gt;Best of all? &lt;strong&gt;Your AI is now 10x faster&lt;/strong&gt;—thanks to &lt;strong&gt;GPU acceleration&lt;/strong&gt;—compared to CPU-bound inferencing. Let’s dive in! 🚀  &lt;/p&gt;


&lt;h2&gt;
  
  
  &lt;strong&gt;Prerequisites ✅&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;You’ll need:  &lt;/p&gt;

&lt;p&gt;1️⃣ &lt;strong&gt;NVIDIA GPU (Required)&lt;/strong&gt; – RTX 3090+, A100, or similar (Pascal+ for CUDA support)&lt;br&gt;&lt;br&gt;
2️⃣ &lt;strong&gt;NVIDIA Drivers &amp;amp; NVIDIA-SMI&lt;/strong&gt; – Verify installation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   nvidia-smi
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;3️⃣ &lt;strong&gt;Linux Distribution&lt;/strong&gt; – Ubuntu 20.04+, Debian, Fedora&lt;br&gt;&lt;br&gt;
4️⃣ &lt;strong&gt;Docker &amp;amp; Kubernetes (K3s)&lt;/strong&gt; – Installed on your machine  &lt;/p&gt;

&lt;p&gt;💡 &lt;em&gt;Not sure if your GPU is supported?&lt;/em&gt; Run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   nvidia-smi | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s2"&gt;"CUDA Version"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  &lt;strong&gt;Step 1: Install Kubernetes (K3s) 🏗️&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;We’re using &lt;strong&gt;K3s&lt;/strong&gt;, a lightweight Kubernetes distribution that’s perfect for rapid deployments.  &lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Installation Steps:&lt;/strong&gt;
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Install K3s:&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   curl &lt;span class="nt"&gt;-sfL&lt;/span&gt; https://get.k3s.io | sh -
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Verify Installation:&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   &lt;span class="nb"&gt;sudo &lt;/span&gt;k3s kubectl get node
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  &lt;strong&gt;Step 2: Deploy Ollama as a StatefulSet 🧠&lt;/strong&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Why a StatefulSet?&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;AI models require &lt;strong&gt;persistent storage&lt;/strong&gt; (so you don’t redownload them on every restart).
&lt;/li&gt;
&lt;li&gt;StatefulSets ensure &lt;strong&gt;model files stay intact across pod restarts&lt;/strong&gt;.
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Save the following as &lt;code&gt;ollama-statefulset.yaml&lt;/code&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;apps/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;StatefulSet&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;ollama&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;serviceName&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ollama"&lt;/span&gt;
  &lt;span class="na"&gt;replicas&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;
  &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;matchLabels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ollama&lt;/span&gt;
  &lt;span class="na"&gt;template&lt;/span&gt;&lt;span class="pi"&gt;:&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;labels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ollama&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;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ollama&lt;/span&gt;
        &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ollama/ollama:latest&lt;/span&gt;
        &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;containerPort&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;11434&lt;/span&gt;
        &lt;span class="na"&gt;env&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;NVIDIA_VISIBLE_DEVICES&lt;/span&gt;
          &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;all&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;NVIDIA_DRIVER_CAPABILITIES&lt;/span&gt;
          &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;compute,utility&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;OLLAMA_DEBUG&lt;/span&gt;
          &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;1"&lt;/span&gt;
        &lt;span class="na"&gt;volumeMounts&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;models&lt;/span&gt;
          &lt;span class="na"&gt;mountPath&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/root/.ollama&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;nvidia.com/gpu&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;
  &lt;span class="na"&gt;volumeClaimTemplates&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&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;models&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;accessModes&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;ReadWriteOnce"&lt;/span&gt; &lt;span class="pi"&gt;]&lt;/span&gt;
      &lt;span class="na"&gt;storageClassName&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;local-path&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;requests&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;storage&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;10Gi&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Deploy the StatefulSet:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl apply &lt;span class="nt"&gt;-f&lt;/span&gt; ollama-statefulset.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  &lt;strong&gt;Step 3: Deploy Open WebUI 🌐&lt;/strong&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Create the Deployment&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Save the following as &lt;code&gt;open-webui-deployment.yaml&lt;/code&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;apps/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;Deployment&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;open-webui&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;replicas&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;
  &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;matchLabels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;open-webui&lt;/span&gt;
  &lt;span class="na"&gt;template&lt;/span&gt;&lt;span class="pi"&gt;:&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;labels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;open-webui&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;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;open-webui&lt;/span&gt;
        &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ghcr.io/open-webui/open-webui:latest&lt;/span&gt;
        &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;containerPort&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;3000&lt;/span&gt;
        &lt;span class="na"&gt;env&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;OLLAMA_BASE_URL&lt;/span&gt;
          &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;http://ollama"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Deploy Open WebUI:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl apply &lt;span class="nt"&gt;-f&lt;/span&gt; open-webui-deployment.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  &lt;strong&gt;Step 4: Access Your Private ChatGPT 🚀&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Use &lt;strong&gt;port forwarding&lt;/strong&gt; to access Open WebUI:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl port-forward svc/open-webui-service 8080:80
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now open your browser and visit:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;http://localhost:8080
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  &lt;strong&gt;Next Steps: Real-World Scaling &amp;amp; Optimizations 🏆&lt;/strong&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1️⃣ &lt;strong&gt;Serve via DNS &amp;amp; Load Balancer&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Instead of using &lt;code&gt;kubectl port-forward&lt;/code&gt;, expose your chatbot via &lt;strong&gt;Ingress + LoadBalancer&lt;/strong&gt;.
&lt;/li&gt;
&lt;li&gt;Add &lt;strong&gt;TLS encryption&lt;/strong&gt; via Cert-Manager + Let’s Encrypt.
&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="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;networking.k8s.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;Ingress&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;chatgpt-ingress&lt;/span&gt;
  &lt;span class="na"&gt;annotations&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;cert-manager.io/cluster-issuer&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;letsencrypt-prod"&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;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;host&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;chatgpt.yourdomain.com&lt;/span&gt;
      &lt;span class="na"&gt;http&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;paths&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/&lt;/span&gt;
            &lt;span class="na"&gt;pathType&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Prefix&lt;/span&gt;
            &lt;span class="na"&gt;backend&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
              &lt;span class="na"&gt;service&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;open-webui-service&lt;/span&gt;
                &lt;span class="na"&gt;port&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
                  &lt;span class="na"&gt;number&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;80&lt;/span&gt;
  &lt;span class="na"&gt;tls&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;hosts&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;chatgpt.yourdomain.com&lt;/span&gt;
      &lt;span class="na"&gt;secretName&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;chatgpt-tls&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2️⃣ &lt;strong&gt;Optimize GPU Utilization&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Use &lt;strong&gt;NVIDIA MPS (Multi-Process Service)&lt;/strong&gt; to &lt;strong&gt;split GPU resources across multiple models&lt;/strong&gt; dynamically.
&lt;/li&gt;
&lt;li&gt;Deploy &lt;strong&gt;multiple AI models in parallel&lt;/strong&gt; (e.g., LLaMA + Mistral) by configuring model-specific &lt;code&gt;resourceRequests&lt;/code&gt;.
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3️⃣ &lt;strong&gt;CI/CD Automation for Model Updates&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Automate deployment with &lt;strong&gt;ArgoCD or GitHub Actions&lt;/strong&gt; for rolling AI model updates.
&lt;/li&gt;
&lt;li&gt;Use &lt;strong&gt;image versioning tags&lt;/strong&gt; (e.g., &lt;code&gt;ollama/ollama:1.2.3&lt;/code&gt;) to &lt;strong&gt;avoid accidental updates&lt;/strong&gt; breaking your chatbot.
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  4️⃣ &lt;strong&gt;Performance Monitoring (GPU Metrics &amp;amp; AI Response Times)&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Integrate &lt;strong&gt;Prometheus + Grafana&lt;/strong&gt; to track:
✅ &lt;strong&gt;GPU memory usage&lt;/strong&gt;
✅ &lt;strong&gt;Inference time per request&lt;/strong&gt;
✅ &lt;strong&gt;Active model sessions&lt;/strong&gt;
&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="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;monitoring.coreos.com/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;ServiceMonitor&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;ollama-monitor&lt;/span&gt;
  &lt;span class="na"&gt;labels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;release&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;prometheus&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;selector&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;matchLabels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ollama&lt;/span&gt;
  &lt;span class="na"&gt;endpoints&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;port&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;metrics&lt;/span&gt;
    &lt;span class="na"&gt;interval&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;15s&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🎯 &lt;strong&gt;Final Thoughts&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;You’ve just built your own &lt;strong&gt;private, GPU-powered ChatGPT&lt;/strong&gt; using Kubernetes, Ollama, and Open WebUI. But this is just the beginning!  &lt;/p&gt;

&lt;p&gt;🔹 &lt;strong&gt;Next Challenges:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
1️⃣ Deploy multiple AI models (LLaMA + Mistral) with GPU partitioning.&lt;br&gt;&lt;br&gt;
2️⃣ Add user authentication (OAuth2 or Keycloak).&lt;br&gt;&lt;br&gt;
3️⃣ Fine-tune AI models on &lt;strong&gt;your own domain-specific dataset&lt;/strong&gt;.  &lt;/p&gt;

&lt;p&gt;💬 &lt;strong&gt;What’s your next AI project?&lt;/strong&gt; Drop a comment below and let’s build something epic together! 🚀  &lt;/p&gt;

</description>
      <category>ai</category>
      <category>kubernetes</category>
      <category>chatgpt</category>
      <category>devops</category>
    </item>
    <item>
      <title>🚀 GitOps Made Simple: Automating Deployments with ArgoCD &amp; Helm</title>
      <dc:creator>Romulo Franca</dc:creator>
      <pubDate>Fri, 07 Feb 2025 12:31:18 +0000</pubDate>
      <link>https://dev.to/romulofrancas/mastering-gitops-how-to-automate-deployments-with-argocd-and-helm-4aob</link>
      <guid>https://dev.to/romulofrancas/mastering-gitops-how-to-automate-deployments-with-argocd-and-helm-4aob</guid>
      <description>&lt;h2&gt;
  
  
  😂 Introduction: Why GitOps? Because CI/CD Needed a Makeover
&lt;/h2&gt;

&lt;p&gt;Picture this: Your team is manually deploying apps to Kubernetes. The YAMLs are scattered, and no one knows which version is running in production. Jenkins jobs fail randomly, and rollback is a &lt;strong&gt;prayer-based process&lt;/strong&gt;. Sound familiar?  &lt;/p&gt;

&lt;p&gt;Enter &lt;strong&gt;GitOps&lt;/strong&gt;—the DevOps methodology that treats Git as the &lt;strong&gt;single source of truth&lt;/strong&gt; for your infrastructure and applications. Instead of manually applying changes, you commit them to Git, and a tool like &lt;strong&gt;ArgoCD&lt;/strong&gt; ensures your cluster stays in sync. Pair this with &lt;strong&gt;Helm&lt;/strong&gt; to manage Kubernetes manifests like a pro, and you've got a rock-solid deployment strategy.  &lt;/p&gt;

&lt;p&gt;By the end of this guide, you'll:&lt;br&gt;&lt;br&gt;
✅ Understand the core principles of &lt;strong&gt;GitOps&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
✅ Set up &lt;strong&gt;ArgoCD&lt;/strong&gt; for automated Kubernetes deployments&lt;br&gt;&lt;br&gt;
✅ Use &lt;strong&gt;Helm&lt;/strong&gt; to simplify and manage Kubernetes applications&lt;br&gt;&lt;br&gt;
✅ Implement &lt;strong&gt;CI/CD pipelines to build, test, and scan container images&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
✅ Learn how to &lt;strong&gt;separate application and infrastructure repositories&lt;/strong&gt; for better modularity  &lt;/p&gt;

&lt;p&gt;So, grab your coffee ☕, and let’s dive into &lt;strong&gt;automated deployments with ArgoCD, Helm, and CI/CD pipelines&lt;/strong&gt;!  &lt;/p&gt;


&lt;h2&gt;
  
  
  🔍 What is GitOps? (And Why You Should Care)
&lt;/h2&gt;
&lt;h3&gt;
  
  
  📌 GitOps in a Nutshell
&lt;/h3&gt;

&lt;p&gt;GitOps is a &lt;strong&gt;developer-centric approach&lt;/strong&gt; to managing infrastructure and applications using Git. It’s based on these core principles:  &lt;/p&gt;

&lt;p&gt;1️⃣ &lt;strong&gt;Declarative Configuration&lt;/strong&gt; – Everything (infra, apps) is defined as code.&lt;br&gt;&lt;br&gt;
2️⃣ &lt;strong&gt;Versioned &amp;amp; Immutable&lt;/strong&gt; – Git acts as the source of truth. Rollbacks are as easy as &lt;code&gt;git revert&lt;/code&gt;.&lt;br&gt;&lt;br&gt;
3️⃣ &lt;strong&gt;Automated Syncing&lt;/strong&gt; – A tool (like ArgoCD) ensures the actual state in Kubernetes matches the desired state in Git.&lt;br&gt;&lt;br&gt;
4️⃣ &lt;strong&gt;Continuous Reconciliation&lt;/strong&gt; – If someone &lt;em&gt;accidentally&lt;/em&gt; applies a change outside Git, GitOps automatically fixes it.  &lt;/p&gt;
&lt;h3&gt;
  
  
  🎯 Why ArgoCD?
&lt;/h3&gt;

&lt;p&gt;ArgoCD is a &lt;strong&gt;lightweight, Kubernetes-native GitOps tool&lt;/strong&gt; that continuously monitors Git repositories and applies the desired state to your cluster.  &lt;/p&gt;

&lt;p&gt;✅ &lt;strong&gt;Self-healing&lt;/strong&gt; – If someone changes something manually, ArgoCD will fix it.&lt;br&gt;&lt;br&gt;
✅ &lt;strong&gt;Multi-cluster support&lt;/strong&gt; – Manage multiple clusters from a single dashboard.&lt;br&gt;&lt;br&gt;
✅ &lt;strong&gt;Easy Rollbacks&lt;/strong&gt; – Revert to a previous commit and ArgoCD will handle the rest.&lt;br&gt;&lt;br&gt;
✅ &lt;strong&gt;RBAC &amp;amp; SSO support&lt;/strong&gt; – Secure your deployments with fine-grained access control.  &lt;/p&gt;


&lt;h2&gt;
  
  
  🔧 Setting Up ArgoCD in Kubernetes
&lt;/h2&gt;

&lt;p&gt;Before we automate anything, let’s get &lt;strong&gt;ArgoCD installed&lt;/strong&gt; on our Kubernetes cluster.  &lt;/p&gt;
&lt;h3&gt;
  
  
  🔹 Step 1: Install ArgoCD
&lt;/h3&gt;

&lt;p&gt;ArgoCD runs inside Kubernetes, and installing it is as simple as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl create namespace argocd
kubectl apply &lt;span class="nt"&gt;-n&lt;/span&gt; argocd &lt;span class="nt"&gt;-f&lt;/span&gt; https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Verify the installation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get pods &lt;span class="nt"&gt;-n&lt;/span&gt; argocd
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  🔹 Step 2: Expose the ArgoCD API Server
&lt;/h3&gt;

&lt;p&gt;By default, ArgoCD runs internally. To access the UI, expose it via &lt;code&gt;kubectl port-forward&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl port-forward svc/argocd-server &lt;span class="nt"&gt;-n&lt;/span&gt; argocd 8080:443
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, open your browser and navigate to &lt;code&gt;https://localhost:8080&lt;/code&gt;. 🎉  &lt;/p&gt;

&lt;h3&gt;
  
  
  🔹 Step 3: Login to ArgoCD
&lt;/h3&gt;

&lt;p&gt;Get the initial admin password:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl &lt;span class="nt"&gt;-n&lt;/span&gt; argocd get secret argocd-initial-admin-secret &lt;span class="nt"&gt;-o&lt;/span&gt; &lt;span class="nv"&gt;jsonpath&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"{.data.password}"&lt;/span&gt; | &lt;span class="nb"&gt;base64&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Login using the CLI:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;argocd login localhost:8080 &lt;span class="nt"&gt;--username&lt;/span&gt; admin &lt;span class="nt"&gt;--password&lt;/span&gt; &amp;lt;your-password&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🛠 Deploying an Application with ArgoCD and Helm
&lt;/h2&gt;

&lt;p&gt;Now that we have ArgoCD running, let’s deploy a sample application using &lt;strong&gt;Helm&lt;/strong&gt;.  &lt;/p&gt;

&lt;h3&gt;
  
  
  📌 What is Helm?
&lt;/h3&gt;

&lt;p&gt;Helm is a &lt;strong&gt;package manager for Kubernetes&lt;/strong&gt; that simplifies deploying applications by using charts. Instead of managing hundreds of YAML files, you define parameters in &lt;code&gt;values.yaml&lt;/code&gt;, and Helm takes care of the rest.  &lt;/p&gt;

&lt;h3&gt;
  
  
  🔹 Step 1: Separate Your Repositories
&lt;/h3&gt;

&lt;p&gt;To follow GitOps best practices, separate your repositories into:&lt;br&gt;&lt;br&gt;
✅ &lt;strong&gt;Application Repository&lt;/strong&gt; – Contains your app code, Dockerfile, and CI/CD pipeline for building images.&lt;br&gt;&lt;br&gt;
✅ &lt;strong&gt;Infrastructure Repository&lt;/strong&gt; – Contains your Helm charts, ArgoCD configurations, and Kubernetes manifests.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;📂 app-repo/
  ├── src/
  ├── Dockerfile
  ├── .github/workflows/build-and-push.yaml  # CI/CD pipeline
  ├── README.md

📂 infra-repo/
  ├── charts/
  ├── values.yaml
  ├── applications/
  ├── argocd.yaml
  ├── README.md
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  🔹 Step 2: CI/CD Pipeline for Building, Testing, and Scanning
&lt;/h3&gt;

&lt;p&gt;Use GitHub Actions, GitLab CI, or Jenkins to:&lt;br&gt;&lt;br&gt;
1️⃣ &lt;strong&gt;Build the container image&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
2️⃣ &lt;strong&gt;Scan for vulnerabilities&lt;/strong&gt; (Trivy, Snyk, or Clair)&lt;br&gt;&lt;br&gt;
3️⃣ &lt;strong&gt;Run tests&lt;/strong&gt; (Unit tests, integration tests)&lt;br&gt;&lt;br&gt;
4️⃣ &lt;strong&gt;Push the image to a container registry&lt;/strong&gt;  &lt;/p&gt;

&lt;p&gt;Example &lt;strong&gt;GitHub Actions Workflow (&lt;code&gt;build-and-push.yaml&lt;/code&gt;)&lt;/strong&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;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Build and Push Docker Image&lt;/span&gt;

&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;push&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;main&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;steps&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;Checkout code&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v4&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;Login to DockerHub&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;echo "${{ secrets.DOCKER_PASSWORD }}" | docker login -u "${{ secrets.DOCKER_USERNAME }}" --password-stdin&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;Build and tag Docker image&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
          &lt;span class="s"&gt;docker build -t my-app:latest .&lt;/span&gt;
          &lt;span class="s"&gt;docker tag my-app:latest my-dockerhub/my-app:${{ github.sha }}&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;Scan image for vulnerabilities&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;aquasecurity/trivy-action@master&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;image-ref&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;my-dockerhub/my-app:${{&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;github.sha&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;}}'&lt;/span&gt;
          &lt;span class="na"&gt;format&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;table'&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;Push Docker image&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
          &lt;span class="s"&gt;docker push my-dockerhub/my-app:${{ github.sha }}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  🔹 Step 3: Configure ArgoCD to Watch Helm Chart Repo
&lt;/h3&gt;

&lt;p&gt;Now, create an ArgoCD application that points to your &lt;strong&gt;Helm chart repository&lt;/strong&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;argoproj.io/v1alpha1&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;Application&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;my-helm-app&lt;/span&gt;
  &lt;span class="na"&gt;namespace&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;argocd&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;destination&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;namespace&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;default&lt;/span&gt;
    &lt;span class="na"&gt;server&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;https://kubernetes.default.svc&lt;/span&gt;
  &lt;span class="na"&gt;project&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;default&lt;/span&gt;
  &lt;span class="na"&gt;source&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;chart&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;my-app&lt;/span&gt;
    &lt;span class="na"&gt;repoURL&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;https://github.com/example/infra-repo&lt;/span&gt;
    &lt;span class="na"&gt;targetRevision&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;main&lt;/span&gt;
    &lt;span class="na"&gt;helm&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;values&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
        &lt;span class="s"&gt;image:&lt;/span&gt;
          &lt;span class="s"&gt;repository: my-dockerhub/my-app&lt;/span&gt;
          &lt;span class="s"&gt;tag: latest&lt;/span&gt;
  &lt;span class="na"&gt;syncPolicy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;automated&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;prune&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;selfHeal&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Apply the application manifest:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl apply &lt;span class="nt"&gt;-f&lt;/span&gt; my-app.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🔐 Best Practices for GitOps with ArgoCD and Helm
&lt;/h2&gt;

&lt;p&gt;✅ &lt;strong&gt;Separate Application &amp;amp; Infrastructure Repositories&lt;/strong&gt; – Keep your app code and deployment configs independent.&lt;br&gt;&lt;br&gt;
✅ &lt;strong&gt;Use CI/CD Pipelines&lt;/strong&gt; – Automate image building, scanning, and testing.&lt;br&gt;&lt;br&gt;
✅ &lt;strong&gt;Enable RBAC in ArgoCD&lt;/strong&gt; – Restrict who can apply changes.&lt;br&gt;&lt;br&gt;
✅ &lt;strong&gt;Use Helm Secrets or SOPS&lt;/strong&gt; – Never store plaintext secrets in Git.&lt;br&gt;&lt;br&gt;
✅ &lt;strong&gt;Monitor with Prometheus &amp;amp; Grafana&lt;/strong&gt; – Use ArgoCD metrics for insights.&lt;br&gt;&lt;br&gt;
✅ &lt;strong&gt;Automate Image Updates&lt;/strong&gt; – Use ArgoCD Image Updater to pull new images.  &lt;/p&gt;




&lt;h2&gt;
  
  
  📢 Conclusion: GitOps FTW! 🚀
&lt;/h2&gt;

&lt;p&gt;By combining &lt;strong&gt;ArgoCD, Helm, and CI/CD pipelines&lt;/strong&gt;, you get:&lt;br&gt;&lt;br&gt;
✔ &lt;strong&gt;Automated deployments&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
✔ &lt;strong&gt;Self-healing applications&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
✔ &lt;strong&gt;Secure &amp;amp; scalable pipelines&lt;/strong&gt;  &lt;/p&gt;

&lt;p&gt;🔥 Try deploying &lt;strong&gt;your own apps&lt;/strong&gt; using GitOps and let me know how it goes! 🚀  &lt;/p&gt;

&lt;p&gt;👉 &lt;strong&gt;Next Steps&lt;/strong&gt;:  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Explore &lt;a href="https://argo-cd.readthedocs.io/" rel="noopener noreferrer"&gt;ArgoCD docs&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Learn about &lt;a href="https://helm.sh/docs/" rel="noopener noreferrer"&gt;Helm&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Check out &lt;a href="https://argocd-image-updater.readthedocs.io/en/stable/" rel="noopener noreferrer"&gt;Argocd Image Updater&lt;/a&gt; for automatically update container images &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Happy GitOps-ing! 🎉&lt;/p&gt;

</description>
      <category>gitops</category>
      <category>devops</category>
      <category>kubernetes</category>
      <category>argocd</category>
    </item>
    <item>
      <title>10 Common Kubernetes Errors and How to Fix Them Like a Pro 🚀</title>
      <dc:creator>Romulo Franca</dc:creator>
      <pubDate>Fri, 07 Feb 2025 11:15:34 +0000</pubDate>
      <link>https://dev.to/romulofrancas/10-common-kubernetes-errors-and-how-to-fix-them-like-a-pro-2h6o</link>
      <guid>https://dev.to/romulofrancas/10-common-kubernetes-errors-and-how-to-fix-them-like-a-pro-2h6o</guid>
      <description>&lt;p&gt;Kubernetes is an incredibly powerful container orchestration platform—but even the best tools have their quirks. Whether you're a developer or a DevOps engineer, you'll sometimes run into issues when deploying and managing Kubernetes workloads. Some errors can be a bit cryptic, but don't worry—we’ve got your back! In this post, we’ll dive into &lt;strong&gt;10 common Kubernetes errors&lt;/strong&gt; and share &lt;strong&gt;pro-level fixes&lt;/strong&gt; to help you troubleshoot like a champ. Let’s get started! 😎&lt;/p&gt;




&lt;h2&gt;
  
  
  1. &lt;strong&gt;CrashLoopBackOff: Pod Keeps Restarting&lt;/strong&gt; 🔄
&lt;/h2&gt;

&lt;h3&gt;
  
  
  ❌ The Problem:
&lt;/h3&gt;

&lt;p&gt;A pod enters a &lt;strong&gt;CrashLoopBackOff&lt;/strong&gt; state, which means it’s continuously crashing and restarting.&lt;/p&gt;

&lt;h3&gt;
  
  
  🔍 Common Causes:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;The application inside the container is crashing due to an error.&lt;/li&gt;
&lt;li&gt;Missing or misconfigured environment variables.&lt;/li&gt;
&lt;li&gt;Insufficient resource allocation.&lt;/li&gt;
&lt;li&gt;Unavailable dependencies (e.g., a required database isn’t accessible).&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  ✅ How to Fix It:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Check pod logs&lt;/strong&gt; to spot the root cause:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   kubectl logs &amp;lt;pod-name&amp;gt; &lt;span class="nt"&gt;-n&lt;/span&gt; &amp;lt;namespace&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Describe the pod&lt;/strong&gt; to see detailed event information:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   kubectl describe pod &amp;lt;pod-name&amp;gt; &lt;span class="nt"&gt;-n&lt;/span&gt; &amp;lt;namespace&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Verify that all dependencies are up and running&lt;/strong&gt; before the pod starts.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Adjust resource limits&lt;/strong&gt; in your deployment YAML:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;   &lt;span class="na"&gt;resources&lt;/span&gt;&lt;span class="pi"&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;128Mi"&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;250m"&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;512Mi"&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;500m"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Fix any application errors&lt;/strong&gt; inside the container.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  2. &lt;strong&gt;ImagePullBackOff: Failed to Pull Container Image&lt;/strong&gt; 🖼️
&lt;/h2&gt;

&lt;h3&gt;
  
  
  ❌ The Problem:
&lt;/h3&gt;

&lt;p&gt;A pod can’t start because it fails to pull the specified container image.&lt;/p&gt;

&lt;h3&gt;
  
  
  🔍 Common Causes:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;The container image doesn’t exist.&lt;/li&gt;
&lt;li&gt;The image tag is incorrect.&lt;/li&gt;
&lt;li&gt;Docker Hub or a private registry authentication failure.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  ✅ How to Fix It:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Check pod events&lt;/strong&gt; to see what’s going wrong:
&lt;/li&gt;
&lt;/ol&gt;

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

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Verify the image name and tag&lt;/strong&gt;:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   docker pull &amp;lt;image&amp;gt;:&amp;lt;tag&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;For private registries&lt;/strong&gt;, ensure you’re using the correct image pull secret:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;   &lt;span class="na"&gt;imagePullSecrets&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;my-secret&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create the secret with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   kubectl create secret docker-registry my-secret &lt;span class="se"&gt;\&lt;/span&gt;
     &lt;span class="nt"&gt;--docker-server&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&amp;lt;registry-url&amp;gt; &lt;span class="se"&gt;\&lt;/span&gt;
     &lt;span class="nt"&gt;--docker-username&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&amp;lt;username&amp;gt; &lt;span class="se"&gt;\&lt;/span&gt;
     &lt;span class="nt"&gt;--docker-password&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&amp;lt;password&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  3. &lt;strong&gt;ErrImagePull: Kubernetes Can’t Pull the Image&lt;/strong&gt; 😵
&lt;/h2&gt;

&lt;h3&gt;
  
  
  ❌ The Problem:
&lt;/h3&gt;

&lt;p&gt;Kubernetes isn’t able to pull the container image—similar to &lt;code&gt;ImagePullBackOff&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  🔍 Common Causes:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;The image name or tag might be wrong.&lt;/li&gt;
&lt;li&gt;The image is private and needs proper authentication.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  ✅ How to Fix It:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Double-check that the image exists&lt;/strong&gt; in the registry.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ensure you have authenticated correctly&lt;/strong&gt; by creating the necessary secret (as shown in Error #2).&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  4. &lt;strong&gt;Pod Stuck in Pending State&lt;/strong&gt; ⏳
&lt;/h2&gt;

&lt;h3&gt;
  
  
  ❌ The Problem:
&lt;/h3&gt;

&lt;p&gt;A pod remains in the &lt;code&gt;Pending&lt;/code&gt; state and never starts.&lt;/p&gt;

&lt;h3&gt;
  
  
  🔍 Common Causes:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Insufficient node resources.&lt;/li&gt;
&lt;li&gt;Taints and tolerations blocking scheduling.&lt;/li&gt;
&lt;li&gt;Mismatched node selectors.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  ✅ How to Fix It:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Describe the pod&lt;/strong&gt; to check for error messages:
&lt;/li&gt;
&lt;/ol&gt;

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

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Check your available nodes&lt;/strong&gt;:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   kubectl get nodes
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Inspect node taints&lt;/strong&gt; that might be keeping the pod from scheduling:
&lt;/li&gt;
&lt;/ol&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;ol&gt;
&lt;li&gt;
&lt;strong&gt;Ensure you’re using the right node selectors or tolerations&lt;/strong&gt; in your YAML:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;   &lt;span class="na"&gt;tolerations&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;node-role.kubernetes.io/master"&lt;/span&gt;
       &lt;span class="na"&gt;operator&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Exists"&lt;/span&gt;
       &lt;span class="na"&gt;effect&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;NoSchedule"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  5. &lt;strong&gt;Node Not Ready&lt;/strong&gt; 🚫
&lt;/h2&gt;

&lt;h3&gt;
  
  
  ❌ The Problem:
&lt;/h3&gt;

&lt;p&gt;A node is marked as &lt;code&gt;NotReady&lt;/code&gt;, so no new pods can be scheduled on it.&lt;/p&gt;

&lt;h3&gt;
  
  
  🔍 Common Causes:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Network connectivity issues.&lt;/li&gt;
&lt;li&gt;Disk pressure.&lt;/li&gt;
&lt;li&gt;Insufficient CPU or memory.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  ✅ How to Fix It:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Check the node status&lt;/strong&gt;:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   kubectl get nodes
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Describe the node&lt;/strong&gt; for more detailed info:
&lt;/li&gt;
&lt;/ol&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;ol&gt;
&lt;li&gt;
&lt;strong&gt;Review the Kubelet logs&lt;/strong&gt; on the node:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   journalctl &lt;span class="nt"&gt;-u&lt;/span&gt; kubelet &lt;span class="nt"&gt;-f&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Restart the Kubelet&lt;/strong&gt;:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   systemctl restart kubelet
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Verify network connectivity&lt;/strong&gt; between the node and the master.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  6. &lt;strong&gt;Volume Mount Failure: Unable to Mount Volume&lt;/strong&gt; 📂
&lt;/h2&gt;

&lt;h3&gt;
  
  
  ❌ The Problem:
&lt;/h3&gt;

&lt;p&gt;A pod fails to start because it can’t mount the specified volume.&lt;/p&gt;

&lt;h3&gt;
  
  
  🔍 Common Causes:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;The Persistent Volume (PV) doesn’t exist.&lt;/li&gt;
&lt;li&gt;The Persistent Volume Claim (PVC) isn’t bound to a PV.&lt;/li&gt;
&lt;li&gt;Incorrect access modes or permissions.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  ✅ How to Fix It:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Check the PVC status&lt;/strong&gt;:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   kubectl get pvc
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If it’s stuck in &lt;code&gt;Pending&lt;/code&gt;, a matching PV might not be available.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Ensure the PV exists and is properly bound&lt;/strong&gt;:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   kubectl get pv
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Review the pod events&lt;/strong&gt; for any mount errors:
&lt;/li&gt;
&lt;/ol&gt;

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

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Confirm that the PVC access mode is correct&lt;/strong&gt;:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;   &lt;span class="na"&gt;accessModes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
     &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;ReadWriteOnce&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Verify file system permissions&lt;/strong&gt; within the pod.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  7. &lt;strong&gt;OOMKilled: Pod Exceeds Memory Limit&lt;/strong&gt; 💥
&lt;/h2&gt;

&lt;h3&gt;
  
  
  ❌ The Problem:
&lt;/h3&gt;

&lt;p&gt;A pod gets terminated because it exceeds its memory allocation, triggering an Out-Of-Memory (OOM) kill.&lt;/p&gt;

&lt;h3&gt;
  
  
  🔍 Common Causes:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Memory limits are set too low.&lt;/li&gt;
&lt;li&gt;A memory leak or inefficient memory usage in the application.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  ✅ How to Fix It:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Check pod logs and events&lt;/strong&gt; to confirm the memory issue:
&lt;/li&gt;
&lt;/ol&gt;

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

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Increase the memory limits&lt;/strong&gt; in your deployment configuration:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&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;1Gi"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Optimize your application&lt;/strong&gt; to reduce memory usage.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  8. &lt;strong&gt;RBAC: Forbidden Error When Accessing Resources&lt;/strong&gt; 🚫🔐
&lt;/h2&gt;

&lt;h3&gt;
  
  
  ❌ The Problem:
&lt;/h3&gt;

&lt;p&gt;You get a &lt;code&gt;forbidden&lt;/code&gt; error when trying to access Kubernetes resources.&lt;/p&gt;

&lt;h3&gt;
  
  
  🔍 Common Causes:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Incorrect or missing RBAC roles.&lt;/li&gt;
&lt;li&gt;Inadequate ServiceAccount permissions.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  ✅ How to Fix It:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Check your user permissions&lt;/strong&gt;:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   kubectl auth can-i get pods &lt;span class="nt"&gt;--as&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&amp;lt;user&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Grant the necessary permissions&lt;/strong&gt; using a RoleBinding:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;   &lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;RoleBinding&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;rbac.authorization.k8s.io/v1&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;pod-reader&lt;/span&gt;
     &lt;span class="na"&gt;namespace&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;default&lt;/span&gt;
   &lt;span class="na"&gt;subjects&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
     &lt;span class="pi"&gt;-&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;User&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;&amp;lt;user&amp;gt;&lt;/span&gt;
   &lt;span class="na"&gt;roleRef&lt;/span&gt;&lt;span class="pi"&gt;:&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;Role&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;pod-reader&lt;/span&gt;
     &lt;span class="na"&gt;apiGroup&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;rbac.authorization.k8s.io&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Apply the RoleBinding&lt;/strong&gt;:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   kubectl apply &lt;span class="nt"&gt;-f&lt;/span&gt; rolebinding.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  9. &lt;strong&gt;Readiness Probe Failing&lt;/strong&gt; 🚦
&lt;/h2&gt;

&lt;h3&gt;
  
  
  ❌ The Problem:
&lt;/h3&gt;

&lt;p&gt;A pod shows as &lt;code&gt;Running&lt;/code&gt; but isn’t ready to serve traffic because its readiness probe is failing.&lt;/p&gt;

&lt;h3&gt;
  
  
  🔍 Common Causes:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;The application isn’t responding on the expected endpoint.&lt;/li&gt;
&lt;li&gt;Misconfigured readiness probe settings.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  ✅ How to Fix It:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Review your probe configuration&lt;/strong&gt;:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;   &lt;span class="na"&gt;readinessProbe&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
     &lt;span class="na"&gt;httpGet&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
       &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/healthz&lt;/span&gt;
       &lt;span class="na"&gt;port&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;8080&lt;/span&gt;
     &lt;span class="na"&gt;initialDelaySeconds&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;5&lt;/span&gt;
     &lt;span class="na"&gt;periodSeconds&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;10&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Ensure the application is running&lt;/strong&gt; and listening on the correct port.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Adjust probe timings&lt;/strong&gt; if needed.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  10. &lt;strong&gt;Service Not Reaching the Pod&lt;/strong&gt; 🌐
&lt;/h2&gt;

&lt;h3&gt;
  
  
  ❌ The Problem:
&lt;/h3&gt;

&lt;p&gt;A service isn’t routing traffic to the intended pod.&lt;/p&gt;

&lt;h3&gt;
  
  
  ✅ How to Fix It:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Make sure pod labels match the service selector&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Verify service endpoints&lt;/strong&gt;:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   kubectl get endpoints &amp;lt;service-name&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Test DNS resolution&lt;/strong&gt; from within a pod:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   kubectl &lt;span class="nb"&gt;exec&lt;/span&gt; &lt;span class="nt"&gt;-it&lt;/span&gt; &amp;lt;pod-name&amp;gt; &lt;span class="nt"&gt;--&lt;/span&gt; nslookup &amp;lt;service-name&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  &lt;strong&gt;Bonus: ConfigMaps and Secrets Not Referenced Correctly&lt;/strong&gt; 🔧
&lt;/h2&gt;

&lt;h3&gt;
  
  
  ❌ The Problem:
&lt;/h3&gt;

&lt;p&gt;Environment variables from ConfigMaps or Secrets aren’t getting injected into your pods.&lt;/p&gt;

&lt;h3&gt;
  
  
  ✅ How to Fix It:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Verify that the ConfigMap or Secret exists&lt;/strong&gt;:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   kubectl get configmap
   kubectl get secret
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Ensure your deployment YAML correctly references these objects&lt;/strong&gt;:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;   &lt;span class="na"&gt;envFrom&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
     &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;configMapRef&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;my-config&lt;/span&gt;
     &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;secretRef&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;my-secret&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Apply the changes and restart your deployment&lt;/strong&gt;:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   kubectl rollout restart deployment &amp;lt;deployment-name&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;Got more Kubernetes issues or tips to share? Drop your questions and comments below—we love hearing from you! 😄&lt;/p&gt;

</description>
      <category>devops</category>
      <category>sre</category>
      <category>kubernetes</category>
      <category>microservices</category>
    </item>
  </channel>
</rss>
