<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <id>https://menraromial.com/blog/</id>
    <title>Menra Romial</title>
    <updated>2025-12-04T00:00:00.000Z</updated>
    <generator>https://github.com/jpmonette/feed</generator>
    <link rel="alternate" href="https://menraromial.com/blog/"/>
    <subtitle>Menra Romial Blog</subtitle>
    <icon>https://menraromial.com/img/favicon.svg</icon>
    <rights>© 2026 Menra Romial</rights>
    <entry>
        <title type="html"><![CDATA[Volunteering at UCC & BDCAT 2025]]></title>
        <id>https://menraromial.com/blog/volunteering-ucc-bdcat-2025/</id>
        <link href="https://menraromial.com/blog/volunteering-ucc-bdcat-2025/"/>
        <updated>2025-12-04T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Four days as a student volunteer at the UCC and BDCAT 2025 conferences in Nantes: behind the scenes of an international academic event.]]></summary>
        <content type="html"><![CDATA[<p>From December 1st to 4th, I had the opportunity to volunteer at the 2025 editions of <strong><a href="https://ucc-conference.org/" target="_blank" rel="noopener noreferrer" class="">UCC</a></strong> (Utility and Cloud Computing) and <strong><a href="https://bdcat-conference.org/" target="_blank" rel="noopener noreferrer" class="">BDCAT</a></strong> (Big Data Computing, Applications and Technologies). Both conferences were hosted together this year, creating an inspiring environment filled with researchers, engineers, and students from around the world.</p>
<!-- -->
<p>Volunteering allowed me to be at the heart of the conference. I helped with attendee check-ins, session logistics, and general coordination throughout the venue. Being behind the scenes gave me a new perspective on how much work and dedication goes into running an international academic event - and it was exciting to contribute to it.</p>
<p>Between tasks, I had the chance to attend keynotes, speak with participants, and discover ongoing work in cloud-edge computing, distributed systems, and large-scale data processing. Discussions were rich, the atmosphere was collaborative, and I left every day with something new to think about.</p>
<p><strong>Highlights:</strong></p>
<ul>
<li class="">Meeting researchers and professionals from various countries</li>
<li class="">Discovering ongoing work in cloud, edge, AI, and big data</li>
<li class="">Helping the organization team ensure everything ran smoothly</li>
<li class="">Attending inspiring presentations and demos</li>
</ul>
<p>These four days were both intense and deeply rewarding. The experience strengthened my interest in distributed systems and data technologies, and it motivated me to stay involved in future academic communities and events.</p>
<blockquote>
<p>"We grow by learning from others, by contributing where we can, and by stepping into communities larger than ourselves."</p>
</blockquote>
<p>A memorable experience, and definitely not the last.</p>]]></content>
        <author>
            <name>Menra Romial</name>
            <uri>https://menraromial.com</uri>
        </author>
        <category label="conference" term="conference"/>
        <category label="community" term="community"/>
        <category label="cloud" term="cloud"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[A Comprehensive Guide to powercap-utils on Linux]]></title>
        <id>https://menraromial.com/blog/comprehensive-guide-powercap-utils-linux/</id>
        <link href="https://menraromial.com/blog/comprehensive-guide-powercap-utils-linux/"/>
        <updated>2025-10-23T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[A practical guide to powercap-utils on Linux: monitor and limit CPU and DRAM power through the kernel Power Capping Framework and Intel RAPL.]]></summary>
        <content type="html"><![CDATA[<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="1-introduction-what-is-powercap-utils">1. Introduction: What is <code>powercap-utils</code>?<a href="https://menraromial.com/blog/comprehensive-guide-powercap-utils-linux/#1-introduction-what-is-powercap-utils" class="hash-link" aria-label="Direct link to 1-introduction-what-is-powercap-utils" title="Direct link to 1-introduction-what-is-powercap-utils" translate="no">​</a></h3>
<p><code>powercap-utils</code> is a suite of user-space command-line tools for Linux that allow you to interact with the kernel's <strong>Power Capping Framework</strong>. This framework provides a standardized way to monitor and limit the power consumption of hardware devices.</p>
<!-- -->
<p>Its most common use is to control <strong>Intel's Running Average Power Limit (RAPL)</strong> and <strong>AMD's RAPL-like features</strong> on modern CPUs. These features let you directly set power budgets for the CPU package, its cores, and DRAM.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="2-prerequisites-and-installation">2. Prerequisites and Installation<a href="https://menraromial.com/blog/comprehensive-guide-powercap-utils-linux/#2-prerequisites-and-installation" class="hash-link" aria-label="Direct link to 2. Prerequisites and Installation" title="Direct link to 2. Prerequisites and Installation" translate="no">​</a></h3>
<h4 class="anchor anchorTargetStickyNavbar_Vzrq" id="prerequisites">Prerequisites<a href="https://menraromial.com/blog/comprehensive-guide-powercap-utils-linux/#prerequisites" class="hash-link" aria-label="Direct link to Prerequisites" title="Direct link to Prerequisites" translate="no">​</a></h4>
<ol>
<li class=""><strong>A Linux System:</strong> Any modern Linux distribution.</li>
<li class=""><strong>Supported Hardware:</strong>
<ul>
<li class="">Intel Sandy Bridge and newer processors.</li>
<li class="">Modern AMD Zen-based processors.</li>
</ul>
</li>
<li class=""><strong>Kernel Support:</strong> The <code>intel_rapl</code> (for Intel) or <code>amd_energy</code> (for AMD) kernel module must be loaded. This is typically automatic.</li>
</ol>
<h4 class="anchor anchorTargetStickyNavbar_Vzrq" id="installation">Installation<a href="https://menraromial.com/blog/comprehensive-guide-powercap-utils-linux/#installation" class="hash-link" aria-label="Direct link to Installation" title="Direct link to Installation" translate="no">​</a></h4>
<p>The package name is usually <code>powercap-utils</code>.</p>
<ul>
<li class="">
<p><strong>On Debian / Ubuntu:</strong></p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token function" style="color:#d73a49">sudo</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">apt</span><span class="token plain"> update</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token function" style="color:#d73a49">sudo</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">apt</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">install</span><span class="token plain"> powercap-utils</span><br></div></code></pre></div></div>
</li>
<li class="">
<p><strong>On Fedora / CentOS / RHEL:</strong></p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token function" style="color:#d73a49">sudo</span><span class="token plain"> dnf </span><span class="token function" style="color:#d73a49">install</span><span class="token plain"> powercap-utils</span><br></div></code></pre></div></div>
</li>
<li class="">
<p><strong>On Arch Linux:</strong></p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token function" style="color:#d73a49">sudo</span><span class="token plain"> pacman </span><span class="token parameter variable" style="color:#36acaa">-S</span><span class="token plain"> powercap-utils</span><br></div></code></pre></div></div>
</li>
</ul>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="3-core-concepts-of-the-power-capping-framework">3. Core Concepts of the Power Capping Framework<a href="https://menraromial.com/blog/comprehensive-guide-powercap-utils-linux/#3-core-concepts-of-the-power-capping-framework" class="hash-link" aria-label="Direct link to 3. Core Concepts of the Power Capping Framework" title="Direct link to 3. Core Concepts of the Power Capping Framework" translate="no">​</a></h3>
<p>The framework is organized as a hierarchy, which you navigate using the tools.</p>
<img decoding="async" loading="lazy" src="https://menraromial.com/img/posts/rapl_domains.png" alt="RAPL domains diagram showing package, core, uncore, and DRAM" style="max-width:100%;height:auto;display:block;margin:0 auto" class="img_ev3q">
<p><em>Figure - RAPL domains: package, core, uncore, and DRAM.</em></p>
<ul>
<li class=""><strong>Control Type:</strong> The top-level driver. This will be <code>intel-rapl</code> on Intel systems.</li>
<li class=""><strong>Zone:</strong> A device or a part of a device that can be power-managed. Common zones are:
<ul>
<li class=""><code>package-0</code> (or <code>0</code>): The entire CPU socket. This is the most important zone.</li>
<li class=""><code>core</code> (sub-zone): A group of CPU cores.</li>
<li class=""><code>uncore</code> (sub-zone): Components like the L3 cache and memory controller.</li>
<li class=""><code>dram</code> (sub-zone): The DRAM interface.</li>
</ul>
</li>
<li class=""><strong>Constraint:</strong> A specific power limiting rule within a zone.
<ul>
<li class=""><code>Constraint 0</code>: The <strong><code>long_term</code></strong> limit. This is the sustained power limit, similar to the CPU's TDP (Thermal Design Power).</li>
<li class=""><code>Constraint 1</code>: The <strong><code>short_term</code></strong> limit. This is a higher power limit that the CPU is allowed to use for a short burst of time.</li>
</ul>
</li>
<li class=""><strong>Parameters:</strong> Each constraint has settings you can read and write:
<ul>
<li class=""><code>power_limit_uw</code>: The power limit in <strong>microwatts (µW)</strong>.</li>
<li class=""><code>time_window_us</code>: The time period in <strong>microseconds (µs)</strong> over which the power limit is enforced.</li>
</ul>
</li>
</ul>
<blockquote>
<p><strong>⚠️ Critical Note on Units:</strong> The tools operate in micro-units. This is the most common source of error.</p>
<ul>
<li class="">To set a limit of <strong>50 Watts</strong>, you must use <code>50000000</code> microwatts.</li>
<li class="">To set a time window of <strong>1 second</strong>, you must use <code>1000000</code> microseconds.</li>
</ul>
</blockquote>
<hr>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="4-the-tools-powercap-info-and-powercap-set">4. The Tools: <code>powercap-info</code> and <code>powercap-set</code><a href="https://menraromial.com/blog/comprehensive-guide-powercap-utils-linux/#4-the-tools-powercap-info-and-powercap-set" class="hash-link" aria-label="Direct link to 4-the-tools-powercap-info-and-powercap-set" title="Direct link to 4-the-tools-powercap-info-and-powercap-set" translate="no">​</a></h3>
<h4 class="anchor anchorTargetStickyNavbar_Vzrq" id="part-1-exploring-with-powercap-info-read-only">Part 1: Exploring with <code>powercap-info</code> (Read-Only)<a href="https://menraromial.com/blog/comprehensive-guide-powercap-utils-linux/#part-1-exploring-with-powercap-info-read-only" class="hash-link" aria-label="Direct link to part-1-exploring-with-powercap-info-read-only" title="Direct link to part-1-exploring-with-powercap-info-read-only" translate="no">​</a></h4>
<p><code>powercap-info</code> is your tool for discovery. It's safe to use as it only reads information.</p>
<p><strong>1. List all power capping control types and their full hierarchy:</strong>
This is the most common command to get an overview of your system.</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">powercap-info</span><br></div></code></pre></div></div>
<p><em>Output (example from an Intel CPU):</em></p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">intel-rapl</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">└── package-0</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    ├── core</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    ├── uncore</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    └── dram</span><br></div></code></pre></div></div>
<p>This shows the control type is <code>intel-rapl</code> and the primary zone is <code>package-0</code>.</p>
<p><strong>2. Get detailed information for a specific zone:</strong>
Based on the <code>--help</code> output, the correct syntax is <code>powercap-info &lt;control-type-name&gt; -z &lt;zone-id&gt;</code>.</p>
<p>Let's inspect <code>package-0</code>, which corresponds to zone <code>0</code>.</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">powercap-info intel-rapl </span><span class="token parameter variable" style="color:#36acaa">-z</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">0</span><br></div></code></pre></div></div>
<p><em>Output (abbreviated):</em></p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">package-0:</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  enabled: 1</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  energy_uj: 1234567890</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  constraints:</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    0: long_term</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">      power_limit_uw: 65000000</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">      time_window_us: 28000000</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">      name: long_term</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    1: short_term</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">      power_limit_uw: 85000000</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">      time_window_us: 2441</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">      name: short_term</span><br></div></code></pre></div></div>
<p><strong>Explanation:</strong></p>
<ul>
<li class="">This package has a <code>long_term</code> limit (constraint <code>0</code>) of 65,000,000 µW (<strong>65 W</strong>).</li>
<li class="">It has a <code>short_term</code> limit (constraint <code>1</code>) of 85,000,000 µW (<strong>85 W</strong>).</li>
<li class=""><code>energy_uj</code> is the total energy consumed (in microjoules) since boot.</li>
</ul>
<p><strong>3. Get a single value:</strong>
The <code>--help</code> shows many flags to query specific values. For example, to get <em>only</em> the power limit for the <code>long_term</code> constraint:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic"># Syntax: powercap-info &lt;control-type&gt; -z &lt;zone&gt; -c &lt;constraint&gt; --c-power-limit</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">powercap-info intel-rapl </span><span class="token parameter variable" style="color:#36acaa">-z</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">0</span><span class="token plain"> </span><span class="token parameter variable" style="color:#36acaa">-c</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">0</span><span class="token plain"> </span><span class="token parameter variable" style="color:#36acaa">-l</span><br></div></code></pre></div></div>
<p><em>Output:</em></p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">65000000</span><br></div></code></pre></div></div>
<p>This is excellent for scripting, as it gives you a clean number to work with.</p>
<h4 class="anchor anchorTargetStickyNavbar_Vzrq" id="part-2-setting-limits-with-powercap-set-writemodify">Part 2: Setting Limits with <code>powercap-set</code> (Write/Modify)<a href="https://menraromial.com/blog/comprehensive-guide-powercap-utils-linux/#part-2-setting-limits-with-powercap-set-writemodify" class="hash-link" aria-label="Direct link to part-2-setting-limits-with-powercap-set-writemodify" title="Direct link to part-2-setting-limits-with-powercap-set-writemodify" translate="no">​</a></h4>
<p><code>powercap-set</code> is used to change the power settings. <strong>You will need <code>sudo</code> for this.</strong></p>
<p><strong>Syntax:</strong> <code>sudo powercap-set &lt;control-type-name&gt; [options]</code></p>
<p><strong>Key Options:</strong></p>
<ul>
<li class=""><code>-z, --zone=&lt;zone-id&gt;</code>: Specifies the zone to modify (e.g., <code>-z 0</code>).</li>
<li class=""><code>-c, --constraint=&lt;constraint-id&gt;</code>: Specifies the constraint (<code>0</code> for long_term, <code>1</code> for short_term).</li>
<li class=""><code>-l, --c-power-limit=&lt;uw&gt;</code>: Sets the power limit in <strong>microwatts</strong>.</li>
<li class=""><code>-s, --c-time-window=&lt;us&gt;</code>: Sets the time window in <strong>microseconds</strong>.</li>
<li class=""><code>-e, --z-enabled=1|0</code>: Enables (<code>1</code>) or disables (<code>0</code>) an entire zone.</li>
</ul>
<p><strong>Example Workflow: Limiting a CPU to 35 Watts</strong></p>
<p>Let's cap the entire CPU package (<code>package-0</code>, which is zone <code>0</code>) to a sustained 35 Watts.</p>
<p><strong>Step 1: Identify the current limits.</strong></p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">powercap-info intel-rapl </span><span class="token parameter variable" style="color:#36acaa">-z</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">0</span><span class="token plain"> </span><span class="token parameter variable" style="color:#36acaa">-c</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">0</span><br></div></code></pre></div></div>
<p>Let's assume the current limit is <code>65000000</code> (65W).</p>
<p><strong>Step 2: Set the new power limit.</strong>
We want to set a 35W limit for the <code>long_term</code> constraint (ID <code>0</code>).
35 Watts = <code>35000000</code> microwatts.</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token function" style="color:#d73a49">sudo</span><span class="token plain"> powercap-set intel-rapl </span><span class="token parameter variable" style="color:#36acaa">-z</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">0</span><span class="token plain"> </span><span class="token parameter variable" style="color:#36acaa">-c</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">0</span><span class="token plain"> </span><span class="token parameter variable" style="color:#36acaa">-l</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">35000000</span><br></div></code></pre></div></div>
<p><strong>Step 3: Verify the change.</strong></p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">powercap-info intel-rapl </span><span class="token parameter variable" style="color:#36acaa">-z</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">0</span><span class="token plain"> </span><span class="token parameter variable" style="color:#36acaa">-c</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">0</span><span class="token plain"> </span><span class="token parameter variable" style="color:#36acaa">-l</span><br></div></code></pre></div></div>
<p><em>New Output:</em></p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">35000000</span><br></div></code></pre></div></div>
<p>Success! The CPU's sustained power limit is now 35W.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="5-practical-example-setting-a-custom-boost-and-sustained-limit">5. Practical Example: Setting a Custom Boost and Sustained Limit<a href="https://menraromial.com/blog/comprehensive-guide-powercap-utils-linux/#5-practical-example-setting-a-custom-boost-and-sustained-limit" class="hash-link" aria-label="Direct link to 5. Practical Example: Setting a Custom Boost and Sustained Limit" title="Direct link to 5. Practical Example: Setting a Custom Boost and Sustained Limit" translate="no">​</a></h3>
<p><strong>Goal:</strong> Configure a CPU to run at a sustained 60W but allow it to boost to 90W for up to 15 seconds.</p>
<p><strong>1. Set the <code>long_term</code> (sustained) limit:</strong></p>
<ul>
<li class="">Constraint: <code>0</code></li>
<li class="">Power: 60W = <code>60000000</code> µW</li>
</ul>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token function" style="color:#d73a49">sudo</span><span class="token plain"> powercap-set intel-rapl </span><span class="token parameter variable" style="color:#36acaa">-z</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">0</span><span class="token plain"> </span><span class="token parameter variable" style="color:#36acaa">-c</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">0</span><span class="token plain"> </span><span class="token parameter variable" style="color:#36acaa">-l</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">60000000</span><br></div></code></pre></div></div>
<p><em>(The default time window for <code>long_term</code> is usually fine, so we don't need to set it.)</em></p>
<p><strong>2. Set the <code>short_term</code> (boost) limit:</strong></p>
<ul>
<li class="">Constraint: <code>1</code></li>
<li class="">Power: 90W = <code>90000000</code> µW</li>
<li class="">Time Window: 15 seconds = <code>15000000</code> µs</li>
</ul>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token function" style="color:#d73a49">sudo</span><span class="token plain"> powercap-set intel-rapl </span><span class="token parameter variable" style="color:#36acaa">-z</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">0</span><span class="token plain"> </span><span class="token parameter variable" style="color:#36acaa">-c</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">1</span><span class="token plain"> </span><span class="token parameter variable" style="color:#36acaa">-l</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">90000000</span><span class="token plain"> </span><span class="token parameter variable" style="color:#36acaa">-s</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">15000000</span><br></div></code></pre></div></div>
<p><strong>3. Verify all settings:</strong></p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">powercap-info intel-rapl </span><span class="token parameter variable" style="color:#36acaa">-z</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">0</span><br></div></code></pre></div></div>
<p>Check the output to confirm that both <code>constraint 0</code> and <code>constraint 1</code> now reflect your new values. The CPU will now adhere to this custom power profile.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="6-scripting-and-automation">6. Scripting and Automation<a href="https://menraromial.com/blog/comprehensive-guide-powercap-utils-linux/#6-scripting-and-automation" class="hash-link" aria-label="Direct link to 6. Scripting and Automation" title="Direct link to 6. Scripting and Automation" translate="no">​</a></h3>
<p>Because the tools can output clean numbers, they are perfect for scripts.</p>
<p><strong>Example: A script to toggle a "low power" mode (25W) and a "high power" mode (80W).</strong></p>
<p><strong><code>power-mode.sh</code></strong></p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token shebang important">#!/bin/bash</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic"># Check for root privileges</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain"> </span><span class="token environment constant" style="color:#36acaa">$EUID</span><span class="token plain"> </span><span class="token parameter variable" style="color:#36acaa">-ne</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">0</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">then</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">   </span><span class="token builtin class-name">echo</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"This script must be run as root"</span><span class="token plain"> </span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">   </span><span class="token builtin class-name">exit</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">1</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">fi</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token assign-left variable" style="color:#36acaa">MODE</span><span class="token operator" style="color:#393A34">=</span><span class="token variable" style="color:#36acaa">$1</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token assign-left variable" style="color:#36acaa">CONTROL_TYPE</span><span class="token operator" style="color:#393A34">=</span><span class="token string" style="color:#e3116c">"intel-rapl"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token assign-left variable" style="color:#36acaa">ZONE</span><span class="token operator" style="color:#393A34">=</span><span class="token string" style="color:#e3116c">"0"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token assign-left variable" style="color:#36acaa">CONSTRAINT</span><span class="token operator" style="color:#393A34">=</span><span class="token string" style="color:#e3116c">"0"</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic"># We will only change the long_term limit</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"</span><span class="token string variable" style="color:#36acaa">$MODE</span><span class="token string" style="color:#e3116c">"</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">==</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"low"</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">then</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token assign-left variable" style="color:#36acaa">POWER_LIMIT_UW</span><span class="token operator" style="color:#393A34">=</span><span class="token number" style="color:#36acaa">25000000</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic"># 25 Watts</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token builtin class-name">echo</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"Setting low power mode (25W)..."</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">elif</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"</span><span class="token string variable" style="color:#36acaa">$MODE</span><span class="token string" style="color:#e3116c">"</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">==</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"high"</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">then</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token assign-left variable" style="color:#36acaa">POWER_LIMIT_UW</span><span class="token operator" style="color:#393A34">=</span><span class="token number" style="color:#36acaa">80000000</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic"># 80 Watts</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token builtin class-name">echo</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"Setting high power mode (80W)..."</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">else</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token builtin class-name">echo</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"Usage: sudo </span><span class="token string variable" style="color:#36acaa">$0</span><span class="token string" style="color:#e3116c"> &lt;low|high&gt;"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token builtin class-name">exit</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">1</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">fi</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">powercap-set </span><span class="token string" style="color:#e3116c">"</span><span class="token string variable" style="color:#36acaa">$CONTROL_TYPE</span><span class="token string" style="color:#e3116c">"</span><span class="token plain"> </span><span class="token parameter variable" style="color:#36acaa">-z</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"</span><span class="token string variable" style="color:#36acaa">$ZONE</span><span class="token string" style="color:#e3116c">"</span><span class="token plain"> </span><span class="token parameter variable" style="color:#36acaa">-c</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"</span><span class="token string variable" style="color:#36acaa">$CONSTRAINT</span><span class="token string" style="color:#e3116c">"</span><span class="token plain"> </span><span class="token parameter variable" style="color:#36acaa">-l</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"</span><span class="token string variable" style="color:#36acaa">$POWER_LIMIT_UW</span><span class="token string" style="color:#e3116c">"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic"># Verify</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token assign-left variable" style="color:#36acaa">CURRENT_LIMIT</span><span class="token operator" style="color:#393A34">=</span><span class="token variable" style="color:#36acaa">$(</span><span class="token variable" style="color:#36acaa">powercap-info </span><span class="token variable string" style="color:#e3116c">"</span><span class="token variable string variable" style="color:#36acaa">$CONTROL_TYPE</span><span class="token variable string" style="color:#e3116c">"</span><span class="token variable" style="color:#36acaa"> </span><span class="token variable parameter variable" style="color:#36acaa">-z</span><span class="token variable" style="color:#36acaa"> </span><span class="token variable string" style="color:#e3116c">"</span><span class="token variable string variable" style="color:#36acaa">$ZONE</span><span class="token variable string" style="color:#e3116c">"</span><span class="token variable" style="color:#36acaa"> </span><span class="token variable parameter variable" style="color:#36acaa">-c</span><span class="token variable" style="color:#36acaa"> </span><span class="token variable string" style="color:#e3116c">"</span><span class="token variable string variable" style="color:#36acaa">$CONSTRAINT</span><span class="token variable string" style="color:#e3116c">"</span><span class="token variable" style="color:#36acaa"> </span><span class="token variable parameter variable" style="color:#36acaa">-l</span><span class="token variable" style="color:#36acaa">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token assign-left variable" style="color:#36acaa">CURRENT_LIMIT_W</span><span class="token operator" style="color:#393A34">=</span><span class="token variable" style="color:#36acaa">$((</span><span class="token variable" style="color:#36acaa">CURRENT_LIMIT </span><span class="token variable operator" style="color:#393A34">/</span><span class="token variable" style="color:#36acaa"> </span><span class="token variable number" style="color:#36acaa">1000000</span><span class="token variable" style="color:#36acaa">))</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token builtin class-name">echo</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"Successfully set power limit to </span><span class="token string variable" style="color:#36acaa">${CURRENT_LIMIT_W}</span><span class="token string" style="color:#e3116c">W."</span><br></div></code></pre></div></div>
<p><strong>How to use the script:</strong></p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token function" style="color:#d73a49">chmod</span><span class="token plain"> +x power-mode.sh</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic"># Set low power mode</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token function" style="color:#d73a49">sudo</span><span class="token plain"> ./power-mode.sh low</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic"># Set high power mode</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token function" style="color:#d73a49">sudo</span><span class="token plain"> ./power-mode.sh high</span><br></div></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="7-conclusion">7. Conclusion<a href="https://menraromial.com/blog/comprehensive-guide-powercap-utils-linux/#7-conclusion" class="hash-link" aria-label="Direct link to 7. Conclusion" title="Direct link to 7. Conclusion" translate="no">​</a></h3>
<p><code>powercap-utils</code> gives you precise, low-level control over your CPU's power consumption. By understanding the hierarchy of control types, zones, and constraints, you can effectively use these tools to manage thermals, optimize performance, and control energy usage.</p>
<p><strong>Key Takeaways:</strong></p>
<ul>
<li class="">Use <code>powercap-info</code> to explore the available zones and constraints on your system.</li>
<li class="">Use <code>sudo powercap-set</code> to apply limits, always remembering that units are in <strong>microwatts</strong> and <strong>microseconds</strong>.</li>
<li class="">The primary targets are usually <code>zone 0</code> (<code>package-0</code>), with <code>constraint 0</code> (<code>long_term</code>) for sustained limits and <code>constraint 1</code> (<code>short_term</code>) for boost behavior.</li>
<li class="">The single-value flags (like <code>-l</code> for <code>powercap-info</code>) are incredibly useful for scripting and verification.</li>
</ul>]]></content>
        <author>
            <name>Menra Romial</name>
            <uri>https://menraromial.com</uri>
        </author>
        <category label="linux" term="linux"/>
        <category label="powercap" term="powercap"/>
        <category label="rapl" term="rapl"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Building a Kubernetes Controller with Kubebuilder from Scratch]]></title>
        <id>https://menraromial.com/blog/building-a-kubernetes-controller-with-kubebuilder-from-scratch/</id>
        <link href="https://menraromial.com/blog/building-a-kubernetes-controller-with-kubebuilder-from-scratch/"/>
        <updated>2025-09-22T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Build a Kubernetes controller (Operator) with Kubebuilder: define a Website custom resource and reconcile it into a Deployment and a Service.]]></summary>
        <content type="html"><![CDATA[<p>In this tutorial, you will learn how to build a custom Kubernetes controller (also known as an Operator) using Kubebuilder. We will create a Custom Resource Definition (CRD) for a simple <code>Website</code> resource. The goal of our controller will be to watch for these <code>Website</code> resources and, for each one, create a corresponding Kubernetes <code>Deployment</code> and <code>Service</code>.</p>
<!-- -->
<p>This is a powerful pattern that allows you to extend the Kubernetes API to manage your own applications declaratively.</p>
<h4 class="anchor anchorTargetStickyNavbar_Vzrq" id="what-we-are-building"><strong>What We Are Building</strong><a href="https://menraromial.com/blog/building-a-kubernetes-controller-with-kubebuilder-from-scratch/#what-we-are-building" class="hash-link" aria-label="Direct link to what-we-are-building" title="Direct link to what-we-are-building" translate="no">​</a></h4>
<p>We will define a <code>Website</code> custom resource that looks like this:</p>
<div class="language-yaml codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-yaml codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic"># config/samples/website_v1alpha1_website.yaml</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token key atrule" style="color:#00a4db">apiVersion</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> website.my.domain/v1alpha1</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token key atrule" style="color:#00a4db">kind</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> Website</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token key atrule" style="color:#00a4db">metadata</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">name</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> my</span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain">first</span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain">website</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token key atrule" style="color:#00a4db">spec</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token comment" style="color:#999988;font-style:italic"># The git repository URL containing the website's static files</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">gitRepo</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"https://github.com/someuser/my-static-site.git"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token comment" style="color:#999988;font-style:italic"># The number of replicas for the web server</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">replicas</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">3</span><br></div></code></pre></div></div>
<p>Our controller will see this resource and automatically create:</p>
<ol>
<li class="">A <code>Deployment</code> to run an Nginx server with the specified number of <code>replicas</code>. We'll imagine it serves content from the <code>gitRepo</code>.</li>
<li class="">A <code>Service</code> of type <code>LoadBalancer</code> to expose the Nginx pods to the internet.</li>
</ol>
<hr>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="prerequisites"><strong>Prerequisites</strong><a href="https://menraromial.com/blog/building-a-kubernetes-controller-with-kubebuilder-from-scratch/#prerequisites" class="hash-link" aria-label="Direct link to prerequisites" title="Direct link to prerequisites" translate="no">​</a></h3>
<p>Before you begin, make sure you have the following tools installed:</p>
<ol>
<li class=""><strong>Go</strong> (version 1.19+): <a href="https://golang.org/dl/" target="_blank" rel="noopener noreferrer" class="">https://golang.org/dl/</a></li>
<li class=""><strong>Docker</strong>: To build container images.</li>
<li class=""><strong><code>kubectl</code></strong>: The Kubernetes command-line tool.</li>
<li class=""><strong>A Kubernetes Cluster</strong>: A local one like <a href="https://minikube.sigs.k8s.io/docs/start/" target="_blank" rel="noopener noreferrer" class="">Minikube</a> or <a href="https://kind.sigs.k8s.io/docs/user/quick-start/" target="_blank" rel="noopener noreferrer" class="">Kind</a> is perfect for development.</li>
<li class=""><strong>Kubebuilder</strong>: The scaffolding tool.
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic"># Install Kubebuilder</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token assign-left variable" style="color:#36acaa">os</span><span class="token operator" style="color:#393A34">=</span><span class="token variable" style="color:#36acaa">$(</span><span class="token variable" style="color:#36acaa">go </span><span class="token variable function" style="color:#d73a49">env</span><span class="token variable" style="color:#36acaa"> GOOS</span><span class="token variable" style="color:#36acaa">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token assign-left variable" style="color:#36acaa">arch</span><span class="token operator" style="color:#393A34">=</span><span class="token variable" style="color:#36acaa">$(</span><span class="token variable" style="color:#36acaa">go </span><span class="token variable function" style="color:#d73a49">env</span><span class="token variable" style="color:#36acaa"> GOARCH</span><span class="token variable" style="color:#36acaa">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token function" style="color:#d73a49">curl</span><span class="token plain"> </span><span class="token parameter variable" style="color:#36acaa">-L</span><span class="token plain"> </span><span class="token parameter variable" style="color:#36acaa">-o</span><span class="token plain"> kubebuilder </span><span class="token string" style="color:#e3116c">"https://go.kubebuilder.io/dl/latest/</span><span class="token string variable" style="color:#36acaa">${os}</span><span class="token string" style="color:#e3116c">/</span><span class="token string variable" style="color:#36acaa">${arch}</span><span class="token string" style="color:#e3116c">"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token function" style="color:#d73a49">sudo</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">mv</span><span class="token plain"> kubebuilder /usr/local/bin/</span><br></div></code></pre></div></div>
</li>
</ol>
<hr>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="step-1-initialize-your-project"><strong>Step 1: Initialize Your Project</strong><a href="https://menraromial.com/blog/building-a-kubernetes-controller-with-kubebuilder-from-scratch/#step-1-initialize-your-project" class="hash-link" aria-label="Direct link to step-1-initialize-your-project" title="Direct link to step-1-initialize-your-project" translate="no">​</a></h3>
<p>First, create a new directory for your project and initialize it with Kubebuilder.</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic"># Create and enter the project directory</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token function" style="color:#d73a49">mkdir</span><span class="token plain"> website-operator</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token builtin class-name">cd</span><span class="token plain"> website-operator</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic"># Initialize the project</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic"># --domain is used for the API group of your CRDs</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic"># --repo is your Go module path (e.g., github.com/your-user/website-operator)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">kubebuilder init </span><span class="token parameter variable" style="color:#36acaa">--domain</span><span class="token plain"> my.domain </span><span class="token parameter variable" style="color:#36acaa">--repo</span><span class="token plain"> github.com/your-user/website-operator</span><br></div></code></pre></div></div>
<p>This command scaffolds a complete project structure, including a <code>Makefile</code>, a <code>main.go</code> file, and a <code>Dockerfile</code>.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="step-2-create-the-api-crd-and-controller"><strong>Step 2: Create the API (CRD and Controller)</strong><a href="https://menraromial.com/blog/building-a-kubernetes-controller-with-kubebuilder-from-scratch/#step-2-create-the-api-crd-and-controller" class="hash-link" aria-label="Direct link to step-2-create-the-api-crd-and-controller" title="Direct link to step-2-create-the-api-crd-and-controller" translate="no">​</a></h3>
<p>Now, let's create the API for our <code>Website</code> resource. This single command will generate the CRD definition, the Go struct for our resource, and a skeleton for our controller.</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic"># Create the API. We'll create the resource and the controller.</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">kubebuilder create api </span><span class="token parameter variable" style="color:#36acaa">--group</span><span class="token plain"> website </span><span class="token parameter variable" style="color:#36acaa">--version</span><span class="token plain"> v1alpha1 </span><span class="token parameter variable" style="color:#36acaa">--kind</span><span class="token plain"> Website</span><br></div></code></pre></div></div>
<p>When prompted, answer <code>y</code> to create both the Resource and the Controller.</p>
<p>This command does several important things:</p>
<ul>
<li class=""><strong><code>api/v1alpha1/website_types.go</code></strong>: This file defines the Go structs that represent your <code>Website</code> resource. This is where you define your <code>Spec</code> (the desired state) and <code>Status</code> (the observed state).</li>
<li class=""><strong><code>controllers/website_controller.go</code></strong>: This is the skeleton for your controller's logic.</li>
<li class=""><strong><code>config/crd/bases/website.my.domain_websites.yaml</code></strong>: The YAML definition for your CRD.</li>
</ul>
<h4 class="anchor anchorTargetStickyNavbar_Vzrq" id="defining-the-spec-and-status"><strong>Defining the <code>Spec</code> and <code>Status</code></strong><a href="https://menraromial.com/blog/building-a-kubernetes-controller-with-kubebuilder-from-scratch/#defining-the-spec-and-status" class="hash-link" aria-label="Direct link to defining-the-spec-and-status" title="Direct link to defining-the-spec-and-status" translate="no">​</a></h4>
<p>Open <code>api/v1alpha1/website_types.go</code>. We need to define the fields for our resource.</p>
<p>Find the <code>WebsiteSpec</code> and <code>WebsiteStatus</code> structs and modify them as follows.</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic">// api/v1alpha1/website_types.go</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// ... (other imports)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// WebsiteSpec defines the desired state of Website</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">type</span><span class="token plain"> WebsiteSpec </span><span class="token keyword" style="color:#00009f">struct</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">	</span><span class="token comment" style="color:#999988;font-style:italic">// INSERT ADDITIONAL SPEC FIELDS - desired state of cluster</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">	</span><span class="token comment" style="color:#999988;font-style:italic">// Important: Run "make" to regenerate code after modifying this file</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">	</span><span class="token comment" style="color:#999988;font-style:italic">// GitRepo is the git repository URL for the website's content.</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">	</span><span class="token comment" style="color:#999988;font-style:italic">// +kubebuilder:validation:Required</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">	GitRepo </span><span class="token builtin">string</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">`json:"gitRepo"`</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">	</span><span class="token comment" style="color:#999988;font-style:italic">// Replicas is the number of desired pods. Defaults to 1.</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">	</span><span class="token comment" style="color:#999988;font-style:italic">// +kubebuilder:validation:Minimum=1</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">	</span><span class="token comment" style="color:#999988;font-style:italic">// +kubebuilder:default=1</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">	</span><span class="token comment" style="color:#999988;font-style:italic">// +optional</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">	Replicas </span><span class="token operator" style="color:#393A34">*</span><span class="token builtin">int32</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">`json:"replicas"`</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// WebsiteStatus defines the observed state of Website</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">type</span><span class="token plain"> WebsiteStatus </span><span class="token keyword" style="color:#00009f">struct</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">	</span><span class="token comment" style="color:#999988;font-style:italic">// INSERT ADDITIONAL STATUS FIELD - define observed state of cluster</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">	</span><span class="token comment" style="color:#999988;font-style:italic">// Important: Run "make" to regenerate code after modifying this file</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">	</span><span class="token comment" style="color:#999988;font-style:italic">// DeploymentStatus reflects the status of the created Deployment.</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">	</span><span class="token comment" style="color:#999988;font-style:italic">// +optional</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">	DeploymentStatus appsv1</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">DeploymentStatus </span><span class="token string" style="color:#e3116c">`json:"deploymentStatus,omitempty"`</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">	</span><span class="token comment" style="color:#999988;font-style:italic">// ServiceStatus reflects the status of the created Service.</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">	</span><span class="token comment" style="color:#999988;font-style:italic">// +optional</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">	ServiceStatus v1</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">ServiceStatus </span><span class="token string" style="color:#e3116c">`json:"serviceStatus,omitempty"`</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// ... (rest of the file)</span><br></div></code></pre></div></div>
<ul>
<li class=""><strong><code>WebsiteSpec</code></strong>: We added <code>GitRepo</code> (a required string) and <code>Replicas</code> (an optional integer with a minimum value of 1). The <code>//+kubebuilder</code> comments are "markers" that generate validation rules in the CRD.</li>
<li class=""><strong><code>WebsiteStatus</code></strong>: We will use this to report the status of the <code>Deployment</code> and <code>Service</code> we create. You'll need to add the <code>appsv1</code> and <code>v1</code> imports from <code>k8s.io/api</code>.</li>
</ul>
<p>After modifying the <code>_types.go</code> file, <strong>always run <code>make</code></strong> to regenerate the deepcopy functions and CRD manifests.</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token function" style="color:#d73a49">make</span><br></div></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="step-3-implement-the-controller-logic"><strong>Step 3: Implement the Controller Logic</strong><a href="https://menraromial.com/blog/building-a-kubernetes-controller-with-kubebuilder-from-scratch/#step-3-implement-the-controller-logic" class="hash-link" aria-label="Direct link to step-3-implement-the-controller-logic" title="Direct link to step-3-implement-the-controller-logic" translate="no">​</a></h3>
<p>This is the most important part. The controller's job is to read the state of a <code>Website</code> resource and take action to make the real world (the cluster state) match the desired state in the <code>Spec</code>.</p>
<p>Open <code>internal/controllers/website_controller.go</code>. The core logic goes inside the <code>Reconcile</code> function.</p>
<h4 class="anchor anchorTargetStickyNavbar_Vzrq" id="the-reconciliation-loop"><strong>The Reconciliation Loop</strong><a href="https://menraromial.com/blog/building-a-kubernetes-controller-with-kubebuilder-from-scratch/#the-reconciliation-loop" class="hash-link" aria-label="Direct link to the-reconciliation-loop" title="Direct link to the-reconciliation-loop" translate="no">​</a></h4>
<p>The <code>Reconcile</code> function is called every time a <code>Website</code> resource is created, updated, or deleted. Its goal is to reach a steady state. It's like a thermostat: it checks the temperature (current state) and turns the heating on or off (takes action) to reach the desired temperature (desired state).</p>
<p>Let's implement the logic.</p>
<ol>
<li class=""><strong>Get the <code>Website</code> resource</strong>: The request contains the name and namespace of the resource that triggered the reconciliation.</li>
<li class=""><strong>Check if Deployment exists</strong>: If not, create it.</li>
<li class=""><strong>If Deployment exists</strong>: Ensure its spec (e.g., number of replicas) matches the <code>Website</code> spec. If not, update it.</li>
<li class=""><strong>Check if Service exists</strong>: If not, create it.</li>
<li class=""><strong>Update Status</strong>: Report the current status back to the <code>Website</code> resource.</li>
</ol>
<h4 class="anchor anchorTargetStickyNavbar_Vzrq" id="updating-the-controller-code"><strong>Updating the Controller Code</strong><a href="https://menraromial.com/blog/building-a-kubernetes-controller-with-kubebuilder-from-scratch/#updating-the-controller-code" class="hash-link" aria-label="Direct link to updating-the-controller-code" title="Direct link to updating-the-controller-code" translate="no">​</a></h4>
<p>Replace the contents of <code>internal/controllers/website_controller.go</code> with the following code. Read the comments carefully to understand each step.</p>
<p>{% raw %}</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic">// internal/controllers/website_controller.go</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">package</span><span class="token plain"> controllers</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">	</span><span class="token string" style="color:#e3116c">"context"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">	</span><span class="token string" style="color:#e3116c">"reflect"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">	appsv1 </span><span class="token string" style="color:#e3116c">"k8s.ioio/api/apps/v1"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">	corev1 </span><span class="token string" style="color:#e3116c">"k8s.io/api/core/v1"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">	</span><span class="token string" style="color:#e3116c">"k8s.io/apimachinery/pkg/api/errors"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">	metav1 </span><span class="token string" style="color:#e3116c">"k8s.io/apimachinery/pkg/apis/meta/v1"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">	</span><span class="token string" style="color:#e3116c">"k8s.io/apimachinery/pkg/runtime"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">	</span><span class="token string" style="color:#e3116c">"k8s.io/apimachinery/pkg/types"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">	ctrl </span><span class="token string" style="color:#e3116c">"sigs.k8s.io/controller-runtime"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">	</span><span class="token string" style="color:#e3116c">"sigs.k8s.io/controller-runtime/pkg/client"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">	</span><span class="token string" style="color:#e3116c">"sigs.k8s.io/controller-runtime/pkg/log"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">	websitev1alpha1 </span><span class="token string" style="color:#e3116c">"github.com/your-user/website-operator/api/v1alpha1"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// WebsiteReconciler reconciles a Website object</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">type</span><span class="token plain"> WebsiteReconciler </span><span class="token keyword" style="color:#00009f">struct</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">	client</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Client</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">	Scheme </span><span class="token operator" style="color:#393A34">*</span><span class="token plain">runtime</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Scheme</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">//+kubebuilder:rbac:groups=website.my.domain,resources=websites,verbs=get;list;watch;create;update;patch;delete</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">//+kubebuilder:rbac:groups=website.my.domain,resources=websites/status,verbs=get;update;patch</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">//+kubebuilder:rbac:groups=website.my.domain,resources=websites/finalizers,verbs=update</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">//+kubebuilder:rbac:groups=apps,resources=deployments,verbs=get;list;watch;create;update;patch;delete</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">//+kubebuilder:rbac:groups=core,resources=services,verbs=get;list;watch;create;update;patch;delete</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">func</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">r </span><span class="token operator" style="color:#393A34">*</span><span class="token plain">WebsiteReconciler</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">Reconcile</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">ctx context</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Context</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> req ctrl</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Request</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">ctrl</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Result</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token builtin">error</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">	logger </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> log</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">FromContext</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">ctx</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">	</span><span class="token comment" style="color:#999988;font-style:italic">// 1. Fetch the Website instance</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">	website </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">&amp;</span><span class="token plain">websitev1alpha1</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Website</span><span class="token punctuation" style="color:#393A34">{</span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">	err </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> r</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Get</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">ctx</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> req</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">NamespacedName</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> website</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">	</span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> err </span><span class="token operator" style="color:#393A34">!=</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">nil</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">		</span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> errors</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">IsNotFound</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">err</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">			logger</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Info</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"Website resource not found. Ignoring since object must be deleted."</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">			</span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> ctrl</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Result</span><span class="token punctuation" style="color:#393A34">{</span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">nil</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">		</span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">		logger</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Error</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">err</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"Failed to get Website"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">		</span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> ctrl</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Result</span><span class="token punctuation" style="color:#393A34">{</span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> err</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">	</span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">	</span><span class="token comment" style="color:#999988;font-style:italic">// 2. Reconcile the Deployment</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">	deployment </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">&amp;</span><span class="token plain">appsv1</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Deployment</span><span class="token punctuation" style="color:#393A34">{</span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">	err </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> r</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Get</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">ctx</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> types</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">NamespacedName</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain">Name</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> website</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Name</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> Namespace</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> website</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Namespace</span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> deployment</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">	</span><span class="token comment" style="color:#999988;font-style:italic">// If the deployment does not exist, create it. Otherwise, update it.</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">	</span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> err </span><span class="token operator" style="color:#393A34">!=</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">nil</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">&amp;&amp;</span><span class="token plain"> errors</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">IsNotFound</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">err</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">		</span><span class="token comment" style="color:#999988;font-style:italic">// Define a new deployment</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">		dep </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> r</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">deploymentForWebsite</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">website</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">		logger</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Info</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"Creating a new Deployment"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"Deployment.Namespace"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> dep</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Namespace</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"Deployment.Name"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> dep</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Name</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">		err </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> r</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Create</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">ctx</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> dep</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">		</span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> err </span><span class="token operator" style="color:#393A34">!=</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">nil</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">			logger</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Error</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">err</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"Failed to create new Deployment"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"Deployment.Namespace"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> dep</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Namespace</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"Deployment.Name"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> dep</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Name</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">			</span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> ctrl</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Result</span><span class="token punctuation" style="color:#393A34">{</span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> err</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">		</span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">		</span><span class="token comment" style="color:#999988;font-style:italic">// Deployment created successfully - return and requeue</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">		</span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> ctrl</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Result</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain">Requeue</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">true</span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">nil</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">	</span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">else</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> err </span><span class="token operator" style="color:#393A34">!=</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">nil</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">		logger</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Error</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">err</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"Failed to get Deployment"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">		</span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> ctrl</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Result</span><span class="token punctuation" style="color:#393A34">{</span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> err</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">	</span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">	</span><span class="token comment" style="color:#999988;font-style:italic">// Ensure the deployment size is the same as the spec</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">	size </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> website</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Spec</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Replicas</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">	</span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">*</span><span class="token plain">deployment</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Spec</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Replicas </span><span class="token operator" style="color:#393A34">!=</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">*</span><span class="token plain">size </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">		deployment</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Spec</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Replicas </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> size</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">		err </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> r</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Update</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">ctx</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> deployment</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">		</span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> err </span><span class="token operator" style="color:#393A34">!=</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">nil</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">			logger</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Error</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">err</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"Failed to update Deployment"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"Deployment.Namespace"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> deployment</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Namespace</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"Deployment.Name"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> deployment</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Name</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">			</span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> ctrl</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Result</span><span class="token punctuation" style="color:#393A34">{</span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> err</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">		</span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">		</span><span class="token comment" style="color:#999988;font-style:italic">// Ask to requeue after 1 minute in order to give time for the</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">		</span><span class="token comment" style="color:#999988;font-style:italic">// pods be created</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">		</span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> ctrl</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Result</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain">RequeueAfter</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> time</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Minute</span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">nil</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">	</span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">	</span><span class="token comment" style="color:#999988;font-style:italic">// 3. Reconcile the Service</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">	service </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">&amp;</span><span class="token plain">corev1</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Service</span><span class="token punctuation" style="color:#393A34">{</span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">	err </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> r</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Get</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">ctx</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> types</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">NamespacedName</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain">Name</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> website</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Name</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> Namespace</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> website</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Namespace</span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> service</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">	</span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> err </span><span class="token operator" style="color:#393A34">!=</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">nil</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">&amp;&amp;</span><span class="token plain"> errors</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">IsNotFound</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">err</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">		</span><span class="token comment" style="color:#999988;font-style:italic">// Define a new service</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">		svc </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> r</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">serviceForWebsite</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">website</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">		logger</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Info</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"Creating a new Service"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"Service.Namespace"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> svc</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Namespace</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"Service.Name"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> svc</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Name</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">		err </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> r</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Create</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">ctx</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> svc</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">		</span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> err </span><span class="token operator" style="color:#393A34">!=</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">nil</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">			logger</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Error</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">err</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"Failed to create new Service"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"Service.Namespace"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> svc</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Namespace</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"Service.Name"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> svc</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Name</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">			</span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> ctrl</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Result</span><span class="token punctuation" style="color:#393A34">{</span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> err</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">		</span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">		</span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> ctrl</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Result</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain">Requeue</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">true</span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">nil</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">	</span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">else</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> err </span><span class="token operator" style="color:#393A34">!=</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">nil</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">		logger</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Error</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">err</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"Failed to get Service"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">		</span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> ctrl</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Result</span><span class="token punctuation" style="color:#393A34">{</span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> err</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">	</span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">	</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">	</span><span class="token comment" style="color:#999988;font-style:italic">// 4. Update the Website status</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">	</span><span class="token comment" style="color:#999988;font-style:italic">// We'll just reflect the deployment status for simplicity</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">	</span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">!</span><span class="token plain">reflect</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">DeepEqual</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">deployment</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Status</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> website</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Status</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">DeploymentStatus</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">		website</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Status</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">DeploymentStatus </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> deployment</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Status</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">		err </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> r</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Status</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Update</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">ctx</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> website</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">		</span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> err </span><span class="token operator" style="color:#393A34">!=</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">nil</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">			logger</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Error</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">err</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"Failed to update Website status"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">			</span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> ctrl</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Result</span><span class="token punctuation" style="color:#393A34">{</span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> err</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">		</span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">	</span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">	</span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> ctrl</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Result</span><span class="token punctuation" style="color:#393A34">{</span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">nil</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// deploymentForWebsite returns a Website Deployment object</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">func</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">r </span><span class="token operator" style="color:#393A34">*</span><span class="token plain">WebsiteReconciler</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">deploymentForWebsite</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">w </span><span class="token operator" style="color:#393A34">*</span><span class="token plain">websitev1alpha1</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Website</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">*</span><span class="token plain">appsv1</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Deployment </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">	labels </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">map</span><span class="token punctuation" style="color:#393A34">[</span><span class="token builtin">string</span><span class="token punctuation" style="color:#393A34">]</span><span class="token builtin">string</span><span class="token punctuation" style="color:#393A34">{</span><span class="token string" style="color:#e3116c">"app"</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> w</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Name</span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">	replicas </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> w</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Spec</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Replicas</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">	</span><span class="token comment" style="color:#999988;font-style:italic">// For a real-world controller, you would likely use an initContainer</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">	</span><span class="token comment" style="color:#999988;font-style:italic">// to clone the gitRepo into a volume. For this tutorial, we'll use</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">	</span><span class="token comment" style="color:#999988;font-style:italic">// a simple nginx image.</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">	dep </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">&amp;</span><span class="token plain">appsv1</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Deployment</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">		ObjectMeta</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> metav1</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">ObjectMeta</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">			Name</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain">      w</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Name</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">			Namespace</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> w</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Namespace</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">		</span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">		Spec</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> appsv1</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">DeploymentSpec</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">			Replicas</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> replicas</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">			Selector</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">&amp;</span><span class="token plain">metav1</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">LabelSelector</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">				MatchLabels</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> labels</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">			</span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">			Template</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> corev1</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">PodTemplateSpec</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">				ObjectMeta</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> metav1</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">ObjectMeta</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">					Labels</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> labels</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">				</span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">				Spec</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> corev1</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">PodSpec</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">					Containers</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain">corev1</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Container</span><span class="token punctuation" style="color:#393A34">{</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">						Image</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"nginx:1.14.2"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">						Name</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain">  </span><span class="token string" style="color:#e3116c">"web-server"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">						Ports</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain">corev1</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">ContainerPort</span><span class="token punctuation" style="color:#393A34">{</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">							ContainerPort</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">80</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">							Name</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain">          </span><span class="token string" style="color:#e3116c">"http"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">						</span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">					</span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">				</span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">			</span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">		</span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">	</span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">	</span><span class="token comment" style="color:#999988;font-style:italic">// Set Website instance as the owner and controller</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">	ctrl</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">SetControllerReference</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">w</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> dep</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> r</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Scheme</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">	</span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> dep</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// serviceForWebsite returns a Website Service object</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">func</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">r </span><span class="token operator" style="color:#393A34">*</span><span class="token plain">WebsiteReconciler</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">serviceForWebsite</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">w </span><span class="token operator" style="color:#393A34">*</span><span class="token plain">websitev1alpha1</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Website</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">*</span><span class="token plain">corev1</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Service </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">	labels </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">map</span><span class="token punctuation" style="color:#393A34">[</span><span class="token builtin">string</span><span class="token punctuation" style="color:#393A34">]</span><span class="token builtin">string</span><span class="token punctuation" style="color:#393A34">{</span><span class="token string" style="color:#e3116c">"app"</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> w</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Name</span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">	svc </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">&amp;</span><span class="token plain">corev1</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Service</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">		ObjectMeta</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> metav1</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">ObjectMeta</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">			Name</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain">      w</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Name</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">			Namespace</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> w</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Namespace</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">		</span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">		Spec</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> corev1</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">ServiceSpec</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">			Selector</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> labels</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">			Ports</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain">corev1</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">ServicePort</span><span class="token punctuation" style="color:#393A34">{</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">				Protocol</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain">   corev1</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">ProtocolTCP</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">				Port</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain">       </span><span class="token number" style="color:#36acaa">80</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">				TargetPort</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> intstr</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">FromString</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"http"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">			</span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">			Type</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> corev1</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">ServiceTypeLoadBalancer</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">		</span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">	</span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">	</span><span class="token comment" style="color:#999988;font-style:italic">// Set Website instance as the owner and controller</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">	ctrl</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">SetControllerReference</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">w</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> svc</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> r</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Scheme</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">	</span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> svc</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// SetupWithManager sets up the controller with the Manager.</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">func</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">r </span><span class="token operator" style="color:#393A34">*</span><span class="token plain">WebsiteReconciler</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">SetupWithManager</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">mgr ctrl</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Manager</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token builtin">error</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">	</span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> ctrl</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">NewControllerManagedBy</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">mgr</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">		</span><span class="token function" style="color:#d73a49">For</span><span class="token punctuation" style="color:#393A34">(</span><span class="token operator" style="color:#393A34">&amp;</span><span class="token plain">websitev1alpha1</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Website</span><span class="token punctuation" style="color:#393A34">{</span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">		</span><span class="token function" style="color:#d73a49">Owns</span><span class="token punctuation" style="color:#393A34">(</span><span class="token operator" style="color:#393A34">&amp;</span><span class="token plain">appsv1</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Deployment</span><span class="token punctuation" style="color:#393A34">{</span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">		</span><span class="token function" style="color:#d73a49">Owns</span><span class="token punctuation" style="color:#393A34">(</span><span class="token operator" style="color:#393A34">&amp;</span><span class="token plain">corev1</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Service</span><span class="token punctuation" style="color:#393A34">{</span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">		</span><span class="token function" style="color:#d73a49">Complete</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">r</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></div></code></pre></div></div>
<p>{% endraw %}</p>
<p><strong>Key changes and explanations:</strong></p>
<ul>
<li class=""><strong>RBAC Permissions (<code>//+kubebuilder:rbac</code>):</strong> We added permissions for the controller to manage <code>Deployments</code> and <code>Services</code>. After adding these, run <code>make manifests</code> to update the RBAC roles in <code>config/rbac/role.yaml</code>.</li>
<li class=""><strong><code>deploymentForWebsite</code> &amp; <code>serviceForWebsite</code>:</strong> These helper functions create the desired Deployment and Service objects.</li>
<li class=""><strong><code>ctrl.SetControllerReference</code></strong>: <strong>This is crucial.</strong> It sets the <code>Website</code> resource as the "owner" of the Deployment and Service. This means when you delete the <code>Website</code> resource, Kubernetes garbage collection will automatically delete the owned Deployment and Service.</li>
<li class=""><strong><code>SetupWithManager</code></strong>: We configured the controller to <code>Own</code> Deployments and Services. This tells the controller-runtime framework to trigger a reconciliation for a <code>Website</code> resource whenever its owned <code>Deployment</code> or <code>Service</code> is changed or deleted.</li>
</ul>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="step-4-run-and-test-the-controller"><strong>Step 4: Run and Test the Controller</strong><a href="https://menraromial.com/blog/building-a-kubernetes-controller-with-kubebuilder-from-scratch/#step-4-run-and-test-the-controller" class="hash-link" aria-label="Direct link to step-4-run-and-test-the-controller" title="Direct link to step-4-run-and-test-the-controller" translate="no">​</a></h3>
<p>Now for the exciting part! Let's run our controller and see it in action.</p>
<h4 class="anchor anchorTargetStickyNavbar_Vzrq" id="1-install-the-crd-into-the-cluster"><strong>1. Install the CRD into the Cluster</strong><a href="https://menraromial.com/blog/building-a-kubernetes-controller-with-kubebuilder-from-scratch/#1-install-the-crd-into-the-cluster" class="hash-link" aria-label="Direct link to 1-install-the-crd-into-the-cluster" title="Direct link to 1-install-the-crd-into-the-cluster" translate="no">​</a></h4>
<p>The cluster needs to know about the <code>Website</code> resource type.</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token function" style="color:#d73a49">make</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">install</span><br></div></code></pre></div></div>
<p>Verify that the CRD is installed:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">kubectl get crd websites.website.my.domain</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic"># NAME                          CREATED AT</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic"># websites.website.my.domain    2023-10-27T10:30:00Z</span><br></div></code></pre></div></div>
<h4 class="anchor anchorTargetStickyNavbar_Vzrq" id="2-run-the-controller-locally"><strong>2. Run the Controller Locally</strong><a href="https://menraromial.com/blog/building-a-kubernetes-controller-with-kubebuilder-from-scratch/#2-run-the-controller-locally" class="hash-link" aria-label="Direct link to 2-run-the-controller-locally" title="Direct link to 2-run-the-controller-locally" translate="no">​</a></h4>
<p>Running the controller on your local machine is fantastic for development and debugging. It will use your local kubeconfig to talk to the cluster.</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token function" style="color:#d73a49">make</span><span class="token plain"> run</span><br></div></code></pre></div></div>
<p>You will see logs from the controller manager starting up. It is now waiting for <code>Website</code> resources to be created.</p>
<h4 class="anchor anchorTargetStickyNavbar_Vzrq" id="3-create-a-website-resource"><strong>3. Create a <code>Website</code> Resource</strong><a href="https://menraromial.com/blog/building-a-kubernetes-controller-with-kubebuilder-from-scratch/#3-create-a-website-resource" class="hash-link" aria-label="Direct link to 3-create-a-website-resource" title="Direct link to 3-create-a-website-resource" translate="no">​</a></h4>
<p>In a <strong>new terminal</strong>, apply the sample <code>Website</code> resource. Kubebuilder has already created a sample for you in <code>config/samples/website_v1alpha1_website.yaml</code>. Let's modify it to match our <code>Spec</code>.</p>
<div class="language-yaml codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-yaml codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic"># config/samples/website_v1alpha1_website.yaml</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token key atrule" style="color:#00a4db">apiVersion</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> website.my.domain/v1alpha1</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token key atrule" style="color:#00a4db">kind</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> Website</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token key atrule" style="color:#00a4db">metadata</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">labels</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token key atrule" style="color:#00a4db">app.kubernetes.io/name</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> website</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token key atrule" style="color:#00a4db">app.kubernetes.io/instance</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> website</span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain">sample</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token key atrule" style="color:#00a4db">app.kubernetes.io/part-of</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> website</span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain">operator</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token key atrule" style="color:#00a4db">app.kubernetes.io/managed-by</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> kustomize</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token key atrule" style="color:#00a4db">app.kubernetes.io/created-by</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> website</span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain">operator</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">name</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> website</span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain">sample</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token key atrule" style="color:#00a4db">spec</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">gitRepo</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"https://github.com/my-user/my-repo.git"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">replicas</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">2</span><br></div></code></pre></div></div>
<p>Apply it:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">kubectl apply </span><span class="token parameter variable" style="color:#36acaa">-f</span><span class="token plain"> config/samples/website_v1alpha1_website.yaml</span><br></div></code></pre></div></div>
<h4 class="anchor anchorTargetStickyNavbar_Vzrq" id="4-observe-the-results"><strong>4. Observe the Results</strong><a href="https://menraromial.com/blog/building-a-kubernetes-controller-with-kubebuilder-from-scratch/#4-observe-the-results" class="hash-link" aria-label="Direct link to 4-observe-the-results" title="Direct link to 4-observe-the-results" translate="no">​</a></h4>
<p>Look at the logs from your <code>make run</code> terminal. You should see the controller creating the Deployment and Service.</p>
<p>Now, check the resources in your cluster:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic"># Check our custom resource</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">kubectl get website</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic"># NAME             AGE</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic"># website-sample   15s</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic"># Check the Deployment created by our controller</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">kubectl get deployment website-sample</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic"># NAME             READY   UP-TO-DATE   AVAILABLE   AGE</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic"># website-sample   2/2     2            2           12s</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic"># Check the Service created by our controller</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">kubectl get </span><span class="token function" style="color:#d73a49">service</span><span class="token plain"> website-sample</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic"># NAME             TYPE           CLUSTER-IP     EXTERNAL-IP   PORT(S)        AGE</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic"># website-sample   LoadBalancer   10.10.10.10    &lt;pending&gt;     80:31234/TCP   10s</span><br></div></code></pre></div></div>
<p>Success! Our controller saw the <code>Website</code> resource and created the corresponding Deployment and Service.</p>
<p>Now, try changing the number of replicas in the YAML file to <code>3</code> and <code>kubectl apply</code> it again. You will see the controller update the Deployment to match.</p>
<h4 class="anchor anchorTargetStickyNavbar_Vzrq" id="5-cleanup"><strong>5. Cleanup</strong><a href="https://menraromial.com/blog/building-a-kubernetes-controller-with-kubebuilder-from-scratch/#5-cleanup" class="hash-link" aria-label="Direct link to 5-cleanup" title="Direct link to 5-cleanup" translate="no">​</a></h4>
<p>Delete the <code>Website</code> resource. Because we set the Owner Reference, the Deployment and Service will be automatically deleted too.</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">kubectl delete </span><span class="token parameter variable" style="color:#36acaa">-f</span><span class="token plain"> config/samples/website_v1alpha1_website.yaml</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic"># Verify they are gone</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">kubectl get deployment,service</span><br></div></code></pre></div></div>
<hr>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="step-5-build-and-deploy-to-the-cluster"><strong>Step 5: Build and Deploy to the Cluster</strong><a href="https://menraromial.com/blog/building-a-kubernetes-controller-with-kubebuilder-from-scratch/#step-5-build-and-deploy-to-the-cluster" class="hash-link" aria-label="Direct link to step-5-build-and-deploy-to-the-cluster" title="Direct link to step-5-build-and-deploy-to-the-cluster" translate="no">​</a></h3>
<p>Running locally is great for development, but for production, you need to run the controller as a <code>Deployment</code> inside the cluster.</p>
<ol>
<li class="">
<p><strong>Build and Push the Docker Image</strong>:
(Replace <code>your-dockerhub-username</code> with your actual username)</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token function" style="color:#d73a49">make</span><span class="token plain"> docker-build </span><span class="token assign-left variable" style="color:#36acaa">IMG</span><span class="token operator" style="color:#393A34">=</span><span class="token plain">your-dockerhub-username/website-operator:v0.0.1</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token function" style="color:#d73a49">make</span><span class="token plain"> docker-push </span><span class="token assign-left variable" style="color:#36acaa">IMG</span><span class="token operator" style="color:#393A34">=</span><span class="token plain">your-dockerhub-username/website-operator:v0.0.1</span><br></div></code></pre></div></div>
</li>
<li class="">
<p><strong>Deploy the Controller to the Cluster</strong>:
This command will use the manifests in the <code>config</code> directory to create the <code>Deployment</code>, <code>RBAC</code> roles, and everything else needed to run the controller.</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token function" style="color:#d73a49">make</span><span class="token plain"> deploy </span><span class="token assign-left variable" style="color:#36acaa">IMG</span><span class="token operator" style="color:#393A34">=</span><span class="token plain">your-dockerhub-username/website-operator:v0.0.1</span><br></div></code></pre></div></div>
</li>
</ol>
<p>Your controller is now running inside the cluster, just like any other application. It will continue to watch for <code>Website</code> resources and reconcile them.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="conclusion-and-next-steps"><strong>Conclusion and Next Steps</strong><a href="https://menraromial.com/blog/building-a-kubernetes-controller-with-kubebuilder-from-scratch/#conclusion-and-next-steps" class="hash-link" aria-label="Direct link to conclusion-and-next-steps" title="Direct link to conclusion-and-next-steps" translate="no">​</a></h3>
<p>Congratulations! You have successfully built a fully functional Kubernetes controller. You learned how to:</p>
<ul>
<li class="">Scaffold a project with Kubebuilder.</li>
<li class="">Define a Custom Resource Definition (<code>CRD</code>).</li>
<li class="">Implement the reconciliation logic in a controller.</li>
<li class="">Set owner references for garbage collection.</li>
<li class="">Run, test, and deploy your controller.</li>
</ul>
<p>From here, you can explore more advanced topics:</p>
<ul>
<li class=""><strong>Finalizers</strong>: To perform cleanup actions before a resource is deleted.</li>
<li class=""><strong>Webhooks</strong>: To validate or mutate your custom resources on creation/update.</li>
<li class=""><strong>More Complex Status Updates</strong>: Provide richer status information about the resources your controller manages.</li>
<li class=""><strong>Testing</strong>: Write unit and integration tests for your controller logic.</li>
</ul>]]></content>
        <author>
            <name>Menra Romial</name>
            <uri>https://menraromial.com</uri>
        </author>
        <category label="kubernetes" term="kubernetes"/>
        <category label="controller" term="controller"/>
        <category label="kubebuilder" term="kubebuilder"/>
        <category label="crd" term="crd"/>
        <category label="opensource" term="opensource"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Guide to Building a Custom Kubernetes Scheduler]]></title>
        <id>https://menraromial.com/blog/guide-building-custom-kubernetes-scheduler/</id>
        <link href="https://menraromial.com/blog/guide-building-custom-kubernetes-scheduler/"/>
        <updated>2025-08-24T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[A step-by-step guide to writing a Kubernetes scheduler plugin with the Scheduling Framework, from concept to a working deployment on a kubeadm cluster.]]></summary>
        <content type="html"><![CDATA[<p>This guide will walk you through creating a custom scheduler plugin that influences where pods are placed based on custom logic. We will build a simple "Network-Aware" plugin that prefers to schedule pods on nodes with a specific network label.</p>
<!-- -->
<p><strong>What We Will Build:</strong></p>
<ul>
<li class=""><strong>A <code>Filter</code> plugin:</strong> It will only allow pods that request <code>high-speed</code> networking to be scheduled on nodes that are labeled as <code>network-topology=high-speed</code>.</li>
<li class=""><strong>A <code>Score</code> plugin:</strong> It will give a higher score to nodes with the <code>high-speed</code> label, making them more desirable.</li>
<li class="">We will then package this plugin into a new scheduler binary, containerize it, and deploy it to a local Kubernetes cluster.</li>
</ul>
<hr>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="part-1-understanding-the-foundations---the-scheduling-framework"><strong>Part 1: Understanding the Foundations - The Scheduling Framework</strong><a href="https://menraromial.com/blog/guide-building-custom-kubernetes-scheduler/#part-1-understanding-the-foundations---the-scheduling-framework" class="hash-link" aria-label="Direct link to part-1-understanding-the-foundations---the-scheduling-framework" title="Direct link to part-1-understanding-the-foundations---the-scheduling-framework" translate="no">​</a></h3>
<p>Before writing any code, it's crucial to understand the "why" and "how".</p>
<h4 class="anchor anchorTargetStickyNavbar_Vzrq" id="what-is-the-kubernetes-scheduler">What is the Kubernetes Scheduler?<a href="https://menraromial.com/blog/guide-building-custom-kubernetes-scheduler/#what-is-the-kubernetes-scheduler" class="hash-link" aria-label="Direct link to What is the Kubernetes Scheduler?" title="Direct link to What is the Kubernetes Scheduler?" translate="no">​</a></h4>
<p>The default Kubernetes scheduler (<code>kube-scheduler</code>) is a control plane component that watches for newly created Pods that have no <code>nodeName</code> assigned. For every Pod it discovers, the scheduler becomes responsible for finding the best Node for that Pod to run on. This process involves two main phases:</p>
<ol>
<li class=""><strong>Filtering (Predicates):</strong> The scheduler finds the set of feasible Nodes where the Pod <em>can</em> run. For example, if a Pod requests 2 CPUs, all nodes with less than 2 available CPUs are filtered out.</li>
<li class=""><strong>Scoring (Priorities):</strong> From the list of feasible nodes, the scheduler ranks each node by assigning it a score. It then picks the node with the highest score. For example, it might prefer a node that has fewer running pods.</li>
</ol>
<h4 class="anchor anchorTargetStickyNavbar_Vzrq" id="the-scheduling-framework-your-entry-point">The Scheduling Framework: Your Entry Point<a href="https://menraromial.com/blog/guide-building-custom-kubernetes-scheduler/#the-scheduling-framework-your-entry-point" class="hash-link" aria-label="Direct link to The Scheduling Framework: Your Entry Point" title="Direct link to The Scheduling Framework: Your Entry Point" translate="no">​</a></h4>
<p>The Scheduling Framework is a pluggable architecture for the <code>kube-scheduler</code> that makes it easy to add custom logic without forking the entire Kubernetes codebase. It exposes a set of <strong>Extension Points</strong> in the scheduling lifecycle where your custom code (a <strong>Plugin</strong>) can be executed.</p>
<p><strong>Visualizing the Extension Points:</strong></p>
<p>Here is the flow of the scheduling process and where the main extension points fit in.</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">                  (A Pod is created without a node)</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">                                  |</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">                                  v</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">+-------------------------------------------------------------------------+</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">|                        SCHEDULING CYCLE (for one Pod)                     |</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">+-------------------------------------------------------------------------+</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">                                  |</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">                                  v</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">[ QueueSort ] &lt;--- Your plugin can sort pods in the scheduling queue.</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">                                  |</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">                                  v</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">+-------------------------------------------------------------------------+</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">|                      SCHEDULING ATTEMPT (for one Pod)                     |</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">+-------------------------------------------------------------------------+</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">|                                 |                                       |</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">|                                 v                                       |</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">| [ PreFilter ] &lt;--- Pre-process info about the Pod before filtering.     |</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">|                                 |                                       |</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">|          --------------------- FOR EACH NODE ----------------------     |</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">|          |                                                        |     |</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">|          |    [ Filter ] &lt;--- Can this Pod run on this Node? (Yes/No) |   |</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">|          |          (If No, Node is discarded for this Pod)        |     |</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">|          |                                                        |     |</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">|          ----------------------------------------------------------     |</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">|                                 |                                       |</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">|                                 v                                       |</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">| [ PostFilter ] &lt;- If no nodes are viable, your plugin can take action.  |</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">|                                 |                                       |</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">|                                 v                                       |</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">| [ PreScore ] &lt;--- Pre-process info before scoring viable nodes.         |</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">|                                 |                                       |</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">|          --------------------- FOR EACH VIABLE NODE ---------------     |</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">|          |                                                        |     |</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">|          |    [ Score ] &lt;--- Give this Node a score (e.g., 0-100).  |   |</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">|          |                                                        |     |</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">|          ----------------------------------------------------------     |</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">|                                 |                                       |</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">|                                 v                                       |</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">| [ NormalizeScore ] &lt;- Modify all scores to fit a common scale.          |</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">|                                 |                                       |</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">|                                 v                                       |</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">|                          (Scheduler picks Node with highest score)        |</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">|                                 |                                       |</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">|                                 v                                       |</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">+-------------------------------------------------------------------------+</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">|                           BINDING CYCLE                                 |</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">+-------------------------------------------------------------------------+</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">|                                 |                                       |</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">|                                 v                                       |</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">| [ Reserve ] &lt;--- Mark resources as "reserved" on the chosen node.       |</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">|                                 |                                       |</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">|                                 v                                       |</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">| [ Permit ] &lt;--- Approve or deny the binding. Can delay binding.         |</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">|                                 |                                       |</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">|                                 v                                       |</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">| [ PreBind ] &lt;--- Actions to take right before the Pod is bound.         |</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">|                                 |                                       |</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">|                                 v                                       |</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">| [ Bind ] &lt;--- The actual binding of the Pod to the Node.                |</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">|                                 |                                       |</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">|                                 v                                       |</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">| [ PostBind ] &lt;--- Actions to take after the binding is successful.      |</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">|                                 |                                       |</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">+-------------------------------------------------------------------------+</span><br></div></code></pre></div></div>
<p>Our plugin will focus on the <strong><code>Filter</code></strong> and <strong><code>Score</code></strong> extension points.</p>
<hr>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="part-2-setting-up-the-professional-development-environment"><strong>Part 2: Setting Up the Professional Development Environment</strong><a href="https://menraromial.com/blog/guide-building-custom-kubernetes-scheduler/#part-2-setting-up-the-professional-development-environment" class="hash-link" aria-label="Direct link to part-2-setting-up-the-professional-development-environment" title="Direct link to part-2-setting-up-the-professional-development-environment" translate="no">​</a></h3>
<p>This is where we align with the project's standards.</p>
<h4 class="anchor anchorTargetStickyNavbar_Vzrq" id="prerequisites">Prerequisites:<a href="https://menraromial.com/blog/guide-building-custom-kubernetes-scheduler/#prerequisites" class="hash-link" aria-label="Direct link to Prerequisites:" title="Direct link to Prerequisites:" translate="no">​</a></h4>
<ol>
<li class=""><strong>Go:</strong> Version 1.19+ (the <code>scheduler-plugins</code> project specifies its version in the <code>go.mod</code> file).</li>
<li class=""><strong>Docker:</strong> To build container images. Make sure the Docker daemon is running.</li>
<li class=""><strong>kubectl:</strong> The Kubernetes command-line tool.</li>
<li class=""><strong><code>kind</code></strong>: Our local Kubernetes cluster.</li>
</ol>
<h4 class="anchor anchorTargetStickyNavbar_Vzrq" id="step-1-clone-the-scheduler-plugins-repository">Step 1: Clone the <code>scheduler-plugins</code> Repository<a href="https://menraromial.com/blog/guide-building-custom-kubernetes-scheduler/#step-1-clone-the-scheduler-plugins-repository" class="hash-link" aria-label="Direct link to step-1-clone-the-scheduler-plugins-repository" title="Direct link to step-1-clone-the-scheduler-plugins-repository" translate="no">​</a></h4>
<p>We will use the official repository not just as a template, but as our direct development environment. This is the standard practice.</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token function" style="color:#d73a49">git</span><span class="token plain"> clone https://github.com/kubernetes-sigs/scheduler-plugins.git</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token builtin class-name">cd</span><span class="token plain"> scheduler-plugins</span><br></div></code></pre></div></div>
<h4 class="anchor anchorTargetStickyNavbar_Vzrq" id="step-2-explore-the-makefile">Step 2: Explore the <code>Makefile</code><a href="https://menraromial.com/blog/guide-building-custom-kubernetes-scheduler/#step-2-explore-the-makefile" class="hash-link" aria-label="Direct link to step-2-explore-the-makefile" title="Direct link to step-2-explore-the-makefile" translate="no">​</a></h4>
<p>The <code>Makefile</code> in this repository is the heart of the development workflow. Instead of running raw <code>go</code> or <code>docker</code> commands, we will use <code>make</code> targets. This ensures consistency and correctness.</p>
<p>Key targets we will use:</p>
<ul>
<li class=""><code>make verify</code>: Runs formatters and linters to ensure code quality. <strong>Always run this before committing.</strong></li>
<li class=""><code>make unit-test</code>: Runs all unit tests in the repository.</li>
<li class=""><code>make local-image</code>: <strong>This is crucial.</strong> It builds a scheduler container image for your local architecture, gives it a standard local name (<code>localhost:5000/...</code>), and loads it directly into your local Docker daemon. Perfect for testing with <code>kind</code>.</li>
<li class=""><code>make build</code>: Compiles the Go binaries (<code>kube-scheduler</code> and <code>controller</code>) into the <code>/bin</code> directory.</li>
</ul>
<hr>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="part-3-developing-our-custom-plugin"><strong>Part 3: Developing Our Custom Plugin</strong><a href="https://menraromial.com/blog/guide-building-custom-kubernetes-scheduler/#part-3-developing-our-custom-plugin" class="hash-link" aria-label="Direct link to part-3-developing-our-custom-plugin" title="Direct link to part-3-developing-our-custom-plugin" translate="no">​</a></h3>
<p>The core logic remains the same, but the process around it will be more rigorous.</p>
<h4 class="anchor anchorTargetStickyNavbar_Vzrq" id="step-1-create-the-plugin-directory-and-file">Step 1: Create the Plugin Directory and File<a href="https://menraromial.com/blog/guide-building-custom-kubernetes-scheduler/#step-1-create-the-plugin-directory-and-file" class="hash-link" aria-label="Direct link to Step 1: Create the Plugin Directory and File" title="Direct link to Step 1: Create the Plugin Directory and File" translate="no">​</a></h4>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token function" style="color:#d73a49">mkdir</span><span class="token plain"> </span><span class="token parameter variable" style="color:#36acaa">-p</span><span class="token plain"> pkg/networkspeed</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token function" style="color:#d73a49">touch</span><span class="token plain"> pkg/networkspeed/networkspeed.go</span><br></div></code></pre></div></div>
<h4 class="anchor anchorTargetStickyNavbar_Vzrq" id="step-2-write-the-plugin-code">Step 2: Write the Plugin Code<a href="https://menraromial.com/blog/guide-building-custom-kubernetes-scheduler/#step-2-write-the-plugin-code" class="hash-link" aria-label="Direct link to Step 2: Write the Plugin Code" title="Direct link to Step 2: Write the Plugin Code" translate="no">​</a></h4>
<p>Place the same Go code from the previous guide into <code>pkg/networkspeed/networkspeed.go</code>. This code implements the <code>Filter</code> and <code>Score</code> extension points.</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic">// pkg/networkspeed/networkspeed.go</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">package</span><span class="token plain"> networkspeed</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">	</span><span class="token string" style="color:#e3116c">"context"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">	</span><span class="token string" style="color:#e3116c">"fmt"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">	v1 </span><span class="token string" style="color:#e3116c">"k8s.io/api/core/v1"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">	</span><span class="token string" style="color:#e3116c">"k8s.io/apimachinery/pkg/runtime"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">	</span><span class="token string" style="color:#e3116c">"k8s.io/klog/v2"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">	</span><span class="token string" style="color:#e3116c">"k8s.io/kubernetes/pkg/scheduler/framework"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// Define plugin name</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> Name </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"Networkspeed"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">	</span><span class="token comment" style="color:#999988;font-style:italic">// Annotation key on a Pod to specify network preference.</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">	PodNetworkAnnotation </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"my-network-preference"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">	</span><span class="token comment" style="color:#999988;font-style:italic">// Label key on a Node to specify the type of network it has.</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">	NodeNetworkLabel </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"network-topology"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">	</span><span class="token comment" style="color:#999988;font-style:italic">// Value for high-speed network preference.</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">	HighSpeedNetwork </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"high-speed"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// Networkspeed is a plugin that filters and scores nodes based on network labels.</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">type</span><span class="token plain"> Networkspeed </span><span class="token keyword" style="color:#00009f">struct</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">	handle framework</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Handle</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// Ensure our plugin implements the necessary interfaces.</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">var</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">_</span><span class="token plain"> framework</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">FilterPlugin </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">&amp;</span><span class="token plain">Networkspeed</span><span class="token punctuation" style="color:#393A34">{</span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">var</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">_</span><span class="token plain"> framework</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">ScorePlugin </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">&amp;</span><span class="token plain">Networkspeed</span><span class="token punctuation" style="color:#393A34">{</span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// Name returns the name of the plugin.</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">func</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">na </span><span class="token operator" style="color:#393A34">*</span><span class="token plain">Networkspeed</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">Name</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token builtin">string</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">	</span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> Name</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// New is the factory function that creates a new instance of the plugin.</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// This is called by the scheduler framework when it initializes.</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">func</span><span class="token plain">  </span><span class="token function" style="color:#d73a49">New</span><span class="token punctuation" style="color:#393A34">(</span><span class="token boolean" style="color:#36acaa">_</span><span class="token plain"> context</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Context</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> obj runtime</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Object</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> handle framework</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Handle</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">framework</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Plugin</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token builtin">error</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">	klog</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">V</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">3</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Infof</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"Creating new Networkspeed plugin"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">	</span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">&amp;</span><span class="token plain">Networkspeed</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">		handle</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> handle</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">	</span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">nil</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// ----------------- FILTERING LOGIC -----------------</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// Filter is called by the framework for each node to see if the pod can be scheduled on it.</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">func</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">na </span><span class="token operator" style="color:#393A34">*</span><span class="token plain">Networkspeed</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">Filter</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">ctx context</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Context</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> state </span><span class="token operator" style="color:#393A34">*</span><span class="token plain">framework</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">CycleState</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> pod </span><span class="token operator" style="color:#393A34">*</span><span class="token plain">v1</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Pod</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> nodeInfo </span><span class="token operator" style="color:#393A34">*</span><span class="token plain">framework</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">NodeInfo</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">*</span><span class="token plain">framework</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Status </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">	klog</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">V</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">3</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Infof</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"Filtering pod %v for node %v"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> pod</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Name</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> nodeInfo</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Node</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Name</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">	</span><span class="token comment" style="color:#999988;font-style:italic">// 1. Get the pod's network preference from its annotations.</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">	podNetworkPreference</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> ok </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> pod</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Annotations</span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain">PodNetworkAnnotation</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">	</span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">!</span><span class="token plain">ok </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">		</span><span class="token comment" style="color:#999988;font-style:italic">// If the pod doesn't have the annotation, it has no special network needs.</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">		</span><span class="token comment" style="color:#999988;font-style:italic">// So, it can run on any node. We allow it.</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">		</span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> framework</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">NewStatus</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">framework</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Success</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">""</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">	</span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">	</span><span class="token comment" style="color:#999988;font-style:italic">// 2. If the pod requests a high-speed network...</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">	</span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> podNetworkPreference </span><span class="token operator" style="color:#393A34">==</span><span class="token plain"> HighSpeedNetwork </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">		</span><span class="token comment" style="color:#999988;font-style:italic">// ...check if the node has the required label.</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">		nodeLabels </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> nodeInfo</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Node</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">GetLabels</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">		nodeNetworkType</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> labelExists </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> nodeLabels</span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain">NodeNetworkLabel</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">		</span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> labelExists </span><span class="token operator" style="color:#393A34">&amp;&amp;</span><span class="token plain"> nodeNetworkType </span><span class="token operator" style="color:#393A34">==</span><span class="token plain"> HighSpeedNetwork </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">			</span><span class="token comment" style="color:#999988;font-style:italic">// The node has the required label. The pod can run here.</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">			klog</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">V</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">3</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Infof</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"Node %v has the required '%s' label. Allowing pod %v."</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> nodeInfo</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Node</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Name</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> HighSpeedNetwork</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> pod</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Name</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">			</span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> framework</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">NewStatus</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">framework</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Success</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">""</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">		</span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">else</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">			</span><span class="token comment" style="color:#999988;font-style:italic">// The node does not have the label. The pod cannot run here.</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">			klog</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">V</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">3</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Infof</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"Node %v does not have the required '%s' label. Filtering out."</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> nodeInfo</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Node</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Name</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> HighSpeedNetwork</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">			</span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> framework</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">NewStatus</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">framework</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Unschedulable</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> fmt</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Sprintf</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"Node %s lacks required network label"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> nodeInfo</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Node</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Name</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">		</span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">	</span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">	</span><span class="token comment" style="color:#999988;font-style:italic">// For any other annotation value, we don't apply any special filtering.</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">	</span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> framework</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">NewStatus</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">framework</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Success</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">""</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// ----------------- SCORING LOGIC -----------------</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// Score is called for each node that passed the Filter phase.</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// It returns a score for the node, with higher scores being better.</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">func</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">na </span><span class="token operator" style="color:#393A34">*</span><span class="token plain">Networkspeed</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">Score</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">ctx context</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Context</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> state </span><span class="token operator" style="color:#393A34">*</span><span class="token plain">framework</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">CycleState</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> pod </span><span class="token operator" style="color:#393A34">*</span><span class="token plain">v1</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Pod</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> nodeName </span><span class="token builtin">string</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token builtin">int64</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">*</span><span class="token plain">framework</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Status</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">	klog</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">V</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">3</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Infof</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"Scoring node %v for pod %v"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> nodeName</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> pod</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Name</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">	nodeInfo</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> err </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> na</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">handle</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">SnapshotSharedLister</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">NodeInfos</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Get</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">nodeName</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">	</span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> err </span><span class="token operator" style="color:#393A34">!=</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">nil</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">		</span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> framework</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">AsStatus</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">fmt</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Errorf</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"getting node %s from snapshot: %w"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> nodeName</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> err</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">	</span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">	nodeLabels </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> nodeInfo</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Node</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">GetLabels</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">	podNetworkPreference</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> ok </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> pod</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Annotations</span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain">PodNetworkAnnotation</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">	</span><span class="token comment" style="color:#999988;font-style:italic">// If the pod wants a high-speed network and the node has it, give it the highest score.</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">	</span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> ok </span><span class="token operator" style="color:#393A34">&amp;&amp;</span><span class="token plain"> podNetworkPreference </span><span class="token operator" style="color:#393A34">==</span><span class="token plain"> HighSpeedNetwork </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">		</span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> nodeNetworkType</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> labelExists </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> nodeLabels</span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain">NodeNetworkLabel</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> labelExists </span><span class="token operator" style="color:#393A34">&amp;&amp;</span><span class="token plain"> nodeNetworkType </span><span class="token operator" style="color:#393A34">==</span><span class="token plain"> HighSpeedNetwork </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">			klog</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">V</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">3</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Infof</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"Node %v matches high-speed preference. Giving max score (100)."</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> nodeName</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">			</span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">100</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> framework</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">NewStatus</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">framework</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Success</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">""</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">		</span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">	</span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">	</span><span class="token comment" style="color:#999988;font-style:italic">// For all other cases, give a minimal score. The scheduler will still use other plugins</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">	</span><span class="token comment" style="color:#999988;font-style:italic">// (like least-allocated) to make a final decision.</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">	klog</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">V</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">3</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">Infof</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"Node %v does not match high-speed preference. Giving min score (10)."</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> nodeName</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">	</span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">10</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> framework</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">NewStatus</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">framework</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Success</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">""</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// ScoreExtensions returns a ScoreExtensions interface if the plugin implements one.</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">func</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">na </span><span class="token operator" style="color:#393A34">*</span><span class="token plain">Networkspeed</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">ScoreExtensions</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> framework</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">ScoreExtensions </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">	</span><span class="token comment" style="color:#999988;font-style:italic">// We don't need to normalize scores, so we return nil.</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">	</span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">nil</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></div></code></pre></div></div>
<h4 class="anchor anchorTargetStickyNavbar_Vzrq" id="step-3-register-the-plugin">Step 3: Register the Plugin<a href="https://menraromial.com/blog/guide-building-custom-kubernetes-scheduler/#step-3-register-the-plugin" class="hash-link" aria-label="Direct link to Step 3: Register the Plugin" title="Direct link to Step 3: Register the Plugin" translate="no">​</a></h4>
<p>This step is also the same. We must tell the main binary about our new plugin.</p>
<p>Edit <code>cmd/scheduler/main.go</code> and add our plugin to the registry.</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic">// cmd/scheduler/main.go</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// ... other imports</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">	</span><span class="token string" style="color:#e3116c">"k8s.io/component-base/cli"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">	</span><span class="token string" style="color:#e3116c">"k8s.io/kubernetes/cmd/kube-scheduler/app"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// IMPORT YOUR PLUGIN'S PACKAGE</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">	</span><span class="token string" style="color:#e3116c">"sigs.k8s.io/scheduler-plugins/pkg/networkspeed"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">	</span><span class="token comment" style="color:#999988;font-style:italic">// ... other plugin imports</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">func</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">main</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">	</span><span class="token comment" style="color:#999988;font-style:italic">// Register all plugins.</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">	command </span><span class="token operator" style="color:#393A34">:=</span><span class="token plain"> app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">NewSchedulerCommand</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">		app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">WithPlugin</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">networkspeed</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Name</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> networkspeed</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">New</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// &lt;-- ADD THIS LINE</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">		app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">WithPlugin</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">coscheduling</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Name</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> coscheduling</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">New</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">		</span><span class="token comment" style="color:#999988;font-style:italic">// ... other plugins</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">	</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// ...</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></div></code></pre></div></div>
<hr>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="part-4-verifying-building-and-packaging"><strong>Part 4: Verifying, Building, and Packaging</strong><a href="https://menraromial.com/blog/guide-building-custom-kubernetes-scheduler/#part-4-verifying-building-and-packaging" class="hash-link" aria-label="Direct link to part-4-verifying-building-and-packaging" title="Direct link to part-4-verifying-building-and-packaging" translate="no">​</a></h3>
<p>This section is completely revamped to use the official <code>Makefile</code>.</p>
<h4 class="anchor anchorTargetStickyNavbar_Vzrq" id="step-1-verify-your-code-quality">Step 1: Verify Your Code Quality<a href="https://menraromial.com/blog/guide-building-custom-kubernetes-scheduler/#step-1-verify-your-code-quality" class="hash-link" aria-label="Direct link to Step 1: Verify Your Code Quality" title="Direct link to Step 1: Verify Your Code Quality" translate="no">​</a></h4>
<p>Before you even think about building, run the verification scripts. This catches formatting errors, dependency issues, and other common problems.</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token function" style="color:#d73a49">make</span><span class="token plain"> verify</span><br></div></code></pre></div></div>
<p>If this command fails, fix the issues it reports (e.g., run <code>go fmt ./...</code>) and try again. This is a standard prerequisite for contributing to open-source projects.</p>
<h4 class="anchor anchorTargetStickyNavbar_Vzrq" id="step-2-build-the-local-container-image">Step 2: Build the Local Container Image<a href="https://menraromial.com/blog/guide-building-custom-kubernetes-scheduler/#step-2-build-the-local-container-image" class="hash-link" aria-label="Direct link to Step 2: Build the Local Container Image" title="Direct link to Step 2: Build the Local Container Image" translate="no">​</a></h4>
<p>This is the most significant improvement. Forget manually setting registry and image names. The <code>local-image</code> target is designed specifically for this workflow.</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token function" style="color:#d73a49">make</span><span class="token plain"> local-image</span><br></div></code></pre></div></div>
<p><strong>What does this command do?</strong></p>
<ol>
<li class="">It compiles your Go code, including the new <code>networkspeed</code> plugin, into a <code>kube-scheduler</code> binary.</li>
<li class="">It builds a container image using Docker.</li>
<li class="">It automatically sets the platform to your local machine's architecture (e.g., <code>linux/amd64</code> or <code>linux/arm64</code>).</li>
<li class="">It tags the image with a convenient name for local development: <code>localhost:5000/scheduler-plugins/kube-scheduler:v0.0.0</code>.</li>
<li class="">It uses the <code>--load</code> flag with <code>docker buildx</code> to ensure the final image is available in your local Docker daemon, ready for <code>kind</code> to use.</li>
</ol>
<p>After it finishes, you can confirm the image exists:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token function" style="color:#d73a49">docker</span><span class="token plain"> images </span><span class="token operator" style="color:#393A34">|</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">grep</span><span class="token plain"> scheduler-plugins</span><br></div></code></pre></div></div>
<p>You should see <code>localhost:5000/scheduler-plugins/kube-scheduler</code>.</p>
<hr>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="part-5--production-grade-deployment-on-vms"><strong>Part 5 : Production-Grade Deployment on VMs</strong><a href="https://menraromial.com/blog/guide-building-custom-kubernetes-scheduler/#part-5--production-grade-deployment-on-vms" class="hash-link" aria-label="Direct link to part-5--production-grade-deployment-on-vms" title="Direct link to part-5--production-grade-deployment-on-vms" translate="no">​</a></h3>
<p>We will provision two Virtual Machines (one control-plane, one worker) and bootstrap a Kubernetes cluster using the <code>kubeadm</code> tool.</p>
<h4 class="anchor anchorTargetStickyNavbar_Vzrq" id="prerequisites-for-this-section">Prerequisites for this Section:<a href="https://menraromial.com/blog/guide-building-custom-kubernetes-scheduler/#prerequisites-for-this-section" class="hash-link" aria-label="Direct link to Prerequisites for this Section:" title="Direct link to Prerequisites for this Section:" translate="no">​</a></h4>
<ul>
<li class=""><strong>VirtualBox and Vagrant:</strong> For easily provisioning and managing local VMs.</li>
<li class=""><strong>Sufficient System Resources:</strong> At least 4 CPUs and 8GB of RAM available for the VMs.</li>
</ul>
<h4 class="anchor anchorTargetStickyNavbar_Vzrq" id="step-1-provision-the-virtual-machines">Step 1: Provision the Virtual Machines<a href="https://menraromial.com/blog/guide-building-custom-kubernetes-scheduler/#step-1-provision-the-virtual-machines" class="hash-link" aria-label="Direct link to Step 1: Provision the Virtual Machines" title="Direct link to Step 1: Provision the Virtual Machines" translate="no">​</a></h4>
<p>We'll use a <code>Vagrantfile</code> to define our two-node cluster. Create a file named <code>Vagrantfile</code> with the following content:</p>
<div class="language-ruby codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-ruby codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain"># Vagrantfile</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">Vagrant.configure("2") do |config|</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  config.vm.box = "ubuntu/jammy64"</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  config.vm.provider "virtualbox" do |v|</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    v.memory = 4096</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    v.cpus = 2</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  end</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  config.vm.define "k8s-control-plane" do |control|</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    control.vm.hostname = "k8s-control-plane"</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    control.vm.network "private_network", ip: "192.168.56.10"</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  end</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  config.vm.define "k8s-worker-01" do |worker|</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    worker.vm.hostname = "k8s-worker-01"</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    worker.vm.network "private_network", ip: "192.168.56.11"</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  end</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">end</span><br></div></code></pre></div></div>
<p>Now, bring up the machines:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">vagrant up</span><br></div></code></pre></div></div>
<h4 class="anchor anchorTargetStickyNavbar_Vzrq" id="step-2-install-container-runtime-and-kubernetes-tools-on-both-vms">Step 2: Install Container Runtime and Kubernetes Tools on Both VMs<a href="https://menraromial.com/blog/guide-building-custom-kubernetes-scheduler/#step-2-install-container-runtime-and-kubernetes-tools-on-both-vms" class="hash-link" aria-label="Direct link to Step 2: Install Container Runtime and Kubernetes Tools on Both VMs" title="Direct link to Step 2: Install Container Runtime and Kubernetes Tools on Both VMs" translate="no">​</a></h4>
<p>Execute these commands on <strong>both</strong> the <code>k8s-control-plane</code> and <code>k8s-worker-01</code> VMs. You can connect using <code>vagrant ssh k8s-control-plane</code> and <code>vagrant ssh k8s-worker-01</code>.</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic"># SSH into each VM and run the following:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic"># 1. Install prerequisites and containerd</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token function" style="color:#d73a49">sudo</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">apt-get</span><span class="token plain"> update</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token function" style="color:#d73a49">sudo</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">apt-get</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">install</span><span class="token plain"> </span><span class="token parameter variable" style="color:#36acaa">-y</span><span class="token plain"> apt-transport-https ca-certificates </span><span class="token function" style="color:#d73a49">curl</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token function" style="color:#d73a49">sudo</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">mkdir</span><span class="token plain"> </span><span class="token parameter variable" style="color:#36acaa">-p</span><span class="token plain"> /etc/apt/keyrings</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token function" style="color:#d73a49">curl</span><span class="token plain"> </span><span class="token parameter variable" style="color:#36acaa">-fsSL</span><span class="token plain"> https://download.docker.com/linux/ubuntu/gpg </span><span class="token operator" style="color:#393A34">|</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">sudo</span><span class="token plain"> gpg </span><span class="token parameter variable" style="color:#36acaa">--dearmor</span><span class="token plain"> </span><span class="token parameter variable" style="color:#36acaa">-o</span><span class="token plain"> /etc/apt/keyrings/docker.gpg</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token builtin class-name">echo</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"deb [arch=</span><span class="token string variable" style="color:#36acaa">$(</span><span class="token string variable" style="color:#36acaa">dpkg --print-architecture</span><span class="token string variable" style="color:#36acaa">)</span><span class="token string" style="color:#e3116c"> signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu </span><span class="token string variable" style="color:#36acaa">$(</span><span class="token string variable" style="color:#36acaa">lsb_release </span><span class="token string variable parameter variable" style="color:#36acaa">-cs</span><span class="token string variable" style="color:#36acaa">)</span><span class="token string" style="color:#e3116c"> stable"</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">|</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">sudo</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">tee</span><span class="token plain"> /etc/apt/sources.list.d/docker.list </span><span class="token operator" style="color:#393A34">&gt;</span><span class="token plain"> /dev/null</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token function" style="color:#d73a49">sudo</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">apt-get</span><span class="token plain"> update</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token function" style="color:#d73a49">sudo</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">apt-get</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">install</span><span class="token plain"> </span><span class="token parameter variable" style="color:#36acaa">-y</span><span class="token plain"> containerd.io</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic"># 2. Configure containerd and enable required kernel modules</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token function" style="color:#d73a49">sudo</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">mkdir</span><span class="token plain"> </span><span class="token parameter variable" style="color:#36acaa">-p</span><span class="token plain"> /etc/containerd</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token function" style="color:#d73a49">sudo</span><span class="token plain"> containerd config default </span><span class="token operator" style="color:#393A34">|</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">sudo</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">tee</span><span class="token plain"> /etc/containerd/config.toml</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token function" style="color:#d73a49">sudo</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">sed</span><span class="token plain"> </span><span class="token parameter variable" style="color:#36acaa">-i</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'s/SystemdCgroup = false/SystemdCgroup = true/'</span><span class="token plain"> /etc/containerd/config.toml</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token function" style="color:#d73a49">cat</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">&lt;&lt;</span><span class="token string" style="color:#e3116c">EOF</span><span class="token string bash punctuation" style="color:#393A34"> </span><span class="token string bash punctuation operator" style="color:#393A34">|</span><span class="token string bash punctuation" style="color:#393A34"> </span><span class="token string bash punctuation function" style="color:#d73a49">sudo</span><span class="token string bash punctuation" style="color:#393A34"> </span><span class="token string bash punctuation function" style="color:#d73a49">tee</span><span class="token string bash punctuation" style="color:#393A34"> /etc/modules-load.d/k8s.conf</span><span class="token string" style="color:#e3116c"></span><br></div><div class="token-line" style="color:#393A34"><span class="token string" style="color:#e3116c">overlay</span><br></div><div class="token-line" style="color:#393A34"><span class="token string" style="color:#e3116c">br_netfilter</span><br></div><div class="token-line" style="color:#393A34"><span class="token string" style="color:#e3116c">EOF</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token function" style="color:#d73a49">sudo</span><span class="token plain"> modprobe overlay</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token function" style="color:#d73a49">sudo</span><span class="token plain"> modprobe br_netfilter</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token function" style="color:#d73a49">cat</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">&lt;&lt;</span><span class="token string" style="color:#e3116c">EOF</span><span class="token string bash punctuation" style="color:#393A34"> </span><span class="token string bash punctuation operator" style="color:#393A34">|</span><span class="token string bash punctuation" style="color:#393A34"> </span><span class="token string bash punctuation function" style="color:#d73a49">sudo</span><span class="token string bash punctuation" style="color:#393A34"> </span><span class="token string bash punctuation function" style="color:#d73a49">tee</span><span class="token string bash punctuation" style="color:#393A34"> /etc/sysctl.d/k8s.conf</span><span class="token string" style="color:#e3116c"></span><br></div><div class="token-line" style="color:#393A34"><span class="token string" style="color:#e3116c">net.bridge.bridge-nf-call-ip6tables = 1</span><br></div><div class="token-line" style="color:#393A34"><span class="token string" style="color:#e3116c">net.bridge.bridge-nf-call-iptables = 1</span><br></div><div class="token-line" style="color:#393A34"><span class="token string" style="color:#e3116c">net.ipv4.ip_forward = 1</span><br></div><div class="token-line" style="color:#393A34"><span class="token string" style="color:#e3116c">EOF</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token function" style="color:#d73a49">sudo</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">sysctl</span><span class="token plain"> </span><span class="token parameter variable" style="color:#36acaa">--system</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token function" style="color:#d73a49">sudo</span><span class="token plain"> systemctl restart containerd</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic"># 3. Disable swap</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token function" style="color:#d73a49">sudo</span><span class="token plain"> swapoff </span><span class="token parameter variable" style="color:#36acaa">-a</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token function" style="color:#d73a49">sudo</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">sed</span><span class="token plain"> </span><span class="token parameter variable" style="color:#36acaa">-i</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'/ swap / s/^\(.*\)$/#\1/g'</span><span class="token plain"> /etc/fstab</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic"># 4. Install kubeadm, kubelet, and kubectl</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token function" style="color:#d73a49">sudo</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">apt-get</span><span class="token plain"> update</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token function" style="color:#d73a49">curl</span><span class="token plain"> </span><span class="token parameter variable" style="color:#36acaa">-fsSLo</span><span class="token plain"> /usr/share/keyrings/kubernetes-archive-keyring.gpg https://packages.cloud.google.com/apt/doc/apt-key.gpg</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token builtin class-name">echo</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"deb [signed-by=/usr/share/keyrings/kubernetes-archive-keyring.gpg] https://apt.kubernetes.io/ kubernetes-xenial main"</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">|</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">sudo</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">tee</span><span class="token plain"> /etc/apt/sources.list.d/kubernetes.list</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token function" style="color:#d73a49">sudo</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">apt-get</span><span class="token plain"> update</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token function" style="color:#d73a49">sudo</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">apt-get</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">install</span><span class="token plain"> </span><span class="token parameter variable" style="color:#36acaa">-y</span><span class="token plain"> kubelet kubeadm kubectl</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token function" style="color:#d73a49">sudo</span><span class="token plain"> apt-mark hold kubelet kubeadm kubectl</span><br></div></code></pre></div></div>
<h4 class="anchor anchorTargetStickyNavbar_Vzrq" id="step-3-initialize-the-control-plane-node">Step 3: Initialize the Control-Plane Node<a href="https://menraromial.com/blog/guide-building-custom-kubernetes-scheduler/#step-3-initialize-the-control-plane-node" class="hash-link" aria-label="Direct link to Step 3: Initialize the Control-Plane Node" title="Direct link to Step 3: Initialize the Control-Plane Node" translate="no">​</a></h4>
<p>Run this command <strong>only on the <code>k8s-control-plane</code> VM</strong>:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic"># On k8s-control-plane</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token function" style="color:#d73a49">sudo</span><span class="token plain"> kubeadm init --pod-network-cidr</span><span class="token operator" style="color:#393A34">=</span><span class="token number" style="color:#36acaa">10.244</span><span class="token plain">.0.0/16 --apiserver-advertise-address</span><span class="token operator" style="color:#393A34">=</span><span class="token number" style="color:#36acaa">192.168</span><span class="token plain">.56.10</span><br></div></code></pre></div></div>
<p>This command will take a few minutes. At the end, it will output two important things:</p>
<ol>
<li class="">Commands to set up <code>kubectl</code> for the <code>vagrant</code> user.</li>
<li class="">A <code>kubeadm join</code> command with a token. <strong>Copy this join command and save it.</strong></li>
</ol>
<p>Run the <code>kubectl</code> setup commands on the control-plane node:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic"># On k8s-control-plane</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token function" style="color:#d73a49">mkdir</span><span class="token plain"> </span><span class="token parameter variable" style="color:#36acaa">-p</span><span class="token plain"> </span><span class="token environment constant" style="color:#36acaa">$HOME</span><span class="token plain">/.kube</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token function" style="color:#d73a49">sudo</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">cp</span><span class="token plain"> </span><span class="token parameter variable" style="color:#36acaa">-i</span><span class="token plain"> /etc/kubernetes/admin.conf </span><span class="token environment constant" style="color:#36acaa">$HOME</span><span class="token plain">/.kube/config</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token function" style="color:#d73a49">sudo</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">chown</span><span class="token plain"> </span><span class="token variable" style="color:#36acaa">$(</span><span class="token variable function" style="color:#d73a49">id</span><span class="token variable" style="color:#36acaa"> </span><span class="token variable parameter variable" style="color:#36acaa">-u</span><span class="token variable" style="color:#36acaa">)</span><span class="token builtin class-name">:</span><span class="token variable" style="color:#36acaa">$(</span><span class="token variable function" style="color:#d73a49">id</span><span class="token variable" style="color:#36acaa"> </span><span class="token variable parameter variable" style="color:#36acaa">-g</span><span class="token variable" style="color:#36acaa">)</span><span class="token plain"> </span><span class="token environment constant" style="color:#36acaa">$HOME</span><span class="token plain">/.kube/config</span><br></div></code></pre></div></div>
<h4 class="anchor anchorTargetStickyNavbar_Vzrq" id="step-4-install-a-cni-network-plugin">Step 4: Install a CNI Network Plugin<a href="https://menraromial.com/blog/guide-building-custom-kubernetes-scheduler/#step-4-install-a-cni-network-plugin" class="hash-link" aria-label="Direct link to Step 4: Install a CNI Network Plugin" title="Direct link to Step 4: Install a CNI Network Plugin" translate="no">​</a></h4>
<p>The cluster nodes will not be <code>Ready</code> until a CNI is installed. From the control-plane node, install Calico:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic"># On k8s-control-plane</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">kubectl apply </span><span class="token parameter variable" style="color:#36acaa">-f</span><span class="token plain"> https://raw.githubusercontent.com/projectcalico/calico/v3.25.0/manifests/calico.yaml</span><br></div></code></pre></div></div>
<h4 class="anchor anchorTargetStickyNavbar_Vzrq" id="step-5-join-the-worker-node">Step 5: Join the Worker Node<a href="https://menraromial.com/blog/guide-building-custom-kubernetes-scheduler/#step-5-join-the-worker-node" class="hash-link" aria-label="Direct link to Step 5: Join the Worker Node" title="Direct link to Step 5: Join the Worker Node" translate="no">​</a></h4>
<p>Now, SSH into the <code>k8s-worker-01</code> VM and run the <code>kubeadm join</code> command that you saved from Step 3. It will look something like this (your token and hash will be different):</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic"># On k8s-worker-01</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token function" style="color:#d73a49">sudo</span><span class="token plain"> kubeadm </span><span class="token function" style="color:#d73a49">join</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">192.168</span><span class="token plain">.56.10:6443 </span><span class="token parameter variable" style="color:#36acaa">--token</span><span class="token plain"> abcdef.1234567890abcdef </span><span class="token punctuation" style="color:#393A34">\</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">	--discovery-token-ca-cert-hash sha256:1234</span><span class="token punctuation" style="color:#393A34">..</span><span class="token plain">.cdef</span><br></div></code></pre></div></div>
<p>After a minute, verify that both nodes are <code>Ready</code> from the control-plane node:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic"># On k8s-control-plane</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">kubectl get nodes</span><br></div></code></pre></div></div>
<h4 class="anchor anchorTargetStickyNavbar_Vzrq" id="step-6-provision-the-static-configuration-on-the-control-plane">Step 6: Provision the Static Configuration on the Control-Plane<a href="https://menraromial.com/blog/guide-building-custom-kubernetes-scheduler/#step-6-provision-the-static-configuration-on-the-control-plane" class="hash-link" aria-label="Direct link to Step 6: Provision the Static Configuration on the Control-Plane" title="Direct link to Step 6: Provision the Static Configuration on the Control-Plane" translate="no">​</a></h4>
<p>This is the critical step. We must place our custom scheduler's configuration file at the exact path <code>/etc/kubernetes/config/scheduler-config.yaml</code> on the <code>k8s-control-plane</code> VM.</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic"># Run this from your local machine (not inside a VM)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">vagrant </span><span class="token function" style="color:#d73a49">ssh</span><span class="token plain"> k8s-control-plane -- </span><span class="token parameter variable" style="color:#36acaa">-t</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'</span><br></div><div class="token-line" style="color:#393A34"><span class="token string" style="color:#e3116c">  sudo mkdir -p /etc/kubernetes/config &amp;&amp; \</span><br></div><div class="token-line" style="color:#393A34"><span class="token string" style="color:#e3116c">  sudo bash -c "cat &gt; /etc/kubernetes/config/scheduler-config.yaml" &lt;&lt;EOF</span><br></div><div class="token-line" style="color:#393A34"><span class="token string" style="color:#e3116c">apiVersion: kubescheduler.config.k8s.io/v1</span><br></div><div class="token-line" style="color:#393A34"><span class="token string" style="color:#e3116c">kind: KubeSchedulerConfiguration</span><br></div><div class="token-line" style="color:#393A34"><span class="token string" style="color:#e3116c">leaderElection:</span><br></div><div class="token-line" style="color:#393A34"><span class="token string" style="color:#e3116c">  leaderElect: false</span><br></div><div class="token-line" style="color:#393A34"><span class="token string" style="color:#e3116c">clientConnection:</span><br></div><div class="token-line" style="color:#393A34"><span class="token string" style="color:#e3116c">  kubeconfig: "/etc/kubernetes/scheduler.conf"</span><br></div><div class="token-line" style="color:#393A34"><span class="token string" style="color:#e3116c">profiles:</span><br></div><div class="token-line" style="color:#393A34"><span class="token string" style="color:#e3116c">  - schedulerName: my-custom-scheduler</span><br></div><div class="token-line" style="color:#393A34"><span class="token string" style="color:#e3116c">    plugins:</span><br></div><div class="token-line" style="color:#393A34"><span class="token string" style="color:#e3116c">      multiPoint:</span><br></div><div class="token-line" style="color:#393A34"><span class="token string" style="color:#e3116c">        enabled:</span><br></div><div class="token-line" style="color:#393A34"><span class="token string" style="color:#e3116c">          - name: "Networkspeed"</span><br></div><div class="token-line" style="color:#393A34"><span class="token string" style="color:#e3116c">EOF'</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic"># Verify the file was created correctly</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">vagrant </span><span class="token function" style="color:#d73a49">ssh</span><span class="token plain"> k8s-control-plane -- </span><span class="token string" style="color:#e3116c">"sudo cat /etc/kubernetes/config/scheduler-config.yaml"</span><br></div></code></pre></div></div>
<h4 class="anchor anchorTargetStickyNavbar_Vzrq" id="step-7-load-the-custom-scheduler-image-onto-the-cluster-nodes">Step 7: Load the Custom Scheduler Image onto the Cluster Nodes<a href="https://menraromial.com/blog/guide-building-custom-kubernetes-scheduler/#step-7-load-the-custom-scheduler-image-onto-the-cluster-nodes" class="hash-link" aria-label="Direct link to Step 7: Load the Custom Scheduler Image onto the Cluster Nodes" title="Direct link to Step 7: Load the Custom Scheduler Image onto the Cluster Nodes" translate="no">​</a></h4>
<p>The container image we built exists only on our local machine. We need to transfer it to our VMs.</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic"># 1. On your local machine, save the Docker image to a tar file</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token function" style="color:#d73a49">docker</span><span class="token plain"> save localhost:5000/scheduler-plugins/kube-scheduler:v0.0.0 </span><span class="token operator" style="color:#393A34">&gt;</span><span class="token plain"> scheduler.tar</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic"># 2. Copy the tar file to both VMs</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">vagrant </span><span class="token function" style="color:#d73a49">scp</span><span class="token plain"> scheduler.tar k8s-control-plane:/home/vagrant/scheduler.tar</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">vagrant </span><span class="token function" style="color:#d73a49">scp</span><span class="token plain"> scheduler.tar k8s-worker-01:/home/vagrant/scheduler.tar</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic"># 3. SSH into EACH VM and load the image into containerd</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic"># On k8s-control-plane:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">vagrant </span><span class="token function" style="color:#d73a49">ssh</span><span class="token plain"> k8s-control-plane -- </span><span class="token string" style="color:#e3116c">"sudo ctr -n=k8s.io images import /home/vagrant/scheduler.tar"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic"># On k8s-worker-01:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">vagrant </span><span class="token function" style="color:#d73a49">ssh</span><span class="token plain"> k8s-worker-01 -- </span><span class="token string" style="color:#e3116c">"sudo ctr -n=k8s.io images import /home/vagrant/scheduler.tar"</span><br></div></code></pre></div></div>
<h4 class="anchor anchorTargetStickyNavbar_Vzrq" id="step-8-deploy-the-custom-scheduler">Step 8: Deploy the Custom Scheduler<a href="https://menraromial.com/blog/guide-building-custom-kubernetes-scheduler/#step-8-deploy-the-custom-scheduler" class="hash-link" aria-label="Direct link to Step 8: Deploy the Custom Scheduler" title="Direct link to Step 8: Deploy the Custom Scheduler" translate="no">​</a></h4>
<p>Create the final <code>deploy-kubeadm.yaml</code> manifest on your local machine. This file is identical to the previous "correct" version, as it's designed to run in a real cluster environment.</p>
<p><code>deploy-kubeadm.yaml</code>:</p>
<div class="language-yaml codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-yaml codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token key atrule" style="color:#00a4db">apiVersion</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> v1</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token key atrule" style="color:#00a4db">kind</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> ServiceAccount</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token key atrule" style="color:#00a4db">metadata</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">name</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> my</span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain">custom</span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain">scheduler</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">namespace</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> kube</span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain">system</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">---</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token key atrule" style="color:#00a4db">apiVersion</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> rbac.authorization.k8s.io/v1</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token key atrule" style="color:#00a4db">kind</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> ClusterRoleBinding</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token key atrule" style="color:#00a4db">metadata</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">name</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> my</span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain">custom</span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain">scheduler</span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain">as</span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain">kube</span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain">scheduler</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token key atrule" style="color:#00a4db">subjects</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain"> </span><span class="token key atrule" style="color:#00a4db">kind</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> ServiceAccount</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">name</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> my</span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain">custom</span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain">scheduler</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">namespace</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> kube</span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain">system</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token key atrule" style="color:#00a4db">roleRef</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">kind</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> ClusterRole</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">name</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> system</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain">kube</span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain">scheduler</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">apiGroup</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> rbac.authorization.k8s.io</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">---</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token key atrule" style="color:#00a4db">apiVersion</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> apps/v1</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token key atrule" style="color:#00a4db">kind</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> Deployment</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token key atrule" style="color:#00a4db">metadata</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">name</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> my</span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain">custom</span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain">scheduler</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">namespace</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> kube</span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain">system</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">labels</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token key atrule" style="color:#00a4db">app</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> my</span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain">custom</span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain">scheduler</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token key atrule" style="color:#00a4db">spec</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">replicas</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">1</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">selector</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token key atrule" style="color:#00a4db">matchLabels</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token key atrule" style="color:#00a4db">app</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> my</span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain">custom</span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain">scheduler</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">template</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token key atrule" style="color:#00a4db">metadata</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token key atrule" style="color:#00a4db">labels</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token key atrule" style="color:#00a4db">app</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> my</span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain">custom</span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain">scheduler</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token key atrule" style="color:#00a4db">spec</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token key atrule" style="color:#00a4db">serviceAccountName</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> my</span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain">custom</span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain">scheduler</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token key atrule" style="color:#00a4db">nodeSelector</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token key atrule" style="color:#00a4db">node-role.kubernetes.io/control-plane</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"true"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token key atrule" style="color:#00a4db">tolerations</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain"> </span><span class="token key atrule" style="color:#00a4db">effect</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> NoSchedule</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token key atrule" style="color:#00a4db">key</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> node</span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain">role.kubernetes.io/control</span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain">plane</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token key atrule" style="color:#00a4db">containers</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain"> </span><span class="token key atrule" style="color:#00a4db">name</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> my</span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain">custom</span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain">scheduler</span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain">ctr</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">          </span><span class="token key atrule" style="color:#00a4db">image</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> localhost</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain">5000/scheduler</span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain">plugins/kube</span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain">scheduler</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain">v0.0.0</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">          </span><span class="token key atrule" style="color:#00a4db">imagePullPolicy</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> IfNotPresent</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">          </span><span class="token key atrule" style="color:#00a4db">args</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain"> /bin/kube</span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain">scheduler</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">-</span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain">authentication</span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain">kubeconfig=/etc/kubernetes/scheduler.conf</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">-</span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain">authorization</span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain">kubeconfig=/etc/kubernetes/scheduler.conf</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">-</span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain">config=/etc/kubernetes/config/scheduler</span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain">config.yaml</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain">v=3</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">          </span><span class="token key atrule" style="color:#00a4db">volumeMounts</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">          </span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain"> </span><span class="token key atrule" style="color:#00a4db">mountPath</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> /etc/kubernetes</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token key atrule" style="color:#00a4db">name</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> etckubernetes</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token key atrule" style="color:#00a4db">readOnly</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token boolean important" style="color:#36acaa">true</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token key atrule" style="color:#00a4db">volumes</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain"> </span><span class="token key atrule" style="color:#00a4db">name</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> etckubernetes</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token key atrule" style="color:#00a4db">hostPath</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">          </span><span class="token key atrule" style="color:#00a4db">path</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> /etc/kubernetes</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">          </span><span class="token key atrule" style="color:#00a4db">type</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> Directory</span><br></div></code></pre></div></div>
<p>Now, apply this manifest to your new <code>kubeadm</code> cluster. You can copy this file to the control-plane node or configure <code>kubectl</code> on your host to point to the new cluster. The simplest is to run it from the control-plane:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic"># Copy the YAML to the control plane</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">vagrant </span><span class="token function" style="color:#d73a49">scp</span><span class="token plain"> deploy-kubeadm.yaml k8s-control-plane:/home/vagrant/</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic"># Apply it from within the control plane VM</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">vagrant </span><span class="token function" style="color:#d73a49">ssh</span><span class="token plain"> k8s-control-plane -- </span><span class="token string" style="color:#e3116c">"kubectl apply -f deploy-kubeadm.yaml"</span><br></div></code></pre></div></div>
<p>Verify the scheduler pod is running on the control-plane node:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">vagrant </span><span class="token function" style="color:#d73a49">ssh</span><span class="token plain"> k8s-control-plane -- </span><span class="token string" style="color:#e3116c">"kubectl get pods -n kube-system -l app=my-custom-scheduler -o wide"</span><br></div></code></pre></div></div>
<hr>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="part-6-testing-the-custom-scheduler"><strong>Part 6: Testing the Custom Scheduler</strong><a href="https://menraromial.com/blog/guide-building-custom-kubernetes-scheduler/#part-6-testing-the-custom-scheduler" class="hash-link" aria-label="Direct link to part-6-testing-the-custom-scheduler" title="Direct link to part-6-testing-the-custom-scheduler" translate="no">​</a></h3>
<p>The testing process is identical, but you will run the commands from your <code>k8s-control-plane</code> VM where <code>kubectl</code> is configured.</p>
<ol>
<li class=""><strong>Label the worker node:</strong>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic"># On k8s-control-plane VM</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    kubectl label </span><span class="token function" style="color:#d73a49">node</span><span class="token plain"> k8s-worker-01 network-topology</span><span class="token operator" style="color:#393A34">=</span><span class="token plain">high-speed</span><br></div></code></pre></div></div>
</li>
<li class=""><strong>Create and apply <code>test-pod.yaml</code>:</strong>
<div class="language-yaml codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-yaml codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic"># test-pod.yaml</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token key atrule" style="color:#00a4db">apiVersion</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> v1</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token key atrule" style="color:#00a4db">kind</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> Pod</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token key atrule" style="color:#00a4db">metadata</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token key atrule" style="color:#00a4db">name</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> high</span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain">speed</span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain">pod</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token key atrule" style="color:#00a4db">annotations</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token key atrule" style="color:#00a4db">my-network-preference</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"high-speed"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token key atrule" style="color:#00a4db">spec</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token key atrule" style="color:#00a4db">schedulerName</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> my</span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain">custom</span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain">scheduler</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token key atrule" style="color:#00a4db">containers</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain"> </span><span class="token key atrule" style="color:#00a4db">name</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> nginx</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token key atrule" style="color:#00a4db">image</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> nginx</span><br></div></code></pre></div></div>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic"># On k8s-control-plane VM, apply the pod</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">kubectl apply </span><span class="token parameter variable" style="color:#36acaa">-f</span><span class="token plain"> test-pod.yaml</span><br></div></code></pre></div></div>
</li>
<li class=""><strong>Verify the pod placement:</strong>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic"># On k8s-control-plane VM</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">kubectl get pod high-speed-pod </span><span class="token parameter variable" style="color:#36acaa">-o</span><span class="token plain"> wide</span><br></div></code></pre></div></div>
The pod should be running on the <code>k8s-worker-01</code> node.</li>
</ol>
<p>You have now successfully built a custom scheduler and deployed it to a realistic, multi-node <code>kubeadm</code> cluster.</p>
<p><strong>Your Professional Next Steps:</strong></p>
<ol>
<li class=""><strong>Write Unit Tests:</strong> Create a <code>pkg/networkspeed/networkspeed_test.go</code> file. The repository has many examples. Once written, you can run them with <code>make unit-test</code>.</li>
<li class=""><strong>Run Integration Tests:</strong> The project has a framework for integration tests that spin up real API servers. You can add one for your plugin and run it via <code>make integration-test</code>.</li>
<li class=""><strong>Pushing to a Real Registry:</strong> When you are ready to share your scheduler, you can use the <code>push-images</code> target. This requires setting environment variables:
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic"># Example for pushing to Docker Hub</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token builtin class-name">export</span><span class="token plain"> </span><span class="token assign-left variable" style="color:#36acaa">REGISTRY</span><span class="token operator" style="color:#393A34">=</span><span class="token plain">docker.io/your-username</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token builtin class-name">export</span><span class="token plain"> </span><span class="token assign-left variable" style="color:#36acaa">RELEASE_VERSION</span><span class="token operator" style="color:#393A34">=</span><span class="token plain">v0.1.0</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token function" style="color:#d73a49">make</span><span class="token plain"> push-images </span><br></div></code></pre></div></div>
This will build and push a properly tagged image (e.g., <code>docker.io/your-username/kube-scheduler:v0.1.0</code>) to a remote registry.</li>
<li class=""><strong>Contribute Back:</strong> If you've built a generally useful plugin, you can contribute it back to the <code>scheduler-plugins</code> project! Following this workflow (<code>make verify</code>, adding tests) is the first step to a successful Pull Request.</li>
</ol>]]></content>
        <author>
            <name>Menra Romial</name>
            <uri>https://menraromial.com</uri>
        </author>
        <category label="kubernetes" term="kubernetes"/>
        <category label="scheduler" term="scheduler"/>
        <category label="kubeadm" term="kubeadm"/>
        <category label="plugin" term="plugin"/>
        <category label="opensource" term="opensource"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Setting Up a Kubernetes Cluster with Kubeadm and CRI-O]]></title>
        <id>https://menraromial.com/blog/kubernetes-with-kubeadm-and-cri.io/</id>
        <link href="https://menraromial.com/blog/kubernetes-with-kubeadm-and-cri.io/"/>
        <updated>2025-03-25T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[A step-by-step guide to a production-ready Kubernetes cluster with Kubeadm and CRI-O: prerequisites, installation, configuration and good practices.]]></summary>
        <content type="html"><![CDATA[<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="prerequisites">Prerequisites<a href="https://menraromial.com/blog/kubernetes-with-kubeadm-and-cri.io/#prerequisites" class="hash-link" aria-label="Direct link to Prerequisites" title="Direct link to Prerequisites" translate="no">​</a></h2>
<p>Before setting up a Kubernetes cluster using Kubeadm and CRI-O, ensure that you meet the following requirements:</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="hardware-requirements">Hardware Requirements<a href="https://menraromial.com/blog/kubernetes-with-kubeadm-and-cri.io/#hardware-requirements" class="hash-link" aria-label="Direct link to Hardware Requirements" title="Direct link to Hardware Requirements" translate="no">​</a></h3>
<ul>
<li class="">At least <strong>2 GB of RAM</strong> per node (4 GB recommended for the master node)</li>
<li class="">At least <strong>2 CPUs</strong> per node</li>
<li class=""><strong>20 GB of free disk space</strong></li>
<li class="">A stable <strong>internet connection</strong></li>
<li class="">All nodes should be able to communicate with each other</li>
</ul>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="software-requirements">Software Requirements<a href="https://menraromial.com/blog/kubernetes-with-kubeadm-and-cri.io/#software-requirements" class="hash-link" aria-label="Direct link to Software Requirements" title="Direct link to Software Requirements" translate="no">​</a></h3>
<ul>
<li class="">A supported <strong>Linux distribution</strong> (Ubuntu 20.04+ or Debian 10+ recommended)</li>
<li class="">User access with <strong>sudo privileges</strong></li>
<li class="">Basic understanding of <strong>Linux command-line interface (CLI)</strong></li>
<li class="">Knowledge of <strong>networking concepts</strong></li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="step-1-configure-kernel-parameters">Step 1: Configure Kernel Parameters<a href="https://menraromial.com/blog/kubernetes-with-kubeadm-and-cri.io/#step-1-configure-kernel-parameters" class="hash-link" aria-label="Direct link to Step 1: Configure Kernel Parameters" title="Direct link to Step 1: Configure Kernel Parameters" translate="no">​</a></h2>
<p>Kubernetes requires some kernel parameters to be set to allow IPtables to see bridged traffic.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="load-required-kernel-modules">Load Required Kernel Modules<a href="https://menraromial.com/blog/kubernetes-with-kubeadm-and-cri.io/#load-required-kernel-modules" class="hash-link" aria-label="Direct link to Load Required Kernel Modules" title="Direct link to Load Required Kernel Modules" translate="no">​</a></h3>
<p>Run the following commands on all nodes:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token function" style="color:#d73a49">cat</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">&lt;&lt;</span><span class="token string" style="color:#e3116c">EOF</span><span class="token string bash punctuation" style="color:#393A34"> </span><span class="token string bash punctuation operator" style="color:#393A34">|</span><span class="token string bash punctuation" style="color:#393A34"> </span><span class="token string bash punctuation function" style="color:#d73a49">sudo</span><span class="token string bash punctuation" style="color:#393A34"> </span><span class="token string bash punctuation function" style="color:#d73a49">tee</span><span class="token string bash punctuation" style="color:#393A34"> /etc/modules-load.d/k8s.conf</span><span class="token string" style="color:#e3116c"></span><br></div><div class="token-line" style="color:#393A34"><span class="token string" style="color:#e3116c">overlay</span><br></div><div class="token-line" style="color:#393A34"><span class="token string" style="color:#e3116c">br_netfilter</span><br></div><div class="token-line" style="color:#393A34"><span class="token string" style="color:#e3116c">EOF</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token function" style="color:#d73a49">sudo</span><span class="token plain"> modprobe overlay</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token function" style="color:#d73a49">sudo</span><span class="token plain"> modprobe br_netfilter</span><br></div></code></pre></div></div>
<!-- -->
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="set-kernel-parameters-for-kubernetes">Set Kernel Parameters for Kubernetes<a href="https://menraromial.com/blog/kubernetes-with-kubeadm-and-cri.io/#set-kernel-parameters-for-kubernetes" class="hash-link" aria-label="Direct link to Set Kernel Parameters for Kubernetes" title="Direct link to Set Kernel Parameters for Kubernetes" translate="no">​</a></h3>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token function" style="color:#d73a49">cat</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">&lt;&lt;</span><span class="token string" style="color:#e3116c">EOF</span><span class="token string bash punctuation" style="color:#393A34"> </span><span class="token string bash punctuation operator" style="color:#393A34">|</span><span class="token string bash punctuation" style="color:#393A34"> </span><span class="token string bash punctuation function" style="color:#d73a49">sudo</span><span class="token string bash punctuation" style="color:#393A34"> </span><span class="token string bash punctuation function" style="color:#d73a49">tee</span><span class="token string bash punctuation" style="color:#393A34"> /etc/sysctl.d/k8s.conf</span><span class="token string" style="color:#e3116c"></span><br></div><div class="token-line" style="color:#393A34"><span class="token string" style="color:#e3116c">net.bridge.bridge-nf-call-iptables  = 1</span><br></div><div class="token-line" style="color:#393A34"><span class="token string" style="color:#e3116c">net.bridge.bridge-nf-call-ip6tables = 1</span><br></div><div class="token-line" style="color:#393A34"><span class="token string" style="color:#e3116c">net.ipv4.ip_forward                 = 1</span><br></div><div class="token-line" style="color:#393A34"><span class="token string" style="color:#e3116c">EOF</span><br></div></code></pre></div></div>
<p>Apply the changes:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token function" style="color:#d73a49">sudo</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">sysctl</span><span class="token plain"> </span><span class="token parameter variable" style="color:#36acaa">--system</span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="step-2-disable-swap">Step 2: Disable Swap<a href="https://menraromial.com/blog/kubernetes-with-kubeadm-and-cri.io/#step-2-disable-swap" class="hash-link" aria-label="Direct link to Step 2: Disable Swap" title="Direct link to Step 2: Disable Swap" translate="no">​</a></h2>
<p>Kubernetes does not work well with swap enabled. Disable it using:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">swapoff </span><span class="token parameter variable" style="color:#36acaa">-a</span><br></div></code></pre></div></div>
<p>To make this change persistent, remove any swap entries from <code>/etc/fstab</code>:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token function" style="color:#d73a49">sudo</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">nano</span><span class="token plain"> /etc/fstab</span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="step-3-install-cri-o-container-runtime-interface---open">Step 3: Install CRI-O (Container Runtime Interface - Open)<a href="https://menraromial.com/blog/kubernetes-with-kubeadm-and-cri.io/#step-3-install-cri-o-container-runtime-interface---open" class="hash-link" aria-label="Direct link to Step 3: Install CRI-O (Container Runtime Interface - Open)" title="Direct link to Step 3: Install CRI-O (Container Runtime Interface - Open)" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="add-cri-o-repository-and-install">Add CRI-O Repository and Install<a href="https://menraromial.com/blog/kubernetes-with-kubeadm-and-cri.io/#add-cri-o-repository-and-install" class="hash-link" aria-label="Direct link to Add CRI-O Repository and Install" title="Direct link to Add CRI-O Repository and Install" translate="no">​</a></h3>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token function" style="color:#d73a49">sudo</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">apt-get</span><span class="token plain"> update </span><span class="token parameter variable" style="color:#36acaa">-y</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token function" style="color:#d73a49">sudo</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">apt-get</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">install</span><span class="token plain"> </span><span class="token parameter variable" style="color:#36acaa">-y</span><span class="token plain"> software-properties-common gpg </span><span class="token function" style="color:#d73a49">curl</span><span class="token plain"> apt-transport-https ca-certificates</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token function" style="color:#d73a49">curl</span><span class="token plain"> </span><span class="token parameter variable" style="color:#36acaa">-fsSL</span><span class="token plain"> https://pkgs.k8s.io/addons:/cri-o:/prerelease:/main/deb/Release.key </span><span class="token operator" style="color:#393A34">|</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">\</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    gpg </span><span class="token parameter variable" style="color:#36acaa">--dearmor</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">|</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">sudo</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">tee</span><span class="token plain"> /etc/apt/keyrings/cri-o-apt-keyring.gpg </span><span class="token operator" style="color:#393A34">&gt;</span><span class="token plain">/dev/null</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token builtin class-name">echo</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"deb [signed-by=/etc/apt/keyrings/cri-o-apt-keyring.gpg] https://pkgs.k8s.io/addons:/cri-o:/prerelease:/main/deb/ /"</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">|</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">\</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token function" style="color:#d73a49">sudo</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">tee</span><span class="token plain"> /etc/apt/sources.list.d/cri-o.list</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token function" style="color:#d73a49">sudo</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">apt-get</span><span class="token plain"> update </span><span class="token parameter variable" style="color:#36acaa">-y</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token function" style="color:#d73a49">sudo</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">apt-get</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">install</span><span class="token plain"> </span><span class="token parameter variable" style="color:#36acaa">-y</span><span class="token plain"> cri-o</span><br></div></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="enable-and-start-cri-o-service">Enable and Start CRI-O Service<a href="https://menraromial.com/blog/kubernetes-with-kubeadm-and-cri.io/#enable-and-start-cri-o-service" class="hash-link" aria-label="Direct link to Enable and Start CRI-O Service" title="Direct link to Enable and Start CRI-O Service" translate="no">​</a></h3>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token function" style="color:#d73a49">sudo</span><span class="token plain"> systemctl daemon-reload</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token function" style="color:#d73a49">sudo</span><span class="token plain"> systemctl </span><span class="token builtin class-name">enable</span><span class="token plain"> crio </span><span class="token parameter variable" style="color:#36acaa">--now</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token function" style="color:#d73a49">sudo</span><span class="token plain"> systemctl start crio.service</span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="step-4-install-kubernetes-components">Step 4: Install Kubernetes Components<a href="https://menraromial.com/blog/kubernetes-with-kubeadm-and-cri.io/#step-4-install-kubernetes-components" class="hash-link" aria-label="Direct link to Step 4: Install Kubernetes Components" title="Direct link to Step 4: Install Kubernetes Components" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="add-kubernetes-repository">Add Kubernetes Repository<a href="https://menraromial.com/blog/kubernetes-with-kubeadm-and-cri.io/#add-kubernetes-repository" class="hash-link" aria-label="Direct link to Add Kubernetes Repository" title="Direct link to Add Kubernetes Repository" translate="no">​</a></h3>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token assign-left variable" style="color:#36acaa">KUBERNETES_VERSION</span><span class="token operator" style="color:#393A34">=</span><span class="token number" style="color:#36acaa">1.30</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token function" style="color:#d73a49">sudo</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">mkdir</span><span class="token plain"> </span><span class="token parameter variable" style="color:#36acaa">-p</span><span class="token plain"> /etc/apt/keyrings</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token function" style="color:#d73a49">curl</span><span class="token plain"> </span><span class="token parameter variable" style="color:#36acaa">-fsSL</span><span class="token plain"> https://pkgs.k8s.io/core:/stable:/v</span><span class="token variable" style="color:#36acaa">$KUBERNETES_VERSION</span><span class="token plain">/deb/Release.key </span><span class="token operator" style="color:#393A34">|</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">\</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    gpg </span><span class="token parameter variable" style="color:#36acaa">--dearmor</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">|</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">sudo</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">tee</span><span class="token plain"> /etc/apt/keyrings/kubernetes-apt-keyring.gpg </span><span class="token operator" style="color:#393A34">&gt;</span><span class="token plain"> /dev/null</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token builtin class-name">echo</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v</span><span class="token string variable" style="color:#36acaa">$KUBERNETES_VERSION</span><span class="token string" style="color:#e3116c">/deb/ /"</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">|</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">\</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token function" style="color:#d73a49">sudo</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">tee</span><span class="token plain"> /etc/apt/sources.list.d/kubernetes.list</span><br></div></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="install-kubeadm-kubelet-and-kubectl">Install Kubeadm, Kubelet, and Kubectl<a href="https://menraromial.com/blog/kubernetes-with-kubeadm-and-cri.io/#install-kubeadm-kubelet-and-kubectl" class="hash-link" aria-label="Direct link to Install Kubeadm, Kubelet, and Kubectl" title="Direct link to Install Kubeadm, Kubelet, and Kubectl" translate="no">​</a></h3>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token function" style="color:#d73a49">sudo</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">apt-get</span><span class="token plain"> update </span><span class="token parameter variable" style="color:#36acaa">-y</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token function" style="color:#d73a49">sudo</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">apt-get</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">install</span><span class="token plain"> </span><span class="token parameter variable" style="color:#36acaa">-y</span><span class="token plain"> </span><span class="token assign-left variable" style="color:#36acaa">kubelet</span><span class="token operator" style="color:#393A34">=</span><span class="token number" style="color:#36acaa">1.30</span><span class="token plain">.0-1.1 </span><span class="token assign-left variable" style="color:#36acaa">kubectl</span><span class="token operator" style="color:#393A34">=</span><span class="token number" style="color:#36acaa">1.30</span><span class="token plain">.0-1.1 </span><span class="token assign-left variable" style="color:#36acaa">kubeadm</span><span class="token operator" style="color:#393A34">=</span><span class="token number" style="color:#36acaa">1.30</span><span class="token plain">.0-1.1</span><br></div></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="configure-kubelet-node-ip">Configure Kubelet Node IP<a href="https://menraromial.com/blog/kubernetes-with-kubeadm-and-cri.io/#configure-kubelet-node-ip" class="hash-link" aria-label="Direct link to Configure Kubelet Node IP" title="Direct link to Configure Kubelet Node IP" translate="no">​</a></h3>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token function" style="color:#d73a49">sudo</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">apt-get</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">install</span><span class="token plain"> </span><span class="token parameter variable" style="color:#36acaa">-y</span><span class="token plain"> jq</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token assign-left variable" style="color:#36acaa">local_ip</span><span class="token operator" style="color:#393A34">=</span><span class="token string" style="color:#e3116c">"</span><span class="token string variable" style="color:#36acaa">$(</span><span class="token string variable function" style="color:#d73a49">ip</span><span class="token string variable" style="color:#36acaa"> </span><span class="token string variable parameter variable" style="color:#36acaa">--json</span><span class="token string variable" style="color:#36acaa"> addr show eno1 </span><span class="token string variable operator" style="color:#393A34">|</span><span class="token string variable" style="color:#36acaa"> jq </span><span class="token string variable parameter variable" style="color:#36acaa">-r</span><span class="token string variable" style="color:#36acaa"> </span><span class="token string variable string" style="color:#e3116c">'.[0].addr_info[] | select(.family == "inet") | .local'</span><span class="token string variable" style="color:#36acaa">)</span><span class="token string" style="color:#e3116c">"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token function" style="color:#d73a49">sudo</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">tee</span><span class="token plain"> /etc/default/kubelet </span><span class="token operator" style="color:#393A34">&gt;</span><span class="token plain"> /dev/null </span><span class="token operator" style="color:#393A34">&lt;&lt;</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">EOF</span><br></div><div class="token-line" style="color:#393A34"><span class="token string" style="color:#e3116c">KUBELET_EXTRA_ARGS=--node-ip=</span><span class="token string variable" style="color:#36acaa">$local_ip</span><span class="token string" style="color:#e3116c"></span><br></div><div class="token-line" style="color:#393A34"><span class="token string" style="color:#e3116c">EOF</span><br></div></code></pre></div></div>
<p><strong>Note:</strong> <code>eno1</code> and <code>enp85s0</code> are network interface names that may vary depending on the system. You can check your network interfaces using:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token function" style="color:#d73a49">ifconfig</span><span class="token plain"> </span><span class="token parameter variable" style="color:#36acaa">-a</span><br></div></code></pre></div></div>
<p>or</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token function" style="color:#d73a49">ip</span><span class="token plain"> a</span><br></div></code></pre></div></div>
<p>Adjust the interface name accordingly based on the output of these commands.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="step-5-initialize-kubernetes-on-the-master-node">Step 5: Initialize Kubernetes on the Master Node<a href="https://menraromial.com/blog/kubernetes-with-kubeadm-and-cri.io/#step-5-initialize-kubernetes-on-the-master-node" class="hash-link" aria-label="Direct link to Step 5: Initialize Kubernetes on the Master Node" title="Direct link to Step 5: Initialize Kubernetes on the Master Node" translate="no">​</a></h2>
<p>Set the master node IP and hostname:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token assign-left variable" style="color:#36acaa">IPADDR</span><span class="token operator" style="color:#393A34">=</span><span class="token string" style="color:#e3116c">"</span><span class="token string variable" style="color:#36acaa">$(</span><span class="token string variable function" style="color:#d73a49">ip</span><span class="token string variable" style="color:#36acaa"> </span><span class="token string variable parameter variable" style="color:#36acaa">--json</span><span class="token string variable" style="color:#36acaa"> addr show enp85s0 </span><span class="token string variable operator" style="color:#393A34">|</span><span class="token string variable" style="color:#36acaa"> jq </span><span class="token string variable parameter variable" style="color:#36acaa">-r</span><span class="token string variable" style="color:#36acaa"> </span><span class="token string variable string" style="color:#e3116c">'.[0].addr_info[] | select(.family == "inet") | .local'</span><span class="token string variable" style="color:#36acaa">)</span><span class="token string" style="color:#e3116c">"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token assign-left variable" style="color:#36acaa">NODENAME</span><span class="token operator" style="color:#393A34">=</span><span class="token variable" style="color:#36acaa">$(</span><span class="token variable function" style="color:#d73a49">hostname</span><span class="token variable" style="color:#36acaa"> </span><span class="token variable parameter variable" style="color:#36acaa">-s</span><span class="token variable" style="color:#36acaa">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token assign-left variable" style="color:#36acaa">POD_CIDR</span><span class="token operator" style="color:#393A34">=</span><span class="token string" style="color:#e3116c">"192.168.0.0/16"</span><br></div></code></pre></div></div>
<p>Initialize Kubernetes:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token function" style="color:#d73a49">sudo</span><span class="token plain"> kubeadm init --apiserver-advertise-address</span><span class="token operator" style="color:#393A34">=</span><span class="token variable" style="color:#36acaa">$IPADDR</span><span class="token plain"> --apiserver-cert-extra-sans</span><span class="token operator" style="color:#393A34">=</span><span class="token variable" style="color:#36acaa">$IPADDR</span><span class="token plain"> --pod-network-cidr</span><span class="token operator" style="color:#393A34">=</span><span class="token variable" style="color:#36acaa">$POD_CIDR</span><span class="token plain"> --node-name </span><span class="token variable" style="color:#36acaa">$NODENAME</span><span class="token plain"> --ignore-preflight-errors Swap --cri-socket unix:///var/run/crio/crio.sock </span><br></div></code></pre></div></div>
<p>Set up kubeconfig for the root user:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token function" style="color:#d73a49">mkdir</span><span class="token plain"> </span><span class="token parameter variable" style="color:#36acaa">-p</span><span class="token plain"> </span><span class="token environment constant" style="color:#36acaa">$HOME</span><span class="token plain">/.kube</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token function" style="color:#d73a49">cp</span><span class="token plain"> </span><span class="token parameter variable" style="color:#36acaa">-i</span><span class="token plain"> /etc/kubernetes/admin.conf </span><span class="token environment constant" style="color:#36acaa">$HOME</span><span class="token plain">/.kube/config</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token function" style="color:#d73a49">chown</span><span class="token plain"> </span><span class="token variable" style="color:#36acaa">$(</span><span class="token variable function" style="color:#d73a49">id</span><span class="token variable" style="color:#36acaa"> </span><span class="token variable parameter variable" style="color:#36acaa">-u</span><span class="token variable" style="color:#36acaa">)</span><span class="token builtin class-name">:</span><span class="token variable" style="color:#36acaa">$(</span><span class="token variable function" style="color:#d73a49">id</span><span class="token variable" style="color:#36acaa"> </span><span class="token variable parameter variable" style="color:#36acaa">-g</span><span class="token variable" style="color:#36acaa">)</span><span class="token plain"> </span><span class="token environment constant" style="color:#36acaa">$HOME</span><span class="token plain">/.kube/config</span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="step-6-deploy-network-and-monitoring-components">Step 6: Deploy Network and Monitoring Components<a href="https://menraromial.com/blog/kubernetes-with-kubeadm-and-cri.io/#step-6-deploy-network-and-monitoring-components" class="hash-link" aria-label="Direct link to Step 6: Deploy Network and Monitoring Components" title="Direct link to Step 6: Deploy Network and Monitoring Components" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="install-calico-network-plugin">Install Calico Network Plugin<a href="https://menraromial.com/blog/kubernetes-with-kubeadm-and-cri.io/#install-calico-network-plugin" class="hash-link" aria-label="Direct link to Install Calico Network Plugin" title="Direct link to Install Calico Network Plugin" translate="no">​</a></h3>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">kubectl apply </span><span class="token parameter variable" style="color:#36acaa">-f</span><span class="token plain"> https://docs.projectcalico.org/manifests/calico.yaml</span><br></div></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="install-metrics-server">Install Metrics Server<a href="https://menraromial.com/blog/kubernetes-with-kubeadm-and-cri.io/#install-metrics-server" class="hash-link" aria-label="Direct link to Install Metrics Server" title="Direct link to Install Metrics Server" translate="no">​</a></h3>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">kubectl apply </span><span class="token parameter variable" style="color:#36acaa">-f</span><span class="token plain"> https://raw.githubusercontent.com/techiescamp/kubeadm-scripts/main/manifests/metrics-server.yaml</span><br></div></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="install-ingress-controller">Install Ingress Controller<a href="https://menraromial.com/blog/kubernetes-with-kubeadm-and-cri.io/#install-ingress-controller" class="hash-link" aria-label="Direct link to Install Ingress Controller" title="Direct link to Install Ingress Controller" translate="no">​</a></h3>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">kubectl apply </span><span class="token parameter variable" style="color:#36acaa">-f</span><span class="token plain"> https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v0.49.0/deploy/static/provider/baremetal/deploy.yaml</span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="step-7-join-worker-nodes-to-the-cluster">Step 7: Join Worker Nodes to the Cluster<a href="https://menraromial.com/blog/kubernetes-with-kubeadm-and-cri.io/#step-7-join-worker-nodes-to-the-cluster" class="hash-link" aria-label="Direct link to Step 7: Join Worker Nodes to the Cluster" title="Direct link to Step 7: Join Worker Nodes to the Cluster" translate="no">​</a></h2>
<p>Generate a join command on the master node:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">kubeadm token create --print-join-command</span><br></div></code></pre></div></div>
<p>Run the output command on worker nodes to join them to the cluster.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="step-8-verify-cluster-status">Step 8: Verify Cluster Status<a href="https://menraromial.com/blog/kubernetes-with-kubeadm-and-cri.io/#step-8-verify-cluster-status" class="hash-link" aria-label="Direct link to Step 8: Verify Cluster Status" title="Direct link to Step 8: Verify Cluster Status" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="check-nodes">Check Nodes<a href="https://menraromial.com/blog/kubernetes-with-kubeadm-and-cri.io/#check-nodes" class="hash-link" aria-label="Direct link to Check Nodes" title="Direct link to Check Nodes" translate="no">​</a></h3>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">kubectl get nodes</span><br></div></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="check-all-pods-in-a-specific-node">Check All Pods in a Specific Node<a href="https://menraromial.com/blog/kubernetes-with-kubeadm-and-cri.io/#check-all-pods-in-a-specific-node" class="hash-link" aria-label="Direct link to Check All Pods in a Specific Node" title="Direct link to Check All Pods in a Specific Node" translate="no">​</a></h3>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">kubectl get pods --all-namespaces --field-selector </span><span class="token assign-left variable" style="color:#36acaa">spec.nodeName</span><span class="token operator" style="color:#393A34">=</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token plain">NODE_NAME</span><span class="token operator" style="color:#393A34">&gt;</span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="troubleshooting-tips">Troubleshooting Tips<a href="https://menraromial.com/blog/kubernetes-with-kubeadm-and-cri.io/#troubleshooting-tips" class="hash-link" aria-label="Direct link to Troubleshooting Tips" title="Direct link to Troubleshooting Tips" translate="no">​</a></h2>
<ul>
<li class="">Always check system logs: <code>journalctl -u kubelet</code></li>
<li class="">Verify node status: <code>kubectl get nodes</code></li>
<li class="">Check pod status: <code>kubectl get pods --all-namespaces</code></li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="security-considerations">Security Considerations<a href="https://menraromial.com/blog/kubernetes-with-kubeadm-and-cri.io/#security-considerations" class="hash-link" aria-label="Direct link to Security Considerations" title="Direct link to Security Considerations" translate="no">​</a></h2>
<ul>
<li class="">Regularly update Kubernetes and CRI-O</li>
<li class="">Implement RBAC (Role-Based Access Control)</li>
<li class="">Use network policies</li>
<li class="">Regularly scan containers for vulnerabilities</li>
</ul>
<p><strong>Note</strong>: Always refer to the official Kubernetes and CRI-O documentation for the most up-to-date information and best practices.</p>]]></content>
        <author>
            <name>Menra Romial</name>
            <uri>https://menraromial.com</uri>
        </author>
        <category label="kubernetes" term="kubernetes"/>
        <category label="kubeadm" term="kubeadm"/>
        <category label="cri.io" term="cri.io"/>
        <category label="beginners" term="beginners"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Setting Up a K3s Cluster with a Hello-World Deployment]]></title>
        <id>https://menraromial.com/blog/setup-k3s-cluster/</id>
        <link href="https://menraromial.com/blog/setup-k3s-cluster/"/>
        <updated>2024-07-07T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Set up a lightweight Kubernetes cluster with K3s, deploy a Hello-World application, and explore namespaces, deployments, services and autoscaling.]]></summary>
        <content type="html"><![CDATA[<p>This tutorial will guide you through setting up a K3s cluster with one master node and two worker nodes, deploying a simple "Hello-World" application, and utilizing various <code>kubectl</code> commands to manage and inspect Kubernetes resources.</p>
<!-- -->
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="prerequisites">Prerequisites<a href="https://menraromial.com/blog/setup-k3s-cluster/#prerequisites" class="hash-link" aria-label="Direct link to Prerequisites" title="Direct link to Prerequisites" translate="no">​</a></h2>
<ul>
<li class="">Three Linux machines (or VMs) with access to each other.</li>
<li class="">Basic understanding of Linux commands and Kubernetes concepts.</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="step-1-installing-k3s">Step 1: Installing K3s<a href="https://menraromial.com/blog/setup-k3s-cluster/#step-1-installing-k3s" class="hash-link" aria-label="Direct link to Step 1: Installing K3s" title="Direct link to Step 1: Installing K3s" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="install-k3s-on-the-master-node">Install K3s on the Master Node<a href="https://menraromial.com/blog/setup-k3s-cluster/#install-k3s-on-the-master-node" class="hash-link" aria-label="Direct link to Install K3s on the Master Node" title="Direct link to Install K3s on the Master Node" translate="no">​</a></h3>
<ol>
<li class="">
<p><strong>SSH into the Master Node:</strong></p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token function" style="color:#d73a49">ssh</span><span class="token plain"> user@master-node-ip</span><br></div></code></pre></div></div>
</li>
<li class="">
<p><strong>Install K3s:</strong></p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token function" style="color:#d73a49">curl</span><span class="token plain"> </span><span class="token parameter variable" style="color:#36acaa">-sfL</span><span class="token plain"> https://get.k3s.io </span><span class="token operator" style="color:#393A34">|</span><span class="token plain">  </span><span class="token assign-left variable" style="color:#36acaa">INSTALL_K3S_VERSION</span><span class="token operator" style="color:#393A34">=</span><span class="token plain">v1.27.12+k3s1 </span><span class="token function" style="color:#d73a49">sh</span><span class="token plain"> </span><span class="token parameter variable" style="color:#36acaa">-s</span><span class="token plain"> - </span><span class="token parameter variable" style="color:#36acaa">--disable</span><span class="token plain"> traefik --write-kubeconfig-mode </span><span class="token number" style="color:#36acaa">644</span><span class="token plain"> --node-name </span><span class="token operator" style="color:#393A34">&lt;</span><span class="token plain">NODE_NAME</span><span class="token operator" style="color:#393A34">&gt;</span><br></div></code></pre></div></div>
</li>
</ol>
<p>The command installs K3s version <code>v1.27.12+k3s1</code> on a node named <code>&lt;NODE_NAME&gt;</code>, disables the default Traefik ingress controller, and sets the permissions for the kubeconfig file to <code>644</code>.</p>
<ol start="3">
<li class="">
<p><strong>Verify Installation:</strong></p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">kubectl get nodes</span><br></div></code></pre></div></div>
<p>You should see the master node listed.</p>
</li>
</ol>
<p><img decoding="async" loading="lazy" src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/97n9mbhc57emcmzbl4j9.png" alt="Image description" class="img_ev3q"></p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="install-k3s-on-the-worker-nodes">Install K3s on the Worker Nodes<a href="https://menraromial.com/blog/setup-k3s-cluster/#install-k3s-on-the-worker-nodes" class="hash-link" aria-label="Direct link to Install K3s on the Worker Nodes" title="Direct link to Install K3s on the Worker Nodes" translate="no">​</a></h3>
<ol>
<li class="">
<p><strong>SSH into each Worker Node:</strong></p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token function" style="color:#d73a49">ssh</span><span class="token plain"> user@worker-node-ip</span><br></div></code></pre></div></div>
</li>
<li class="">
<p><strong>Get the token from the master node</strong></p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token function" style="color:#d73a49">cat</span><span class="token plain"> /var/lib/rancher/k3s/server/node-token</span><br></div></code></pre></div></div>
</li>
<li class="">
<p><strong>Install K3s on Worker Nodes:</strong></p>
<p>On each worker node, run:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token function" style="color:#d73a49">curl</span><span class="token plain"> </span><span class="token parameter variable" style="color:#36acaa">-sfL</span><span class="token plain"> https://get.k3s.io </span><span class="token operator" style="color:#393A34">|</span><span class="token plain"> </span><span class="token assign-left variable" style="color:#36acaa">INSTALL_K3S_VERSION</span><span class="token operator" style="color:#393A34">=</span><span class="token plain">v1.27.12+k3s1  </span><span class="token assign-left variable" style="color:#36acaa">K3S_NODE_NAME</span><span class="token operator" style="color:#393A34">=</span><span class="token plain">YOUR_NODE_NAME </span><span class="token assign-left variable" style="color:#36acaa">K3S_URL</span><span class="token operator" style="color:#393A34">=</span><span class="token plain">https://master-node-ip:6443 </span><span class="token assign-left variable" style="color:#36acaa">K3S_TOKEN</span><span class="token operator" style="color:#393A34">=</span><span class="token plain">YOUR_NODE_TOKEN </span><span class="token function" style="color:#d73a49">sh</span><span class="token plain"> -</span><br></div></code></pre></div></div>
<p>You can find the <code>YOUR_NODE_TOKEN</code> value on the master node at <code>/var/lib/rancher/k3s/server/node-token</code>.</p>
</li>
</ol>
<p><img decoding="async" loading="lazy" src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0w2dhl0ynwvsr5r19e2j.png" alt="Image description" class="img_ev3q"></p>
<ol start="3">
<li class="">
<p><strong>Verify Worker Nodes Join the Cluster:</strong></p>
<p>On the master node, run:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">kubectl get nodes</span><br></div></code></pre></div></div>
<p>You should see all nodes (master and workers) listed.</p>
</li>
</ol>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="step-2-verifying-node-status">Step 2: Verifying Node Status<a href="https://menraromial.com/blog/setup-k3s-cluster/#step-2-verifying-node-status" class="hash-link" aria-label="Direct link to Step 2: Verifying Node Status" title="Direct link to Step 2: Verifying Node Status" translate="no">​</a></h2>
<p>To check the status of the nodes:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">kubectl get nodes</span><br></div></code></pre></div></div>
<p>You should see the master and worker nodes with the status <code>Ready</code>.</p>
<p><img decoding="async" loading="lazy" src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/js3ik5rdbentis2q3rvv.png" alt="Image description" class="img_ev3q"></p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="step-3-creating-a-pod">Step 3: Creating a Pod<a href="https://menraromial.com/blog/setup-k3s-cluster/#step-3-creating-a-pod" class="hash-link" aria-label="Direct link to Step 3: Creating a Pod" title="Direct link to Step 3: Creating a Pod" translate="no">​</a></h2>
<p>Create a simple pod to ensure everything is working correctly.</p>
<ol>
<li class="">
<p><strong>Create a YAML file named <code>hello-world-pod.yaml</code>:</strong></p>
<div class="language-yaml codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-yaml codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token key atrule" style="color:#00a4db">apiVersion</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> v1</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token key atrule" style="color:#00a4db">kind</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> Pod</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token key atrule" style="color:#00a4db">metadata</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token key atrule" style="color:#00a4db">name</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> hello</span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain">world</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token key atrule" style="color:#00a4db">spec</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token key atrule" style="color:#00a4db">containers</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain"> </span><span class="token key atrule" style="color:#00a4db">name</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> hello</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token key atrule" style="color:#00a4db">image</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> busybox  </span><span class="token comment" style="color:#999988;font-style:italic"># Replace with your desired Docker image</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div></code></pre></div></div>
</li>
<li class="">
<p><strong>Apply the YAML file to create the pod:</strong></p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">kubectl apply </span><span class="token parameter variable" style="color:#36acaa">-f</span><span class="token plain"> hello-world-pod.yaml</span><br></div></code></pre></div></div>
</li>
<li class="">
<p><strong>Verify the Pod is Running:</strong></p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">kubectl get pods</span><br></div></code></pre></div></div>
</li>
<li class="">
<p><strong>Describe the Pod:</strong></p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">kubectl describe pod hello-world</span><br></div></code></pre></div></div>
</li>
</ol>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="step-4-deleting-the-pod">Step 4: Deleting the Pod<a href="https://menraromial.com/blog/setup-k3s-cluster/#step-4-deleting-the-pod" class="hash-link" aria-label="Direct link to Step 4: Deleting the Pod" title="Direct link to Step 4: Deleting the Pod" translate="no">​</a></h2>
<p>To delete the pod:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">kubectl delete pod hello-world</span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="step-5-deploying-the-application">Step 5: Deploying the Application<a href="https://menraromial.com/blog/setup-k3s-cluster/#step-5-deploying-the-application" class="hash-link" aria-label="Direct link to Step 5: Deploying the Application" title="Direct link to Step 5: Deploying the Application" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="creating-a-namespace">Creating a namespace<a href="https://menraromial.com/blog/setup-k3s-cluster/#creating-a-namespace" class="hash-link" aria-label="Direct link to Creating a namespace" title="Direct link to Creating a namespace" translate="no">​</a></h3>
<p>A namespace in Kubernetes is used to organize and manage resources within a cluster, providing isolation and a way to divide cluster resources among multiple users or teams.</p>
<p>The commands used in this process are:</p>
<ol>
<li class="">
<p><strong>View Existing Namespaces</strong>:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">kubectl get namespaces</span><br></div></code></pre></div></div>
<p>or</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">kubectl get ns</span><br></div></code></pre></div></div>
</li>
<li class="">
<p><strong>Create a New Namespace</strong>:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">kubectl create namespace demo</span><br></div></code></pre></div></div>
</li>
<li class="">
<p><strong>Verify the Creation of the Namespace</strong>:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">kubectl get namespaces</span><br></div></code></pre></div></div>
</li>
</ol>
<p>This process ensures you have successfully created the <code>demo</code> namespace and confirmed its presence in your Kubernetes cluster.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="deployment-yaml-file">Deployment YAML File<a href="https://menraromial.com/blog/setup-k3s-cluster/#deployment-yaml-file" class="hash-link" aria-label="Direct link to Deployment YAML File" title="Direct link to Deployment YAML File" translate="no">​</a></h3>
<p>A deployment in Kubernetes is a controller that manages the creation, scaling, and updating of a set of replicated Pods, ensuring the desired state of an application is maintained.</p>
<p>Create a file named <code>hello-world-deployment.yaml</code> with the following content:</p>
<div class="language-yaml codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-yaml codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token key atrule" style="color:#00a4db">apiVersion</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> apps/v1</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token key atrule" style="color:#00a4db">kind</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> Deployment</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token key atrule" style="color:#00a4db">metadata</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">name</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> hello</span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain">world</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">namespace</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> demo</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token key atrule" style="color:#00a4db">spec</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">replicas</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">5</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">selector</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token key atrule" style="color:#00a4db">matchLabels</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token key atrule" style="color:#00a4db">app</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> hello</span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain">world</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">template</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token key atrule" style="color:#00a4db">metadata</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token key atrule" style="color:#00a4db">labels</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token key atrule" style="color:#00a4db">app</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> hello</span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain">world</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token key atrule" style="color:#00a4db">spec</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token key atrule" style="color:#00a4db">containers</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain"> </span><span class="token key atrule" style="color:#00a4db">name</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> hello</span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain">world</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">          </span><span class="token key atrule" style="color:#00a4db">image</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> bashofmann/rancher</span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain">demo</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain">1.0.0</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">          </span><span class="token key atrule" style="color:#00a4db">imagePullPolicy</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> Always</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">          </span><span class="token key atrule" style="color:#00a4db">resources</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token key atrule" style="color:#00a4db">requests</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">              </span><span class="token key atrule" style="color:#00a4db">memory</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"12Mi"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">              </span><span class="token key atrule" style="color:#00a4db">cpu</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"2m"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">          </span><span class="token key atrule" style="color:#00a4db">ports</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain"> </span><span class="token key atrule" style="color:#00a4db">containerPort</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">8080</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">              </span><span class="token key atrule" style="color:#00a4db">name</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> web</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">              </span><span class="token key atrule" style="color:#00a4db">protocol</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> TCP</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">          </span><span class="token key atrule" style="color:#00a4db">env</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain"> </span><span class="token key atrule" style="color:#00a4db">name</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> COW_COLOR</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">              </span><span class="token key atrule" style="color:#00a4db">value</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> purple</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">          </span><span class="token key atrule" style="color:#00a4db">readinessProbe</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token key atrule" style="color:#00a4db">httpGet</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">              </span><span class="token key atrule" style="color:#00a4db">path</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> /</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">              </span><span class="token key atrule" style="color:#00a4db">port</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> web</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">          </span><span class="token key atrule" style="color:#00a4db">livenessProbe</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token key atrule" style="color:#00a4db">httpGet</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">              </span><span class="token key atrule" style="color:#00a4db">path</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> /</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">              </span><span class="token key atrule" style="color:#00a4db">port</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> web</span><br></div></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="explanation-of-the-yaml-file">Explanation of the YAML File<a href="https://menraromial.com/blog/setup-k3s-cluster/#explanation-of-the-yaml-file" class="hash-link" aria-label="Direct link to Explanation of the YAML File" title="Direct link to Explanation of the YAML File" translate="no">​</a></h3>
<ul>
<li class=""><strong>apiVersion</strong>: Specifies the version of the Kubernetes API to use.</li>
<li class=""><strong>kind</strong>: Specifies the type of resource being created (Deployment).</li>
<li class=""><strong>metadata</strong>: Contains data that helps uniquely identify the object, including a <code>name</code> and <code>namespace</code>.</li>
<li class=""><strong>spec</strong>: Defines the desired state of the Deployment.
<ul>
<li class=""><strong>replicas</strong>: Number of pod replicas to run.</li>
<li class=""><strong>selector</strong>: Defines how the Deployment finds which Pods to manage.</li>
<li class=""><strong>template</strong>: Defines the Pods that will be created.
<ul>
<li class=""><strong>metadata</strong>: Labels for the Pods.</li>
<li class=""><strong>spec</strong>: Specification of the containers within the Pods.
<ul>
<li class=""><strong>containers</strong>: List of containers in the Pod.
<ul>
<li class=""><strong>name</strong>: Name of the container.</li>
<li class=""><strong>image</strong>: Docker image to use for the container.</li>
<li class=""><strong>imagePullPolicy</strong>: Policy to use for image pulls.</li>
<li class=""><strong>ports</strong>: Ports to expose from the container.</li>
<li class=""><strong>env</strong>: Environment variables for the container.</li>
<li class=""><strong>readinessProbe</strong>: Defines a probe to check if the container is ready.</li>
<li class=""><strong>livenessProbe</strong>: Defines a probe to check if the container is alive.</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
<hr>
<p>This is a Go demo application used for demonstrating Kubernetes and load balancing.</p>
<p>It will create a colored icon for each replica within a ReplicaSet and indicate which one most recently served a response. Replicas which haven't been heard from will begin to fade out, until after a configurable number of seconds they will disappear.</p>
<p>For more information on using the container image, please click <a href="https://github.com/bashofmann/rancher-demo" target="_blank" rel="noopener noreferrer" class="">here</a>.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="apply-the-deployment">Apply the Deployment<a href="https://menraromial.com/blog/setup-k3s-cluster/#apply-the-deployment" class="hash-link" aria-label="Direct link to Apply the Deployment" title="Direct link to Apply the Deployment" translate="no">​</a></h3>
<ol>
<li class="">
<p><strong>Apply the YAML file to create the Deployment:</strong></p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">kubectl apply </span><span class="token parameter variable" style="color:#36acaa">-f</span><span class="token plain"> hello-world-deployment.yaml</span><br></div></code></pre></div></div>
</li>
<li class="">
<p><strong>Verify the Deployment and Pods:</strong></p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">kubectl get deployments </span><span class="token parameter variable" style="color:#36acaa">-n</span><span class="token plain"> demo</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">kubectl get pods </span><span class="token parameter variable" style="color:#36acaa">-n</span><span class="token plain"> demo</span><br></div></code></pre></div></div>
</li>
<li class="">
<p><strong>Check the ReplicaSets:</strong></p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">kubectl get replicaset </span><span class="token parameter variable" style="color:#36acaa">-n</span><span class="token plain"> demo</span><br></div></code></pre></div></div>
</li>
<li class="">
<p><strong>For more information on replicas:</strong></p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">kubectl get pods </span><span class="token parameter variable" style="color:#36acaa">-n</span><span class="token plain"> demo </span><span class="token parameter variable" style="color:#36acaa">-o</span><span class="token plain"> wide</span><br></div></code></pre></div></div>
<p><code>-o wide</code>: Provides additional details about each pod, such as the node it's running on, the IP address, the container images, and more.</p>
</li>
<li class="">
<p><strong>See the pods metrics</strong></p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">kubectl </span><span class="token function" style="color:#d73a49">top</span><span class="token plain"> pods </span><span class="token parameter variable" style="color:#36acaa">-n</span><span class="token plain"> demo</span><br></div></code></pre></div></div>
<p>For nodes</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">kubectl </span><span class="token function" style="color:#d73a49">top</span><span class="token plain"> nodes</span><br></div></code></pre></div></div>
</li>
</ol>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="step-6-exposing-the-application">Step 6: Exposing the Application<a href="https://menraromial.com/blog/setup-k3s-cluster/#step-6-exposing-the-application" class="hash-link" aria-label="Direct link to Step 6: Exposing the Application" title="Direct link to Step 6: Exposing the Application" translate="no">​</a></h2>
<p>Create a service to expose the Deployment.</p>
<p>A service in Kubernetes provides a stable network endpoint to access a set of pods, ensuring consistent access despite pod restarts or IP changes.</p>
<h4 class="anchor anchorTargetStickyNavbar_Vzrq" id="types-of-services">Types of Services:<a href="https://menraromial.com/blog/setup-k3s-cluster/#types-of-services" class="hash-link" aria-label="Direct link to Types of Services:" title="Direct link to Types of Services:" translate="no">​</a></h4>
<ul>
<li class=""><strong>ClusterIP</strong>: Exposes the service on an internal IP within the cluster, making it accessible only within the cluster.</li>
<li class=""><strong>NodePort</strong>: Exposes the service on each node's IP at a static port, making it accessible from outside the cluster using <code>&lt;NodeIP&gt;:&lt;NodePort&gt;</code>.</li>
<li class=""><strong>LoadBalancer</strong>: Exposes the service externally using a cloud provider's load balancer.</li>
<li class=""><strong>ExternalName</strong>: Maps the service to the contents of the <code>externalName</code> field (e.g., <code>foo.bar.example.com</code>), creating a DNS alias.</li>
</ul>
<ol>
<li class="">
<p><strong>Create a ClusterIP Service:</strong></p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">kubectl expose deployment hello-world </span><span class="token parameter variable" style="color:#36acaa">--type</span><span class="token operator" style="color:#393A34">=</span><span class="token plain">ClusterIP </span><span class="token parameter variable" style="color:#36acaa">--name</span><span class="token operator" style="color:#393A34">=</span><span class="token plain">hello-world-service </span><span class="token parameter variable" style="color:#36acaa">--port</span><span class="token operator" style="color:#393A34">=</span><span class="token number" style="color:#36acaa">8080</span><span class="token plain"> --target-port</span><span class="token operator" style="color:#393A34">=</span><span class="token number" style="color:#36acaa">8080</span><span class="token plain"> </span><span class="token parameter variable" style="color:#36acaa">-n</span><span class="token plain"> demo</span><br></div></code></pre></div></div>
<ul>
<li class=""><strong>expose deployment hello-world</strong>: Creates a service to expose the deployment named <code>hello-world</code>.</li>
<li class=""><strong><code>--type=ClusterIP</code></strong>: Specifies the type of service to create. <code>ClusterIP</code> means the service will be accessible only within the cluster.</li>
<li class=""><strong><code>--name=hello-world-service</code></strong>: Assigns the name <code>hello-world-service</code> to the newly created service.</li>
<li class=""><strong><code>--port=8080</code></strong>: Defines the port on which the service will be exposed.</li>
<li class=""><strong><code>--target-port=8080</code></strong>: Specifies the port on the pod that the service should forward traffic to.</li>
<li class=""><strong><code>-n demo</code></strong>: Limits the scope of the command to the <code>demo</code> namespace.</li>
</ul>
</li>
<li class="">
<p><strong>Verify the Service:</strong></p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">kubectl get svc </span><span class="token parameter variable" style="color:#36acaa">-n</span><span class="token plain"> demo</span><br></div></code></pre></div></div>
</li>
</ol>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="step-7-accessing-the-application">Step 7: Accessing the Application<a href="https://menraromial.com/blog/setup-k3s-cluster/#step-7-accessing-the-application" class="hash-link" aria-label="Direct link to Step 7: Accessing the Application" title="Direct link to Step 7: Accessing the Application" translate="no">​</a></h2>
<p>To access the application from your local machine, use <code>kubectl port-forward</code>:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">kubectl port-forward svc/hello-world-service </span><span class="token number" style="color:#36acaa">8080</span><span class="token plain">:8080 </span><span class="token parameter variable" style="color:#36acaa">-n</span><span class="token plain"> demo </span><span class="token parameter variable" style="color:#36acaa">--address</span><span class="token plain"> node_address</span><br></div></code></pre></div></div>
<p>Open your browser and go to <code>http://node_address:8080</code> to see the application in action.</p>
<ol>
<li class=""><strong>Create a service of type LoadBalancer</strong></li>
</ol>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">kubectl expose deployment hello-world </span><span class="token parameter variable" style="color:#36acaa">--type</span><span class="token operator" style="color:#393A34">=</span><span class="token plain">LoadBalancer </span><span class="token parameter variable" style="color:#36acaa">--name</span><span class="token operator" style="color:#393A34">=</span><span class="token plain">hello-world-service-loadbalancing </span><span class="token parameter variable" style="color:#36acaa">--port</span><span class="token operator" style="color:#393A34">=</span><span class="token number" style="color:#36acaa">8080</span><span class="token plain"> --target-port</span><span class="token operator" style="color:#393A34">=</span><span class="token number" style="color:#36acaa">8080</span><span class="token plain"> </span><span class="token parameter variable" style="color:#36acaa">-n</span><span class="token plain"> demo</span><br></div></code></pre></div></div>
<p>Open your browser and go to <code>http://any_node_address:PORT</code> to see the application in action.
<code>PORT</code> here is generated by default, see the image below.</p>
<p><img decoding="async" loading="lazy" src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2r1n2277m60ukt74wohs.png" alt="Image description" class="img_ev3q"></p>
<p>Application on the browser</p>
<p><img decoding="async" loading="lazy" src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0mah2fyxsrjsat6wdah6.png" alt="Image description" class="img_ev3q"></p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="step-8-inspecting-resources">Step 8: Inspecting Resources<a href="https://menraromial.com/blog/setup-k3s-cluster/#step-8-inspecting-resources" class="hash-link" aria-label="Direct link to Step 8: Inspecting Resources" title="Direct link to Step 8: Inspecting Resources" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="describing-a-pod">Describing a Pod<a href="https://menraromial.com/blog/setup-k3s-cluster/#describing-a-pod" class="hash-link" aria-label="Direct link to Describing a Pod" title="Direct link to Describing a Pod" translate="no">​</a></h3>
<p>To get detailed information about a specific pod:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">kubectl describe pod </span><span class="token operator" style="color:#393A34">&lt;</span><span class="token plain">pod-name</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token plain"> </span><span class="token parameter variable" style="color:#36acaa">-n</span><span class="token plain"> demo</span><br></div></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="describing-a-deployment">Describing a Deployment<a href="https://menraromial.com/blog/setup-k3s-cluster/#describing-a-deployment" class="hash-link" aria-label="Direct link to Describing a Deployment" title="Direct link to Describing a Deployment" translate="no">​</a></h3>
<p>To get detailed information about the deployment:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">kubectl describe deployment hello-world </span><span class="token parameter variable" style="color:#36acaa">-n</span><span class="token plain"> demo</span><br></div></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="viewing-pod-logs">Viewing Pod Logs<a href="https://menraromial.com/blog/setup-k3s-cluster/#viewing-pod-logs" class="hash-link" aria-label="Direct link to Viewing Pod Logs" title="Direct link to Viewing Pod Logs" translate="no">​</a></h3>
<p>To view the logs of a pod:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">kubectl logs </span><span class="token parameter variable" style="color:#36acaa">-f</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">&lt;</span><span class="token plain">pod-name</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token plain"> </span><span class="token parameter variable" style="color:#36acaa">-n</span><span class="token plain"> demo</span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="step-9-cleaning-up">Step 9: Cleaning Up<a href="https://menraromial.com/blog/setup-k3s-cluster/#step-9-cleaning-up" class="hash-link" aria-label="Direct link to Step 9: Cleaning Up" title="Direct link to Step 9: Cleaning Up" translate="no">​</a></h2>
<p>To delete all the resources created:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">kubectl delete namespace demo</span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="conclusion">Conclusion<a href="https://menraromial.com/blog/setup-k3s-cluster/#conclusion" class="hash-link" aria-label="Direct link to Conclusion" title="Direct link to Conclusion" translate="no">​</a></h2>
<p>You've successfully set up a K3s cluster, deployed a simple application, and used various <code>kubectl</code> commands to manage and inspect Kubernetes resources. This foundation will help you explore Kubernetes further and leverage its capabilities.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="bonus">Bonus<a href="https://menraromial.com/blog/setup-k3s-cluster/#bonus" class="hash-link" aria-label="Direct link to Bonus" title="Direct link to Bonus" translate="no">​</a></h2>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="scaling-and-deploying-a-horizontal-pod-autoscaler-in-kubernetes">Scaling and Deploying a Horizontal Pod Autoscaler in Kubernetes<a href="https://menraromial.com/blog/setup-k3s-cluster/#scaling-and-deploying-a-horizontal-pod-autoscaler-in-kubernetes" class="hash-link" aria-label="Direct link to Scaling and Deploying a Horizontal Pod Autoscaler in Kubernetes" title="Direct link to Scaling and Deploying a Horizontal Pod Autoscaler in Kubernetes" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="step-1-scaling-updown-manually">Step 1: Scaling Up/Down Manually<a href="https://menraromial.com/blog/setup-k3s-cluster/#step-1-scaling-updown-manually" class="hash-link" aria-label="Direct link to Step 1: Scaling Up/Down Manually" title="Direct link to Step 1: Scaling Up/Down Manually" translate="no">​</a></h3>
<p>You can manually scale the number of replicas in a deployment using the <code>kubectl scale</code> command.</p>
<h4 class="anchor anchorTargetStickyNavbar_Vzrq" id="scale-up">Scale Up<a href="https://menraromial.com/blog/setup-k3s-cluster/#scale-up" class="hash-link" aria-label="Direct link to Scale Up" title="Direct link to Scale Up" translate="no">​</a></h4>
<p>To scale the <code>hello-world</code> deployment to 10 replicas:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">kubectl scale deployment hello-world </span><span class="token parameter variable" style="color:#36acaa">--replicas</span><span class="token operator" style="color:#393A34">=</span><span class="token number" style="color:#36acaa">10</span><span class="token plain"> </span><span class="token parameter variable" style="color:#36acaa">-n</span><span class="token plain"> demo</span><br></div></code></pre></div></div>
<h4 class="anchor anchorTargetStickyNavbar_Vzrq" id="scale-down">Scale Down<a href="https://menraromial.com/blog/setup-k3s-cluster/#scale-down" class="hash-link" aria-label="Direct link to Scale Down" title="Direct link to Scale Down" translate="no">​</a></h4>
<p>To scale the <code>hello-world</code> deployment back down to 3 replicas:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">kubectl scale deployment hello-world </span><span class="token parameter variable" style="color:#36acaa">--replicas</span><span class="token operator" style="color:#393A34">=</span><span class="token number" style="color:#36acaa">3</span><span class="token plain"> </span><span class="token parameter variable" style="color:#36acaa">-n</span><span class="token plain"> demo</span><br></div></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="step-2-deploying-a-horizontal-pod-autoscaler-hpa">Step 2: Deploying a Horizontal Pod Autoscaler (HPA)<a href="https://menraromial.com/blog/setup-k3s-cluster/#step-2-deploying-a-horizontal-pod-autoscaler-hpa" class="hash-link" aria-label="Direct link to Step 2: Deploying a Horizontal Pod Autoscaler (HPA)" title="Direct link to Step 2: Deploying a Horizontal Pod Autoscaler (HPA)" translate="no">​</a></h3>
<p>The Horizontal Pod Autoscaler automatically adjusts the number of pod replicas in a deployment based on observed CPU utilization (or other select metrics).</p>
<h4 class="anchor anchorTargetStickyNavbar_Vzrq" id="prerequisites-1">Prerequisites<a href="https://menraromial.com/blog/setup-k3s-cluster/#prerequisites-1" class="hash-link" aria-label="Direct link to Prerequisites" title="Direct link to Prerequisites" translate="no">​</a></h4>
<p>Ensure that the Metrics Server is deployed in your cluster. The Metrics Server collects resource metrics from the Kubernetes nodes and pods and is required for HPA to function.</p>
<p>To install the Metrics Server:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">kubectl apply </span><span class="token parameter variable" style="color:#36acaa">-f</span><span class="token plain"> https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml</span><br></div></code></pre></div></div>
<h4 class="anchor anchorTargetStickyNavbar_Vzrq" id="deploy-hpa-for-the-hello-world-deployment">Deploy HPA for the <code>hello-world</code> Deployment<a href="https://menraromial.com/blog/setup-k3s-cluster/#deploy-hpa-for-the-hello-world-deployment" class="hash-link" aria-label="Direct link to deploy-hpa-for-the-hello-world-deployment" title="Direct link to deploy-hpa-for-the-hello-world-deployment" translate="no">​</a></h4>
<ol>
<li class="">
<p><strong>Create the HPA</strong></p>
<p>Create the file <code>hello-world-hpa.yaml</code></p>
<div class="language-yaml codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-yaml codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token key atrule" style="color:#00a4db">apiVersion</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> autoscaling/v2</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token key atrule" style="color:#00a4db">kind</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> HorizontalPodAutoscaler</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token key atrule" style="color:#00a4db">metadata</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">   </span><span class="token key atrule" style="color:#00a4db">name</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> hello</span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain">world</span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain">autoscaler</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">   </span><span class="token key atrule" style="color:#00a4db">namespace</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> demo</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token key atrule" style="color:#00a4db">spec</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">   </span><span class="token key atrule" style="color:#00a4db">scaleTargetRef</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">     </span><span class="token key atrule" style="color:#00a4db">apiVersion</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> apps/v1</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">     </span><span class="token key atrule" style="color:#00a4db">kind</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> Deployment</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">     </span><span class="token key atrule" style="color:#00a4db">name</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> hello</span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain">world</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">   </span><span class="token key atrule" style="color:#00a4db">minReplicas</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">5</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">   </span><span class="token key atrule" style="color:#00a4db">maxReplicas</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">20</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">   </span><span class="token key atrule" style="color:#00a4db">metrics</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">   </span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain"> </span><span class="token key atrule" style="color:#00a4db">type</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> Resource</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">     </span><span class="token key atrule" style="color:#00a4db">resource</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">       </span><span class="token key atrule" style="color:#00a4db">name</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> cpu</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">       </span><span class="token key atrule" style="color:#00a4db">target</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">         </span><span class="token key atrule" style="color:#00a4db">type</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> Utilization</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">         </span><span class="token key atrule" style="color:#00a4db">averageUtilization</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">70</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">   </span><span class="token key atrule" style="color:#00a4db">behavior</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">     </span><span class="token key atrule" style="color:#00a4db">scaleUp</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">       </span><span class="token key atrule" style="color:#00a4db">stabilizationWindowSeconds</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">10</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">       </span><span class="token key atrule" style="color:#00a4db">policies</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">       </span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain"> </span><span class="token key atrule" style="color:#00a4db">type</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> Pods</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">         </span><span class="token key atrule" style="color:#00a4db">value</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">1</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">         </span><span class="token key atrule" style="color:#00a4db">periodSeconds</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">5</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">     </span><span class="token key atrule" style="color:#00a4db">scaleDown</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">       </span><span class="token key atrule" style="color:#00a4db">stabilizationWindowSeconds</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">10</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">       </span><span class="token key atrule" style="color:#00a4db">policies</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">       </span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain"> </span><span class="token key atrule" style="color:#00a4db">type</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> Pods</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">         </span><span class="token key atrule" style="color:#00a4db">value</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">1</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">         </span><span class="token key atrule" style="color:#00a4db">periodSeconds</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">5</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div></code></pre></div></div>
<p>Apply</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">kubectl apply </span><span class="token parameter variable" style="color:#36acaa">-f</span><span class="token plain"> hello-world-hpa.yaml</span><br></div></code></pre></div></div>
<p>This command sets up an HPA for the <code>hello-world</code> deployment that:</p>
<ul>
<li class="">Targets 70% CPU utilization.</li>
<li class="">Scales the number of pod replicas between 1 and 10 based on the observed CPU utilization.</li>
</ul>
</li>
<li class="">
<p><strong>Verify the HPA</strong></p>
<p>To check the status of the HPA:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">kubectl get hpa </span><span class="token parameter variable" style="color:#36acaa">-n</span><span class="token plain"> demo</span><br></div></code></pre></div></div>
<p>The output should show something like this:</p>
<div class="language-plaintext codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-plaintext codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">NAME          REFERENCE                TARGETS   MINPODS   MAXPODS   REPLICAS   AGE</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">hello-world   Deployment/hello-world   10%/50%   1         10        3          5m</span><br></div></code></pre></div></div>
</li>
</ol>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="step-3-testing-the-hpa">Step 3: Testing the HPA<a href="https://menraromial.com/blog/setup-k3s-cluster/#step-3-testing-the-hpa" class="hash-link" aria-label="Direct link to Step 3: Testing the HPA" title="Direct link to Step 3: Testing the HPA" translate="no">​</a></h3>
<p>To test the HPA, you can simulate a load on the <code>hello-world</code> pods to observe the scaling behavior. Here's how you can do it:</p>
<ol>
<li class="">
<p><strong>Run a Load Generator Pod</strong></p>
<p>Create a pod that continuously sends requests to the <code>hello-world</code> service. Create a file named <code>load-generator.yaml</code> with the following content:</p>
<div class="language-yaml codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-yaml codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token key atrule" style="color:#00a4db">apiVersion</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> v1</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token key atrule" style="color:#00a4db">kind</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> Pod</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token key atrule" style="color:#00a4db">metadata</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">name</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> load</span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain">generator</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">namespace</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> demo</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token key atrule" style="color:#00a4db">spec</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token key atrule" style="color:#00a4db">containers</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain"> </span><span class="token key atrule" style="color:#00a4db">name</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> busybox</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token key atrule" style="color:#00a4db">image</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> busybox</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token key atrule" style="color:#00a4db">args</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain"> /bin/sh</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain">c</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">|</span><span class="token scalar string" style="color:#e3116c"></span><br></div><div class="token-line" style="color:#393A34"><span class="token scalar string" style="color:#e3116c">      while true; do wget -q -O- http://NODE_IP_ADDRESS:8080; done</span><br></div></code></pre></div></div>
<p>Apply this YAML file:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">kubectl apply </span><span class="token parameter variable" style="color:#36acaa">-f</span><span class="token plain"> load-generator.yaml</span><br></div></code></pre></div></div>
</li>
<li class="">
<p><strong>Monitor the HPA</strong></p>
<p>Keep an eye on the HPA status to see how it adjusts the number of replicas:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token function" style="color:#d73a49">watch</span><span class="token plain"> </span><span class="token parameter variable" style="color:#36acaa">-n3</span><span class="token plain"> kubectl get hpa,pod </span><span class="token parameter variable" style="color:#36acaa">-n</span><span class="token plain"> demo </span><span class="token parameter variable" style="color:#36acaa">-o</span><span class="token plain"> wide</span><br></div></code></pre></div></div>
<p>You should see the <code>TARGETS</code> column indicating higher CPU utilization, and the <code>REPLICAS</code> column increasing as the HPA scales up the deployment.</p>
</li>
<li class="">
<p><strong>Stop the Load Generator</strong></p>
<p>Once you've observed the scaling behavior, delete the load generator pod:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">kubectl delete pod load-generator </span><span class="token parameter variable" style="color:#36acaa">-n</span><span class="token plain"> demo</span><br></div></code></pre></div></div>
</li>
</ol>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="summary">Summary<a href="https://menraromial.com/blog/setup-k3s-cluster/#summary" class="hash-link" aria-label="Direct link to Summary" title="Direct link to Summary" translate="no">​</a></h3>
<ul>
<li class=""><strong>Manual Scaling</strong>: Use <code>kubectl scale</code> to manually adjust the number of replicas.</li>
<li class=""><strong>Horizontal Pod Autoscaler (HPA)</strong>: Automatically adjusts the number of replicas based on CPU utilization (or other metrics).</li>
<li class=""><strong>Metrics Server</strong>: Required for HPA to function, it collects resource metrics.</li>
<li class=""><strong>Testing HPA</strong>: Use a load generator to simulate traffic and observe the HPA scaling behavior.</li>
</ul>
<p>This guide helps you understand and implement both manual and automatic scaling in Kubernetes, ensuring your applications can handle varying loads efficiently.</p>
<p><strong>Congratulations !!!</strong></p>
<blockquote>
<p>Why did the Kubernetes developer go broke?
Because he lost all his containers! 🤣</p>
</blockquote>
<hr>]]></content>
        <author>
            <name>Menra Romial</name>
            <uri>https://menraromial.com</uri>
        </author>
        <category label="kubernetes" term="kubernetes"/>
        <category label="k3s" term="k3s"/>
        <category label="beginners" term="beginners"/>
    </entry>
</feed>