<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[DevOps Journey with M Hassan]]></title><description><![CDATA[I am writing these blogs because I recently completed a comprehensive DevOps course where I gained in-depth knowledge of the topics mentioned. As I progressed t]]></description><link>https://hassandevops.com</link><generator>RSS for Node</generator><lastBuildDate>Wed, 15 Apr 2026 17:58:04 GMT</lastBuildDate><atom:link href="https://hassandevops.com/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[🤖 From Chatbots to AI Agents — Understanding the Agent Era (Lecture 1 Notes)]]></title><description><![CDATA[The world of AI is rapidly evolving. We are moving from simple chatbots that answer questions to intelligent agents that can think, plan, and take actions.
In this blog, I’ll break down the key concep]]></description><link>https://hassandevops.com/from-chatbots-to-ai-agents-understanding-the-agent-era-lecture-1-notes</link><guid isPermaLink="true">https://hassandevops.com/from-chatbots-to-ai-agents-understanding-the-agent-era-lecture-1-notes</guid><dc:creator><![CDATA[Muhammad Hassan]]></dc:creator><pubDate>Mon, 23 Feb 2026 07:47:41 GMT</pubDate><enclosure url="https://cloudmate-test.s3.us-east-1.amazonaws.com/uploads/covers/6463a2a12777a9c8a9df119e/e381141a-773c-4df5-b74a-9c562741e0f3.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>The world of AI is rapidly evolving. We are moving from simple chatbots that answer questions to intelligent agents that can <strong>think, plan, and take actions</strong>.</p>
<p>In this blog, I’ll break down the key concepts from Lecture 1, including:</p>
<ul>
<li><p>Chatbot vs Agent differences</p>
</li>
<li><p>Agent architecture</p>
</li>
<li><p>Why the “Agent Era” has started</p>
</li>
<li><p>Operational challenges</p>
</li>
<li><p>Scaling AI agents in production</p>
</li>
</ul>
<p>Let’s dive in.</p>
<hr />
<h2>🧠 Chatbot vs AI Agent — The Fundamental Difference</h2>
<p>The lecture begins by explaining the core difference.</p>
<p>A <strong>chatbot</strong> is reactive — it waits for input and produces a response.</p>
<p>An <strong>AI agent</strong>, however, is proactive — it can decide, plan, and execute tasks.</p>
<p>According to the slide on <strong>page 1</strong>, the key differences are:</p>
<h3>Chatbot</h3>
<ul>
<li><p>Role: Interface</p>
</li>
<li><p>Function: Reactive</p>
</li>
<li><p>Output: Answers questions</p>
</li>
<li><p>Status: No real decision-making</p>
</li>
</ul>
<h3>AI Agent</h3>
<ul>
<li><p>Role: Operator</p>
</li>
<li><p>Function: Goal-driven</p>
</li>
<li><p>Output: Executes workflows</p>
</li>
<li><p>Status: Makes decisions</p>
</li>
</ul>
<p>👉 The best summary from the slide:</p>
<blockquote>
<p>“One waits for input; the other takes action.”</p>
<p>1</p>
</blockquote>
<hr />
<h2>🔄 How Chatbots Work vs How Agents Work</h2>
<p>The architecture is completely different.</p>
<h3>Chatbot Flow</h3>
<p>As shown on <strong>page 2</strong>, chatbot processing is simple:</p>
<pre><code class="language-plaintext">Input → LLM Prediction → Output
</code></pre>
<p>Characteristics:</p>
<ul>
<li><p>Stateless</p>
</li>
<li><p>Single-shot response</p>
</li>
<li><p>No memory</p>
</li>
<li><p>No tool usage</p>
</li>
</ul>
<hr />
<h3>Agent Loop</h3>
<p>Agents operate in a continuous loop:</p>
<ul>
<li><p>Perception (understanding input)</p>
</li>
<li><p>Reasoning (planning)</p>
</li>
<li><p>Tool usage</p>
</li>
<li><p>Action</p>
</li>
<li><p>Reflection (self-correction)</p>
</li>
</ul>
<p>This makes agents:</p>
<ul>
<li><p>Stateful</p>
</li>
<li><p>Multi-step</p>
</li>
<li><p>Self-correcting</p>
</li>
<li><p>Capable of retries</p>
<p>1</p>
</li>
</ul>
<hr />
<h2>🚀 Why We Entered the “Agent Era”</h2>
<p>According to <strong>page 3</strong>, three major technological advancements made AI agents possible:</p>
<h3>1️⃣ Reasoning Costs Dropped</h3>
<p>Modern models like GPT-4 can plan tasks efficiently.</p>
<hr />
<h3>2️⃣ Tool Interfaces Standardized</h3>
<p>Universal function calling allows agents to interact with APIs easily.</p>
<hr />
<h3>3️⃣ Memory Systems Matured</h3>
<p>Vector databases allow agents to retain context and history.</p>
<hr />
<p>Because of these changes, AI is evolving:</p>
<blockquote>
<p>From AI as a Copilot → To AI as a Teammate.</p>
<p>1</p>
</blockquote>
<hr />
<h2>🏗️ The Architecture of an AI Agent</h2>
<p>A powerful diagram on <strong>page 4</strong> explains the four core components.</p>
<h3>Agent = LLM + Memory + Tools + Planning</h3>
<p>Let’s break them down.</p>
<hr />
<h3>👁️ Perception (The Eyes)</h3>
<p>Inputs from:</p>
<ul>
<li><p>Databases</p>
</li>
<li><p>Slack messages</p>
</li>
<li><p>Webhooks</p>
</li>
<li><p>APIs</p>
</li>
</ul>
<hr />
<h3>🧠 Reasoning (The Brain)</h3>
<p>Handles:</p>
<ul>
<li><p>Planning</p>
</li>
<li><p>Tool selection</p>
</li>
<li><p>Reflection</p>
</li>
</ul>
<hr />
<h3>🧾 Memory (The Context)</h3>
<p>Stores:</p>
<ul>
<li><p>Chat history</p>
</li>
<li><p>Vector embeddings</p>
</li>
<li><p>State information</p>
</li>
</ul>
<hr />
<h3>✋ Action (The Hands)</h3>
<p>Executes tasks:</p>
<ul>
<li><p>API calls</p>
</li>
<li><p>Scripts</p>
</li>
<li><p>File operations</p>
<p>1</p>
</li>
</ul>
<hr />
<h2>⚖️ Deterministic vs Probabilistic Systems</h2>
<p>A very important concept appears on <strong>page 5</strong>.</p>
<h3>Traditional Microservices</h3>
<ul>
<li><p>Deterministic behavior</p>
</li>
<li><p>Predictable latency (~200ms)</p>
</li>
<li><p>Fixed cost</p>
</li>
</ul>
<hr />
<h3>AI Agents</h3>
<ul>
<li><p>Probabilistic behavior</p>
</li>
<li><p>Variable latency (reasoning loops)</p>
</li>
<li><p>Cost varies widely</p>
</li>
</ul>
<p>This means:</p>
<p>👉 Agents are powerful but harder to predict.</p>
<hr />
<h2>⚠️ Operational Challenges of AI Agents</h2>
<p>Running agents in production introduces new risks.</p>
<p>According to <strong>page 6</strong>, major hazards include:</p>
<h3>💰 Cost Control</h3>
<p>Infinite reasoning loops can burn budget quickly.</p>
<hr />
<h3>🔍 Observability</h3>
<p>Traditional CPU metrics are insufficient — we need to track <strong>decision paths</strong>.</p>
<hr />
<h3>🔐 Security</h3>
<p>Agents may have shell or system access, creating risk.</p>
<hr />
<h3>🧠 State Management</h3>
<p>Maintaining memory consistency across failures is difficult.</p>
<p>1</p>
<hr />
<h2>🛡️ Introducing AgentOps</h2>
<p>To manage agents safely, a new discipline is emerging: <strong>AgentOps</strong>.</p>
<p>The diagram on <strong>page 7</strong> highlights key principles:</p>
<ul>
<li><p>Flight Recorder → Capture reasoning chains</p>
</li>
<li><p>Circuit Breaker → Stop runaway loops</p>
</li>
<li><p>Guardrails → Prevent dangerous actions</p>
</li>
</ul>
<p>Goal:</p>
<p>Operate autonomous systems reliably and securely.</p>
<p>1</p>
<hr />
<h2>📈 Scaling AI Agents in Production</h2>
<p>According to <strong>page 8</strong>, real-world deployments require handling:</p>
<ul>
<li><p>10,000 parallel agent loops</p>
</li>
<li><p>50+ external APIs</p>
</li>
<li><p>Distributed state management</p>
</li>
</ul>
<p>This shows:</p>
<p>👉 Deploying agents is easy.  </p>
<p>👉 Orchestrating them at scale is the real challenge.</p>
<hr />
<h2>🔮 The Future of DevOps: Managing Intelligence</h2>
<p>The final slide (page 9) gives a powerful insight:</p>
<p>Yesterday → Managing stateless microservices  </p>
<p>Tomorrow → Managing stateful decision systems</p>
<p>This changes the DevOps role dramatically:</p>
<blockquote>
<p>You are no longer just keeping servers up — you are keeping intelligence aligned.</p>
<p>1</p>
</blockquote>
<hr />
<h1>🧩 Final Thoughts</h1>
<p>AI agents represent a massive shift in computing:</p>
<ul>
<li><p>From reactive systems → To autonomous decision makers</p>
</li>
<li><p>From static workflows → To dynamic reasoning loops</p>
</li>
<li><p>From infrastructure management → To intelligence management</p>
</li>
</ul>
<p>This is why we are entering the <strong>Agent Era</strong>.</p>
<iframe src="https://www.youtube.com/watch?v=KeJUZ2nqZGc&amp;t=5s"></iframe>]]></content:encoded></item><item><title><![CDATA[Red Hat Certified System Administrator]]></title><description><![CDATA[Day 1: Introduction to RHCSA & Installation
What is RHCSA?
RHCSA stands for Red Hat Certified System Administrator.
Why RHCSA is Important

Industry-recognized Linux certification

Required for Linux system administration jobs

Builds strong foundati...]]></description><link>https://hassandevops.com/red-hat-certified-system-administrator</link><guid isPermaLink="true">https://hassandevops.com/red-hat-certified-system-administrator</guid><dc:creator><![CDATA[Muhammad Hassan]]></dc:creator><pubDate>Mon, 05 Jan 2026 06:46:55 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1767594867513/47ed850a-7746-4530-a689-81315a1a4d33.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="heading-day-1-introduction-to-rhcsa-amp-installation"><strong>Day 1: Introduction to RHCSA &amp; Installation</strong></h2>
<h3 id="heading-what-is-rhcsa"><strong>What is RHCSA?</strong></h3>
<p><strong>RHCSA</strong> stands for <strong>Red Hat Certified System Administrator</strong>.</p>
<h3 id="heading-why-rhcsa-is-important"><strong>Why RHCSA is Important</strong></h3>
<ul>
<li><p>Industry-recognized Linux certification</p>
</li>
<li><p>Required for <strong>Linux system administration jobs</strong></p>
</li>
<li><p>Builds strong foundation in:</p>
<ul>
<li><p>Linux OS</p>
</li>
<li><p>Users &amp; permissions</p>
</li>
<li><p>Filesystems</p>
</li>
<li><p>Networking</p>
</li>
<li><p>Services &amp; processes</p>
</li>
</ul>
</li>
<li><p>Useful for <strong>DevOps, SysAdmin, Cloud, and Server roles</strong></p>
</li>
</ul>
<h3 id="heading-how-we-install-linux-for-practice"><strong>How We Install Linux for Practice</strong></h3>
<p>We do <strong>not</strong> install Linux directly on our main system. Instead, we use <strong>Virtualization</strong>.</p>
<h3 id="heading-virtual-machine-vm"><strong>Virtual Machine (VM)</strong></h3>
<ul>
<li><p>We use <strong>VMware</strong> (or VirtualBox)</p>
</li>
<li><p>A VM allows us to run an <strong>OS inside another OS</strong></p>
</li>
<li><p>Example:</p>
<ul>
<li><p>Host OS: Windows</p>
</li>
<li><p>Guest OS: RHEL / CentOS / Rocky Linux</p>
</li>
</ul>
</li>
</ul>
<h3 id="heading-installation-steps-high-level"><strong>Installation Steps (High Level)</strong></h3>
<ol>
<li><p>Install VMware</p>
</li>
<li><p>Create a new Virtual Machine</p>
</li>
<li><p>Attach Linux ISO file</p>
</li>
<li><p>Allocate:</p>
<ul>
<li><p>RAM</p>
</li>
<li><p>CPU</p>
</li>
<li><p>Disk</p>
</li>
</ul>
</li>
<li><p>Install Linux OS inside VM</p>
</li>
</ol>
<p>✅ <strong>This method is safe and widely used for learning and testing</strong></p>
<hr />
<h2 id="heading-day-2-linux-directory-structure-amp-basic-commands"><strong>Day 2: Linux Directory Structure &amp; Basic Commands</strong></h2>
<h3 id="heading-root-directory"><strong>Root Directory</strong> <code>/</code></h3>
<p>Linux has a <strong>single root directory</strong> <code>/</code>. Everything starts from here.</p>
<h3 id="heading-important-system-directories"><strong>Important System Directories</strong></h3>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Directory</td><td>Purpose</td></tr>
</thead>
<tbody>
<tr>
<td><code>/</code></td><td>Root of the filesystem</td></tr>
<tr>
<td><code>/root</code></td><td>Home directory of <strong>root user</strong></td></tr>
<tr>
<td><code>/home</code></td><td>Home directories of normal users</td></tr>
<tr>
<td><code>/bin</code></td><td>Essential user commands (ls, cp, mv)</td></tr>
<tr>
<td><code>/sbin</code></td><td>System/admin commands</td></tr>
<tr>
<td><code>/etc</code></td><td>Configuration files</td></tr>
<tr>
<td><code>/var</code></td><td>Logs, mail, variable data</td></tr>
<tr>
<td><code>/tmp</code></td><td>Temporary files</td></tr>
<tr>
<td><code>/boot</code></td><td>Bootloader &amp; kernel files</td></tr>
</tbody>
</table>
</div><hr />
<h3 id="heading-basic-commands-learned"><strong>Basic Commands Learned</strong></h3>
<pre><code class="lang-plaintext">whoami
</code></pre>
<p>➡ Shows <strong>current logged-in user</strong></p>
<pre><code class="lang-plaintext">ls
</code></pre>
<p>➡ Lists files and directories</p>
<pre><code class="lang-plaintext">cd
</code></pre>
<p>➡ Changes directory</p>
<p>Examples:</p>
<pre><code class="lang-plaintext">cd /etc
cd ..
cd ~
</code></pre>
<hr />
<h3 id="heading-linux-terminal-prompt-explained"><strong>Linux Terminal Prompt Explained</strong></h3>
<p>Example:</p>
<pre><code class="lang-plaintext">hassan@server1:/home/hassan$
</code></pre>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Part</td><td>Meaning</td></tr>
</thead>
<tbody>
<tr>
<td><code>hassan</code></td><td>Username</td></tr>
<tr>
<td><code>server1</code></td><td>Hostname</td></tr>
<tr>
<td><code>/home/hassan</code></td><td>Current directory</td></tr>
<tr>
<td><code>$</code></td><td>Normal user</td></tr>
<tr>
<td><code>#</code></td><td>Root user</td></tr>
</tbody>
</table>
</div><p>✅ <strong>Correction:</strong></p>
<ul>
<li><p><code>$</code> → normal user</p>
</li>
<li><p><code>#</code> → root (admin) user</p>
</li>
</ul>
<hr />
<h2 id="heading-day-3-how-linux-os-boots-file-commands"><strong>Day 3: How Linux OS Boots + File Commands</strong></h2>
<h3 id="heading-how-operating-system-works-boot-process"><strong>How Operating System Works (Boot Process)</strong></h3>
<p>Correct boot order:</p>
<ol>
<li><p><strong>BIOS / UEFI</strong></p>
<ul>
<li>Initializes hardware</li>
</ul>
</li>
<li><p><strong>Bootloader (GRUB2)</strong></p>
<ul>
<li><p>Loads the kernel</p>
</li>
<li><p>Allows selecting different OS</p>
</li>
</ul>
</li>
<li><p><strong>Kernel</strong></p>
<ul>
<li><p>Core of OS</p>
</li>
<li><p>Manages CPU, memory, devices</p>
</li>
</ul>
</li>
<li><p><strong>init / systemd</strong></p>
<ul>
<li>Starts services</li>
</ul>
</li>
<li><p><strong>Login Screen</strong></p>
<ul>
<li>OS is ready to use</li>
</ul>
</li>
</ol>
<p>✅ <strong>Correction:</strong></p>
<ul>
<li><p>BIOS <strong>does not load the OS directly</strong></p>
</li>
<li><p>BIOS/UEFI loads the <strong>bootloader</strong></p>
</li>
<li><p>Bootloader loads the <strong>kernel</strong></p>
</li>
<li><p>Kernel starts the OS</p>
</li>
</ul>
<h3 id="heading-multiple-os-concept"><strong>Multiple OS Concept</strong></h3>
<ul>
<li><p>If multiple OS are installed</p>
</li>
<li><p>GRUB menu allows choosing which OS to boot</p>
</li>
</ul>
<h1 id="heading-one-line-memory-trick">🧠 One-Line Memory Trick</h1>
<ul>
<li><p><strong>Linux:</strong><br />  <code>UEFI → GRUB → Kernel → systemd → Services → Ready</code></p>
</li>
<li><p><strong>Windows:</strong><br />  <code>UEFI → Boot Manager → Kernel → Services → Login → Ready</code></p>
</li>
</ul>
<hr />
<h3 id="heading-file-commands"><strong>File Commands</strong></h3>
<pre><code class="lang-plaintext">cp source destination
</code></pre>
<p>➡ Copy files or directories</p>
<p>Examples:</p>
<pre><code class="lang-plaintext">cp file1 file2
cp -r dir1 dir2
</code></pre>
<pre><code class="lang-plaintext">mv source destination
</code></pre>
<p>➡ Move or rename files</p>
<p>Examples:</p>
<pre><code class="lang-plaintext">mv file1 /tmp
mv oldname newname
</code></pre>
<hr />
<h3 id="heading-change-hostname"><strong>Change Hostname</strong></h3>
<p>Temporary:</p>
<pre><code class="lang-plaintext">hostname newname
</code></pre>
<p>Permanent (Recommended):</p>
<pre><code class="lang-plaintext">hostnamectl set-hostname newname
</code></pre>
<hr />
<h2 id="heading-day-4-bios-vs-uefi-editors-amp-practice-tasks"><strong>Day 4: BIOS vs UEFI, Editors &amp; Practice Tasks</strong></h2>
<h3 id="heading-bios-vs-uefi"><strong>BIOS vs UEFI</strong></h3>
<div class="hn-table">
<table>
<thead>
<tr>
<td>BIOS</td><td>UEFI</td></tr>
</thead>
<tbody>
<tr>
<td>Old technology</td><td>Modern</td></tr>
<tr>
<td>Slow boot</td><td>Fast boot</td></tr>
<tr>
<td>MBR partition</td><td>GPT partition</td></tr>
<tr>
<td>Limited disk size</td><td>Supports large disks</td></tr>
<tr>
<td>Text-based</td><td>GUI support</td></tr>
</tbody>
</table>
</div><p>✅ <strong>UEFI is used in modern systems</strong></p>
<hr />
<h3 id="heading-text-editors"><strong>Text Editors</strong></h3>
<p>Linux has command-line editors.</p>
<h4 id="heading-nano-easy"><strong>Nano (Easy)</strong></h4>
<pre><code class="lang-plaintext">nano file.txt
</code></pre>
<ul>
<li><p>Easy to use</p>
</li>
<li><p>Shortcuts shown at bottom</p>
</li>
<li><p>Save: <code>CTRL + O</code></p>
</li>
<li><p>Exit: <code>CTRL + X</code></p>
</li>
</ul>
<h4 id="heading-vim-advanced"><strong>Vim (Advanced)</strong></h4>
<pre><code class="lang-plaintext">vim file.txt
</code></pre>
<p>Modes:</p>
<ul>
<li><p><strong>Normal mode</strong> (default)</p>
</li>
<li><p><strong>Insert mode</strong> → <code>i</code></p>
</li>
<li><p><strong>Command mode</strong> → <code>:</code></p>
</li>
</ul>
<p>Common commands:</p>
<pre><code class="lang-plaintext">i        # insert mode
:w       # save
:q       # quit
:wq      # save and quit
:q!      # quit without saving
</code></pre>
<hr />
<h3 id="heading-practice-tasks"><strong>Practice Tasks</strong></h3>
<ul>
<li><p>Create files</p>
</li>
<li><p>Edit files using nano &amp; vim</p>
</li>
<li><p>Copy and move files</p>
</li>
<li><p>Rename files</p>
</li>
<li><p>Change hostname</p>
</li>
<li><p>Navigate directories</p>
</li>
</ul>
<hr />
<h2 id="heading-summary">✅ Summary</h2>
<p>You learned:</p>
<ul>
<li><p>RHCSA basics and importance</p>
</li>
<li><p>Linux installation using VMware</p>
</li>
<li><p>Linux directory structure</p>
</li>
<li><p>Basic Linux commands</p>
</li>
<li><p>Boot process (BIOS → GRUB → Kernel → OS)</p>
</li>
<li><p>BIOS vs UEFI</p>
</li>
<li><p>File operations</p>
</li>
<li><p>Nano &amp; Vim editors</p>
</li>
</ul>
<h1 id="heading-rhcsa-class-notes-day-5-amp-6"><strong>RHCSA – Class Notes (Day 5 &amp; 6)</strong></h1>
<hr />
<h2 id="heading-day-5-file-and-directory-management"><strong>Day 5: File and Directory Management</strong></h2>
<h3 id="heading-copying-directories"><strong>Copying Directories</strong></h3>
<pre><code class="lang-plaintext">cp -r source_directory destination_directory
</code></pre>
<ul>
<li><p><code>-r</code> → recursive (copy directory and all its contents)</p>
</li>
<li><p>Example:</p>
</li>
</ul>
<pre><code class="lang-plaintext">cp -r /home/hassan/docs /home/hassan/backup_docs
</code></pre>
<hr />
<h3 id="heading-deleting-files"><strong>Deleting Files</strong></h3>
<pre><code class="lang-plaintext">rm filename
</code></pre>
<ul>
<li>Removes a file</li>
</ul>
<pre><code class="lang-plaintext">rm -i filename
</code></pre>
<ul>
<li>Asks <strong>confirmation</strong> before deletion</li>
</ul>
<hr />
<h3 id="heading-deleting-directories"><strong>Deleting Directories</strong></h3>
<pre><code class="lang-plaintext">rmdir directory_name
</code></pre>
<ul>
<li>Removes <strong>empty directories only</strong></li>
</ul>
<pre><code class="lang-plaintext">rm -r directory_name
</code></pre>
<ul>
<li>Removes <strong>directory and all contents recursively</strong></li>
</ul>
<pre><code class="lang-plaintext">rm -rf directory_name
</code></pre>
<ul>
<li><p>Removes <strong>directory and contents without warning</strong></p>
</li>
<li><p>⚠️ <strong>Use carefully</strong>! Can delete important data</p>
</li>
</ul>
<hr />
<h3 id="heading-wildcard"><strong>Wildcard</strong> <code>*</code></h3>
<ul>
<li><p><code>*</code> is used to represent <strong>all files or directories</strong></p>
</li>
<li><p>Example:</p>
</li>
</ul>
<pre><code class="lang-plaintext">rm *.txt
</code></pre>
<ul>
<li>Deletes all <code>.txt</code> files in current directory</li>
</ul>
<hr />
<h3 id="heading-command-structure"><strong>Command Structure</strong></h3>
<pre><code class="lang-plaintext">command [options] [arguments]
</code></pre>
<ul>
<li><p><strong>Command</strong> → what to do (<code>ls</code>, <code>cp</code>, <code>rm</code>)</p>
</li>
<li><p><strong>Options</strong> → modify behavior (<code>-l</code>, <code>-r</code>, <code>-f</code>)</p>
</li>
<li><p><strong>Arguments</strong> → files or directories to operate on</p>
</li>
</ul>
<p><strong>Example:</strong></p>
<pre><code class="lang-plaintext">ls -l /home/hassan
</code></pre>
<hr />
<h3 id="heading-hidden-files"><strong>Hidden Files</strong></h3>
<ul>
<li><p>Files starting with <code>.</code> are hidden</p>
</li>
<li><p>Create a hidden file:</p>
</li>
</ul>
<pre><code class="lang-plaintext">touch .hiddenfile
</code></pre>
<hr />
<h3 id="heading-clear-terminal"><strong>Clear Terminal</strong></h3>
<pre><code class="lang-plaintext">clear
</code></pre>
<ul>
<li>Clears the screen</li>
</ul>
<hr />
<h3 id="heading-creating-directories"><strong>Creating Directories</strong></h3>
<pre><code class="lang-plaintext">mkdir folder_name
</code></pre>
<h4 id="heading-nested-directories"><strong>Nested Directories</strong></h4>
<pre><code class="lang-plaintext">mkdir -p parent_folder/child_folder
</code></pre>
<ul>
<li><code>-p</code> → create parent directories if they don’t exist</li>
</ul>
<h4 id="heading-creating-multiple-folders"><strong>Creating Multiple Folders</strong></h4>
<pre><code class="lang-plaintext">mkdir folder{1..10}
</code></pre>
<ul>
<li>Creates <code>folder1</code>, <code>folder2</code>, … <code>folder10</code></li>
</ul>
<h4 id="heading-creating-multiple-files"><strong>Creating Multiple Files</strong></h4>
<pre><code class="lang-plaintext">touch file{1..10}.txt
</code></pre>
<ul>
<li>Creates <code>file1.txt</code> → <code>file10.txt</code></li>
</ul>
<hr />
<h3 id="heading-viewing-directory-tree"><strong>Viewing Directory Tree</strong></h3>
<pre><code class="lang-plaintext">tree directory_name
</code></pre>
<hr />
<h2 id="heading-day-6-reading-file-content-amp-searching"><strong>Day 6: Reading File Content &amp; Searching</strong></h2>
<h3 id="heading-view-file-content"><strong>View File Content</strong></h3>
<h4 id="heading-cat"><strong>cat</strong></h4>
<pre><code class="lang-plaintext">cat /etc/services
</code></pre>
<ul>
<li>Displays <strong>entire file content</strong></li>
</ul>
<h4 id="heading-more"><strong>more</strong></h4>
<pre><code class="lang-plaintext">more /etc/fstab
</code></pre>
<ul>
<li>Shows file <strong>page by page</strong> (use space to scroll)</li>
</ul>
<h4 id="heading-less"><strong>less</strong></h4>
<ul>
<li><p>Better alternative to <code>more</code></p>
</li>
<li><p>Scroll forward/backward</p>
</li>
</ul>
<pre><code class="lang-plaintext">less /etc/fstab
</code></pre>
<h4 id="heading-head"><strong>head</strong></h4>
<pre><code class="lang-plaintext">head -n 10 /etc/services
</code></pre>
<ul>
<li>Shows first <strong>10 lines</strong> of file</li>
</ul>
<h4 id="heading-tail"><strong>tail</strong></h4>
<pre><code class="lang-plaintext">tail -n 10 /etc/services
</code></pre>
<ul>
<li>Shows last <strong>10 lines</strong> of file</li>
</ul>
<h4 id="heading-nl"><strong>nl</strong></h4>
<pre><code class="lang-plaintext">nl /etc/services
</code></pre>
<ul>
<li>Shows file content with <strong>line numbers</strong></li>
</ul>
<hr />
<h3 id="heading-search-inside-files-grep"><strong>Search Inside Files –</strong> <code>grep</code></h3>
<pre><code class="lang-plaintext">grep "pattern" filename
</code></pre>
<ul>
<li><p>Search for <strong>specific text</strong> in a file</p>
</li>
<li><p>Example:</p>
</li>
</ul>
<pre><code class="lang-plaintext">grep "ftp" /etc/services
</code></pre>
<h4 id="heading-with-options"><strong>With options</strong></h4>
<ul>
<li><p><code>-i</code> → ignore case</p>
</li>
<li><p><code>-c</code> → show <strong>count</strong> of matching lines</p>
</li>
<li><p><code>-v</code> → show <strong>non-matching lines</strong></p>
</li>
<li><p><code>-n</code> → show <strong>line numbers</strong></p>
</li>
</ul>
<p>Example:</p>
<pre><code class="lang-plaintext">grep -i "ftp" /etc/services
grep -c "ssh" /etc/services
</code></pre>
<hr />
<h3 id="heading-word-count-wc"><strong>Word Count –</strong> <code>wc</code></h3>
<pre><code class="lang-plaintext">wc filename
</code></pre>
<ul>
<li>Shows lines, words, characters</li>
</ul>
<p>Options:</p>
<ul>
<li><p><code>-l</code> → number of lines</p>
</li>
<li><p><code>-w</code> → number of words</p>
</li>
<li><p><code>-c</code> → number of bytes</p>
</li>
<li><p><code>-m</code> → number of characters</p>
</li>
</ul>
<p>Example:</p>
<pre><code class="lang-plaintext">wc -l /etc/services
wc -w /etc/services
</code></pre>
<hr />
<h3 id="heading-redirection-amp-operators"><strong>Redirection &amp; Operators</strong></h3>
<ul>
<li><strong>Redirect output to a file</strong></li>
</ul>
<pre><code class="lang-plaintext">ls &gt; file.txt
</code></pre>
<ul>
<li><p>Overwrites <code>file.txt</code> with output of <code>ls</code></p>
</li>
<li><p><strong>Append output to a file</strong></p>
</li>
</ul>
<pre><code class="lang-plaintext">ls &gt;&gt; file.txt
</code></pre>
<ul>
<li><p>Adds output to the <strong>end</strong> of <code>file.txt</code></p>
</li>
<li><p><strong>Pipes</strong> (send output of one command to another)</p>
</li>
</ul>
<pre><code class="lang-plaintext">cat /etc/services | grep ftp
</code></pre>
<p>✅ <strong>Correction:</strong></p>
<ul>
<li><p><code>&gt;</code> → overwrite</p>
</li>
<li><p><code>&gt;&gt;</code> → append</p>
</li>
<li><p><code>|</code> → pipe (send output to another command)</p>
</li>
</ul>
<hr />
<h3 id="heading-summary-day-5-amp-6"><strong>Summary – Day 5 &amp; 6</strong></h3>
<p>You learned:</p>
<ul>
<li><p>Copying, moving, deleting files and directories</p>
</li>
<li><p>Wildcards <code>*</code> for multiple files</p>
</li>
<li><p>Command structure (command → options → arguments)</p>
</li>
<li><p>Hidden files and creating them</p>
</li>
<li><p>Creating folders/files in bulk</p>
</li>
<li><p>Reading files (<code>cat</code>, <code>more</code>, <code>less</code>, <code>head</code>, <code>tail</code>, <code>nl</code>)</p>
</li>
<li><p>Searching in files (<code>grep</code> with options)</p>
</li>
<li><p>Word count (<code>wc</code>)</p>
</li>
<li><p>Redirection (<code>&gt;</code>, <code>&gt;&gt;</code>) and pipes (<code>|</code>)</p>
</li>
</ul>
<h2 id="heading-day-7-operators-in-linux"><strong>Day 7: Operators in Linux</strong></h2>
<p>Linux allows combining commands and controlling execution flow using <strong>operators</strong>.</p>
<hr />
<h3 id="heading-1-semicolon"><strong>1️⃣ Semicolon</strong> <code>;</code></h3>
<ul>
<li><p><strong>Purpose:</strong> Run multiple commands <strong>sequentially</strong>, <strong>regardless of whether previous commands succeed or fail</strong></p>
</li>
<li><p><strong>Syntax:</strong></p>
</li>
</ul>
<pre><code class="lang-plaintext">command1; command2; command3
</code></pre>
<ul>
<li><strong>Example:</strong></li>
</ul>
<pre><code class="lang-plaintext">echo "Hello"; ls; pwd
</code></pre>
<ul>
<li><p>Output:</p>
<ol>
<li><p>Prints “Hello”</p>
</li>
<li><p>Lists files</p>
</li>
<li><p>Shows current directory</p>
</li>
</ol>
</li>
</ul>
<p>✅ <strong>Note:</strong> Commands run <strong>one by one</strong> even if one fails.</p>
<hr />
<h3 id="heading-2-single-pipe"><strong>2️⃣ Single Pipe</strong> <code>|</code></h3>
<ul>
<li><p><strong>Purpose:</strong> Sends output of first command as input to second command</p>
</li>
<li><p><strong>Syntax:</strong></p>
</li>
</ul>
<pre><code class="lang-plaintext">command1 | command2
</code></pre>
<ul>
<li><strong>Example:</strong></li>
</ul>
<pre><code class="lang-plaintext">cat /etc/services | grep ftp
</code></pre>
<ul>
<li><code>cat</code> prints file → <code>grep</code> filters only lines containing “ftp”</li>
</ul>
<hr />
<h3 id="heading-3-double-and-ampamp"><strong>3️⃣ Double AND</strong> <code>&amp;&amp;</code></h3>
<ul>
<li><p><strong>Purpose:</strong> Run <strong>second command only if the first command succeeds</strong></p>
</li>
<li><p><strong>Syntax:</strong></p>
</li>
</ul>
<pre><code class="lang-plaintext">command1 &amp;&amp; command2
</code></pre>
<ul>
<li><strong>Example:</strong></li>
</ul>
<pre><code class="lang-plaintext">mkdir test &amp;&amp; cd test
</code></pre>
<ul>
<li>Only enters <code>test</code> folder if folder creation <strong>succeeds</strong></li>
</ul>
<hr />
<h3 id="heading-4-single-and-amp"><strong>4️⃣ Single AND</strong> <code>&amp;</code></h3>
<ul>
<li><p><strong>Purpose:</strong> Run command in <strong>background</strong></p>
</li>
<li><p><strong>Syntax:</strong></p>
</li>
</ul>
<pre><code class="lang-plaintext">command &amp;
</code></pre>
<ul>
<li><strong>Example:</strong></li>
</ul>
<pre><code class="lang-plaintext">gedit file.txt &amp;
</code></pre>
<ul>
<li>Opens <code>gedit</code> in background, so terminal is <strong>free to use</strong></li>
</ul>
<hr />
<h3 id="heading-5-double-pipe"><strong>5️⃣ Double Pipe</strong> <code>||</code></h3>
<ul>
<li><p><strong>Purpose:</strong> Run <strong>second command only if the first command fails</strong></p>
</li>
<li><p><strong>Syntax:</strong></p>
</li>
</ul>
<pre><code class="lang-plaintext">command1 || command2
</code></pre>
<ul>
<li><strong>Example:</strong></li>
</ul>
<pre><code class="lang-plaintext">cd nonexistfolder || echo "Folder does not exist"
</code></pre>
<ul>
<li>If <code>cd</code> fails, prints warning</li>
</ul>
<hr />
<h3 id="heading-summary-of-operators"><strong>Summary of Operators</strong></h3>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Operator</td><td>Purpose</td></tr>
</thead>
<tbody>
<tr>
<td><code>;</code></td><td>Run commands sequentially, ignore errors</td></tr>
<tr>
<td><code>&amp;&amp;</code></td><td>Run next command only if previous succeeds</td></tr>
<tr>
<td>`</td><td></td></tr>
<tr>
<td><code>&amp;</code></td><td>Run command in background</td></tr>
<tr>
<td>`</td><td>`</td></tr>
</tbody>
</table>
</div><hr />
<h2 id="heading-user-and-group-management"><strong>User and Group Management</strong></h2>
<p>Linux manages <strong>users and groups</strong> for <strong>access control</strong> and <strong>permissions</strong>.</p>
<hr />
<h3 id="heading-types-of-users"><strong>Types of Users</strong></h3>
<div class="hn-table">
<table>
<thead>
<tr>
<td>User Type</td><td>Description</td><td>UID</td></tr>
</thead>
<tbody>
<tr>
<td><strong>Root user</strong></td><td>Super admin, full privileges</td><td><code>0</code></td></tr>
<tr>
<td><strong>System user</strong></td><td>Used by OS services, limited login</td><td><code>1–999</code></td></tr>
<tr>
<td><strong>Regular user</strong></td><td>Normal human user, limited privileges</td><td><code>1000+</code></td></tr>
</tbody>
</table>
</div><hr />
<h3 id="heading-types-of-groups"><strong>Types of Groups</strong></h3>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Group Type</td><td>Description</td></tr>
</thead>
<tbody>
<tr>
<td><strong>Root group</strong></td><td>Associated with root user, admin group</td></tr>
<tr>
<td><strong>System group</strong></td><td>For OS processes and services</td></tr>
<tr>
<td><strong>Regular group</strong></td><td>For normal users, sharing resources</td></tr>
</tbody>
</table>
</div><hr />
<h3 id="heading-commands-basics"><strong>Commands (Basics)</strong></h3>
<ul>
<li><strong>View current user</strong></li>
</ul>
<pre><code class="lang-plaintext">whoami
</code></pre>
<ul>
<li><strong>View groups of a user</strong></li>
</ul>
<pre><code class="lang-plaintext">groups username
</code></pre>
<ul>
<li><strong>View all users</strong></li>
</ul>
<pre><code class="lang-plaintext">cat /etc/passwd
</code></pre>
<ul>
<li><strong>View all groups</strong></li>
</ul>
<pre><code class="lang-plaintext">cat /etc/group
</code></pre>
<hr />
<p>✅ <strong>Corrections / Clarifications</strong></p>
<ol>
<li><p>UID ranges for system vs regular users:</p>
<ul>
<li><p>System: 1–999</p>
</li>
<li><p>Regular: 1000+</p>
</li>
</ul>
</li>
<li><p>Background operator: single <code>&amp;</code> runs <strong>command in background</strong>, not a chain.</p>
</li>
<li><p>Pipes and logical operators (<code>&amp;&amp;</code>, <code>||</code>) are different:</p>
<ul>
<li><p><code>|</code> → sends <strong>output to input</strong></p>
</li>
<li><p><code>&amp;&amp;</code> / <code>||</code> → controls <strong>execution flow</strong></p>
</li>
</ul>
</li>
</ol>
<hr />
<h3 id="heading-examples"><strong>Examples</strong></h3>
<pre><code class="lang-plaintext"># Sequential execution
echo "Start"; ls; echo "End"

# Logical AND
mkdir demo &amp;&amp; cd demo

# Logical OR
cd nofolder || echo "Folder not found"

# Background process
gedit file.txt &amp;

# Pipe
cat /etc/services | grep ftp
</code></pre>
<hr />
<p>This covers <strong>Day 7 operators + intro to user &amp; group management</strong>.</p>
<h1 id="heading-rhcsa-day-8-user-and-group-management"><strong>RHCSA Day 8 – User and Group Management</strong></h1>
<p>User and group management is a <strong>core topic in RHCSA</strong> and very important for real-world Linux administration. On Day 8, we focused on creating users, managing passwords, understanding user IDs (UIDs), group IDs (GIDs), and how Linux stores user and group information internally.</p>
<hr />
<h2 id="heading-1-adding-a-new-user">1. Adding a New User</h2>
<p>To create a new user in Linux, we use the <code>useradd</code> command.</p>
<pre><code class="lang-bash">useradd username
</code></pre>
<p>Example:</p>
<pre><code class="lang-bash">useradd ali
</code></pre>
<p>This command:</p>
<ul>
<li><p>Creates the user</p>
</li>
<li><p>Assigns a UID automatically</p>
</li>
<li><p>Creates a home directory <code>/home/ali</code></p>
</li>
<li><p>Assigns a default shell</p>
</li>
</ul>
<blockquote>
<p>⚠️ By default, the user does <strong>not</strong> have a password yet.</p>
</blockquote>
<hr />
<h2 id="heading-2-setting-or-changing-user-password">2. Setting or Changing User Password</h2>
<p>To set or change a password, use:</p>
<pre><code class="lang-bash">passwd username
</code></pre>
<p>Example:</p>
<pre><code class="lang-bash">passwd ali
</code></pre>
<p>You will be prompted to enter and confirm the password.</p>
<hr />
<h2 id="heading-3-checking-user-id-and-group-information">3. Checking User ID and Group Information</h2>
<h3 id="heading-check-uid-and-gid">Check UID and GID</h3>
<pre><code class="lang-bash">id username
</code></pre>
<p>Example:</p>
<pre><code class="lang-bash">id ali
</code></pre>
<p>Output shows:</p>
<ul>
<li><p>UID (User ID)</p>
</li>
<li><p>GID (Primary Group ID)</p>
</li>
<li><p>Secondary groups</p>
</li>
</ul>
<h3 id="heading-check-current-logged-in-user">Check Current Logged-in User</h3>
<pre><code class="lang-bash">whoami
</code></pre>
<hr />
<h2 id="heading-4-types-of-users-in-linux">4. Types of Users in Linux</h2>
<p>Linux has <strong>three main types of users</strong>:</p>
<div class="hn-table">
<table>
<thead>
<tr>
<td>User Type</td><td>Description</td><td>UID Range</td></tr>
</thead>
<tbody>
<tr>
<td>Root User</td><td>Superuser with full access</td><td>0</td></tr>
<tr>
<td>System User</td><td>Used by services and processes</td><td>1–999</td></tr>
<tr>
<td>Regular User</td><td>Normal human users</td><td>1000+</td></tr>
</tbody>
</table>
</div><hr />
<h2 id="heading-5-modifying-a-user-user-management">5. Modifying a User (User Management)</h2>
<p>The <code>usermod</code> command is used to modify user properties.</p>
<h3 id="heading-example-set-account-expiry-date">Example: Set Account Expiry Date</h3>
<pre><code class="lang-bash">usermod -e 2026-12-31 ali
</code></pre>
<h3 id="heading-lock-a-user-account">Lock a User Account</h3>
<pre><code class="lang-bash">usermod -L ali
</code></pre>
<h3 id="heading-unlock-a-user-account">Unlock a User Account</h3>
<pre><code class="lang-bash">usermod -U ali
</code></pre>
<hr />
<h2 id="heading-6-password-aging-and-expiry">6. Password Aging and Expiry</h2>
<p>We can control password policies using <code>chage</code>.</p>
<pre><code class="lang-bash">chage username
</code></pre>
<p>Example:</p>
<pre><code class="lang-bash">chage ali
</code></pre>
<p>To view password aging info:</p>
<pre><code class="lang-bash">chage -l ali
</code></pre>
<p>You can:</p>
<ul>
<li><p>Set password expiry</p>
</li>
<li><p>Force password change</p>
</li>
<li><p>Set warning days</p>
</li>
</ul>
<hr />
<h2 id="heading-7-users-vs-groups">7. Users vs Groups</h2>
<h3 id="heading-what-is-a-user">What is a User?</h3>
<ul>
<li><p>An individual account</p>
</li>
<li><p>Has its own UID</p>
</li>
<li><p>Can log in</p>
</li>
</ul>
<h3 id="heading-what-is-a-group">What is a Group?</h3>
<ul>
<li><p>Collection of users</p>
</li>
<li><p>Used to manage permissions easily</p>
</li>
<li><p>Identified by GID</p>
</li>
</ul>
<blockquote>
<p>Groups make permission management easier instead of assigning permissions user by user.</p>
</blockquote>
<hr />
<h2 id="heading-8-adding-groups">8. Adding Groups</h2>
<pre><code class="lang-bash">groupadd groupname
</code></pre>
<p>Example:</p>
<pre><code class="lang-bash">groupadd developers
</code></pre>
<hr />
<h2 id="heading-9-primary-and-secondary-groups">9. Primary and Secondary Groups</h2>
<h3 id="heading-primary-group">Primary Group</h3>
<ul>
<li><p>Each user has <strong>one primary group</strong></p>
</li>
<li><p>Assigned at user creation</p>
</li>
<li><p>Used by default when creating files</p>
</li>
</ul>
<h3 id="heading-secondary-groups">Secondary Groups</h3>
<ul>
<li><p>Additional groups a user belongs to</p>
</li>
<li><p>Used for extra permissions</p>
</li>
</ul>
<h3 id="heading-add-user-to-a-secondary-group">Add User to a Secondary Group</h3>
<pre><code class="lang-bash">usermod -aG groupname username
</code></pre>
<p>Example:</p>
<pre><code class="lang-bash">usermod -aG developers ali
</code></pre>
<blockquote>
<p>⚠️ <code>-a</code> is very important. Without it, existing groups will be removed.</p>
</blockquote>
<hr />
<h2 id="heading-10-checking-user-and-group-files">10. Checking User and Group Files</h2>
<p>Linux stores user and group information in <code>/etc</code> directory.</p>
<h3 id="heading-etcpasswd"><code>/etc/passwd</code></h3>
<pre><code class="lang-bash">cat /etc/passwd
</code></pre>
<p>Contains:</p>
<ul>
<li><p>Username</p>
</li>
<li><p>UID</p>
</li>
<li><p>GID</p>
</li>
<li><p>Home directory</p>
</li>
<li><p>Shell</p>
</li>
</ul>
<blockquote>
<p>Passwords are <strong>not stored here</strong>.</p>
</blockquote>
<hr />
<h3 id="heading-etcshadow"><code>/etc/shadow</code></h3>
<pre><code class="lang-bash">cat /etc/shadow
</code></pre>
<p>Contains:</p>
<ul>
<li><p>Encrypted passwords</p>
</li>
<li><p>Password expiry info</p>
</li>
</ul>
<blockquote>
<p>Only readable by <strong>root user</strong>.</p>
</blockquote>
<hr />
<h3 id="heading-etcgroup"><code>/etc/group</code></h3>
<pre><code class="lang-bash">cat /etc/group
</code></pre>
<p>Contains:</p>
<ul>
<li><p>Group name</p>
</li>
<li><p>GID</p>
</li>
<li><p>Group members</p>
</li>
</ul>
<hr />
<h2 id="heading-11-summary-day-8">11. Summary (Day 8)</h2>
<p>On Day 8, we learned:</p>
<ul>
<li><p>How to add users and set passwords</p>
</li>
<li><p>How to check UID, GID, and group membership</p>
</li>
<li><p>Difference between users and groups</p>
</li>
<li><p>Primary vs secondary groups</p>
</li>
<li><p>How to add users to groups</p>
</li>
<li><p>User modification and password expiry</p>
</li>
<li><p>Internal Linux files: <code>/etc/passwd</code>, <code>/etc/shadow</code>, <code>/etc/group</code></p>
</li>
</ul>
<p>This topic is <strong>very important for RHCSA exam and real Linux administration</strong>.</p>
]]></content:encoded></item><item><title><![CDATA[CCNA Notes]]></title><description><![CDATA[Day 1 & Day 2 (Expanded + Corrected)

🔹 DAY 1 (Detailed)
1️⃣ What is CCNA?
CCNA (Cisco Certified Network Associate) is a foundational networking course by Cisco.
It helps you understand:

How computers and devices communicate

How data travels from ...]]></description><link>https://hassandevops.com/ccna-notes</link><guid isPermaLink="true">https://hassandevops.com/ccna-notes</guid><dc:creator><![CDATA[Muhammad Hassan]]></dc:creator><pubDate>Mon, 05 Jan 2026 06:32:28 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1767593749074/aef78833-41f1-4945-af65-2678779bbc44.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="heading-day-1-amp-day-2-expanded-corrected"><strong>Day 1 &amp; Day 2 (Expanded + Corrected)</strong></h2>
<hr />
<h1 id="heading-day-1-detailed"><strong>🔹 DAY 1 (Detailed)</strong></h1>
<h2 id="heading-1-what-is-ccna">1️⃣ What is CCNA?</h2>
<p><strong>CCNA (Cisco Certified Network Associate)</strong> is a foundational networking course by Cisco.</p>
<p>It helps you understand:</p>
<ul>
<li><p>How computers and devices communicate</p>
</li>
<li><p>How data travels from one device to another</p>
</li>
<li><p>Networking concepts used in real-world networks</p>
</li>
</ul>
<p>CCNA is mainly focused on:</p>
<ul>
<li><p>Networking fundamentals</p>
</li>
<li><p>OSI &amp; TCP/IP models</p>
</li>
<li><p>Routing and switching basics</p>
</li>
<li><p>Protocols and troubleshooting</p>
</li>
</ul>
<hr />
<h2 id="heading-2-osi-model-detailed-explanation-with-zoom-example">2️⃣ OSI Model (Detailed Explanation with Zoom Example)</h2>
<p>The <strong>OSI (Open Systems Interconnection) Model</strong> is a <strong>7-layer reference model</strong> used to understand how data moves in a network.</p>
<p>📌 <strong>Important:</strong></p>
<ul>
<li><p>OSI is mostly used for <strong>learning and understanding</strong></p>
</li>
<li><p>Data flow:</p>
<ul>
<li><p><strong>Sender:</strong> Layer 7 → Layer 1</p>
</li>
<li><p><strong>Receiver:</strong> Layer 1 → Layer 7</p>
</li>
</ul>
</li>
</ul>
<hr />
<h3 id="heading-layer-7-application-layer">🔹 Layer 7 – Application Layer</h3>
<ul>
<li><p>This is where the <strong>user interacts with the network</strong></p>
</li>
<li><p>Provides services to applications</p>
</li>
</ul>
<p><strong>Examples:</strong></p>
<ul>
<li><p>Zoom</p>
</li>
<li><p>Browser (Chrome)</p>
</li>
<li><p>WhatsApp</p>
</li>
<li><p>Email</p>
</li>
</ul>
<p>📌 When you send a message on Zoom, it starts here.</p>
<hr />
<h3 id="heading-layer-6-presentation-layer">🔹 Layer 6 – Presentation Layer</h3>
<ul>
<li><p>Responsible for:</p>
<ul>
<li><p><strong>Encryption</strong></p>
</li>
<li><p><strong>Decryption</strong></p>
</li>
<li><p><strong>Compression</strong></p>
</li>
<li><p><strong>Formatting</strong></p>
</li>
</ul>
</li>
</ul>
<p><strong>Example:</strong></p>
<ul>
<li><p>Zoom encrypts your message so no one else can read it</p>
</li>
<li><p>Compresses data to reduce size</p>
</li>
</ul>
<hr />
<h3 id="heading-layer-5-session-layer">🔹 Layer 5 – Session Layer</h3>
<ul>
<li><p>Creates, manages, and terminates <strong>sessions</strong></p>
</li>
<li><p>Keeps communication alive</p>
</li>
</ul>
<p><strong>Example:</strong></p>
<ul>
<li><p>Maintains your Zoom meeting connection</p>
</li>
<li><p>Handles reconnects if connection drops briefly</p>
</li>
</ul>
<hr />
<h3 id="heading-layer-4-transport-layer">🔹 Layer 4 – Transport Layer</h3>
<ul>
<li><p>Ensures data delivery</p>
</li>
<li><p>Decides <strong>which protocol to use</strong></p>
</li>
</ul>
<p><strong>Protocols:</strong></p>
<ul>
<li><p><strong>TCP:</strong> Reliable, ordered, slower (Zoom login, file transfer)</p>
</li>
<li><p><strong>UDP:</strong> Fast, no guarantee (Live video/audio)</p>
</li>
</ul>
<hr />
<h3 id="heading-layer-3-network-layer">🔹 Layer 3 – Network Layer</h3>
<ul>
<li><p>Responsible for <strong>routing</strong></p>
</li>
<li><p>Uses <strong>IP addresses</strong></p>
</li>
<li><p>Finds the <strong>best path</strong> for data</p>
</li>
</ul>
<p>📌 Routers work at this layer.</p>
<hr />
<h3 id="heading-layer-2-data-link-layer">🔹 Layer 2 – Data Link Layer</h3>
<ul>
<li><p>Uses <strong>MAC addresses</strong></p>
</li>
<li><p>Error detection</p>
</li>
<li><p>Creates frames</p>
</li>
</ul>
<p>📌 Switches work at this layer.</p>
<hr />
<h3 id="heading-layer-1-physical-layer">🔹 Layer 1 – Physical Layer</h3>
<ul>
<li><p>Physical transmission of data</p>
</li>
<li><p>No logic, no addressing</p>
</li>
</ul>
<p><strong>Examples:</strong></p>
<ul>
<li><p>Ethernet cable</p>
</li>
<li><p>Fiber optic cable</p>
</li>
<li><p>Wi-Fi signals</p>
</li>
</ul>
<p>📌 Hubs work at this layer.</p>
<hr />
<h2 id="heading-3-tcpip-model-real-world-model">3️⃣ TCP/IP Model (Real-World Model)</h2>
<p>The <strong>TCP/IP model</strong> is used in <strong>real networking</strong>.</p>
<div class="hn-table">
<table>
<thead>
<tr>
<td>TCP/IP Layer</td><td>OSI Layers</td></tr>
</thead>
<tbody>
<tr>
<td>Application</td><td>7, 6, 5</td></tr>
<tr>
<td>Transport</td><td>4</td></tr>
<tr>
<td>Internet</td><td>3</td></tr>
<tr>
<td>Network Access</td><td>2, 1</td></tr>
</tbody>
</table>
</div><p>📌 OSI = learning model<br />📌 TCP/IP = practical model</p>
<hr />
<h2 id="heading-4-protocol-detailed">4️⃣ Protocol (Detailed)</h2>
<p>A <strong>protocol</strong> is a <strong>set of rules</strong> that devices follow to communicate.</p>
<p>Without protocols:</p>
<ul>
<li><p>Devices won’t understand each other</p>
</li>
<li><p>Communication will fail</p>
</li>
</ul>
<p><strong>Examples:</strong></p>
<ul>
<li><p>HTTP / HTTPS → Web</p>
</li>
<li><p>TCP / UDP → Transport</p>
</li>
<li><p>FTP → File transfer</p>
</li>
</ul>
<p>📌 Communication happens using <strong>protocols on the same layer</strong>.</p>
<hr />
<h1 id="heading-day-2-detailed"><strong>🔹 DAY 2 (Detailed)</strong></h1>
<h2 id="heading-1-header">1️⃣ Header</h2>
<p>A <strong>header</strong> is extra information added to data by each layer.</p>
<p>Header includes:</p>
<ul>
<li><p>Source address</p>
</li>
<li><p>Destination address</p>
</li>
<li><p>Protocol information</p>
</li>
<li><p>Control details</p>
</li>
</ul>
<p>Each OSI layer adds <strong>its own header</strong>.</p>
<hr />
<h2 id="heading-2-encapsulation-amp-decapsulation-detailed">2️⃣ Encapsulation &amp; Decapsulation (Detailed)</h2>
<h3 id="heading-encapsulation-sender-side">🔹 Encapsulation (Sender Side)</h3>
<ul>
<li><p>Happens when data is <strong>sent</strong></p>
</li>
<li><p>Data moves from <strong>Layer 7 → Layer 1</strong></p>
</li>
<li><p>Each layer adds its header</p>
</li>
</ul>
<p>📦 <strong>Envelope Example:</strong></p>
<ul>
<li><p>Data = letter</p>
</li>
<li><p>Each layer = one envelope</p>
</li>
<li><p>Final envelope is sent on the wire</p>
</li>
</ul>
<hr />
<h3 id="heading-decapsulation-receiver-side">🔹 Decapsulation (Receiver Side)</h3>
<ul>
<li><p>Happens when data is <strong>received</strong></p>
</li>
<li><p>Data moves from <strong>Layer 1 → Layer 7</strong></p>
</li>
<li><p>Each layer removes its header</p>
</li>
</ul>
<p>📦 Receiver opens envelopes one by one until data reaches application.</p>
<hr />
<h2 id="heading-3-data-names-at-each-layer">3️⃣ Data Names at Each Layer</h2>
<div class="hn-table">
<table>
<thead>
<tr>
<td>OSI Layer</td><td>Data Name</td></tr>
</thead>
<tbody>
<tr>
<td>Layer 7–5</td><td>Data</td></tr>
<tr>
<td>Layer 4</td><td>Segment</td></tr>
<tr>
<td>Layer 3</td><td>Packet</td></tr>
<tr>
<td>Layer 2</td><td>Frame</td></tr>
<tr>
<td>Layer 1</td><td>Bits</td></tr>
</tbody>
</table>
</div><hr />
<h2 id="heading-4-networking-devices-amp-osi-layers">4️⃣ Networking Devices &amp; OSI Layers</h2>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Device</td><td>OSI Layer</td><td>Description</td></tr>
</thead>
<tbody>
<tr>
<td>Hub</td><td>Layer 1</td><td>Sends data to all ports</td></tr>
<tr>
<td>Switch</td><td>Layer 2</td><td>Uses MAC addresses</td></tr>
<tr>
<td>Router</td><td>Layer 3</td><td>Uses IP &amp; routing</td></tr>
</tbody>
</table>
</div><hr />
<h2 id="heading-5-lan-amp-wan">5️⃣ LAN &amp; WAN</h2>
<h3 id="heading-lan-local-area-network">🔹 LAN (Local Area Network)</h3>
<ul>
<li><p>Small network (home, office, school)</p>
</li>
<li><p>Uses switches</p>
</li>
</ul>
<h3 id="heading-wan-wide-area-network">🔹 WAN (Wide Area Network)</h3>
<ul>
<li><p>Large network (cities, countries)</p>
</li>
<li><p>Routers connect LANs</p>
</li>
</ul>
<p>📌 <strong>Two or more routers connected together form a WAN</strong></p>
<hr />
<h2 id="heading-6-bare-metal-vs-shared-hosting">6️⃣ Bare Metal vs Shared Hosting</h2>
<h3 id="heading-bare-metal">🔹 Bare Metal</h3>
<ul>
<li><p>Dedicated physical server</p>
</li>
<li><p>Full hardware access</p>
</li>
<li><p>High performance</p>
</li>
</ul>
<p><strong>Example:</strong><br />Company data center server</p>
<hr />
<h3 id="heading-shared-hosting">🔹 Shared Hosting</h3>
<ul>
<li><p>Multiple users share same server</p>
</li>
<li><p>Limited control</p>
</li>
<li><p>Lower cost</p>
</li>
</ul>
<p><strong>Example:</strong><br />Cheap website hosting</p>
<hr />
<h2 id="heading-7-unicast-multicast-amp-broadcast">7️⃣ Unicast, Multicast &amp; Broadcast</h2>
<h3 id="heading-unicast">🔹 Unicast</h3>
<ul>
<li><p>One sender → one receiver</p>
</li>
<li><p>Most common communication</p>
</li>
</ul>
<p><strong>Example:</strong><br />Sending message to one person on Zoom</p>
<hr />
<h3 id="heading-multicast">🔹 Multicast</h3>
<ul>
<li>One sender → selected group</li>
</ul>
<p><strong>Example:</strong><br />Online live class to selected students</p>
<hr />
<h3 id="heading-broadcast">🔹 Broadcast</h3>
<ul>
<li>One sender → all devices in network</li>
</ul>
<p><strong>Example:</strong><br />ARP request</p>
<p>📌 Broadcast works <strong>only in LAN</strong>, not across routers.</p>
<hr />
<h2 id="heading-final-quick-revision">✅ FINAL QUICK REVISION</h2>
<ul>
<li><p>OSI = 7 layers</p>
</li>
<li><p>TCP/IP = 4 layers</p>
</li>
<li><p>Encapsulation = sender</p>
</li>
<li><p>Decapsulation = receiver</p>
</li>
<li><p>Hub → L1, Switch → L2, Router → L3</p>
</li>
<li><p>LAN = local, WAN = network of LANs</p>
</li>
<li><p>Bare metal = dedicated</p>
</li>
<li><p>Shared hosting = shared</p>
</li>
<li><p>Unicast / Multicast / Broadcast = delivery types</p>
</li>
</ul>
<h1 id="heading-day-3-routers-addressing-amp-real-world-infrastructure"><strong>DAY 3 – Routers, Addressing &amp; Real-World Infrastructure</strong></h1>
<hr />
<h2 id="heading-1-router-introduction-amp-characteristics">1️⃣ Router (Introduction &amp; Characteristics)</h2>
<p>A <strong>router</strong> is a <strong>networking device</strong> mainly used to <strong>connect different networks</strong>.</p>
<h3 id="heading-characteristics-of-a-router">🔹 Characteristics of a Router</h3>
<p>1️⃣ <strong>Router is a Unicast Device</strong></p>
<ul>
<li><p>A router forwards data from <strong>one sender to one specific destination</strong></p>
</li>
<li><p>It does <strong>not broadcast data to everyone</strong></p>
</li>
<li><p>Uses <strong>IP addresses</strong> to make decisions</p>
</li>
</ul>
<p>✅ (Correct: Router = Unicast device)</p>
<hr />
<p>2️⃣ <strong>Router is Used at the Edge of LAN and WAN</strong></p>
<ul>
<li><p>Routers sit at the <strong>boundary (edge)</strong> between:</p>
<ul>
<li><p><strong>LAN (Local Area Network)</strong></p>
</li>
<li><p><strong>WAN (Wide Area Network)</strong></p>
</li>
</ul>
</li>
</ul>
<p>📌 Example:</p>
<ul>
<li>Office LAN → Router → ISP / Internet (WAN)</li>
</ul>
<hr />
<p>3️⃣ <strong>Router is a Layer 3 Device</strong></p>
<ul>
<li><p>Works at <strong>OSI Layer 3 (Network Layer)</strong></p>
</li>
<li><p>Uses <strong>IP addressing</strong></p>
</li>
<li><p>Makes routing decisions</p>
</li>
</ul>
<hr />
<p>4️⃣ <strong>Router is Used for Routing</strong></p>
<ul>
<li><p><strong>Routing</strong> = selecting the <strong>best path</strong> for data</p>
</li>
<li><p>Router checks routing table and forwards packets</p>
</li>
</ul>
<p><strong>5️⃣ Routers Connect Different Networks</strong></p>
<p>Router is used to communicate between <strong>two or more different networks</strong>.<br />If devices are on <strong>different networks</strong>, they cannot communicate directly.<br />A <strong>router acts as a gateway</strong> and forwards data from one network to another using IP addresses.</p>
<p><strong>Example:</strong><br />A device in <strong>192.168.1.0/24</strong> network can communicate with a device in <strong>10.0.0.0/24</strong> network only through a <strong>router</strong>.</p>
<p>If you want, I can also simplify it more for CCNA notes 📘</p>
<hr />
<h2 id="heading-2-router-ports-corrected-amp-explained">2️⃣ Router Ports (Corrected &amp; Explained)</h2>
<p>Your teacher showed <strong>router images</strong> and explained ports.</p>
<h3 id="heading-wan-ports-serial-ports">🔹 WAN Ports (Serial Ports)</h3>
<ul>
<li><p><strong>Serial ports are used for WAN connections</strong></p>
</li>
<li><p>Used to connect:</p>
<ul>
<li><p>Router to router</p>
</li>
<li><p>Router to ISP</p>
</li>
</ul>
</li>
</ul>
<p>📌 Common WAN media:</p>
<ul>
<li><p>Fiber optic</p>
</li>
<li><p>Radio link</p>
</li>
<li><p>VSAT (Satellite)</p>
</li>
</ul>
<p>✅ Correct term: <strong>Serial Interface / WAN Interface</strong></p>
<hr />
<h3 id="heading-lan-ports-ethernet-ports">🔹 LAN Ports (Ethernet Ports)</h3>
<p>Routers have <strong>Ethernet LAN ports</strong> for local networks.</p>
<p>There are <strong>three main Ethernet speed types</strong> 👇</p>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Name (Corrected)</td><td>Speed</td></tr>
</thead>
<tbody>
<tr>
<td><strong>Ethernet</strong></td><td>10 Mbps</td></tr>
<tr>
<td><strong>Fast Ethernet</strong></td><td>100 Mbps</td></tr>
<tr>
<td><strong>Gigabit Ethernet</strong></td><td>1000 Mbps (1 Gbps)</td></tr>
</tbody>
</table>
</div><p>❌ Wrong terms corrected:</p>
<ul>
<li><p>“1 MB” ❌ → <strong>10 Mbps / 100 Mbps / 1000 Mbps</strong></p>
</li>
<li><p>“Super fast” ❌ → <strong>Gigabit Ethernet</strong></p>
</li>
</ul>
<p>📌 These LAN ports connect:</p>
<ul>
<li><p>PCs</p>
</li>
<li><p>Switches</p>
</li>
<li><p>Servers</p>
</li>
</ul>
<hr />
<h2 id="heading-3-router-amp-switch-hardware-inside-amp-outside">3️⃣ Router &amp; Switch Hardware (Inside &amp; Outside)</h2>
<p>Your teacher showed <strong>inside and outside components</strong>.</p>
<h3 id="heading-outside-components">🔹 Outside Components</h3>
<ul>
<li><p>Ethernet ports</p>
</li>
<li><p>Serial ports</p>
</li>
<li><p>Power port</p>
</li>
<li><p>Status LEDs</p>
</li>
<li><p>Cooling vents</p>
</li>
</ul>
<hr />
<h3 id="heading-inside-components">🔹 Inside Components</h3>
<ul>
<li><p><strong>CPU</strong> → Processes routing decisions</p>
</li>
<li><p><strong>RAM</strong> → Running configuration</p>
</li>
<li><p><strong>ROM</strong> → Bootstrap &amp; POST</p>
</li>
<li><p><strong>Flash Memory</strong> → IOS storage</p>
</li>
<li><p><strong>Fan</strong> → Cooling</p>
</li>
</ul>
<p>📌 Switches also have:</p>
<ul>
<li><p>CPU</p>
</li>
<li><p>RAM</p>
</li>
<li><p>Fan</p>
</li>
<li><p>Ports<br />  (but switches work at Layer 2 mainly)</p>
</li>
</ul>
<hr />
<h2 id="heading-4-addressing-introduction">4️⃣ Addressing (Introduction)</h2>
<p>Teacher explained that <strong>networking uses addresses</strong>.</p>
<h3 id="heading-three-common-addresses">🔹 Three Common Addresses</h3>
<p>1️⃣ <strong>MAC Address</strong><br />2️⃣ <strong>IP Address</strong><br />3️⃣ <strong>Serial Address</strong> (covered later)</p>
<p>📌 For now, focus was on <strong>MAC &amp; IP</strong></p>
<hr />
<h2 id="heading-5-mac-address-physical-address">5️⃣ MAC Address (Physical Address)</h2>
<h3 id="heading-what-is-a-mac-address">🔹 What is a MAC Address?</h3>
<ul>
<li><p><strong>MAC (Media Access Control) address</strong> is a <strong>physical address</strong></p>
</li>
<li><p>Assigned by the <strong>manufacturer</strong></p>
</li>
<li><p>Stored in <strong>network interface hardware</strong></p>
</li>
<li><p>Works at <strong>Layer 2</strong></p>
</li>
</ul>
<p>📌 Format example:<br /><code>00:1A:2B:3C:4D:5E</code></p>
<hr />
<h3 id="heading-one-device-can-have-multiple-mac-addresses">🔹 One Device Can Have Multiple MAC Addresses</h3>
<p>Your example is <strong>100% correct</strong> ✅</p>
<p>A <strong>laptop</strong> can have:</p>
<ul>
<li><p><strong>Wi-Fi MAC address</strong></p>
</li>
<li><p><strong>Ethernet MAC address</strong></p>
</li>
<li><p><strong>Bluetooth MAC address</strong></p>
</li>
</ul>
<p>📌 Reason:</p>
<ul>
<li>Each <strong>network interface</strong> has its <strong>own MAC address</strong></li>
</ul>
<hr />
<h2 id="heading-6-banking-fintech-network-infrastructure-real-world-example">6️⃣ Banking / FinTech Network Infrastructure (Real-World Example)</h2>
<p>Teacher explained <strong>real banking infrastructure</strong>.</p>
<hr />
<h3 id="heading-head-office-main-data-center">🔹 Head Office (Main Data Center)</h3>
<ul>
<li><p>Central location</p>
</li>
<li><p>Contains:</p>
<ul>
<li><p>Core switches</p>
</li>
<li><p>Routers</p>
</li>
<li><p>Database servers</p>
</li>
<li><p>Application servers</p>
</li>
</ul>
</li>
</ul>
<p>This forms a <strong>LAN at headquarters</strong>.</p>
<hr />
<h3 id="heading-branch-offices">🔹 Branch Offices</h3>
<ul>
<li><p>Branches connect to <strong>head office</strong></p>
</li>
<li><p>Connection methods:</p>
<ul>
<li><p><strong>Fiber optic</strong></p>
</li>
<li><p><strong>Radio links</strong></p>
</li>
<li><p><strong>VSAT (Satellite)</strong></p>
</li>
</ul>
</li>
</ul>
<p>This creates a <strong>WAN</strong></p>
<hr />
<h3 id="heading-atm-network-flow-corrected-amp-explained">🔹 ATM Network Flow (Corrected &amp; Explained)</h3>
<p>When a user enters <strong>ATM PIN</strong>:</p>
<p>1️⃣ ATM machine<br />→ connects to <strong>local switch</strong></p>
<p>2️⃣ Switch<br />→ connects to <strong>router</strong></p>
<p>3️⃣ Router<br />→ sends data via <strong>WAN (fiber / radio / VSAT)</strong></p>
<p>4️⃣ Head Office Router<br />→ Head Office Switch</p>
<p>5️⃣ Switch<br />→ <strong>Database servers</strong></p>
<p>6️⃣ DB server<br />→ verifies PIN &amp; balance<br />→ response sent back through same path</p>
<p>📌 This is a <strong>real-time network transaction</strong></p>
<hr />
<h2 id="heading-7-point-to-point-communication-important-concept">7️⃣ Point-to-Point Communication (Important Concept)</h2>
<p>Teacher explained <strong>FinTech / Banking communication type</strong>.</p>
<h3 id="heading-point-to-point">🔹 Point-to-Point</h3>
<ul>
<li><p>One sender ↔ one receiver</p>
</li>
<li><p><strong>Bi-directional</strong></p>
</li>
<li><p>Very secure and reliable</p>
</li>
</ul>
<p>📌 Used by:</p>
<ul>
<li><p>Banks</p>
</li>
<li><p>FinTech apps</p>
</li>
<li><p>ATM networks</p>
</li>
</ul>
<hr />
<h3 id="heading-direction-types-corrected">🔹 Direction Types (Corrected)</h3>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Type</td><td>Explanation</td></tr>
</thead>
<tbody>
<tr>
<td><strong>Unidirectional</strong></td><td>One-way communication</td></tr>
<tr>
<td><strong>Bi-directional</strong> ✅</td><td>Two-way communication</td></tr>
<tr>
<td><strong>Omni-directional</strong></td><td>One-to-many</td></tr>
</tbody>
</table>
</div><p>📌 Banking uses <strong>bi-directional point-to-point</strong>,<br />❌ NOT broadcast or omni-directional.</p>
<hr />
<h2 id="heading-day-3-quick-revision">✅ DAY-3 QUICK REVISION</h2>
<ul>
<li><p>Router = Layer 3, Unicast, Routing device</p>
</li>
<li><p>Router connects LAN ↔ WAN</p>
</li>
<li><p>Serial ports → WAN</p>
</li>
<li><p>Ethernet / Fast Ethernet / Gigabit Ethernet → LAN</p>
</li>
<li><p>MAC address = physical address</p>
</li>
<li><p>One device can have multiple MACs</p>
</li>
<li><p>Banking networks use WAN + point-to-point</p>
</li>
<li><p>ATM → Switch → Router → WAN → Head Office → DB</p>
</li>
</ul>
<h1 id="heading-day-4-mac-address-ip-address-amp-number-systems"><strong>🔹 DAY 4 – MAC Address, IP Address &amp; Number Systems</strong></h1>
<hr />
<h2 id="heading-1-mac-address-detailed">1️⃣ MAC Address (Detailed)</h2>
<h3 id="heading-what-is-a-mac-address-1">🔹 What is a MAC Address?</h3>
<ul>
<li><p><strong>MAC (Media Access Control) address</strong> is a <strong>physical address</strong></p>
</li>
<li><p>It is <strong>assigned by the manufacturer</strong></p>
</li>
<li><p>Stored in the <strong>network interface hardware</strong></p>
</li>
<li><p>Works at <strong>OSI Layer 2 (Data Link Layer)</strong></p>
</li>
<li><p>MAC address is <strong>unique worldwide</strong></p>
</li>
</ul>
<hr />
<h3 id="heading-mac-address-naming-conventions-formats">🔹 MAC Address Naming Conventions (Formats)</h3>
<p>MAC address can be written in <strong>different formats</strong>, but the value remains the same.</p>
<p>Examples:</p>
<ul>
<li><p><strong>Colon format:</strong><br />  <code>00:1A:2B:3C:4D:5E</code></p>
</li>
<li><p><strong>Hyphen format:</strong><br />  <code>00-1A-2B-3C-4D-5E</code></p>
</li>
<li><p><strong>Cisco format:</strong><br />  <code>001A.2B3C.4D5E</code></p>
</li>
</ul>
<p>📌 These are just <strong>different representations</strong>, not different MACs.</p>
<hr />
<h3 id="heading-mac-address-structure">🔹 MAC Address Structure</h3>
<p>A MAC address is <strong>48 bits total</strong>.</p>
<p>It is divided into <strong>two main parts</strong>:</p>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Part</td><td>Size</td><td>Meaning</td></tr>
</thead>
<tbody>
<tr>
<td><strong>Vendor Code (OUI)</strong></td><td>24 bits</td><td>Company / Manufacturer</td></tr>
<tr>
<td><strong>Serial Number</strong></td><td>24 bits</td><td>Unique device number</td></tr>
</tbody>
</table>
</div><p>✅ Corrected term:</p>
<ul>
<li>“Verder code” ❌ → <strong>Vendor code (OUI)</strong> ✅</li>
</ul>
<p>📌 Example:</p>
<pre><code class="lang-plaintext">00:1A:2B | 3C:4D:5E
Vendor     Serial Number
</code></pre>
<hr />
<h2 id="heading-2-ip-address-ipv4">2️⃣ IP Address (IPv4)</h2>
<h3 id="heading-what-is-an-ip-address">🔹 What is an IP Address?</h3>
<ul>
<li><p><strong>IP (Internet Protocol) address</strong> is a <strong>logical address</strong></p>
</li>
<li><p>Works at <strong>OSI Layer 3 (Network Layer)</strong></p>
</li>
<li><p>Used for <strong>routing and identification</strong></p>
</li>
<li><p>Can <strong>change</strong> (unlike MAC address)</p>
</li>
</ul>
<hr />
<h3 id="heading-ipv4-address-structure">🔹 IPv4 Address Structure</h3>
<ul>
<li><p>IPv4 address is <strong>32 bits</strong></p>
</li>
<li><p>Written in <strong>decimal dotted format</strong></p>
</li>
</ul>
<p>Example:</p>
<pre><code class="lang-plaintext">192.168.1.10
</code></pre>
<p>Each number is <strong>8 bits (1 byte)</strong>.</p>
<hr />
<h3 id="heading-ip-address-parts">🔹 IP Address Parts</h3>
<p>An IP address is divided into:</p>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Part</td><td>Purpose</td></tr>
</thead>
<tbody>
<tr>
<td><strong>Network Address</strong></td><td>Identifies the network</td></tr>
<tr>
<td><strong>Host Address</strong></td><td>Identifies the device</td></tr>
</tbody>
</table>
</div><p>📌 Example:</p>
<pre><code class="lang-plaintext">192.168.1.10
Network   Host
</code></pre>
<hr />
<h2 id="heading-3-classes-of-ip-addresses">3️⃣ Classes of IP Addresses</h2>
<p>IPv4 addresses are divided into <strong>classes</strong> based on range.</p>
<h3 id="heading-ip-address-classes-basic">🔹 IP Address Classes (Basic)</h3>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Class</td><td>Range</td><td>Usage</td></tr>
</thead>
<tbody>
<tr>
<td><strong>Class A</strong></td><td>1 – 126</td><td>Very large networks</td></tr>
<tr>
<td><strong>Class B</strong></td><td>128 – 191</td><td>Medium networks</td></tr>
<tr>
<td><strong>Class C</strong></td><td>192 – 223</td><td>Small networks</td></tr>
<tr>
<td><strong>Class D</strong></td><td>224 – 239</td><td>Multicast</td></tr>
<tr>
<td><strong>Class E</strong></td><td>240 – 255</td><td>Experimental</td></tr>
</tbody>
</table>
</div><p>📌 Commonly used:</p>
<ul>
<li><p>Home &amp; office → <strong>Class C</strong></p>
</li>
<li><p>Large companies → <strong>Class A / B</strong></p>
</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1767607836717/2d9239ea-df46-4f58-b768-e6acdbd79595.jpeg" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1768380219752/70eb39b7-ba04-4f88-b9e7-b0cadb67877b.webp" alt class="image--center mx-auto" /></p>
<hr />
<h2 id="heading-4-number-systems-in-networking">4️⃣ Number Systems in Networking</h2>
<p>Networking uses <strong>three number systems</strong>:</p>
<div class="hn-table">
<table>
<thead>
<tr>
<td>System</td><td>Base</td></tr>
</thead>
<tbody>
<tr>
<td><strong>Decimal</strong></td><td>Base 10</td></tr>
<tr>
<td><strong>Binary</strong></td><td>Base 2</td></tr>
<tr>
<td><strong>Hexadecimal</strong></td><td>Base 16</td></tr>
</tbody>
</table>
</div><hr />
<h3 id="heading-decimal">🔹 Decimal</h3>
<ul>
<li><p>Digits: <strong>0–9</strong></p>
</li>
<li><p>Used by humans</p>
</li>
<li><p>Example: <code>192</code></p>
</li>
</ul>
<hr />
<h3 id="heading-binary">🔹 Binary</h3>
<ul>
<li><p>Digits: <strong>0 and 1</strong></p>
</li>
<li><p>Used by computers</p>
</li>
<li><p>Example:</p>
</li>
</ul>
<pre><code class="lang-plaintext">11000000
</code></pre>
<hr />
<h3 id="heading-hexadecimal">🔹 Hexadecimal</h3>
<ul>
<li><p>Digits: <strong>0–9 and A–F</strong></p>
</li>
<li><p>Used to represent <strong>binary in short form</strong></p>
</li>
<li><p>Commonly used in <strong>MAC addresses</strong></p>
</li>
</ul>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Hex</td><td>Binary</td></tr>
</thead>
<tbody>
<tr>
<td>0</td><td>0000</td></tr>
<tr>
<td>A</td><td>1010</td></tr>
<tr>
<td>F</td><td>1111</td></tr>
</tbody>
</table>
</div><hr />
<h2 id="heading-5-binary-hexadecimal-conversion">5️⃣ Binary ↔ Hexadecimal Conversion</h2>
<h3 id="heading-binary-to-hexadecimal">🔹 Binary to Hexadecimal</h3>
<ul>
<li><p>Group binary into <strong>4 bits</strong></p>
</li>
<li><p>Convert each group to hex</p>
</li>
</ul>
<p>Example:</p>
<pre><code class="lang-plaintext">Binary: 1100 1010
Hex:     C    A
</code></pre>
<hr />
<h3 id="heading-hexadecimal-to-binary">🔹 Hexadecimal to Binary</h3>
<ul>
<li>Convert each hex digit into <strong>4-bit binary</strong></li>
</ul>
<p>Example:</p>
<pre><code class="lang-plaintext">Hex: A
Binary: 1010
</code></pre>
<hr />
<h2 id="heading-6-where-these-are-used">6️⃣ Where These Are Used</h2>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Address</td><td>Uses</td></tr>
</thead>
<tbody>
<tr>
<td><strong>MAC Address</strong></td><td>Local delivery (Layer 2)</td></tr>
<tr>
<td><strong>IP Address</strong></td><td>Routing between networks (Layer 3)</td></tr>
<tr>
<td><strong>Binary</strong></td><td>Internal computer processing</td></tr>
<tr>
<td><strong>Hexadecimal</strong></td><td>MAC addresses, troubleshooting</td></tr>
</tbody>
</table>
</div><hr />
<h2 id="heading-day-4-quick-revision">✅ DAY-4 QUICK REVISION</h2>
<ul>
<li><p>MAC = physical, 48-bit</p>
</li>
<li><p>Vendor code = 24-bit, Serial number = 24-bit</p>
</li>
<li><p>IPv4 = 32-bit</p>
</li>
<li><p>IP = Network + Host</p>
</li>
<li><p>Classes: A, B, C, D, E</p>
</li>
<li><p>Binary = base 2</p>
</li>
<li><p>Decimal = base 10</p>
</li>
<li><p>Hex = base 16</p>
</li>
<li><p>MAC addresses often written in hex</p>
</li>
</ul>
<h1 id="heading-ccna-day-5"><strong>📘 CCNA – Day 5</strong></h1>
<h2 id="heading-network-design-ip-planning-amp-address-classes"><strong>Network Design, IP Planning &amp; Address Classes</strong></h2>
<hr />
<h2 id="heading-1-network-lifecycle-design-deploy-troubleshoot">1️⃣ Network Lifecycle: Design → Deploy → Troubleshoot</h2>
<p>In networking, we <strong>never directly deploy</strong> a network.<br />There is a <strong>proper lifecycle</strong>:</p>
<h3 id="heading-1-design">🔹 1. Design</h3>
<ul>
<li><p>Decide:</p>
<ul>
<li><p>How many <strong>sites</strong> (branches, offices)</p>
</li>
<li><p>How many <strong>devices</strong></p>
</li>
<li><p>Which <strong>IP range</strong> to use</p>
</li>
<li><p>Which devices (routers, switches)</p>
</li>
</ul>
</li>
<li><p>Good design avoids future problems</p>
</li>
</ul>
<hr />
<h3 id="heading-2-deploy">🔹 2. Deploy</h3>
<ul>
<li><p>Implement the designed network</p>
</li>
<li><p>Configure:</p>
<ul>
<li><p>IP addresses</p>
</li>
<li><p>Routers</p>
</li>
<li><p>Switches</p>
</li>
</ul>
</li>
<li><p>Connect devices physically and logically</p>
</li>
</ul>
<hr />
<h3 id="heading-3-troubleshoot">🔹 3. Troubleshoot</h3>
<ul>
<li><p>Fix issues after deployment</p>
</li>
<li><p>Check:</p>
<ul>
<li><p>Connectivity</p>
</li>
<li><p>IP conflicts</p>
</li>
<li><p>Routing problems</p>
</li>
</ul>
</li>
</ul>
<p>📌 <strong>Rule:</strong><br />👉 A good design = less troubleshooting</p>
<hr />
<h2 id="heading-2-ip-address-planning-very-important">2️⃣ IP Address Planning (Very Important)</h2>
<p>Before assigning IPs, we must answer:</p>
<ul>
<li><p>How many <strong>sites</strong> are there?</p>
</li>
<li><p>How many <strong>devices per site</strong>?</p>
</li>
<li><p>Will the network <strong>grow in future</strong>?</p>
</li>
</ul>
<p>📌 Based on this, we choose:</p>
<ul>
<li><p><strong>IP class</strong></p>
</li>
<li><p><strong>IP range</strong></p>
</li>
<li><p><strong>Subnet size</strong></p>
</li>
</ul>
<hr />
<h2 id="heading-3-types-of-networks-based-on-size">3️⃣ Types of Networks (Based on Size)</h2>
<h3 id="heading-small-network">🔹 Small Network</h3>
<ul>
<li><p>Home network</p>
</li>
<li><p>Small office</p>
</li>
<li><p>Few devices</p>
</li>
</ul>
<hr />
<h3 id="heading-medium-network">🔹 Medium Network</h3>
<ul>
<li><p>Schools</p>
</li>
<li><p>Small companies</p>
</li>
<li><p>Multiple departments</p>
</li>
</ul>
<hr />
<h3 id="heading-enterprise-network">🔹 Enterprise Network</h3>
<ul>
<li><p>Large organizations</p>
</li>
<li><p>Multiple branches</p>
</li>
<li><p>Centralized management</p>
</li>
</ul>
<hr />
<h3 id="heading-large-networks-carrier-networks">🔹 Large Networks (Carrier Networks)</h3>
<p>These are called <strong>Carrier Networks</strong>.</p>
<p>📌 Examples:</p>
<ul>
<li><p><strong>Jazz</strong></p>
</li>
<li><p><strong>Zong</strong></p>
</li>
<li><p><strong>Ufone</strong></p>
</li>
<li><p><strong>Telenor</strong></p>
</li>
</ul>
<p>Characteristics:</p>
<ul>
<li><p>Very large IP ranges</p>
</li>
<li><p>Millions of users</p>
</li>
<li><p>Operate at national or international level</p>
</li>
</ul>
<hr />
<h2 id="heading-4-why-ip-address-127-is-not-used">4️⃣ Why IP Address 127 is NOT Used</h2>
<h3 id="heading-question">🔹 Question:</h3>
<p>Why <strong>Class A does not use 127.x.x.x</strong>?</p>
<h3 id="heading-answer">🔹 Answer:</h3>
<ul>
<li><p><strong>127.x.x.x</strong> is reserved for <strong>loopback</strong></p>
</li>
<li><p>Used for <strong>testing the local system</strong></p>
</li>
</ul>
<p>Example:</p>
<pre><code class="lang-plaintext">127.0.0.1 → localhost
</code></pre>
<p>📌 This address:</p>
<ul>
<li><p>Never leaves the device</p>
</li>
<li><p>Is not used in networks</p>
</li>
</ul>
<p>✅ That’s why:</p>
<ul>
<li><p>Class A usable range = <strong>1 – 126</strong></p>
</li>
<li><p><strong>127 is skipped</strong></p>
</li>
</ul>
<hr />
<h2 id="heading-5-ipv4-classes-overview">5️⃣ IPv4 Classes Overview</h2>
<p>IPv4 has <strong>5 classes</strong>, based on <strong>leading bits</strong> and <strong>range</strong>.</p>
<hr />
<h2 id="heading-6-leading-bit-ldb-leading-bit-pattern">6️⃣ Leading Bit (LDB / Leading Bit Pattern)</h2>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1768228269221/84c6e55f-ed66-4085-8e2f-52c793524620.png" alt class="image--center mx-auto" /></p>
<h3 id="heading-what-is-a-leading-bit">🔹 What is a Leading Bit?</h3>
<ul>
<li><p>The <strong>first few bits</strong> of an IP address</p>
</li>
<li><p>Used to identify the <strong>class of IP</strong></p>
</li>
</ul>
<hr />
<h3 id="heading-class-wise-leading-bits">🔹 Class-wise Leading Bits</h3>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Class</td><td>Leading Bits</td><td>First Octet Range</td></tr>
</thead>
<tbody>
<tr>
<td>A</td><td>0</td><td>1 – 126</td></tr>
<tr>
<td>B</td><td>10</td><td>128 – 191</td></tr>
<tr>
<td>C</td><td>110</td><td>192 – 223</td></tr>
<tr>
<td>D</td><td>1110</td><td>224 – 239</td></tr>
<tr>
<td>E</td><td>1111</td><td>240 – 255</td></tr>
</tbody>
</table>
</div><p>📌 Leading bits help routers understand:</p>
<ul>
<li><p>Network size</p>
</li>
<li><p>Address type</p>
</li>
</ul>
<hr />
<h2 id="heading-7-number-of-networks-amp-hosts-classful">7️⃣ Number of Networks &amp; Hosts (Classful)</h2>
<h3 id="heading-class-a">🔹 Class A</h3>
<ul>
<li><p>Network bits: 8</p>
</li>
<li><p>Host bits: 24</p>
</li>
<li><p>Hosts per network: <strong>16,777,214</strong></p>
</li>
</ul>
<hr />
<h3 id="heading-class-b">🔹 Class B</h3>
<ul>
<li><p>Network bits: 16</p>
</li>
<li><p>Host bits: 16</p>
</li>
<li><p>Hosts per network: <strong>65,534</strong></p>
</li>
</ul>
<hr />
<h3 id="heading-class-c">🔹 Class C</h3>
<ul>
<li><p>Network bits: 24</p>
</li>
<li><p>Host bits: 8</p>
</li>
<li><p>Hosts per network: <strong>254</strong></p>
</li>
</ul>
<p>📌 Formula:</p>
<pre><code class="lang-plaintext">Hosts = 2^n – 2
</code></pre>
<p>(–2 for Network ID &amp; Broadcast)</p>
<hr />
<h2 id="heading-8-ip-address-vs-network-identifier">8️⃣ IP Address vs Network Identifier</h2>
<h3 id="heading-ip-address">🔹 IP Address</h3>
<ul>
<li><p>Assigned to a <strong>device</strong></p>
</li>
<li><p>Used for communication</p>
</li>
</ul>
<p>Example:</p>
<pre><code class="lang-plaintext">192.168.1.10
</code></pre>
<hr />
<h3 id="heading-network-identifier-network-id">🔹 Network Identifier (Network ID)</h3>
<ul>
<li><p>Identifies the <strong>network</strong></p>
</li>
<li><p>First address of the network</p>
</li>
<li><p><strong>Cannot be assigned to a device</strong></p>
</li>
</ul>
<p>Example:</p>
<pre><code class="lang-plaintext">192.168.1.0
</code></pre>
<hr />
<h2 id="heading-9-network-id-vs-broadcast-id">9️⃣ Network ID vs Broadcast ID</h2>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Type</td><td>Purpose</td><td>Usable?</td></tr>
</thead>
<tbody>
<tr>
<td><strong>Network ID</strong></td><td>Identifies network</td><td>❌ No</td></tr>
<tr>
<td><strong>Broadcast ID</strong></td><td>Send data to all devices</td><td>❌ No</td></tr>
</tbody>
</table>
</div><p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1768228486552/67234994-f4f0-4941-9187-dd9999383ac9.jpeg" alt class="image--center mx-auto" /></p>
<hr />
<h3 id="heading-broadcast-address">🔹 Broadcast Address</h3>
<ul>
<li><p>Last IP of the network</p>
</li>
<li><p>Sends data to <strong>all devices in LAN</strong></p>
</li>
</ul>
<p>Example:</p>
<pre><code class="lang-plaintext">192.168.1.255
</code></pre>
<hr />
<h2 id="heading-reserved-amp-usable-ips-in-each-class">🔟 Reserved &amp; Usable IPs in Each Class</h2>
<h3 id="heading-class-c-example">🔹 Class C Example</h3>
<pre><code class="lang-plaintext">192.168.1.0   → Network ID (Reserved)
192.168.1.1   → First usable IP
192.168.1.254 → Last usable IP
192.168.1.255 → Broadcast (Reserved)
</code></pre>
<p>📌 Usable IPs = <strong>254</strong></p>
<hr />
<h2 id="heading-11-summary-table-classful-ips">1️⃣1️⃣ Summary Table (Classful IPs)</h2>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Class</td><td>Range</td><td>Usable Hosts</td></tr>
</thead>
<tbody>
<tr>
<td>A</td><td>1–126</td><td>16 million</td></tr>
<tr>
<td>B</td><td>128–191</td><td>65k</td></tr>
<tr>
<td>C</td><td>192–223</td><td>254</td></tr>
<tr>
<td>D</td><td>Multicast</td><td>N/A</td></tr>
<tr>
<td>E</td><td>Experimental</td><td>N/A</td></tr>
</tbody>
</table>
</div><hr />
<h2 id="heading-day-5-quick-revision">✅ DAY-5 QUICK REVISION</h2>
<ul>
<li><p>Network lifecycle: Design → Deploy → Troubleshoot</p>
</li>
<li><p>Choose IP range based on <strong>sites &amp; devices</strong></p>
</li>
<li><p>Carrier networks = Jazz, Zong</p>
</li>
<li><p>127.x.x.x = loopback (not usable)</p>
</li>
<li><p>Leading bits identify IP class</p>
</li>
<li><p>Network ID &amp; Broadcast are <strong>reserved</strong></p>
</li>
<li><p>Hosts = 2^n – 2</p>
</li>
</ul>
<h1 id="heading-ccna-day-6"><strong>CCNA – Day 6</strong></h1>
<h2 id="heading-public-vs-private-ip-subnet-masks-amp-inter-network-communication"><strong>Public vs Private IP, Subnet Masks &amp; Inter-Network Communication</strong></h2>
<hr />
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1768228398613/5b0451ae-ba8a-4f26-99c8-50b4e17cca74.jpeg" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1768380261650/b030df3c-1b41-4483-85fa-36c29280d51f.jpeg" alt class="image--center mx-auto" /></p>
<h2 id="heading-1-public-ip-address">1️⃣ Public IP Address</h2>
<h3 id="heading-what-is-a-public-ip">🔹 What is a Public IP?</h3>
<p>A <strong>Public IP address</strong> is an IP address that:</p>
<ul>
<li><p>Is <strong>globally unique</strong></p>
</li>
<li><p>Is reachable from the <strong>internet</strong></p>
</li>
<li><p>Is assigned by an <strong>ISP</strong></p>
</li>
</ul>
<h3 id="heading-key-characteristics">🔹 Key Characteristics</h3>
<ul>
<li><p><strong>Paid</strong> (you get it from ISP)</p>
</li>
<li><p>Usually <strong>static</strong> (does not change frequently)</p>
</li>
<li><p>Used for:</p>
<ul>
<li><p>Websites</p>
</li>
<li><p>Servers</p>
</li>
<li><p>Public services</p>
</li>
</ul>
</li>
</ul>
<p>📌 Example use:</p>
<ul>
<li><p>Google server</p>
</li>
<li><p>Bank website</p>
</li>
<li><p>Public cloud servers</p>
</li>
</ul>
<hr />
<h2 id="heading-2-private-ip-address">2️⃣ Private IP Address</h2>
<h3 id="heading-what-is-a-private-ip">🔹 What is a Private IP?</h3>
<p>A <strong>Private IP address</strong> is used <strong>inside local networks (LANs)</strong>.</p>
<ul>
<li><p>Not reachable directly from the internet</p>
</li>
<li><p>Can be reused in different networks</p>
</li>
<li><p>Free to use</p>
</li>
</ul>
<hr />
<h3 id="heading-rfc-defined-private-ip-ranges">🔹 RFC-Defined Private IP Ranges</h3>
<p>Private IP ranges are defined by <strong>RFC 1918</strong>.</p>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Class</td><td>Private IP Range</td></tr>
</thead>
<tbody>
<tr>
<td><strong>Class A</strong></td><td>10.0.0.0 – 10.255.255.255</td></tr>
<tr>
<td><strong>Class B</strong></td><td>172.16.0.0 – 172.31.255.255</td></tr>
<tr>
<td><strong>Class C</strong></td><td>192.168.0.0 – 192.168.255.255</td></tr>
</tbody>
</table>
</div><p>📌 These ranges are <strong>internationally reserved</strong> for private use.</p>
<p><img src alt class="image--center mx-auto" /></p>
<hr />
<h2 id="heading-3-public-vs-private-ip-comparison">3️⃣ Public vs Private IP (Comparison)</h2>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Feature</td><td>Public IP</td><td>Private IP</td></tr>
</thead>
<tbody>
<tr>
<td>Scope</td><td>Global</td><td>Local</td></tr>
<tr>
<td>Unique</td><td>Yes (Worldwide)</td><td>No</td></tr>
<tr>
<td>Cost</td><td>Paid</td><td>Free</td></tr>
<tr>
<td>Internet Access</td><td>Direct</td><td>Indirect</td></tr>
<tr>
<td>Example</td><td>Bank server</td><td>Home router</td></tr>
</tbody>
</table>
</div><hr />
<h2 id="heading-4-subnet-mask-classful">4️⃣ Subnet Mask (Classful)</h2>
<p>A <strong>subnet mask</strong> tells:</p>
<ul>
<li><p>Which part is <strong>network</strong></p>
</li>
<li><p>Which part is <strong>host</strong></p>
</li>
</ul>
<hr />
<h3 id="heading-default-subnet-masks">🔹 Default Subnet Masks</h3>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Class</td><td>Subnet Mask</td><td>CIDR</td></tr>
</thead>
<tbody>
<tr>
<td><strong>Class A</strong></td><td>255.0.0.0</td><td>/8</td></tr>
<tr>
<td><strong>Class B</strong></td><td>255.255.0.0</td><td>/16</td></tr>
<tr>
<td><strong>Class C</strong></td><td>255.255.255.0</td><td>/24</td></tr>
</tbody>
</table>
</div><p>📌 These are <strong>default (classful) subnet masks</strong>.</p>
<hr />
<h2 id="heading-5-same-network-communication">5️⃣ Same Network Communication</h2>
<h3 id="heading-devices-on-same-network">🔹 Devices on Same Network</h3>
<ul>
<li><p>Two devices can <strong>communicate directly</strong> if:</p>
<ul>
<li><p>They are in the <strong>same network</strong></p>
</li>
<li><p>They have the <strong>same subnet mask</strong></p>
</li>
</ul>
</li>
</ul>
<p>📌 Example:</p>
<pre><code class="lang-plaintext">192.168.1.10 /24
192.168.1.20 /24
</code></pre>
<p>✔ Direct communication</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1768228331773/8aa8d91f-c691-4c1a-a6da-a34191bf6113.jpeg" alt class="image--center mx-auto" /></p>
<hr />
<h2 id="heading-6-different-network-communication">6️⃣ Different Network Communication</h2>
<h3 id="heading-devices-on-different-networks">🔹 Devices on Different Networks</h3>
<ul>
<li>If devices are in <strong>different networks</strong>, they <strong>cannot communicate directly</strong></li>
</ul>
<p>📌 Example:</p>
<pre><code class="lang-plaintext">192.168.1.10 /24
192.168.2.10 /24
</code></pre>
<p>❌ Direct communication not possible</p>
<hr />
<h3 id="heading-role-of-router">🔹 Role of Router</h3>
<ul>
<li><p>A <strong>router is required</strong> to:</p>
<ul>
<li><p>Connect different networks</p>
</li>
<li><p>Forward packets between networks</p>
</li>
</ul>
</li>
<li><p>Router acts as a <strong>default gateway</strong></p>
</li>
</ul>
<p>📌 Flow:</p>
<pre><code class="lang-plaintext">Device → Switch → Router → Other Network
</code></pre>
<hr />
<h2 id="heading-7-why-router-is-needed">7️⃣ Why Router is Needed</h2>
<ul>
<li><p>Switch works only in <strong>same network</strong></p>
</li>
<li><p>Router works between <strong>different networks</strong></p>
</li>
<li><p>Router uses:</p>
<ul>
<li><p>IP address</p>
</li>
<li><p>Routing table</p>
</li>
</ul>
</li>
</ul>
<p>📌 Without router:</p>
<ul>
<li>No inter-network communication</li>
</ul>
<hr />
<h2 id="heading-8-real-world-example">8️⃣ Real-World Example</h2>
<h3 id="heading-home-network">🔹 Home Network</h3>
<ul>
<li><p>Devices use <strong>private IPs</strong></p>
</li>
<li><p>Router has:</p>
<ul>
<li><p>Private IP (LAN side)</p>
</li>
<li><p>Public IP (WAN side)</p>
</li>
</ul>
</li>
<li><p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1768228302803/4746dcab-34bd-47ee-af20-d9b5673ff326.jpeg" alt class="image--center mx-auto" /></p>
</li>
</ul>
<p>📌 Router connects:</p>
<pre><code class="lang-plaintext">Private Network ↔ Internet
</code></pre>
<hr />
<h2 id="heading-day-6-quick-revision">✅ DAY-6 QUICK REVISION</h2>
<ul>
<li><p>Public IP = paid, global, static</p>
</li>
<li><p>Private IP = free, local, reusable</p>
</li>
<li><p>RFC 1918 defines private IP ranges</p>
</li>
<li><p>Subnet mask defines network &amp; host</p>
</li>
<li><p>Same network → direct communication</p>
</li>
<li><p>Different networks → router required</p>
</li>
<li><p>Router = gateway between networks</p>
</li>
</ul>
<h1 id="heading-day-7-device-connectivity-methods-amp-practical-network-setup-cisco-packet-tracer"><strong>Day 7 – Device Connectivity Methods &amp; Practical Network Setup (Cisco Packet Tracer)</strong></h1>
<p>On <strong>Day 7</strong>, our focus shifted from IP addressing and routing theory to <strong>device connectivity methods</strong> and a <strong>hands-on practical lab</strong> using <strong>Cisco Packet Tracer</strong>. This day was important because it connected theory with real-world networking practice.</p>
<hr />
<h2 id="heading-1-device-connectivity-methods">1. Device Connectivity Methods</h2>
<p>In networking, there are <strong>three primary ways to connect to network devices (routers/switches)</strong>:</p>
<h3 id="heading-11-console-connection">1.1 Console Connection</h3>
<p>A <strong>console connection</strong> is used for <strong>initial configuration and troubleshooting</strong> of network devices.</p>
<ul>
<li><p>It provides <strong>out-of-band management</strong>, meaning it works even if the network is down</p>
</li>
<li><p>Requires a <strong>console (rollover) cable</strong></p>
</li>
<li><p>Commonly used when:</p>
<ul>
<li><p>A device is new</p>
</li>
<li><p>IP configuration is not done</p>
</li>
<li><p>Remote access (SSH/Telnet) is not available</p>
</li>
</ul>
</li>
</ul>
<p><strong>Key Points:</strong></p>
<ul>
<li><p>No IP address required</p>
</li>
<li><p>Direct physical access is needed</p>
</li>
<li><p>Very secure (local access only)</p>
</li>
</ul>
<hr />
<h3 id="heading-12-aux-auxiliary-connection">1.2 AUX (Auxiliary) Connection</h3>
<p>The <strong>AUX port</strong> is mainly used for <strong>remote management via modem</strong>.</p>
<ul>
<li><p>Works as an <strong>out-of-band connection</strong></p>
</li>
<li><p>Mostly used in older or backup management scenarios</p>
</li>
<li><p>Less common in modern enterprise networks</p>
</li>
</ul>
<p><strong>Key Points:</strong></p>
<ul>
<li><p>Requires authentication</p>
</li>
<li><p>Used when console access is not physically possible</p>
</li>
<li><p>Largely replaced by SSH today</p>
</li>
</ul>
<hr />
<h3 id="heading-13-interface-based-connections-in-band-management">1.3 Interface-Based Connections (In-Band Management)</h3>
<p>Interface connections require a <strong>working network</strong> and an <strong>IP address</strong>. There are two main types:</p>
<h4 id="heading-a-telnet">a) Telnet</h4>
<p>Telnet allows remote login to network devices over the network.</p>
<ul>
<li><p>Uses <strong>TCP port 23</strong></p>
</li>
<li><p>Data (username/password) is sent in <strong>plain text</strong></p>
</li>
</ul>
<p><strong>Disadvantages:</strong></p>
<ul>
<li><p>Not secure</p>
</li>
<li><p>Vulnerable to sniffing and attacks</p>
</li>
</ul>
<hr />
<h4 id="heading-b-ssh-secure-shell">b) SSH (Secure Shell)</h4>
<p>SSH is the <strong>secure alternative to Telnet</strong>.</p>
<ul>
<li><p>Uses <strong>TCP port 22</strong></p>
</li>
<li><p>Encrypts all communication</p>
</li>
</ul>
<p><strong>Advantages:</strong></p>
<ul>
<li><p>Secure</p>
</li>
<li><p>Industry standard for device management</p>
</li>
<li><p>Preferred over Telnet in production environments</p>
</li>
</ul>
<hr />
<h2 id="heading-2-practical-lab-cisco-packet-tracer-network-design">2. Practical Lab – Cisco Packet Tracer Network Design</h2>
<p>After learning the theory, we implemented a <strong>practical topology</strong> in <strong>Cisco Packet Tracer</strong>.</p>
<h3 id="heading-21-devices-used">2.1 Devices Used</h3>
<ul>
<li><p><strong>2 × Routers:</strong> Cisco 2811 (IOS 15)</p>
</li>
<li><p><strong>2 × Switches:</strong> Cisco 3560-24PS</p>
</li>
<li><p><strong>2 × PCs</strong></p>
</li>
<li><p><strong>2 × Servers</strong></p>
</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1768737039384/6d9bd62e-7dcf-4c36-84c6-1e88d633509a.png" alt class="image--center mx-auto" /></p>
<h3 id="heading-22-router-to-router-connection-serial-link">2.2 Router-to-Router Connection (Serial Link)</h3>
<ul>
<li><p>The two routers were connected using a <strong>serial cable</strong> (red cable with a clock sign)</p>
</li>
<li><p>One router acts as <strong>DCE</strong> (provides clock rate)</p>
</li>
<li><p>The other acts as <strong>DTE</strong></p>
</li>
</ul>
<p>Before connecting:</p>
<ul>
<li>We installed <strong>VIC-2D (Smart Serial Port)</strong> modules into both routers using <strong>drag-and-drop</strong></li>
</ul>
<p>This step is required because routers do not have serial ports by default.</p>
<hr />
<h3 id="heading-23-lan-setup-on-each-router">2.3 LAN Setup on Each Router</h3>
<p>For each router:</p>
<ul>
<li><p>One <strong>3560-24PS switch</strong> was connected</p>
</li>
<li><p>Under each switch:</p>
<ul>
<li><p><strong>1 PC</strong></p>
</li>
<li><p><strong>1 Server</strong></p>
</li>
</ul>
</li>
</ul>
<p>This created <strong>two LANs</strong>, each connected to a router, and both routers connected via a <strong>WAN serial link</strong>.</p>
<hr />
<h2 id="heading-3-network-cables-and-their-usage">3. Network Cables and Their Usage</h2>
<p>We also learned about <strong>network cable types</strong> and where to use them.</p>
<h3 id="heading-31-straight-through-cable">3.1 Straight-Through Cable</h3>
<p>Used to connect <strong>different types of devices</strong>:</p>
<ul>
<li><p>PC → Switch</p>
</li>
<li><p>Switch → Router</p>
</li>
<li><p>Server → Switch</p>
</li>
</ul>
<p><strong>Logic:</strong></p>
<ul>
<li>Transmit (TX) and Receive (RX) pins are already matched</li>
</ul>
<hr />
<h3 id="heading-32-crossover-cable">3.2 Crossover Cable</h3>
<p>Used to connect <strong>same type of devices</strong>:</p>
<ul>
<li><p>PC → PC</p>
</li>
<li><p>Switch → Switch</p>
</li>
<li><p>Router → Router (Ethernet)</p>
</li>
</ul>
<p><strong>Logic:</strong></p>
<ul>
<li>TX and RX pins need to be crossed manually</li>
</ul>
<blockquote>
<p>Note: Modern devices support <strong>Auto-MDIX</strong>, which automatically handles this, but understanding crossover cables is still important for fundamentals.</p>
</blockquote>
<hr />
<h3 id="heading-33-rollover-cable">3.3 Rollover Cable</h3>
<p>Used for <strong>console connections only</strong>:</p>
<ul>
<li><p>PC → Router Console Port</p>
</li>
<li><p>PC → Switch Console Port</p>
</li>
</ul>
<p><strong>Key Points:</strong></p>
<ul>
<li><p>Pin order is fully reversed</p>
</li>
<li><p>Not used for data traffic</p>
</li>
<li><p>Commonly available, so no need to create it manually</p>
</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1768730162799/c0eb7cfa-e619-4213-be7e-4f889d6d7438.png" alt class="image--center mx-auto" /></p>
<hr />
<h2 id="heading-4-key-takeaways-from-day-7">4. Key Takeaways from Day 7</h2>
<ul>
<li><p>Learned <strong>three device connectivity methods</strong>: Console, AUX, and Interface-based (Telnet/SSH)</p>
</li>
<li><p>Understood why <strong>SSH is preferred over Telnet</strong></p>
</li>
<li><p>Built a <strong>complete multi-router network</strong> in Cisco Packet Tracer</p>
</li>
<li><p>Learned when to use <strong>straight, crossover, and rollover cables</strong></p>
</li>
<li><p>Gained practical exposure to <strong>WAN serial connections</strong> using DCE/DTE concepts</p>
</li>
</ul>
<hr />
<p>Day 7 strengthened our understanding of <strong>real-world networking</strong>, combining theory, device access methods, and hands-on topology design.</p>
<p>Done 👍<br />I’ve written <strong>Day 7</strong> as a <strong>detailed blog-style document</strong> and placed it in the canvas.</p>
<p>What I covered clearly and step by step:</p>
<ul>
<li><p><strong>All three device connectivity methods</strong>: Console, AUX, and Interface</p>
</li>
<li><p><strong>Telnet vs SSH</strong> (ports, security, use cases)</p>
</li>
<li><p><strong>Complete Cisco Packet Tracer practical</strong>:</p>
<ul>
<li><p>2 × Cisco 2811 routers (IOS 15)</p>
</li>
<li><p>VIC-2D smart serial module</p>
</li>
<li><p>Serial DCE/DTE connection (red cable with clock)</p>
</li>
<li><p>2 × 3560-24PS switches</p>
</li>
<li><p>PCs and Servers under each LAN</p>
</li>
</ul>
</li>
<li><p><strong>All cable types</strong>:</p>
<ul>
<li><p>Straight-through</p>
</li>
<li><p>Crossover</p>
</li>
<li><p>Rollover (console)</p>
</li>
</ul>
</li>
</ul>
<h1 id="heading-day-8-router-cli-modes-ip-configuration-amp-basic-commands-cisco-packet-tracer"><strong>Day 8 – Router CLI Modes, IP Configuration &amp; Basic Commands (Cisco Packet Tracer)</strong></h1>
<p>In <strong>Day 8</strong>, we started <strong>practical router configuration</strong> in <strong>Cisco Packet Tracer</strong>. This lecture focused on understanding the <strong>Router CLI (Command Line Interface)</strong>, its <strong>different modes</strong>, and performing <strong>basic IP configuration on router interfaces</strong>.</p>
<p>This day is very important because it is the <strong>foundation of real router configuration</strong>.</p>
<hr />
<h2 id="heading-1-router-cli-command-line-interface">1. Router CLI (Command Line Interface)</h2>
<p>Cisco routers and switches are mainly configured using the <strong>CLI</strong>. When we open a router and click on the <strong>CLI tab</strong>, the router starts in a default mode.</p>
<p>The CLI works in <strong>different modes</strong>, and each mode has a specific purpose.</p>
<hr />
<h2 id="heading-2-router-cli-modes">2. Router CLI Modes</h2>
<h3 id="heading-21-user-exec-mode">2.1 User EXEC Mode</h3>
<ul>
<li><p>This is the <strong>default mode</strong></p>
</li>
<li><p>Prompt ends with <code>&gt;</code></p>
</li>
<li><p>Very limited access</p>
</li>
<li><p>Used only for basic checking</p>
</li>
</ul>
<p>Example:</p>
<pre><code class="lang-plaintext">Router&gt;
</code></pre>
<p>To move to the next mode, we use:</p>
<pre><code class="lang-plaintext">enable
</code></pre>
<hr />
<h3 id="heading-22-privileged-exec-mode-enable-mode">2.2 Privileged EXEC Mode (Enable Mode)</h3>
<ul>
<li><p>Prompt ends with <code>#</code></p>
</li>
<li><p>Full monitoring access</p>
</li>
<li><p>Required to enter configuration modes</p>
</li>
</ul>
<p>Example:</p>
<pre><code class="lang-plaintext">Router#
</code></pre>
<p>This mode allows us to:</p>
<ul>
<li><p>View configuration</p>
</li>
<li><p>Restart the device</p>
</li>
<li><p>Enter global configuration mode</p>
</li>
</ul>
<hr />
<h3 id="heading-23-global-configuration-mode">2.3 Global Configuration Mode</h3>
<ul>
<li><p>Used to configure <strong>global router settings</strong></p>
</li>
<li><p>Prompt ends with <code>(config)#</code></p>
</li>
</ul>
<p>Command to enter:</p>
<pre><code class="lang-plaintext">configure terminal
</code></pre>
<p>Example:</p>
<pre><code class="lang-plaintext">Router(config)#
</code></pre>
<p>From this mode, we can configure:</p>
<ul>
<li><p>Hostname</p>
</li>
<li><p>Routing</p>
</li>
<li><p>Interfaces</p>
</li>
</ul>
<hr />
<h3 id="heading-24-interface-configuration-mode">2.4 Interface Configuration Mode</h3>
<ul>
<li><p>Used to configure a <strong>specific interface</strong></p>
</li>
<li><p>Prompt ends with <code>(config-if)#</code></p>
</li>
</ul>
<p>Example:</p>
<pre><code class="lang-plaintext">interface fastEthernet0/0
</code></pre>
<p>Example prompt:</p>
<pre><code class="lang-plaintext">Router(config-if)#
</code></pre>
<hr />
<h2 id="heading-3-assigning-ip-address-to-router-interface">3. Assigning IP Address to Router Interface</h2>
<p>After entering <strong>interface configuration mode</strong>, we learned how to assign an IP address.</p>
<h3 id="heading-ip-address-command">🔹 IP Address Command</h3>
<p>Syntax:</p>
<pre><code class="lang-plaintext">ip address &lt;IP-address&gt; &lt;subnet-mask&gt;
</code></pre>
<p>Example:</p>
<pre><code class="lang-plaintext">ip address 192.168.1.1 255.255.255.0
</code></pre>
<p>This command assigns:</p>
<ul>
<li><p>IP address</p>
</li>
<li><p>Subnet mask</p>
</li>
</ul>
<hr />
<h2 id="heading-4-enabling-the-interface-no-shutdown">4. Enabling the Interface (no shutdown)</h2>
<p>By default, router interfaces are <strong>administratively down</strong>.</p>
<p>To enable the interface, we use:</p>
<pre><code class="lang-plaintext">no shutdown
</code></pre>
<p>After this command:</p>
<ul>
<li><p>Interface becomes <strong>up</strong></p>
</li>
<li><p>Communication is possible</p>
</li>
</ul>
<p>📌 Without <code>no shutdown</code>, the interface will not work even if IP is configured.</p>
<hr />
<h2 id="heading-5-moving-between-modes">5. Moving Between Modes</h2>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Action</td><td>Command</td></tr>
</thead>
<tbody>
<tr>
<td>User → Privileged</td><td><code>enable</code></td></tr>
<tr>
<td>Privileged → Global</td><td><code>configure terminal</code></td></tr>
<tr>
<td>Global → Interface</td><td><code>interface &lt;name&gt;</code></td></tr>
<tr>
<td>One step back</td><td><code>exit</code></td></tr>
<tr>
<td>Directly to privileged</td><td><code>end</code></td></tr>
</tbody>
</table>
</div><hr />
<h2 id="heading-6-cli-help-amp-shortcuts">6. CLI Help &amp; Shortcuts</h2>
<h3 id="heading-61-using-question-mark">6.1 Using Question Mark (?)</h3>
<p>The <strong>question mark (</strong><code>?</code>) is used for help.</p>
<p>Examples:</p>
<pre><code class="lang-plaintext">Router&gt; ?
Router# show ?
Router(config)# ip ?
</code></pre>
<p>This shows:</p>
<ul>
<li><p>Available commands</p>
</li>
<li><p>Available options</p>
</li>
</ul>
<hr />
<h3 id="heading-62-using-tab-key">6.2 Using TAB Key</h3>
<p>The <strong>TAB key</strong> is used to auto-complete commands.</p>
<p>Example:</p>
<pre><code class="lang-plaintext">conf&lt;TAB&gt;
</code></pre>
<p>Completes to:</p>
<pre><code class="lang-plaintext">configure
</code></pre>
<p>Benefits:</p>
<ul>
<li><p>Faster typing</p>
</li>
<li><p>Fewer mistakes</p>
</li>
</ul>
<hr />
<h2 id="heading-7-why-day-8-is-important">7. Why Day 8 Is Important</h2>
<ul>
<li><p>All real router configuration is done using CLI</p>
</li>
<li><p>Understanding modes prevents misconfiguration</p>
</li>
<li><p>IP addressing and <code>no shutdown</code> are mandatory steps</p>
</li>
</ul>
<p>This lecture prepares us for:</p>
<ul>
<li><p>Router-to-router communication</p>
</li>
<li><p>Routing protocols</p>
</li>
<li><p>WAN and LAN configuration</p>
</li>
</ul>
<hr />
<h2 id="heading-8-key-takeaways-day-8">8. Key Takeaways – Day 8</h2>
<ul>
<li><p>Routers use <strong>CLI</strong> for configuration</p>
</li>
<li><p>CLI has multiple modes</p>
</li>
<li><p><code>enable</code> enters privileged mode</p>
</li>
<li><p><code>configure terminal</code> enters global config</p>
</li>
<li><p>Interface mode is used for IP configuration</p>
</li>
<li><p><code>ip address</code> assigns IP</p>
</li>
<li><p><code>no shutdown</code> activates interface</p>
</li>
<li><p><code>?</code> gives help</p>
</li>
<li><p><code>TAB</code> completes commands</p>
</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1769110362866/4ca0bf69-62d1-4e67-b722-45bf0830a267.png" alt class="image--center mx-auto" /></p>
<h2 id="heading-day-9-router-hardware-structure-memory-and-configuration-management">Day 9 – Router Hardware Structure, Memory, and Configuration Management</h2>
<p>In <strong>Day 9</strong>, we went deeper into <strong>router internals and configuration management</strong>. This lecture helped us understand <strong>how routers are physically and logically structured</strong>, how Cisco routers <strong>store configurations</strong>, and how to <strong>secure and save configurations properly</strong>.</p>
<hr />
<h2 id="heading-1-physical-structure-of-a-router">1. Physical Structure of a Router</h2>
<p>A Cisco router is built in a <strong>hierarchical physical structure</strong>:</p>
<h3 id="heading-modules-slots-ports">🔹 Modules → Slots → Ports</h3>
<ul>
<li><p><strong>Modules</strong>: Hardware cards installed in a router</p>
</li>
<li><p><strong>Slots</strong>: Locations inside the router where modules are placed</p>
</li>
<li><p><strong>Ports / Interfaces</strong>: Actual physical connectors used to attach cables</p>
</li>
</ul>
<h3 id="heading-interface-numbering-format">🔹 Interface Numbering Format</h3>
<p>Interfaces are named using this pattern:</p>
<pre><code class="lang-plaintext">&lt;interface-type&gt; &lt;module&gt;/&lt;slot&gt;/&lt;port&gt;
</code></pre>
<p>Example:</p>
<pre><code class="lang-plaintext">FastEthernet 0/1/1
</code></pre>
<p>Meaning:</p>
<ul>
<li><p>Module number = 0</p>
</li>
<li><p>Slot number = 1</p>
</li>
<li><p>Port number = 1</p>
</li>
</ul>
<p>📌 This numbering helps uniquely identify each physical interface on a router.</p>
<hr />
<h2 id="heading-2-show-ip-interface-brief">2. show ip interface brief</h2>
<p>The command:</p>
<pre><code class="lang-plaintext">show ip interface brief
</code></pre>
<p>Provides a <strong>quick summary</strong> of all router interfaces.</p>
<h3 id="heading-what-it-shows">🔹 What It Shows</h3>
<ul>
<li><p>Interface name</p>
</li>
<li><p>IP address</p>
</li>
<li><p>Interface status (up/down)</p>
</li>
<li><p>Protocol status</p>
</li>
</ul>
<p>📌 This command displays <strong>temporary (running) information</strong> stored in memory.</p>
<hr />
<h2 id="heading-3-router-memory-types-very-important">3. Router Memory Types (Very Important)</h2>
<p>Cisco routers use <strong>multiple types of memory</strong>, each with a specific role.</p>
<hr />
<h3 id="heading-31-ram-random-access-memory">3.1 RAM (Random Access Memory)</h3>
<ul>
<li><p><strong>Volatile</strong> (data is lost on reboot)</p>
</li>
<li><p>Stores:</p>
<ul>
<li><p>Running configuration</p>
</li>
<li><p>Routing tables</p>
</li>
<li><p>ARP cache</p>
</li>
<li><p>Temporary processes</p>
</li>
</ul>
</li>
</ul>
<p>📌 Commands like <code>show running-config</code> read data from <strong>RAM</strong>.</p>
<hr />
<h3 id="heading-32-nvram-non-volatile-ram">3.2 NVRAM (Non-Volatile RAM)</h3>
<ul>
<li><p><strong>Non-volatile</strong> (data remains after reboot)</p>
</li>
<li><p>Stores:</p>
<ul>
<li>Startup configuration</li>
</ul>
</li>
</ul>
<p>📌 Used to load configuration when router boots.</p>
<hr />
<h3 id="heading-33-flash-memory">3.3 Flash Memory</h3>
<ul>
<li><p><strong>Non-volatile</strong></p>
</li>
<li><p>Stores:</p>
<ul>
<li>Cisco IOS image</li>
</ul>
</li>
</ul>
<p>📌 Router loads IOS from flash into RAM during boot.</p>
<hr />
<h3 id="heading-34-rom-read-only-memory">3.4 ROM (Read Only Memory)</h3>
<ul>
<li><p><strong>Non-volatile</strong></p>
</li>
<li><p>Stores:</p>
<ul>
<li><p>POST (Power-On Self-Test)</p>
</li>
<li><p>Bootstrap program</p>
</li>
</ul>
</li>
</ul>
<p>📌 Used during router startup.</p>
<hr />
<h2 id="heading-4-running-configuration-vs-startup-configuration">4. Running Configuration vs Startup Configuration</h2>
<h3 id="heading-running-configuration">🔹 Running Configuration</h3>
<ul>
<li><p>Stored in <strong>RAM</strong></p>
</li>
<li><p>Active configuration</p>
</li>
<li><p>Lost after reboot if not saved</p>
</li>
</ul>
<p>Command:</p>
<pre><code class="lang-plaintext">show running-config
</code></pre>
<hr />
<h3 id="heading-startup-configuration">🔹 Startup Configuration</h3>
<ul>
<li><p>Stored in <strong>NVRAM</strong></p>
</li>
<li><p>Loaded when router starts</p>
</li>
</ul>
<p>Command:</p>
<pre><code class="lang-plaintext">show startup-config
</code></pre>
<hr />
<h2 id="heading-5-saving-configuration-write-command">5. Saving Configuration (Write Command)</h2>
<p>To save the current running configuration:</p>
<pre><code class="lang-plaintext">write
</code></pre>
<p>or</p>
<pre><code class="lang-plaintext">copy running-config startup-config
</code></pre>
<h3 id="heading-what-this-does">🔹 What This Does</h3>
<ul>
<li><p>Copies configuration from <strong>RAM → NVRAM</strong></p>
</li>
<li><p>Ensures configuration is not lost after reboot</p>
</li>
</ul>
<p>📌 Always save configuration after making changes.</p>
<hr />
<h2 id="heading-6-enable-password-vs-enable-secret">6. Enable Password vs Enable Secret</h2>
<h3 id="heading-enable-password">🔹 enable password</h3>
<ul>
<li><p>Stored in <strong>plain text</strong> (or weak encryption)</p>
</li>
<li><p>Less secure</p>
</li>
</ul>
<hr />
<h3 id="heading-enable-secret">🔹 enable secret</h3>
<ul>
<li><p>Stored in <strong>hashed form</strong></p>
</li>
<li><p>Much more secure</p>
</li>
<li><p>Overrides <code>enable password</code> if both are set</p>
</li>
</ul>
<p>Command example:</p>
<pre><code class="lang-plaintext">enable secret mypassword
</code></pre>
<p>📌 Best practice: <strong>Always use enable secret</strong>.</p>
<hr />
<h2 id="heading-7-hashing-vs-encryption">7. Hashing vs Encryption</h2>
<h3 id="heading-encryption">🔹 Encryption</h3>
<ul>
<li><p>Can be <strong>reversed</strong></p>
</li>
<li><p>Original password can be recovered</p>
</li>
</ul>
<h3 id="heading-hashing">🔹 Hashing</h3>
<ul>
<li><p><strong>One-way process</strong></p>
</li>
<li><p>Cannot be reversed</p>
</li>
</ul>
<p>📌 Cisco uses <strong>hashing</strong> for <code>enable secret</code>.</p>
<hr />
<h2 id="heading-8-show-version-command">8. show version Command</h2>
<p>The command:</p>
<pre><code class="lang-plaintext">show version
</code></pre>
<p>Displays detailed system information:</p>
<ul>
<li><p>IOS version</p>
</li>
<li><p>Router uptime</p>
</li>
<li><p>Hardware model</p>
</li>
<li><p>Memory size</p>
</li>
<li><p>Configuration register</p>
</li>
</ul>
<p>📌 Very useful for troubleshooting and audits.</p>
<hr />
<h2 id="heading-9-key-takeaways-day-9">9. Key Takeaways – Day 9</h2>
<ul>
<li><p>Router interfaces follow <strong>module/slot/port</strong> structure</p>
</li>
<li><p><code>show ip interface brief</code> gives quick interface status</p>
</li>
<li><p>RAM is volatile, NVRAM and Flash are non-volatile</p>
</li>
<li><p>Running config is in RAM, startup config is in NVRAM</p>
</li>
<li><p>Always save config using <code>write</code></p>
</li>
<li><p><code>enable secret</code> is more secure than <code>enable password</code></p>
</li>
<li><p>Hashing is one-way, encryption is reversible</p>
</li>
<li><p><code>show version</code> provides system-level details</p>
</li>
</ul>
<hr />
<p>Day 9 built a strong understanding of <strong>router internals, memory, and secure configuration handling</strong>, which is essential before moving into advanced routing topics.</p>
<h1 id="heading-day-10-interface-troubleshooting-link-states-amp-serial-communication"><strong>Day 10 – Interface Troubleshooting, Link States &amp; Serial Communication</strong></h1>
<p>In <strong>Day 10</strong>, we focused on <strong>deep interface-level troubleshooting</strong> using Cisco router commands. The goal of this lecture was to understand <strong>how links behave</strong>, how to <strong>read interface status correctly</strong>, and how to <strong>identify real-world WAN issues</strong> step by step.</p>
<p>This lecture is extremely important because <strong>most real network problems start at the interface/link level</strong>.</p>
<hr />
<h2 id="heading-1-show-interface-command-detailed-view">1. show interface Command (Detailed View)</h2>
<p>Previously, we used:</p>
<pre><code class="lang-plaintext">show ip interface brief
</code></pre>
<p>which gives <strong>summary information</strong> for all interfaces.</p>
<p>In Day 10, we learned to use:</p>
<pre><code class="lang-plaintext">show interface &lt;interface-name&gt;
</code></pre>
<h3 id="heading-example">Example:</h3>
<pre><code class="lang-plaintext">show interface serial 0/0/0
show interface serial 0/1/1
</code></pre>
<p>📌 This command shows <strong>detailed information for a single interface</strong>, allowing us to <strong>troubleshoot one interface at a time</strong>.</p>
<hr />
<h2 id="heading-2-understanding-the-first-line-of-show-interface">2. Understanding the First Line of show interface</h2>
<p>The <strong>most important line</strong> in the output is the <strong>first line</strong>.</p>
<p>Example output:</p>
<pre><code class="lang-plaintext">Serial0/0/0 is up, line protocol is up
</code></pre>
<h3 id="heading-meaning">Meaning:</h3>
<ul>
<li><p><strong>Interface is up</strong> → Physical / hardware layer is working</p>
</li>
<li><p><strong>Line protocol is up</strong> → Software / data-link layer is working</p>
</li>
</ul>
<p>📌 Simple rule:</p>
<ul>
<li><p>Interface = <strong>Physical side</strong></p>
</li>
<li><p>Line protocol = <strong>Software side</strong></p>
</li>
</ul>
<p>This single line already tells us <strong>where the problem is</strong>.</p>
<hr />
<h2 id="heading-3-link-concept-very-important">3. Link Concept (Very Important)</h2>
<p>A <strong>link</strong> is the <strong>connection between two routers</strong>.</p>
<p>Example:</p>
<ul>
<li><p>One router belongs to <strong>Jazz (Customer)</strong></p>
</li>
<li><p>The other router belongs to <strong>PTCL (Service Provider)</strong></p>
</li>
</ul>
<p>📌 PTCL provides:</p>
<ul>
<li><p>Bandwidth</p>
</li>
<li><p>WAN connectivity</p>
</li>
</ul>
<p>📌 Jazz consumes that service.</p>
<p>The link exists <strong>only when both sides are correctly configured and active</strong>.</p>
<hr />
<h2 id="heading-4-interface-status-scenarios">4. Interface Status Scenarios</h2>
<p>There are <strong>four possible interface status combinations</strong>:</p>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Interface</td><td>Line Protocol</td><td>Meaning</td></tr>
</thead>
<tbody>
<tr>
<td>up</td><td>up</td><td>Link is working perfectly</td></tr>
<tr>
<td>down</td><td>down</td><td>Physical problem or interface shutdown</td></tr>
<tr>
<td>up</td><td>down</td><td>Software / configuration issue</td></tr>
<tr>
<td>down</td><td>up</td><td>Practically not possible</td></tr>
</tbody>
</table>
</div><hr />
<h2 id="heading-5-scenario-1-down-down-both-sides">5. Scenario 1 – down / down (Both Sides)</h2>
<h3 id="heading-situation">Situation:</h3>
<ul>
<li><p>Jazz router: <strong>down / down</strong></p>
</li>
<li><p>PTCL router: <strong>administratively down</strong></p>
</li>
</ul>
<h3 id="heading-explanation-corrected-amp-clarified">Explanation (Corrected &amp; Clarified):</h3>
<p>✔ Your understanding is <strong>correct</strong>.</p>
<ul>
<li><p>PTCL controls the WAN interface provided to Jazz</p>
</li>
<li><p>PTCL can <strong>shutdown the interface</strong> using:</p>
</li>
</ul>
<pre><code class="lang-plaintext">shutdown
</code></pre>
<h3 id="heading-result">Result:</h3>
<ul>
<li>PTCL side shows:</li>
</ul>
<pre><code class="lang-plaintext">administratively down, line protocol down
</code></pre>
<ul>
<li>Jazz side shows:</li>
</ul>
<pre><code class="lang-plaintext">down, down
</code></pre>
<p>📌 This usually means:</p>
<ul>
<li><p>Service provider has <strong>disabled the link</strong></p>
</li>
<li><p>Cable is disconnected OR</p>
</li>
<li><p>Interface is shut down on one side</p>
</li>
</ul>
<hr />
<h2 id="heading-6-ping-command">6. Ping Command</h2>
<p>To test connectivity, we learned the <strong>ping command</strong>.</p>
<pre><code class="lang-plaintext">ping &lt;destination-ip&gt;
</code></pre>
<h3 id="heading-how-ping-works">How ping works:</h3>
<ul>
<li><p>Uses <strong>ICMP (Internet Control Message Protocol)</strong></p>
</li>
<li><p>Sends <strong>echo request</strong> packets</p>
</li>
<li><p>Receives <strong>echo reply</strong> packets</p>
</li>
</ul>
<p>📌 Ping helps us verify:</p>
<ul>
<li><p>IP reachability</p>
</li>
<li><p>Link connectivity</p>
</li>
</ul>
<hr />
<h2 id="heading-7-scenario-2-up-down-software-issue">7. Scenario 2 – up / down (Software Issue)</h2>
<h3 id="heading-situation-1">Situation:</h3>
<ul>
<li><p>Physical side is <strong>up</strong></p>
</li>
<li><p>Line protocol is <strong>down</strong></p>
</li>
</ul>
<p>This means:</p>
<ul>
<li><p>Cable is connected</p>
</li>
<li><p>Interface is enabled</p>
</li>
<li><p>But <strong>software/configuration problem exists</strong></p>
</li>
</ul>
<hr />
<h3 id="heading-causes-of-line-protocol-down">Causes of line protocol down</h3>
<p>There are <strong>three common reasons</strong>:</p>
<p>1️⃣ <strong>Encapsulation mismatch</strong><br />2️⃣ <strong>Clock rate issue</strong> (DCE/DTE)<br />3️⃣ <strong>Keepalive mismatch</strong></p>
<p>In Day 10, we focused mainly on <strong>encapsulation</strong>.</p>
<hr />
<h2 id="heading-8-encapsulation-hdlc-vs-ppp">8. Encapsulation (HDLC vs PPP)</h2>
<p>By default, Cisco serial interfaces use:</p>
<ul>
<li><strong>HDLC encapsulation</strong></li>
</ul>
<p>We can verify encapsulation using:</p>
<pre><code class="lang-plaintext">show interface serial &lt;interface-name&gt;
</code></pre>
<p>This output shows whether the interface is using:</p>
<ul>
<li><p>HDLC</p>
</li>
<li><p>PPP</p>
</li>
<li><p>Frame Relay</p>
</li>
</ul>
<hr />
<h3 id="heading-creating-encapsulation-mismatch-lab-scenario">Creating Encapsulation Mismatch (Lab Scenario)</h3>
<p>On the <strong>PTCL router</strong>, we changed encapsulation:</p>
<pre><code class="lang-plaintext">encapsulation ppp
</code></pre>
<p>While on the <strong>Jazz router</strong>, encapsulation remained:</p>
<ul>
<li>HDLC (default)</li>
</ul>
<h3 id="heading-result-1">Result:</h3>
<ul>
<li><p>Physical layer → <strong>up</strong></p>
</li>
<li><p>Line protocol → <strong>down</strong></p>
</li>
</ul>
<p>📌 This confirms:</p>
<ul>
<li>Encapsulation mismatch causes <strong>up / down</strong> state on both sides</li>
</ul>
<hr />
<h2 id="heading-9-key-takeaways-day-10">9. Key Takeaways – Day 10</h2>
<ul>
<li><p><code>show interface</code> gives detailed interface info</p>
</li>
<li><p>First line of output is the most important</p>
</li>
<li><p>Interface = hardware, line protocol = software</p>
</li>
<li><p>Link exists only if both sides are correctly configured</p>
</li>
<li><p>down/down usually means physical or shutdown issue</p>
</li>
<li><p>up/down usually means configuration mismatch</p>
</li>
<li><p>Ping uses ICMP echo requests</p>
</li>
<li><p>Encapsulation mismatch (HDLC vs PPP) breaks the link</p>
</li>
</ul>
<hr />
<p>Day 10 built strong <strong>real-world WAN troubleshooting skills</strong>, which are essential for service-provider and enterprise networks.</p>
]]></content:encoded></item><item><title><![CDATA[🚀 Containerizing a .NET 8 Application with SQL Server using Docker]]></title><description><![CDATA[GitHub Repository: https://github.com/musayyab-ali/GradLink_App

In this blog, I will walk you through how I containerized a .NET 8 application that connects to a SQL Server (MSSQL) database. The project was cloned from the above GitHub repository an...]]></description><link>https://hassandevops.com/containerizing-a-net-8-application-with-sql-server-using-docker</link><guid isPermaLink="true">https://hassandevops.com/containerizing-a-net-8-application-with-sql-server-using-docker</guid><dc:creator><![CDATA[Muhammad Hassan]]></dc:creator><pubDate>Fri, 18 Apr 2025 11:26:39 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1744975258913/748e9eef-159c-47b9-b87f-6b6f1e5eea3c.webp" length="0" type="image/jpeg"/><content:encoded><![CDATA[<blockquote>
<p><strong>GitHub Repository:</strong> <a target="_blank" href="https://github.com/musayyab-ali/GradLink_App">https://github.com/musayyab-ali/GradLink_App</a></p>
</blockquote>
<p><a target="_blank" href="https://github.com/musayyab-ali/GradLink_App">In this blog, I will walk you through how</a> I containerized a .NET <a target="_blank" href="https://github.com/musayyab-ali/GradLink_App">8 application that connects to a SQL Server</a> (MSSQL) database. The project was cloned from the above GitHub repository and customized to run smoothly inside Docker containers using a persistent volume for the database.</p>
<hr />
<h2 id="heading-prerequisites">🛠️ Prerequisites</h2>
<ul>
<li><p>Docker installed on your machine</p>
</li>
<li><p>.NET 8 <a target="_blank" href="https://github.com/musayyab-ali/GradLink_App">SDK (for local development and testing)</a></p>
</li>
</ul>
<hr />
<h2 id="heading-step-1-set-up-mssql-database-in-dockerhttpsgithubcommusayyab-aligradlinkapp"><a target="_blank" href="https://github.com/musayyab-ali/GradLink_App">🧱 Step 1: Set Up MSSQL Database in Docker</a></h2>
<p><a target="_blank" href="https://github.com/musayyab-ali/GradLink_App">We start by c</a>reating <a target="_blank" href="https://github.com/musayyab-ali/GradLink_App">a SQL Server container using the following command:</a></p>
<pre><code class="lang-plaintext">docker run -e "ACCEPT_EULA=Y" -e "MSSQL_SA_PASSWORD=hassan@123" \
   -p 1433:1433 --name sql1 --hostname sql1 \
   -v sql1data:/var/opt/mssql \
   --restart unless-stopped \
   -d mcr.microsoft.com/mssql/server:2022-latest
</code></pre>
<p>🔍 <strong>What this does:</strong></p>
<ul>
<li><p>Sets up SQL Server with a persistent volum<a target="_blank" href="https://github.com/musayyab-ali/GradLink_App">e <code>sql1data</code></a></p>
</li>
<li><p><a target="_blank" href="https://github.com/musayyab-ali/GradLink_App">Maps port 1433 to your local system for access</a></p>
</li>
<li><p><a target="_blank" href="https://github.com/musayyab-ali/GradLink_App">Au</a>tomatically <a target="_blank" href="https://github.com/musayyab-ali/GradLink_App">restarts unless manually stopped</a></p>
</li>
</ul>
<h2 id="heading-step-2-restore-sql-server-database-from-backup">🧑‍💻 Step 2: Restore SQL Server Database from Backup</h2>
<p>If you have an existing database backup file (e.g., <code>newGradLink.bak</code>), you can restore it to your SQL Server container using the following commands:</p>
<ol>
<li><p><strong>Check Backup Files</strong><br /> Use <code>sqlcmd</code> to verify the contents of the backup file:</p>
<pre><code class="lang-plaintext"> sqlcmd -S localhost -U sa -P 'hassan@123' -Q "RESTORE FILELISTONLY FROM DISK = '/var/opt/mssql/backup/newGradLink.bak'"
</code></pre>
</li>
<li><p><strong>Restore Database</strong><br /> After verifying, restore the database using this command:</p>
<pre><code class="lang-plaintext"> sqlcmd -S localhost -U sa -P 'hassan@123' -Q "
 RESTORE DATABASE gradlink
 FROM DISK = '/var/opt/mssql/backup/newGradLink.bak'
 WITH MOVE 'GradLink' TO '/var/opt/mssql/data/gradlink.mdf',
      MOVE 'GradLink_log' TO '/var/opt/mssql/data/gradlink_log.ldf',
      REPLACE;"
</code></pre>
</li>
</ol>
<blockquote>
<p>📝 <strong>Note:</strong> Make sure the paths (e.g., <code>/var/opt/mssql/backup/</code>) in the SQL Server container are valid and the backup file is placed in the correct directory.</p>
</blockquote>
<hr />
<h2 id="heading-stephttpsgithubcommusayyab-aligradlinkapp-3-update-connection-string-in-appsettingsjsonhttpsgithubcommusayyab-aligradlinkapp"><a target="_blank" href="https://github.com/musayyab-ali/GradLink_App">⚙️ Step</a> 3: Up<a target="_blank" href="https://github.com/musayyab-ali/GradLink_App">date Connection String in <code>appsettings.json</code></a></h2>
<p>Before <a target="_blank" href="https://github.com/musayyab-ali/GradLink_App">building the .NET container, make sure your</a> <code>GradLink/</code> pro<a target="_blank" href="https://github.com/musayyab-ali/GradLink_App">ject’s <code>appsettings.json</code> contains the correct</a> connection string:</p>
<pre><code class="lang-plaintext">{
  "ConnectionStrings": {
    "DefaultConnection": "Data Source=xxxxxxxx; Initial Catalog=GradLink; User ID=sa; Password=hassan@123; MultipleActiveResultSets=True;TrustServerCertificate=True; Integrated Security=False;"
  },
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "AllowedHosts": "*"
}
</code></pre>
<blockquote>
<p>📝 Replace <code>172.21.114.18</code> with your Docker bridge IP or the IP of <a target="_blank" href="https://github.com/musayyab-ali/GradLink_App">the SQL Server container if you’re in a cus</a>tom network.</p>
</blockquote>
<hr />
<h2 id="heading-step-4-create-the-dockerfile">📦 Step 4: Create the Dockerfile</h2>
<p>Here's the <code>Dockerfile</code> used to <a target="_blank" href="https://github.com/musayyab-ali/GradLink_App">build the .NET app container:</a></p>
<pre><code class="lang-plaintext"># Use .NET 8 SDK for build
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build

WORKDIR /app

# Copy csproj files and restore as distinct layers
COPY GradLink/GradLink.csproj GradLink/
COPY GradLink.Model/GradLink.Model.csproj GradLink.Model/
COPY GradLink.Repository/GradLink.Repository.csproj GradLink.Repository/

RUN dotnet restore GradLink/GradLink.csproj

# Copy everything else and build
COPY . .
RUN dotnet publish GradLink/GradLink.csproj -c Release -o out

# Runtime image
FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS runtime
WORKDIR /app
COPY --from=build /app/out .

ENTRYPOINT ["dotnet", "GradLink.dll"]
</code></pre>
<hr />
<h2 id="heading-step-5-build-and-run-the-net-container">🛠️ Step 5: Build and Run the .NET Container</h2>
<h3 id="heading-build-the-docker-imagehttpsgithubcommusayyab-aligradlinkapp">✅ Build the Docker <a target="_blank" href="https://github.com/musayyab-ali/GradLink_App">Image</a></h3>
<pre><code class="lang-plaintext">cdocker build -t gradlink-app .
</code></pre>
<h3 id="heading-run-the-container-and-link-to-sqlhttpsgithubcommusayyab-aligradlinkapp-server"><a target="_blank" href="https://github.com/musayyab-ali/GradLink_App">🚀 Run the Container and Link to SQL</a> Server</h3>
<pre><code class="lang-plaintext"> docker run -d -p 5000:8080 --name gradlink-app --link sql1 gradlink-app
</code></pre>
<ul>
<li><p>Application will be available at <a target="_blank" href="http://localhost:8080"><code>http://localhost:8080</code></a></p>
</li>
<li><p>SQL Se<a target="_blank" href="https://github.com/musayyab-ali/GradLink_App">rver is accessible inside the container as <code>s</code></a><code>ql1</code></p>
</li>
</ul>
<hr />
<h2 id="heading-persistent-volume-for-sql-serverhttpsgithubcommusayyab-aligradlinkapp">🔄 Per<a target="_blank" href="https://github.com/musayyab-ali/GradLink_App">sistent Volume for SQL Server</a></h2>
<p><a target="_blank" href="https://github.com/musayyab-ali/GradLink_App">The <code>-v sql1da</code></a><code>ta:/var/opt/ms</code><a target="_blank" href="https://github.com/musayyab-ali/GradLink_App"><code>sql</code> volume ensures that your database data persists even if the container restart</a>s or is recreated.</p>
<hr />
<h2 id="heading-final-checklist">✅ Final Checklist</h2>
<ul>
<li><p>✅ MSSQL container up and running ✔️</p>
</li>
<li><p>✅ <code>ap</code><a target="_blank" href="https://github.com/musayyab-ali/GradLink_App"><code>psettings.json</code> updated ✔️</a></p>
</li>
<li><p><a target="_blank" href="https://github.com/musayyab-ali/GradLink_App">✅ .NET app container built and running ✔️</a></p>
</li>
<li><p><a target="_blank" href="https://github.com/musayyab-ali/GradLink_App">✅ Persistent volume for DB ✔️</a></p>
</li>
</ul>
<hr />
<h2 id="heading-conclusionhttpsgithubcommusayyab-aligradlinkapp"><a target="_blank" href="https://github.com/musayyab-ali/GradLink_App">🏁 Conclusion</a></h2>
<p><a target="_blank" href="https://github.com/musayyab-ali/GradLink_App">You’ve success</a>f<a target="_blank" href="https://github.com/musayyab-ali/GradLink_App">ully containerized a .NET 8 web application with a linked SQL Server instance. This setup is</a> great for local development, testing, or preparing your app for cloud/container orchestration platforms like Kubernetes.</p>
<h2 id="heading-important-notes">📝 Important Notes:</h2>
<h3 id="heading-1-use-a-custom-docker-network-recommended">1. 🔗 Use a Custom Docker Network (Recommended)</h3>
<p>To ensure both containers can talk to each other by name:</p>
<pre><code class="lang-plaintext">bashCopyEdit# Create a custom network
docker network create gradlink-network

# Run SQL Server container on this network
docker run -e "ACCEPT_EULA=Y" -e "MSSQL_SA_PASSWORD=hassan@123" \
   -p 1433:1433 --name sql1 --hostname sql1 \
   -v sql1data:/var/opt/mssql \
   --network gradlink-network \
   --restart unless-stopped \
   -d mcr.microsoft.com/mssql/server:2022-latest

# Run your .NET app container on the same network
docker run -d -p 8080:80 --name gradlink-app \
   --network gradlink-network \
   gradlink-app
</code></pre>
<p>This setup allows your .NET app to reach SQL Server via <code>sql1</code> instead of needing an IP address.</p>
]]></content:encoded></item><item><title><![CDATA[Day 10 – GitLab CI/CD for Python & Using GitLab Container Registry]]></title><description><![CDATA[Today, I set up a complete CI/CD pipeline using GitLab for a Python FastAPI application, and published the Docker image to GitLab’s Container Registry.
🐳 Dockerfile for Python FastAPI App
# Base Python image
FROM python:3.12-slim

# Set working dire...]]></description><link>https://hassandevops.com/day-10-gitlab-cicd-for-python-and-using-gitlab-container-registry</link><guid isPermaLink="true">https://hassandevops.com/day-10-gitlab-cicd-for-python-and-using-gitlab-container-registry</guid><dc:creator><![CDATA[Muhammad Hassan]]></dc:creator><pubDate>Wed, 09 Apr 2025 11:42:56 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1744198967188/9c097bc7-c72e-4cd8-9b69-7c592502e10f.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Today, I set up a complete CI/CD pipeline using <strong>GitLab</strong> for a <strong>Python FastAPI</strong> application, and published the Docker image to <strong>GitLab’s Container Registry</strong>.</p>
<h3 id="heading-dockerfile-for-python-fastapi-app">🐳 Dockerfile for Python FastAPI App</h3>
<pre><code class="lang-plaintext"># Base Python image
FROM python:3.12-slim

# Set working directory inside the container
WORKDIR /usr/local/app

# Copy requirements and install dependencies
COPY requirements.txt ./
RUN pip install --no-cache-dir -r requirements.txt

# Copy application code
COPY src ./src

# Expose the application port
EXPOSE 8000

# Create and switch to non-root user
RUN useradd app
USER app

# Run the app
CMD ["uvicorn", "src.main:app", "--host", "0.0.0.0", "--port", "8000"]
</code></pre>
<h3 id="heading-gitlab-cicd-setup">🛠 GitLab CI/CD Setup</h3>
<ul>
<li><p>Built Docker image in GitLab pipeline</p>
</li>
<li><p>Pushed it to GitLab’s private container registry</p>
</li>
<li><p>Used <code>:1.2.0</code> version tag</p>
</li>
</ul>
<h3 id="heading-kubernetes-deployment">☸️ Kubernetes Deployment</h3>
<pre><code class="lang-plaintext">apiVersion: apps/v1
kind: Deployment
metadata:
  name: mypythonapp
spec:
  replicas: 1
  selector:
    matchLabels:
      app: mypythonapp
  template:
    metadata:
      labels:
        app: mypythonapp
    spec:
      containers:
        - name: mypythonapp
          image: gitlab.hassandevops.site:5050/ramdanbootcamp/multistage-python-cicd:1.2.0
          ports:
            - containerPort: 8000
      imagePullSecrets:
        - name: gitlab-registry-secret
</code></pre>
<h3 id="heading-ingress-with-tls">🌐 Ingress with TLS</h3>
<pre><code class="lang-plaintext">apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: mypythonapp-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: "/"
spec:
  rules:
    - host: python.hassandevops.site
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: mypythonapp-svc
                port:
                  number: 80
  tls:
    - hosts:
        - python.hassandevops.site
      secretName: hassandevops-tls
</code></pre>
<p>✅ FastAPI containerized, published, and deployed to Kubernetes with GitLab CI/CD. SSL configured and domain routing set. Solid progress!</p>
<hr />
<h2 id="heading-day-9-blue-green-deployment-with-gitlab-cicd-spring-boot">🚀 Day 9 – Blue-Green Deployment with GitLab CI/CD (Spring Boot)</h2>
<p>Today was all about <strong>zero-downtime deployments</strong>. I implemented a <strong>Blue-Green Deployment strategy</strong> for a Spring Boot app using GitLab CI/CD and Kubernetes.</p>
<h3 id="heading-multistage-dockerfile-java-app">🐳 Multistage Dockerfile (Java App)</h3>
<pre><code class="lang-plaintext"># Stage 1: Build
FROM eclipse-temurin:17-jdk-alpine AS builder
WORKDIR /usr/src/app
COPY . .
RUN chmod +x mvnw
RUN ./mvnw clean package -DskipTests

# Stage 2: Runtime
FROM eclipse-temurin:17-jdk-alpine
WORKDIR /usr/src/app
COPY --from=builder /usr/src/app/target/*.jar app.jar
EXPOSE 8080
CMD ["java", "-jar", "app.jar"]
</code></pre>
<h3 id="heading-gitlab-cicd-pipeline-with-kaniko">🔁 GitLab CI/CD Pipeline with Kaniko</h3>
<pre><code class="lang-plaintext">stages:
  - build
  - deploy

build-Blue:
  stage: build
  image: gcr.io/kaniko-project/executor:v1.23.2-debug
  script:
    - /kaniko/executor --context "${CI_PROJECT_DIR}" --dockerfile "${CI_PROJECT_DIR}/Dockerfile" --destination "${CI_REGISTRY_IMAGE}:Blue"

build-Green:
  stage: build
  image: gcr.io/kaniko-project/executor:v1.23.2-debug
  script:
    - /kaniko/executor --context "${CI_PROJECT_DIR}" --dockerfile "${CI_PROJECT_DIR}/Dockerfile" --destination "${CI_REGISTRY_IMAGE}:Green"

deploy-job:
  stage: deploy
  image: alpine:latest
  before_script:
    - apk add --no-cache openssh sshpass
  script:
    - sshpass -p "$MICROK8S_PASSWORD" scp -o StrictHostKeyChecking=no k8s/*.yml ${MICROK8S_USERNAME}@${MICROK8S_IP_ADDRESS}:/path/
    - sshpass -p "$MICROK8S_PASSWORD" ssh -o StrictHostKeyChecking=no ${MICROK8S_USERNAME}@${MICROK8S_IP_ADDRESS} "cd /path &amp;&amp; microk8s.kubectl apply -f ."
</code></pre>
<h3 id="heading-blue-amp-green-deployments">☸️ Blue &amp; Green Deployments</h3>
<p>Both versions are deployed, but only one serves traffic at a time.</p>
<h4 id="heading-bankapp-blue-deployment"><code>bankapp-blue</code> Deployment</h4>
<pre><code class="lang-plaintext">metadata:
  name: bankapp-blue
spec:
  selector:
    matchLabels:
      app: bankapp
      version: blue
  template:
    metadata:
      labels:
        app: bankapp
        version: blue
    spec:
      containers:
        - image: ...:Blue
</code></pre>
<h4 id="heading-bankapp-green-deployment"><code>bankapp-green</code> Deployment</h4>
<pre><code class="lang-plaintext">metadata:
  name: bankapp-green
spec:
  selector:
    matchLabels:
      app: bankapp
      version: green
  template:
    metadata:
      labels:
        app: bankapp
        version: green
    spec:
      containers:
        - image: ...:Green
</code></pre>
<h3 id="heading-switching-traffic">💡 Switching Traffic</h3>
<p>The service selector decides which version is live:</p>
<pre><code class="lang-plaintext">selector:
  app: bankapp
  version: blue  # Change to green when needed
</code></pre>
<h3 id="heading-mysql-setup">🔐 MySQL Setup</h3>
<pre><code class="lang-plaintext">apiVersion: apps/v1
kind: Deployment
metadata:
  name: mysql
spec:
  containers:
    - image: mysql:8
      env:
        - name: MYSQL_ROOT_PASSWORD
          valueFrom:
            secretKeyRef:
              key: MYSQL_ROOT_PASSWORD
</code></pre>
<hr />
<p>✅ Now I can deploy, test, and switch versions in Kubernetes <strong>without downtime</strong>. All thanks to <strong>GitLab CI/CD + Blue-Green Strategy</strong> 💙💚</p>
]]></content:encoded></item><item><title><![CDATA[Day 9 – GitLab CI/CD for Python + Container Registry + Kubernetes Deployment]]></title><description><![CDATA[Welcome to Day 8 of the Ramdan DevOps Bootcamp! Today, we dove into real-world DevOps practices by implementing CI/CD pipelines for a Python API using GitLab CI, building Docker images, pushing them to the GitLab Container Registry, and deploying the...]]></description><link>https://hassandevops.com/day-9-gitlab-cicd-for-python-container-registry-kubernetes-deployment</link><guid isPermaLink="true">https://hassandevops.com/day-9-gitlab-cicd-for-python-container-registry-kubernetes-deployment</guid><dc:creator><![CDATA[Muhammad Hassan]]></dc:creator><pubDate>Wed, 09 Apr 2025 11:36:23 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1744198399513/1d8bc2ee-86ee-40a2-a62f-c93f9eb5e261.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Welcome to <strong>Day 8</strong> of the <strong>Ramdan DevOps Bootcamp</strong>! Today, we dove into real-world DevOps practices by implementing <strong>CI/CD pipelines for a Python API</strong> using <strong>GitLab CI</strong>, building <strong>Docker images</strong>, pushing them to the <strong>GitLab Container Registry</strong>, and deploying them via <strong>Kubernetes</strong>.</p>
<p>Let’s break down what we accomplished 👇</p>
<hr />
<h3 id="heading-python-app-setup-with-docker">🐍 Python App Setup with Docker</h3>
<p>We containerized a basic <strong>FastAPI</strong> application using this Dockerfile:</p>
<pre><code class="lang-plaintext"># Base Python image
FROM python:3.12-slim

# Set working directory inside the container
WORKDIR /usr/local/app

# Copy requirements file and install dependencies
COPY requirements.txt ./
RUN pip install --no-cache-dir -r requirements.txt

# Copy application source code
COPY src ./src

# Expose application port
EXPOSE 8000

# Switch to a non-root user for better security
RUN useradd app
USER app

# Run the application
CMD ["uvicorn", "src.main:app", "--host", "0.0.0.0", "--port", "8000"]
</code></pre>
<p>✅ Lightweight<br />✅ Secure (non-root user)<br />✅ Production-ready</p>
<hr />
<h3 id="heading-gitlab-cicd-pipeline">⚙️ GitLab CI/CD Pipeline</h3>
<p>We configured a GitLab CI/CD pipeline to automatically:</p>
<ol>
<li><p>Build the Docker image.</p>
</li>
<li><p>Push it to the <strong>GitLab Container Registry</strong>.</p>
</li>
<li><p>Optionally trigger deployment (manual or automatic).</p>
</li>
</ol>
<p>A sample <code>.gitlab-ci.yml</code> might look like this:</p>
<pre><code class="lang-plaintext">image: docker:latest

services:
  - docker:build

stages:
  - build
  - push

variables:
  IMAGE_TAG: $CI_REGISTRY_IMAGE:$CI_COMMIT_TAG

before_script:
  - echo "$CI_JOB_TOKEN" | docker login -u gitlab-ci-token --password-stdin $CI_REGISTRY

build:
  stage: build
  script:
    - docker build -t $IMAGE_TAG .
    - docker push $IMAGE_TAG
  only:
    - tags
</code></pre>
<blockquote>
<p>💡 We trigger builds on Git tags like <code>1.2.0</code> to produce versioned images.</p>
</blockquote>
<hr />
<h3 id="heading-image-hosting-with-gitlab-container-registry">🐳 Image Hosting with GitLab Container Registry</h3>
<p>No need for Docker Hub or external registries. GitLab gives us a built-in container registry:</p>
<pre><code class="lang-plaintext">tgitlab.hassandevops.site:5050/ramdanbootcamp/multistage-python-cicd:1.2.0
</code></pre>
<p>You can access it under your project &gt; <code>Packages &amp; Registries</code> &gt; <code>Container Registry</code>.</p>
<hr />
<h3 id="heading-kubernetes-deployment">☸️ Kubernetes Deployment</h3>
<p>After pushing our Docker image, we deployed it to Kubernetes using the following YAML configs:</p>
<h4 id="heading-deployment">✅ Deployment</h4>
<pre><code class="lang-plaintext">apiVersion: apps/v1
kind: Deployment
metadata:
  name: mypythonapp
spec:
  replicas: 1
  selector:
    matchLabels:
      app: mypythonapp
  template:
    metadata:
      labels:
        app: mypythonapp
    spec:
      containers:
        - name: mypythonapp
          image: gitlab.hassandevops.site:5050/ramdanbootcamp/multistage-python-cicd:1.2.0
          ports:
            - containerPort: 8000
      imagePullSecrets:
        - name: gitlab-registry-secret
</code></pre>
<blockquote>
<p>🔐 <code>imagePullSecrets</code> helps Kubernetes authenticate with GitLab's private registry.</p>
</blockquote>
<h4 id="heading-service">✅ Service</h4>
<pre><code class="lang-plaintext">apiVersion: v1
kind: Service
metadata:
  name: mypythonapp-svc
spec:
  selector:
    app: mypythonapp
  ports:
    - protocol: TCP
      port: 80
      targetPort: 8000
</code></pre>
<h4 id="heading-ingress-with-ssl">✅ Ingress (with SSL)</h4>
<pre><code class="lang-plaintext">apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: mypythonapp-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: "/"
spec:
  rules:
    - host: python.hassandevops.site
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: mypythonapp-svc
                port:
                  number: 80
  tls:
    - hosts:
        - python.hassandevops.site
      secretName: hassandevops-tls
</code></pre>
<blockquote>
<p>🌐 Our Python app is now live at <a target="_blank" href="https://python.hassandevops.site"><strong>https://python.hassandevops.site</strong></a></p>
</blockquote>
<hr />
<h3 id="heading-pro-tip-creating-the-gitlab-registry-secret">🔐 Pro Tip: Creating the GitLab Registry Secret</h3>
<p>To pull private images in Kubernetes, create a secret:</p>
<pre><code class="lang-plaintext">kubectl create secret docker-registry gitlab-registry-secret \
  --docker-server=gitlab.hassandevops.site:5050 \
  --docker-username=&lt;your-username&gt; \
  --docker-password=&lt;your-token&gt; \
  --docker-email=you@example.com
</code></pre>
]]></content:encoded></item><item><title><![CDATA[🔒 Full Guide: Setting Up SSL for Monitoring, Docker, and Kubernetes (MicroK8s)]]></title><description><![CDATA[📌 Introduction
Securing your services with SSL is crucial for any production environment. In this blog, I’ll share how I configured SSL certificates (Let's Encrypt) across three major environments:

Monitoring stack (Grafana, Prometheus, cAdvisor)

...]]></description><link>https://hassandevops.com/full-guide-setting-up-ssl-for-monitoring-docker-and-kubernetes-microk8s</link><guid isPermaLink="true">https://hassandevops.com/full-guide-setting-up-ssl-for-monitoring-docker-and-kubernetes-microk8s</guid><category><![CDATA[Grafana]]></category><category><![CDATA[Docker]]></category><category><![CDATA[k8s]]></category><category><![CDATA[WordPress]]></category><dc:creator><![CDATA[Muhammad Hassan]]></dc:creator><pubDate>Wed, 19 Mar 2025 09:21:38 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1742375681449/8d368d88-f2a5-423d-823b-ca9fbb1ec7e1.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="heading-introduction">📌 Introduction</h2>
<p>Securing your services with SSL is crucial for any production environment. In this blog, I’ll share how I configured SSL certificates (Let's Encrypt) across three major environments:</p>
<ol>
<li><p>Monitoring stack (Grafana, Prometheus, cAdvisor)</p>
</li>
<li><p>Docker-based WordPress deployment</p>
</li>
<li><p>Kubernetes MicroK8s deployments using Ingress</p>
</li>
</ol>
<hr />
<h2 id="heading-step-1-ssl-for-monitoring-stack-grafana-prometheus-cadvisor">✅ Step 1: SSL for Monitoring Stack (Grafana, Prometheus, cAdvisor)</h2>
<h3 id="heading-nginx-reverse-proxy-configuration">🔧 Nginx Reverse Proxy Configuration</h3>
<pre><code class="lang-plaintext"># Redirect all HTTP traffic to HTTPS
server {
    listen 80;
    server_name grafana.hassandevops.site prometheus.hassandevops.site cadvisor.hassandevops.site;

    return 301 https://$host$request_uri;
}

# Grafana HTTPS
server {
    listen 443 ssl;
    server_name grafana.hassandevops.site;

    ssl_certificate /etc/letsencrypt/live/hassandevops.site/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/hassandevops.site/privkey.pem;

    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_prefer_server_ciphers on;

    location / {
        proxy_pass http://localhost:3000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}

# Prometheus HTTPS
server {
    listen 443 ssl;
    server_name prometheus.hassandevops.site;

    ssl_certificate /etc/letsencrypt/live/hassandevops.site/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/hassandevops.site/privkey.pem;

    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_prefer_server_ciphers on;

    location / {
        proxy_pass http://localhost:9090;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}

# cAdvisor HTTPS
server {
    listen 443 ssl;
    server_name cadvisor.hassandevops.site;

    ssl_certificate /etc/letsencrypt/live/hassandevops.site/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/hassandevops.site/privkey.pem;

    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_prefer_server_ciphers on;

    location / {
        proxy_pass http://localhost:8080;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}
</code></pre>
<h3 id="heading-ssl-certificate-placement">📂 SSL Certificate Placement:</h3>
<pre><code class="lang-plaintext">/etc/ssl/hassandevops.site/fullchain.pem
/etc/ssl/hassandevops.site/privkey.pem
</code></pre>
<hr />
<h2 id="heading-step-2-docker-wordpress-ssl-setup-dockerhassandevopssite">✅ Step 2: Docker WordPress SSL Setup (docker.hassandevops.site)</h2>
<h3 id="heading-docker-compose">📄 Docker Compose:</h3>
<pre><code class="lang-plaintext">version: '3.8'

services:
  wordpress:
    image: wordpress
    restart: always
    ports:
      - 127.0.0.1:8081:80  # Only accessible from localhost
    environment:
      WORDPRESS_DB_HOST: db
      WORDPRESS_DB_USER: exampleuser
      WORDPRESS_DB_PASSWORD: examplepass
      WORDPRESS_DB_NAME: exampledb
    volumes:
      - wordpress:/var/www/html

  db:
    image: mysql:8.0
    restart: always
    environment:
      MYSQL_DATABASE: exampledb
      MYSQL_USER: exampleuser
      MYSQL_PASSWORD: examplepass
      MYSQL_RANDOM_ROOT_PASSWORD: '1'
    volumes:
      - db:/var/lib/mysql

volumes:
  wordpress:
  db:
</code></pre>
<h3 id="heading-docker-nginx-reverse-proxy">🔧 Docker Nginx Reverse Proxy:</h3>
<pre><code class="lang-plaintext">server {
    listen 80;
    server_name docker.hassandevops.site;
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl;
    server_name docker.hassandevops.site;

    ssl_certificate /etc/ssl/hassandevops.site/fullchain.pem;
    ssl_certificate_key /etc/ssl/hassandevops.site/privkey.pem;

    location / {
        proxy_pass http://127.0.0.1:8081;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}
</code></pre>
<h3 id="heading-certificate-copied-via-scp">📂 Certificate copied via SCP:</h3>
<pre><code class="lang-plaintext">scp -r /etc/ssl/hassandevops.site root@Docker-Server:/etc/ssl/hassandevops.site
</code></pre>
<hr />
<h2 id="heading-step-3-kubernetes-microk8s-ssl-via-ingress-wordpress-amp-nginx-apps">✅ Step 3: Kubernetes (MicroK8s) SSL via Ingress - WordPress &amp; NGINX Apps</h2>
<h3 id="heading-ssl-certificate-copied-to-k8s-server">📂 SSL Certificate copied to K8s Server:</h3>
<pre><code class="lang-plaintext">scp -r /etc/ssl/hassandevops.site root@K8s-Server:/etc/ssl/hassandevops.site
</code></pre>
<h3 id="heading-kubernetes-ingress-with-custom-tls">📄 Kubernetes Ingress with Custom TLS:</h3>
<pre><code class="lang-plaintext">apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-app
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx-app
  template:
    metadata:
      labels:
        app: nginx-app
    spec:
      containers:
      - name: nginx-app
        image: nginx:1.14.2
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: nginx-service
spec:
  selector:
    app: nginx-app
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: nginx-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  tls:
  - hosts:
      - nginx.hassandevops.site
    secretName: hassandevops-tls
  rules:
  - host: nginx.hassandevops.site
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: nginx-service
            port:
              number: 80
</code></pre>
<pre><code class="lang-plaintext">apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: wordpress-pvc
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 5Gi
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: mysql-pvc
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 5Gi
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: mysql
spec:
  replicas: 1
  selector:
    matchLabels:
      app: mysql
  template:
    metadata:
      labels:
        app: mysql
    spec:
      containers:
      - name: mysql
        image: mysql:8.0
        env:
        - name: MYSQL_DATABASE
          value: exampledb
        - name: MYSQL_USER
          value: exampleuser
        - name: MYSQL_PASSWORD
          value: examplepass
        - name: MYSQL_RANDOM_ROOT_PASSWORD
          value: "1"
        volumeMounts:
        - name: mysql-storage
          mountPath: /var/lib/mysql
      volumes:
      - name: mysql-storage
        persistentVolumeClaim:
          claimName: mysql-pvc
---
apiVersion: v1
kind: Service
metadata:
  name: mysql
spec:
  selector:
    app: mysql
  ports:
    - protocol: TCP
      port: 3306
      targetPort: 3306
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: wordpress
spec:
  replicas: 1
  selector:
    matchLabels:
      app: wordpress
  template:
    metadata:
      labels:
        app: wordpress
    spec:
      containers:
      - name: wordpress
        image: wordpress
        ports:
        - containerPort: 80
        env:
        - name: WORDPRESS_DB_HOST
          value: mysql
        - name: WORDPRESS_DB_USER
          value: exampleuser
        - name: WORDPRESS_DB_PASSWORD
          value: examplepass
        - name: WORDPRESS_DB_NAME
          value: exampledb
        volumeMounts:
        - name: wordpress-storage
          mountPath: /var/www/html
      volumes:
      - name: wordpress-storage
        persistentVolumeClaim:
          claimName: wordpress-pvc
---
apiVersion: v1
kind: Service
metadata:
  name: wordpress
spec:
  selector:
    app: wordpress
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: wordpress-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  tls:
  - hosts:
      - wordpress.hassandevops.site
    secretName: hassandevops-tls
  rules:
  - host: wordpress.hassandevops.site
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: wordpress
            port:
              number: 80
</code></pre>
<h3 id="heading-tls-secret-creation">🔐 TLS Secret Creation:</h3>
<pre><code class="lang-plaintext">kubectl create secret tls nginx-tls --cert=/etc/ssl/hassandevops.site/fullchain.pem --key=/etc/ssl/hassandevops.site/privkey.pem
kubectl create secret tls wordpress-tls --cert=/etc/ssl/hassandevops.site/fullchain.pem --key=/etc/ssl/hassandevops.site/privkey.pem
</code></pre>
<hr />
<h2 id="heading-final-outcome">📈 Final Outcome:</h2>
<p>✅ <a target="_blank" href="https://grafana.hassandevops.site"><strong>https://grafana.hassandevops.site</strong></a> - Secured<br />✅ <a target="_blank" href="https://cadvisor.hassandevops.site"><strong>https://cadvisor.hassandevops.site</strong></a> - Secured<br />✅ <a target="_blank" href="https://docker.hassandevops.site"><strong>https://docker.hassandevops.site</strong></a> - WordPress on Docker Secured<br />✅ <a target="_blank" href="https://nginx.hassandevops.site"><strong>https://nginx.hassandevops.site</strong></a> - NGINX App on K8s Secured<br />✅ <a target="_blank" href="https://wordpress.hassandevops.site"><strong>https://wordpress.hassandevops.site</strong></a> - WordPress on K8s Secured</p>
<hr />
<h2 id="heading-conclusion">🎯 Conclusion:</h2>
<p>This setup ensures your entire monitoring stack, Docker deployments, and Kubernetes services are secured with valid SSL certificates.<br />Proper reverse proxy configuration, TLS secret handling, and using Let's Encrypt certificates bring production-level security to your projects.</p>
]]></content:encoded></item><item><title><![CDATA[Day 8: Deploying with GitLab CI/CD & Docker Compose (WordPress + MySQL Stack)]]></title><description><![CDATA[In today's blog, we automate deploying a WordPress and MySQL stack using Docker Compose through GitLab CI/CD. Additionally, we’ll discuss an important issue if you later switch WordPress to run on port 80.

📜 Docker Compose File — docker-compose.yam...]]></description><link>https://hassandevops.com/day-8-deploying-with-gitlab-cicd-and-docker-compose-wordpress-mysql-stack</link><guid isPermaLink="true">https://hassandevops.com/day-8-deploying-with-gitlab-cicd-and-docker-compose-wordpress-mysql-stack</guid><category><![CDATA[GitLab]]></category><category><![CDATA[WordPress]]></category><category><![CDATA[MySQL]]></category><dc:creator><![CDATA[Muhammad Hassan]]></dc:creator><pubDate>Tue, 18 Mar 2025 09:36:04 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1742290123276/28f82200-6bbf-4fca-adfb-29a743d28ff5.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In today's blog, we automate deploying a <strong>WordPress and MySQL stack</strong> using <strong>Docker Compose</strong> through <strong>GitLab CI/CD</strong>. Additionally, we’ll discuss an important issue if you later switch WordPress to run on <strong>port 80</strong>.</p>
<hr />
<h2 id="heading-docker-compose-file-docker-composeyaml">📜 <strong>Docker Compose File —</strong> <code>docker-compose.yaml</code></h2>
<p>Here’s the stack configuration:</p>
<pre><code class="lang-plaintext">version: '3.8'

services:
  wordpress:
    image: wordpress
    restart: always
    ports:
      - 8080:80  # WordPress runs on port 8080
    environment:
      WORDPRESS_DB_HOST: db
      WORDPRESS_DB_USER: exampleuser
      WORDPRESS_DB_PASSWORD: examplepass
      WORDPRESS_DB_NAME: exampledb
    volumes:
      - wordpress:/var/www/html

  db:
    image: mysql:8.0
    restart: always
    environment:
      MYSQL_DATABASE: exampledb
      MYSQL_USER: exampleuser
      MYSQL_PASSWORD: examplepass
      MYSQL_RANDOM_ROOT_PASSWORD: '1'
    volumes:
      - db:/var/lib/mysql

volumes:
  wordpress:
  db:
</code></pre>
<p>✅ <strong>Access WordPress:</strong> <code>http://&lt;YOUR_VM_IP&gt;:8080</code></p>
<hr />
<h2 id="heading-gitlab-cicd-pipeline-gitlab-ciyml">🤖 <strong>GitLab CI/CD Pipeline —</strong> <code>.gitlab-ci.yml</code></h2>
<pre><code class="lang-plaintext">stages:
  - deploy

deploy-job:
  stage: deploy
  image: alpine:latest

  before_script:
    - apk add --no-cache openssh sshpass

  script:
    - sshpass -p "$DOCKER_VM_PASSWORD" scp -o StrictHostKeyChecking=no docker-compose.yaml ${DOCKER_VM_USERNAME}@${DOCKER_VM_IP_ADDRESS}:/${DOCKER_VM_USERNAME}/docker-compose.yaml
    - sshpass -p "$DOCKER_VM_PASSWORD" ssh -o StrictHostKeyChecking=no ${DOCKER_VM_USERNAME}@${DOCKER_VM_IP_ADDRESS} "
        cd /${DOCKER_VM_USERNAME} &amp;&amp; 
        docker compose -f docker-compose.yaml down &amp;&amp;
        docker compose -f docker-compose.yaml up -d
      "

  tags:
    - microk8s
</code></pre>
<p>✅ <strong>Environment Variables Needed:</strong></p>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Variable Name</td><td>Description</td></tr>
</thead>
<tbody>
<tr>
<td><code>DOCKER_VM_IP_ADDRESS</code></td><td>Remote Docker server's IP</td></tr>
<tr>
<td><code>DOCKER_VM_USERNAME</code></td><td>SSH username</td></tr>
<tr>
<td><code>DOCKER_VM_PASSWORD</code></td><td>SSH password</td></tr>
</tbody>
</table>
</div><hr />
<h2 id="heading-running-wordpress-on-port-80-beware-of-redirection-issues">⚠ <strong>Running WordPress on Port 80 - Beware of Redirection Issues</strong></h2>
<p>If you decide to change <code>8080:80</code> to <code>80:80</code> in your <code>docker-compose.yaml</code> to run WordPress on port <strong>80</strong>, you might face a <strong>redirection issue</strong>.</p>
<hr />
<h3 id="heading-reason-for-the-redirection">❌ <strong>Reason for the Redirection</strong></h3>
<p>WordPress <strong>stores the site URL</strong> (with the port) in the <strong>database</strong> when it's first installed. For example, if you ran it on:</p>
<pre><code class="lang-plaintext">http://68.183.86.22:8080
</code></pre>
<p>WordPress stores this URL inside the <code>wp_options</code> table (fields: <code>siteurl</code> and <code>home</code>). So, when you shift to <strong>port 80</strong>, WordPress <strong>still tries to redirect</strong> to the old port.</p>
<hr />
<h2 id="heading-how-to-check-stored-url-in-wordpress">🔍 <strong>How to Check Stored URL in WordPress</strong></h2>
<ol>
<li>Connect to the MySQL container:</li>
</ol>
<pre><code class="lang-plaintext">docker exec -it &lt;db-container-name&gt; mysql -u exampleuser -pexamplepass
</code></pre>
<p>Example:</p>
<pre><code class="lang-plaintext">docker exec -it root-db-1 mysql -u exampleuser -pexamplepass
</code></pre>
<ol start="2">
<li>Run these SQL commands:</li>
</ol>
<pre><code class="lang-plaintext">USE exampledb;
SELECT option_name, option_value FROM wp_options WHERE option_name IN ('siteurl', 'home');
</code></pre>
<p>You’ll likely see:</p>
<pre><code class="lang-plaintext">http://68.183.86.22:8080
</code></pre>
<hr />
<h2 id="heading-how-to-fix-the-redirect">✅ <strong>How to Fix the Redirect</strong></h2>
<p>Update the <code>siteurl</code> and <code>home</code> directly in the database:</p>
<pre><code class="lang-plaintext">UPDATE wp_options SET option_value = 'http://68.183.86.22' WHERE option_name = 'siteurl';
UPDATE wp_options SET option_value = 'http://68.183.86.22' WHERE option_name = 'home';
</code></pre>
<hr />
<h2 id="heading-restart-wordpress-container-optional-but-recommended">🔄 <strong>Restart WordPress Container (Optional but Recommended)</strong></h2>
<pre><code class="lang-plaintext">docker restart &lt;wordpress-container-name&gt;
</code></pre>
<p>Example:</p>
<pre><code class="lang-plaintext">docker restart root-wordpress-1
</code></pre>
<hr />
<h2 id="heading-final-step">🌐 <strong>Final Step:</strong></h2>
<ul>
<li><p>Clear browser cache or try incognito mode.</p>
</li>
<li><p>Access your WordPress on:</p>
</li>
</ul>
<pre><code class="lang-plaintext">http://68.183.86.22
</code></pre>
<hr />
<h2 id="heading-summary">🎯 <strong>Summary</strong></h2>
<p>✅ GitLab CI/CD deploys your WordPress stack automatically<br />✅ Docker Compose makes multi-container deployment simple<br />✅ WordPress stores its base URL on first install<br />✅ Update the database if you change the port later</p>
]]></content:encoded></item><item><title><![CDATA[Day 7: GitLab Basic CI/CD Pipeline for Deploying to MicroK8s (WordPress/NGINX Example)]]></title><description><![CDATA[1. NGINX Deployment (nginx.yaml)
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-app
  labels:
    app: nginx-app
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx-app
  template:
    metadata:
      labels:
        app: ...]]></description><link>https://hassandevops.com/day-7-gitlab-basic-cicd-pipeline-for-deploying-to-microk8s-wordpressnginx-example</link><guid isPermaLink="true">https://hassandevops.com/day-7-gitlab-basic-cicd-pipeline-for-deploying-to-microk8s-wordpressnginx-example</guid><category><![CDATA[GitLab]]></category><category><![CDATA[Pipeline]]></category><category><![CDATA[nginx]]></category><category><![CDATA[WordPress]]></category><dc:creator><![CDATA[Muhammad Hassan]]></dc:creator><pubDate>Tue, 18 Mar 2025 09:27:44 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1742289430279/e40f1be9-7fb7-4997-b9da-50b1d42f52cd.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="heading-1-nginx-deployment-nginxyaml"><strong>1. NGINX Deployment (</strong><code>nginx.yaml</code>)</h2>
<pre><code class="lang-plaintext">apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-app
  labels:
    app: nginx-app
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx-app
  template:
    metadata:
      labels:
        app: nginx-app
    spec:
      containers:
      - name: nginx-container
        image: nginx:1.14.2
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: nginx-service
  labels:
    app: nginx-app
spec:
  selector:
    app: nginx-app
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
  type: ClusterIP
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: nginx-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
  - host: nginx.hassandevops.site
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: nginx-service
            port:
              number: 80
</code></pre>
<hr />
<h2 id="heading-nginx-gitlab-pipeline-gitlab-ciyml">✅ <strong>NGINX GitLab Pipeline (</strong><code>.gitlab-ci.yml</code>)</h2>
<pre><code class="lang-plaintext">stages:
  - deploy

deploy-nginx:
  stage: deploy
  image: alpine:latest
  before_script:
    - apk add --no-cache openssh sshpass
  script:
    - sshpass -p "$MICROK8S_PASSWORD" scp -o StrictHostKeyChecking=no kubernetes/nginx.yaml ${MICROK8S_USERNAME}@${MICROK8S_IP_ADDRESS}:/${MICROK8S_USERNAME}/nginx.yaml
    - sshpass -p "$MICROK8S_PASSWORD" ssh -o StrictHostKeyChecking=no ${MICROK8S_USERNAME}@${MICROK8S_IP_ADDRESS} "cd /${MICROK8S_USERNAME} &amp;&amp; microk8s.kubectl apply -f nginx.yaml"
  tags:
    - microk8s
</code></pre>
<hr />
<h2 id="heading-2-wordpress-deployment-wordpressyaml">✅ <strong>2. WordPress Deployment (</strong><code>wordpress.yaml</code>)</h2>
<pre><code class="lang-plaintext">apiVersion: apps/v1
kind: Deployment
metadata:
  name: wordpress-app
  labels:
    app: wordpress-app
spec:
  replicas: 1
  selector:
    matchLabels:
      app: wordpress-app
  template:
    metadata:
      labels:
        app: wordpress-app
    spec:
      containers:
      - name: wordpress
        image: wordpress:latest
        ports:
        - containerPort: 80
        env:
        - name: WORDPRESS_DB_HOST
          value: mysql-service
        - name: WORDPRESS_DB_USER
          value: wordpress
        - name: WORDPRESS_DB_PASSWORD
          value: wordpress
---
apiVersion: v1
kind: Service
metadata:
  name: wordpress-service
  labels:
    app: wordpress-app
spec:
  selector:
    app: wordpress-app
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
  type: ClusterIP
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: wordpress-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
  - host: wordpress.hassandevops.site
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: wordpress-service
            port:
              number: 80
</code></pre>
<hr />
<h2 id="heading-wordpress-gitlab-pipeline-gitlab-ciyml">✅ <strong>WordPress GitLab Pipeline (</strong><code>.gitlab-ci.yml</code>)</h2>
<pre><code class="lang-plaintext">stages:
  - deploy

deploy-wordpress:
  stage: deploy
  image: alpine:latest
  before_script:
    - apk add --no-cache openssh sshpass
  script:
    - sshpass -p "$MICROK8S_PASSWORD" scp -o StrictHostKeyChecking=no kubernetes/wordpress.yaml ${MICROK8S_USERNAME}@${MICROK8S_IP_ADDRESS}:/${MICROK8S_USERNAME}/wordpress.yaml
    - sshpass -p "$MICROK8S_PASSWORD" ssh -o StrictHostKeyChecking=no ${MICROK8S_USERNAME}@${MICROK8S_IP_ADDRESS} "cd /${MICROK8S_USERNAME} &amp;&amp; microk8s.kubectl apply -f wordpress.yaml"
  tags:
    - microk8s
</code></pre>
<hr />
<h2 id="heading-reminder-for-wordpress-pending-issue">✅ <strong>Reminder for WordPress Pending Issue:</strong></h2>
<p>👉 <strong>WordPress might stay "Pending"</strong> if storage is not enabled.<br />💪 <strong>Fix:</strong></p>
<pre><code class="lang-plaintext">microk8s enable storage
</code></pre>
<hr />
<h2 id="heading-final-urls">✅ <strong>Final URLs:</strong></h2>
<div class="hn-table">
<table>
<thead>
<tr>
<td>App</td><td>URL</td></tr>
</thead>
<tbody>
<tr>
<td><strong>NGINX</strong></td><td><a target="_blank" href="http://nginx.hassandevops.site">http://nginx.hassandevops.site</a></td></tr>
<tr>
<td><strong>WordPress</strong></td><td><a target="_blank" href="http://wordpress.hassandevops.site">http://wordpress.hassandevops.site</a></td></tr>
</tbody>
</table>
</div><hr />
<p>Ready to generate the blog post or want me to add <strong>MySQL setup YAML</strong> too for WordPress?</p>
]]></content:encoded></item><item><title><![CDATA[Day 6: MicroK8s Integration with GitLab Runner using Helm]]></title><description><![CDATA[📌 This document is prepared with the help of official GitLab and Helm documentation.


✅ Step 1: Install Helm
Install Helm using Snap:
snap install helm --classic


✅ Step 2: Add the GitLab Helm Repository
helm repo add gitlab https://charts.gitlab....]]></description><link>https://hassandevops.com/day-6-microk8s-integration-with-gitlab-runner-using-helm</link><guid isPermaLink="true">https://hassandevops.com/day-6-microk8s-integration-with-gitlab-runner-using-helm</guid><category><![CDATA[GitLab]]></category><category><![CDATA[microk8s]]></category><dc:creator><![CDATA[Muhammad Hassan]]></dc:creator><pubDate>Tue, 18 Mar 2025 09:16:02 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1742288943811/89bc20f9-3de9-46bb-8811-b801bcc497ca.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<blockquote>
<p>📌 <em>This document is prepared with the help of official GitLab and Helm documentation.</em></p>
</blockquote>
<hr />
<h3 id="heading-step-1-install-helm">✅ <strong>Step 1: Install Helm</strong></h3>
<p>Install Helm using Snap:</p>
<pre><code class="lang-plaintext">snap install helm --classic
</code></pre>
<hr />
<h3 id="heading-step-2-add-the-gitlab-helm-repository">✅ <strong>Step 2: Add the GitLab Helm Repository</strong></h3>
<pre><code class="lang-plaintext">helm repo add gitlab https://charts.gitlab.io
</code></pre>
<p>Update the repository:</p>
<pre><code class="lang-plaintext">helm repo update gitlab
</code></pre>
<hr />
<h3 id="heading-step-3-check-available-gitlab-runner-chart-versions">✅ <strong>Step 3: Check Available GitLab Runner Chart Versions</strong></h3>
<pre><code class="lang-plaintext">helm search repo -l gitlab/gitlab-runner
</code></pre>
<p><strong>Sample output:</strong></p>
<pre><code class="lang-plaintext">NAME                    CHART VERSION   APP VERSION     DESCRIPTION
gitlab/gitlab-runner    0.74.0          17.9.0          GitLab Runner
gitlab/gitlab-runner    0.73.3          17.8.3          GitLab Runner
gitlab/gitlab-runner    0.73.2          17.8.2          GitLab Runner
gitlab/gitlab-runner    0.73.1          17.8.1          GitLab Runner
gitlab/gitlab-runner    0.73.0          17.8.0          GitLab Runner
gitlab/gitlab-runner    0.72.1          17.7.1          GitLab Runner
gitlab/gitlab-runner    0.72.0          17.7.0          GitLab Runner
</code></pre>
<hr />
<h3 id="heading-step-4-prepare-the-helmvaluesyaml-for-runner-configuration">✅ <strong>Step 4: Prepare the</strong> <code>helm_values.yaml</code> for Runner Configuration</h3>
<p>Create a file named <code>helm_values.yaml</code> with the following content:</p>
<pre><code class="lang-plaintext">concurrent: 5
logFormat: json

rbac:
  create: true
  rules:
    - apiGroups: [""]
      resources: ["configmaps", "events", "pods", "pods/attach", "pods/exec", "secrets", "services"]
      verbs: ["get", "list", "watch", "create", "patch", "update", "delete"]

runners:
  config: |
    [[runners]]
      [runners.kubernetes]
        namespace = "{{.Release.Namespace}}"
        image = "alpine"
</code></pre>
<hr />
<h3 id="heading-step-5-register-the-gitlab-runner">✅ <strong>Step 5: Register the GitLab Runner</strong></h3>
<p>Go to <strong>GitLab Admin &gt; Runners</strong> and get your <strong>GitLab URL</strong> and <strong>Registration Token</strong>.</p>
<p>Register the runner:</p>
<pre><code class="lang-plaintext">gitlab-runner register \
  --url https://&lt;Your-GitLab-URL&gt; \
  --token &lt;Your-Token&gt;
</code></pre>
<blockquote>
<p>🔎 <strong>Note:</strong> Save the URL and token. You'll need them in the next step.</p>
</blockquote>
<hr />
<h3 id="heading-step-6-install-the-gitlab-runner-using-helm">✅ <strong>Step 6: Install the GitLab Runner using Helm</strong></h3>
<p>Apply the Helm chart with the following command:</p>
<pre><code class="lang-plaintext">microk8s.helm install \
  --namespace gitlab-runner \
  --create-namespace \
  --atomic \
  --timeout 120s \
  --set gitlabUrl=https://&lt;Your-GitLab-URL&gt; \
  --set runnerToken=&lt;Your-Token&gt; \
  --values helm_values.yaml \
  gitlab-runner gitlab/gitlab-runner \
  --version 0.74.0
</code></pre>
<hr />
<h3 id="heading-step-7-verify-the-gitlab-runner-pod-in-microk8s">✅ <strong>Step 7: Verify the GitLab Runner Pod in MicroK8s</strong></h3>
<p>Check the deployed runner pod:</p>
<pre><code class="lang-plaintext">microk8s.kubectl get pod -n gitlab-runner
</code></pre>
<p><strong>Sample Output:</strong></p>
<pre><code class="lang-plaintext">NAME                             READY   STATUS    RESTARTS   AGE
gitlab-runner-7f957d884f-frb59   1/1     Running   0          5m51s
</code></pre>
<hr />
<h2 id="heading-gitlab-runner-successfully-integrated-with-microk8s">🎉 <strong>GitLab Runner successfully integrated with MicroK8s!</strong></h2>
<p>Your GitLab Runner is now up and running, ready to execute your CI/CD pipelines within your MicroK8s Kubernetes cluster. ✅</p>
]]></content:encoded></item><item><title><![CDATA[Day 5: Understanding the Full Spectrum of GitLab Features for DevOps Success]]></title><description><![CDATA[Introduction
How you manage your software projects directly impacts productivity, collaboration, and delivery speed. Imagine a team pushing code updates daily without version tracking, testing, or deployment pipelines. Chaos, right?
Thankfully, we ha...]]></description><link>https://hassandevops.com/understanding-the-full-spectrum-of-gitlab-features-for-devops-success</link><guid isPermaLink="true">https://hassandevops.com/understanding-the-full-spectrum-of-gitlab-features-for-devops-success</guid><category><![CDATA[GitLab]]></category><dc:creator><![CDATA[Muhammad Hassan]]></dc:creator><pubDate>Tue, 18 Mar 2025 09:07:33 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1742288407947/7668007a-41b1-42da-9153-a7c35c774694.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="heading-introduction">Introduction</h2>
<p>How you manage your software projects directly impacts productivity, collaboration, and delivery speed. Imagine a team pushing code updates daily without version tracking, testing, or deployment pipelines. Chaos, right?</p>
<p>Thankfully, we have powerful platforms like <strong>GitLab</strong> to prevent such nightmares. GitLab is not just a Git repository manager — it’s an <strong>all-in-one DevSecOps platform</strong> designed to streamline the entire software development lifecycle (SDLC).</p>
<p>In this guide, you’ll learn:<br />✅ What GitLab is<br />✅ Its core features<br />✅ Benefits for developers and organizations<br />✅ How it compares with GitHub and Bitbucket<br />✅ How to get started in minutes</p>
<blockquote>
<p><strong>Bonus:</strong> Enroll in our Git Fundamentals course (now 50% off!) and master version control while exploring this guide.</p>
</blockquote>
<hr />
<h2 id="heading-what-is-gitlab">What is GitLab?</h2>
<p>GitLab started as a web-based Git repository manager but has evolved into a <strong>complete DevOps platform</strong>. Today, teams use GitLab to:</p>
<p>✅ Manage version control<br />✅ Automate CI/CD pipelines<br />✅ Track issues and manage tasks<br />✅ Ensure security and compliance<br />✅ Monitor application performance</p>
<p>All from a <strong>single, unified interface</strong>. Whether you’re a solo developer, a growing startup, or an enterprise team — GitLab scales to fit your needs.</p>
<hr />
<h2 id="heading-core-features-of-gitlab">Core Features of GitLab</h2>
<h3 id="heading-git-repositories">🔗 Git Repositories</h3>
<p>GitLab offers robust Git-based repositories supporting <strong>branching, merge requests, and commit histories</strong> — perfect for seamless team collaboration.</p>
<h3 id="heading-built-in-cicd-pipelines">⚙️ Built-in CI/CD Pipelines</h3>
<p>No need for third-party tools. GitLab’s CI/CD is built-in and powered by simple YAML configurations. Automate builds, tests, and deployments effortlessly — even integrate with Docker or Kubernetes for scalable cloud deployments.</p>
<pre><code class="lang-plaintext">stages:
  - build
  - test
  - deploy

build-job:
  stage: build
  script:
    - echo "Building..."

test-job:
  stage: test
  script:
    - echo "Testing..."

deploy-job:
  stage: deploy
  script:
    - echo "Deploying..."
</code></pre>
<h3 id="heading-auto-devops">🚀 Auto DevOps</h3>
<p>Automate everything! With <strong>Auto DevOps</strong>, GitLab offers pre-configured templates to build, test, and deploy applications — perfect for teams that want to move fast.</p>
<h3 id="heading-project-management">🗂 Project Management</h3>
<p>GitLab isn’t just code — it’s project management too:</p>
<ul>
<li><p>Issue boards</p>
</li>
<li><p>Milestones</p>
</li>
<li><p>Labels &amp; burndown charts</p>
</li>
</ul>
<p>Visualize, plan, and execute your development roadmap without leaving the platform.</p>
<h3 id="heading-gitlab-pages">🌐 GitLab Pages</h3>
<p>Host static websites, portfolios, and documentation directly from your repo — free and fast with <strong>GitLab Pages</strong>.</p>
<hr />
<h2 id="heading-why-choose-gitlab-advantages">Why Choose GitLab? (Advantages)</h2>
<h3 id="heading-all-in-one-devsecops-platform">✅ All-in-One DevSecOps Platform</h3>
<p>No juggling between tools. GitLab bundles version control, CI/CD, project management, and security — all under one roof.</p>
<h3 id="heading-powerful-collaboration">✅ Powerful Collaboration</h3>
<p>GitLab enhances teamwork with merge requests, issue tracking, and built-in chat integrations. Fewer blockers, more productivity.</p>
<h3 id="heading-scalability-for-every-team">✅ Scalability for Every Team</h3>
<p>From hobby projects to large enterprises, GitLab supports cloud-hosted and self-hosted deployments — <strong>flexible and secure</strong>.</p>
<h3 id="heading-built-in-security">✅ Built-in Security</h3>
<p>Security is baked in, not bolted on. GitLab offers:</p>
<ul>
<li><p>Static and dynamic code analysis</p>
</li>
<li><p>Container scanning</p>
</li>
<li><p>Vulnerability management</p>
</li>
</ul>
<p>Keep your applications safe — right from development.</p>
<hr />
<h2 id="heading-gitlab-vs-github-vs-bitbucket">GitLab vs GitHub vs Bitbucket</h2>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Criteria</td><td><strong>GitLab</strong></td><td><strong>GitHub</strong></td><td><strong>Bitbucket</strong></td></tr>
</thead>
<tbody>
<tr>
<td><strong>Launch Year</strong></td><td>2011</td><td>2008</td><td>2008</td></tr>
<tr>
<td><strong>Best For</strong></td><td>DevOps teams, enterprises</td><td>Open-source, general developers</td><td>Teams using Atlassian (Jira/Confluence)</td></tr>
<tr>
<td><strong>CI/CD</strong></td><td>Built-in, robust</td><td>GitHub Actions (added later)</td><td>Built-in but limited</td></tr>
<tr>
<td><strong>Security</strong></td><td>Comprehensive (code scan, vuln mgmt)</td><td>Advanced security (premium)</td><td>Basic</td></tr>
<tr>
<td><strong>Project Mgmt</strong></td><td>Native tools (boards, burndown)</td><td>Limited (relies on third parties)</td><td>Strong Jira integration</td></tr>
<tr>
<td><strong>Hosting</strong></td><td>Cloud &amp; Self-hosted</td><td>Cloud &amp; Self-hosted</td><td>Cloud &amp; Self-hosted</td></tr>
</tbody>
</table>
</div><p>✅ <strong>Verdict:</strong> Choose GitLab if you want an integrated CI/CD, security, and project management platform out of the box.</p>
<hr />
<h2 id="heading-getting-started-with-gitlab-in-minutes">Getting Started with GitLab (In Minutes 🚀)</h2>
<h3 id="heading-1-sign-up-free">1️⃣ Sign Up Free</h3>
<p>Head over to <a target="_blank" href="https://gitlab.com">GitLab.com</a> and create your free account.</p>
<h3 id="heading-2-create-your-first-project">2️⃣ Create Your First Project</h3>
<pre><code class="lang-plaintext">git clone git@gitlab.com:your-username/your-repo.git
</code></pre>
<p>Start coding, commit changes, and push:</p>
<pre><code class="lang-plaintext">git add .
git commit -m "Initial commit"
git push origin main
</code></pre>
<h3 id="heading-3-set-up-your-cicd">3️⃣ Set Up Your CI/CD</h3>
<p>Add a <code>.gitlab-ci.yml</code> file — pipelines run automatically!</p>
<h3 id="heading-4-use-gitlab-runners">4️⃣ Use GitLab Runners</h3>
<p>Runners execute your jobs:</p>
<ul>
<li><p>Shared Runners (free)</p>
</li>
<li><p>Self-hosted (for full control)</p>
</li>
</ul>
<p>Register your runner:</p>
<pre><code class="lang-plaintext">gitlab-runner register
</code></pre>
<h3 id="heading-5-manage-issues-and-merge-requests">5️⃣ Manage Issues and Merge Requests</h3>
<p>Use GitLab’s boards, milestones, and merge requests to manage your project like a pro.</p>
<hr />
]]></content:encoded></item><item><title><![CDATA[Day 4: Monitoring Setup Journey: Checkmk, Prometheus, Grafana, and More on Ubuntu 22.04]]></title><description><![CDATA[Checkmk Installation and Client Integration
✅ Environment Setup

Host Machine: Laptop (where Checkmk web UI is accessed)

Remote Machine: Ubuntu 22.04 server (Checkmk server setup)

Client Machines: Ubuntu servers to be monitored


⚠ Important: Ensur...]]></description><link>https://hassandevops.com/day-4-monitoring-setup-journey-checkmk-prometheus-grafana-and-more-on-ubuntu-2204</link><guid isPermaLink="true">https://hassandevops.com/day-4-monitoring-setup-journey-checkmk-prometheus-grafana-and-more-on-ubuntu-2204</guid><category><![CDATA[checkmk]]></category><category><![CDATA[#prometheus]]></category><category><![CDATA[Grafana]]></category><category><![CDATA[Ubuntu]]></category><dc:creator><![CDATA[Muhammad Hassan]]></dc:creator><pubDate>Tue, 18 Mar 2025 08:55:27 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1742287835875/8aac78ed-c6dd-4688-8a9b-2562541954e9.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="heading-checkmk-installation-and-client-integration"><strong>Checkmk Installation and Client Integration</strong></h2>
<h3 id="heading-environment-setup">✅ <strong>Environment Setup</strong></h3>
<ul>
<li><p><strong>Host Machine:</strong> Laptop (where Checkmk web UI is accessed)</p>
</li>
<li><p><strong>Remote Machine:</strong> Ubuntu 22.04 server (Checkmk server setup)</p>
</li>
<li><p><strong>Client Machines:</strong> Ubuntu servers to be monitored</p>
</li>
</ul>
<p>⚠ <strong>Important:</strong> Ensure TCP port <code>6556</code> is open on all client machines.</p>
<hr />
<h3 id="heading-step-1-install-checkmk-on-remote-machine"><strong>Step 1: Install Checkmk on Remote Machine</strong></h3>
<pre><code class="lang-plaintext">sudo apt update &amp;&amp; sudo apt upgrade -y
</code></pre>
<p>Download Checkmk Raw Edition:</p>
<pre><code class="lang-plaintext">wget https://download.checkmk.com/checkmk/2.3.0p27/check-mk-raw-2.3.0p27_0.jammy_amd64.deb
</code></pre>
<p>Ensure <code>sources.list</code> has the required Ubuntu repositories:</p>
<pre><code class="lang-plaintext">deb http://archive.ubuntu.com/ubuntu/ jammy main
deb http://archive.ubuntu.com/ubuntu/ jammy universe
deb http://archive.ubuntu.com/ubuntu jammy-security main
deb http://archive.ubuntu.com/ubuntu jammy-security universe
</code></pre>
<p>Install Checkmk:</p>
<pre><code class="lang-plaintext">sudo apt install ./check-mk-raw-2.3.0p27_0.jammy_amd64.deb -y
omd version
</code></pre>
<hr />
<h3 id="heading-step-2-create-and-start-a-checkmk-site"><strong>Step 2: Create and Start a Checkmk Site</strong></h3>
<pre><code class="lang-plaintext">sudo omd create osfp
sudo omd start osfp
</code></pre>
<p>Enable external access:</p>
<pre><code class="lang-plaintext">sudo omd config osfp set APACHE_TCP_ADDR 0.0.0.0
</code></pre>
<p>Access the web interface:</p>
<pre><code class="lang-plaintext">http://&lt;server-public-ip&gt;/osfp
</code></pre>
<hr />
<h3 id="heading-step-3-install-checkmk-agent-on-client-machines"><strong>Step 3: Install Checkmk Agent on Client Machines</strong></h3>
<ul>
<li><p>Download the agent from <strong>Setup &gt; Agents &gt; Linux</strong> in the Checkmk UI.</p>
</li>
<li><p>Transfer the agent to the client:</p>
</li>
</ul>
<pre><code class="lang-plaintext">scp -i &lt;pem-file&gt; check-mk-agent_2.3.0p27-1_all.deb &lt;user&gt;@&lt;client-ip&gt;:~
</code></pre>
<ul>
<li>Install on the client:</li>
</ul>
<pre><code class="lang-plaintext">sudo dpkg -i check-mk-agent_2.3.0p27-1_all.deb
check_mk_agent
</code></pre>
<hr />
<h3 id="heading-step-4-add-client-as-a-host-in-checkmk"><strong>Step 4: Add Client as a Host in Checkmk</strong></h3>
<ol>
<li><p>Navigate: <strong>Setup &gt; Hosts &gt; Add Host</strong></p>
</li>
<li><p>Add the hostname and private IP</p>
</li>
<li><p>Save → Run Service Discovery → Activate Changes</p>
</li>
<li><p>Validate via <strong>Monitor &gt; All Hosts</strong></p>
</li>
</ol>
<hr />
<h2 id="heading-checkmk-didnt-work-for-me">❌ <strong>Checkmk Didn’t Work for Me</strong></h2>
<p>Even after following the guide, my Checkmk server kept showing the <strong>DOWN</strong> status. I couldn’t resolve it after several retries and decided to switch to <strong>Prometheus + Grafana</strong> for monitoring.</p>
<hr />
<h2 id="heading-prometheus-amp-grafana-setup-optimized">✅ <strong>Prometheus &amp; Grafana Setup (Optimized)</strong></h2>
<h3 id="heading-final-docker-compose"><strong>Final Docker Compose</strong></h3>
<pre><code class="lang-plaintext">version: '3.8'

services:
  prometheus:
    image: prom/prometheus:latest
    container_name: prometheus
    volumes:
      - ./prometheus.yml:/etc/prometheus/prometheus.yml
      - prometheus-storage:/prometheus
    ports:
      - "9090:9090"
    restart: always
    networks:
      - monitoring

  grafana:
    image: grafana/grafana:latest
    container_name: grafana
    ports:
      - "3000:3000"
    environment:
      - GF_SECURITY_ADMIN_PASSWORD=${GRAFANA_ADMIN_PASSWORD}
    volumes:
      - grafana-storage:/var/lib/grafana
    restart: always
    networks:
      - monitoring

  cadvisor:
    image: gcr.io/cadvisor/cadvisor:latest
    container_name: cadvisor
    ports:
      - "8080:8080"
    volumes:
      - /:/rootfs:ro
      - /var/run:/var/run:ro
      - /sys:/sys:ro
      - /var/lib/docker/:/var/lib/docker:ro
    restart: always
    networks:
      - monitoring

networks:
  monitoring:
    driver: bridge

volumes:
  grafana-storage:
  prometheus-storage:
</code></pre>
<hr />
<h3 id="heading-prometheus-configuration-prometheusyml"><strong>Prometheus Configuration (prometheus.yml)</strong></h3>
<pre><code class="lang-plaintext">global:
  scrape_interval: 15s

scrape_configs:
  - job_name: 'prometheus'
    static_configs:
      - targets: ['localhost:9090']

  - job_name: 'node_exporter'
    static_configs:
      - targets:
        - '10.122.0.3:9100'
        - '10.122.0.2:9200'
        - '10.122.0.6:9200'
        - '10.122.0.5:9100'

  - job_name: 'cadvisor'
    static_configs:
      - targets:
        - '10.122.0.3:8080'

  - job_name: 'kube-state-metrics'
    static_configs:
      - targets:
        - '139.59.43.181:31776'
</code></pre>
<hr />
<h2 id="heading-node-exporter-installation-v190">✅ <strong>Node Exporter Installation (v1.9.0)</strong></h2>
<pre><code class="lang-plaintext">VERSION=1.9.0  
wget https://github.com/prometheus/node_exporter/releases/download/v${VERSION}/node_exporter-${VERSION}.linux-amd64.tar.gz
tar xvf node_exporter-${VERSION}.linux-amd64.tar.gz
sudo mv node_exporter-${VERSION}.linux-amd64/node_exporter /usr/local/bin/
</code></pre>
<p>Create systemd service:</p>
<pre><code class="lang-plaintext">sudo tee /etc/systemd/system/node_exporter.service &gt; /dev/null &lt;&lt;EOF
[Unit]
Description=Prometheus Node Exporter
After=network.target

[Service]
User=nobody
ExecStart=/usr/local/bin/node_exporter
Restart=always

[Install]
WantedBy=multi-user.target
EOF
</code></pre>
<p>Start and enable:</p>
<pre><code class="lang-plaintext">sudo systemctl daemon-reload
sudo systemctl enable node_exporter
sudo systemctl start node_exporter
</code></pre>
<p>Verify:</p>
<pre><code class="lang-plaintext">curl http://localhost:9100/metrics
</code></pre>
<hr />
<h2 id="heading-cadvisor-for-container-monitoring">✅ <strong>cAdvisor for Container Monitoring</strong></h2>
<p>If cAdvisor isn’t running, start it:</p>
<pre><code class="lang-plaintext">docker run -d --name=cadvisor \
  --restart always \
  --volume=/var/lib/docker/:/var/lib/docker:ro \
  --volume=/sys:/sys:ro \
  --volume=/var/run/docker.sock:/var/run/docker.sock:ro \
  --volume=/etc/machine-id:/etc/machine-id:ro \
  --publish=8080:8080 \
  gcr.io/cadvisor/cadvisor:latest
</code></pre>
<p>Check if running:</p>
<pre><code class="lang-plaintext">ss -tulnp | grep 8080
</code></pre>
<p>Expected:</p>
<pre><code class="lang-plaintext">tcp   LISTEN   0   128   0.0.0.0:8080   0.0.0.0:*   users:(("cadvisor",pid,fd))
</code></pre>
<hr />
<h2 id="heading-kubernetes-metrics-monitoring">✅ <strong>Kubernetes Metrics Monitoring</strong></h2>
<p>For Kubernetes:</p>
<ul>
<li><p>Use <code>kube-state-metrics</code></p>
</li>
<li><p>Add the correct target in <code>prometheus.yml</code></p>
</li>
</ul>
<hr />
<p>Setting Up Metrics Server and Kube-State-Metrics in MicroK8s for Prometheus Monitoring</p>
<p>Monitoring is a crucial part of running any Kubernetes cluster. In this guide, we’ll walk through setting up the <strong>metrics-server</strong> and <strong>kube-state-metrics</strong> in a <strong>MicroK8s</strong> environment and making them accessible for Prometheus scraping.</p>
<hr />
<h2 id="heading-step-1-install-metrics-server">✅ Step 1: Install Metrics Server</h2>
<p>The <strong>metrics-server</strong> provides resource usage metrics (CPU, memory) for Kubernetes objects. It's required for <code>kubectl top</code> commands and is commonly used by autoscalers.</p>
<h3 id="heading-download-and-apply-the-metrics-server-yaml">Download and apply the metrics-server YAML:</h3>
<pre><code class="lang-plaintext">microk8s.kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml
</code></pre>
<h3 id="heading-verify-if-the-metrics-server-deployment-is-running">Verify if the metrics-server deployment is running:</h3>
<pre><code class="lang-plaintext">microk8s.kubectl get deployment -n kube-system | grep metrics-server
</code></pre>
<hr />
<h2 id="heading-step-2-expose-metrics-server-as-nodeport-optional-but-useful-for-external-access">✅ Step 2: Expose Metrics Server as NodePort (Optional but Useful for External Access)</h2>
<p>By default, the metrics-server runs as a ClusterIP service. If you want to scrape it externally or from Prometheus, you can expose it as a NodePort:</p>
<pre><code class="lang-plaintext">microk8s.kubectl patch svc metrics-server -n kube-system -p '{"spec": {"type": "NodePort"}}'
</code></pre>
<h3 id="heading-check-the-nodeport-details">Check the NodePort details:</h3>
<pre><code class="lang-plaintext">microk8s.kubectl get svc -n kube-system metrics-server
</code></pre>
<hr />
<h2 id="heading-step-3-enable-prometheus-in-microk8s">✅ Step 3: Enable Prometheus in MicroK8s</h2>
<p>MicroK8s provides a built-in Prometheus addon that simplifies the setup.</p>
<pre><code class="lang-plaintext">microk8s enable prometheus
</code></pre>
<p>Once enabled, Prometheus and Grafana will be running inside your cluster.</p>
<hr />
<h2 id="heading-step-4-locate-kube-state-metrics">✅ Step 4: Locate Kube-State-Metrics</h2>
<p>The <strong>kube-state-metrics</strong> is automatically deployed as part of the Prometheus addon in MicroK8s. It provides cluster state information (deployments, pods, nodes, etc.) that Prometheus scrapes.</p>
<h3 id="heading-check-if-the-kube-state-metrics-pod-is-running">Check if the kube-state-metrics pod is running:</h3>
<pre><code class="lang-plaintext">microk8s.kubectl get pods --all-namespaces | grep kube-state-metrics
</code></pre>
<h3 id="heading-get-the-kube-state-metrics-service-information">Get the kube-state-metrics service information:</h3>
<pre><code class="lang-plaintext">microk8s.kubectl get svc -n observability | grep kube-state-metrics
</code></pre>
<p>You should see the NodePort or ClusterIP assigned to this service.</p>
<hr />
<h2 id="heading-step-5-configure-prometheus-to-scrape-kube-state-metrics">✅ Step 5: Configure Prometheus to Scrape Kube-State-Metrics</h2>
<p>In your Prometheus configuration, you need to add a job for <code>kube-state-metrics</code>. Replace the IP and port with the actual NodePort or ClusterIP you retrieved in the previous step.</p>
<pre><code class="lang-plaintext"> - job_name: 'kube-state-metrics'
    static_configs:
      - targets:
          - '139.59.43.181:31479'  # Replace with your kube-state-metrics NodePort
</code></pre>
]]></content:encoded></item><item><title><![CDATA[Day 3: Docker, Docker Compose, and MicroK8s Installation on Ubuntu 22.04]]></title><description><![CDATA[In this guide, we will walk through the installation of Docker, Docker Compose, and MicroK8s on Ubuntu 22.04. The commands are tested on the following machine specs:

RAM: 4GB

CPU: 2 cores

Storage: 25GB



🚀 Docker & Docker Compose Installation on...]]></description><link>https://hassandevops.com/day-3-docker-docker-compose-and-microk8s-installation-on-ubuntu-2204</link><guid isPermaLink="true">https://hassandevops.com/day-3-docker-docker-compose-and-microk8s-installation-on-ubuntu-2204</guid><category><![CDATA[microk8]]></category><category><![CDATA[k8s]]></category><category><![CDATA[Docker]]></category><dc:creator><![CDATA[Muhammad Hassan]]></dc:creator><pubDate>Tue, 18 Mar 2025 08:16:01 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1742285731727/54c0cfab-948c-47ee-a46f-7c79bd7ca81d.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In this guide, we will walk through the installation of <strong>Docker</strong>, <strong>Docker Compose</strong>, and <strong>MicroK8s</strong> on <strong>Ubuntu 22.04</strong>. The commands are tested on the following machine specs:</p>
<ul>
<li><p><strong>RAM:</strong> 4GB</p>
</li>
<li><p><strong>CPU:</strong> 2 cores</p>
</li>
<li><p><strong>Storage:</strong> 25GB</p>
</li>
</ul>
<hr />
<h2 id="heading-docker-amp-docker-compose-installation-on-ubuntu-2204">🚀 Docker &amp; Docker Compose Installation on Ubuntu 22.04</h2>
<h3 id="heading-step-1-update-the-machine">🔄 Step 1: Update the Machine</h3>
<pre><code class="lang-plaintext">sudo apt update -y
</code></pre>
<h3 id="heading-step-2-remove-conflicting-packages">🧹 Step 2: Remove Conflicting Packages</h3>
<pre><code class="lang-plaintext">for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do 
  sudo apt-get remove $pkg; 
done
</code></pre>
<h3 id="heading-step-3-setup-dockers-apt-repository">📦 Step 3: Setup Docker’s APT Repository</h3>
<h4 id="heading-add-dockers-official-gpg-key">Add Docker's Official GPG Key:</h4>
<pre><code class="lang-plaintext">sudo apt-get update
sudo apt-get install ca-certificates curl -y
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc
</code></pre>
<h4 id="heading-add-docker-repository">Add Docker Repository:</h4>
<pre><code class="lang-plaintext">echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] \
https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | \
sudo tee /etc/apt/sources.list.d/docker.list &gt; /dev/null
</code></pre>
<pre><code class="lang-plaintext">sudo apt-get update
</code></pre>
<h3 id="heading-step-4-install-docker-amp-docker-compose">📥 Step 4: Install Docker &amp; Docker Compose</h3>
<pre><code class="lang-plaintext">sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin -y
</code></pre>
<h3 id="heading-step-5-verify-docker-installation">✅ Step 5: Verify Docker Installation</h3>
<pre><code class="lang-plaintext">sudo docker run hello-world
</code></pre>
<h3 id="heading-step-6-run-docker-as-a-non-root-user">👨‍💻 Step 6: Run Docker as a Non-Root User</h3>
<pre><code class="lang-plaintext">sudo groupadd docker
sudo usermod -aG docker $USER
newgrp docker
docker run hello-world
</code></pre>
<p>Now you can run Docker without <code>sudo</code>.</p>
<hr />
<h2 id="heading-install-microk8s-on-ubuntu-2204">☸️ Install MicroK8s on Ubuntu 22.04</h2>
<h3 id="heading-step-1-update-the-machine-1">🔄 Step 1: Update the Machine</h3>
<pre><code class="lang-plaintext">sudo apt update -y
</code></pre>
<h3 id="heading-step-2-install-microk8s">📥 Step 2: Install MicroK8s</h3>
<pre><code class="lang-plaintext">sudo snap install microk8s --classic --channel=1.32
</code></pre>
<h3 id="heading-step-3-add-your-user-to-the-microk8s-group">👥 Step 3: Add Your User to the MicroK8s Group</h3>
<pre><code class="lang-plaintext">sudo usermod -a -G microk8s $USER
mkdir -p ~/.kube
chmod 0700 ~/.kube
</code></pre>
<h3 id="heading-step-4-apply-group-changes">🔄 Step 4: Apply Group Changes</h3>
<p>Exit and log in again or run:</p>
<pre><code class="lang-plaintext">exit
</code></pre>
<h3 id="heading-step-5-check-microk8s-status">✅ Step 5: Check MicroK8s Status</h3>
<pre><code class="lang-plaintext">microk8s status --wait-ready
</code></pre>
<h3 id="heading-step-6-set-kubernetes-alias">🔗 Step 6: Set Kubernetes Alias</h3>
<pre><code class="lang-plaintext">alias kubectl='microk8s kubectl'
</code></pre>
<h3 id="heading-step-7-access-kubernetes-cluster">☸️ Step 7: Access Kubernetes Cluster</h3>
<pre><code class="lang-plaintext">kubectl get nodes
</code></pre>
<hr />
<h2 id="heading-adding-a-worker-node-to-microk8s-cluster">🏗️ Adding a Worker Node to MicroK8s Cluster</h2>
<h3 id="heading-step-1-install-microk8s-on-worker-node">📥 Step 1: Install MicroK8s on Worker Node</h3>
<pre><code class="lang-plaintext">sudo apt update -y
sudo snap install microk8s --classic --channel=1.32
</code></pre>
<h3 id="heading-step-2-get-join-command-from-master-node">🖥️ Step 2: Get Join Command from Master Node</h3>
<pre><code class="lang-plaintext">microk8s add-node
</code></pre>
<p>This will provide a join command like:</p>
<pre><code class="lang-plaintext">sudo microk8s join &lt;join-command&gt;
</code></pre>
<blockquote>
<p>⚠️ <strong>Important:</strong> Both machines (master and worker) must be on the same network.</p>
</blockquote>
<h3 id="heading-step-3-run-join-command-on-worker-node">🔗 Step 3: Run Join Command on Worker Node</h3>
<pre><code class="lang-plaintext">sudo microk8s join &lt;join-command&gt;
</code></pre>
<h3 id="heading-step-4-verify-node-is-joined-on-master-node">✅ Step 4: Verify Node is Joined (on Master Node)</h3>
<pre><code class="lang-plaintext">microk8s kubectl get nodes
</code></pre>
<h3 id="heading-optional-set-alias-for-kubectl">🔗 Optional: Set Alias for kubectl</h3>
<pre><code class="lang-plaintext">alias kubectl='microk8s kubectl'
</code></pre>
<h3 id="heading-to-stop-microk8s">⏹️ To Stop MicroK8s</h3>
<pre><code class="lang-plaintext">microk8s stop
</code></pre>
<hr />
<h2 id="heading-conclusion">✅ Conclusion</h2>
<p>You’ve successfully installed <strong>Docker</strong>, <strong>Docker Compose</strong>, and <strong>MicroK8s</strong> on your Ubuntu 22.04 machine. Whether you’re running containers or deploying Kubernetes clusters locally, this guide should help you get started with containerization and orchestration smoothly.</p>
]]></content:encoded></item><item><title><![CDATA[Day 1&2: Installing and Configuring GitLab on Ubuntu]]></title><description><![CDATA[I am using a DigitalOcean free account, which gives me $200 in credits. You can use my referral code to get the same offer: https://m.do.co/c/1fd4ef5ca074.
To set up the server, I created a Droplet with the following specifications:

8GB RAM, 4-core ...]]></description><link>https://hassandevops.com/day-1and2-installing-and-configuring-gitlab-on-ubuntu</link><guid isPermaLink="true">https://hassandevops.com/day-1and2-installing-and-configuring-gitlab-on-ubuntu</guid><category><![CDATA[GitLab]]></category><dc:creator><![CDATA[Muhammad Hassan]]></dc:creator><pubDate>Thu, 06 Mar 2025 08:55:52 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1741251247449/108dbc01-190f-4f29-8f36-dc312b7703a1.webp" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>I am using a <strong>DigitalOcean free account</strong>, which gives me <strong>$200</strong> in credits. You can use my referral code to get the same offer: <a target="_blank" href="https://m.do.co/c/1fd4ef5ca074">https://m.do.co/c/1fd4ef5ca074</a>.</p>
<p>To set up the server, I created a <strong>Droplet</strong> with the following specifications:</p>
<ul>
<li><p><strong>8GB RAM, 4-core CPU</strong> (recommended for optimal performance)</p>
</li>
<li><p><strong>Ubuntu 24.04 LTS</strong> (must use one of: 20.04 LTS, 22.04 LTS, or 24.04 LTS)</p>
</li>
</ul>
<p>Additionally, I configured my <strong>DNS A record</strong> to point my <strong>GitLab subdomain</strong> (<code>gitlab.hassandevops.site</code>) to my server's <strong>public IP address</strong> using <strong>GoDaddy</strong> as my domain registrar. Make sure to do this in your <strong>GoDaddy DNS settings</strong> before proceeding.</p>
<p>GitLab is a popular DevOps platform that allows you to manage repositories, CI/CD pipelines, and more. In this guide, we will walk through the installation and initial configuration of GitLab on an Ubuntu server.</p>
<h2 id="heading-step-1-install-and-configure-dependencies">Step 1: Install and Configure Dependencies</h2>
<p>Before installing GitLab, ensure that your system is up-to-date and that necessary dependencies are installed. Run the following commands:</p>
<pre><code class="lang-plaintext">sudo apt-get update
sudo apt-get install -y curl openssh-server ca-certificates tzdata perl
</code></pre>
<p>Additionally, install Postfix (or an alternative SMTP solution) to enable notification emails:</p>
<pre><code class="lang-plaintext">sudo apt-get install -y postfix
</code></pre>
<p>During the Postfix installation, a configuration screen may appear. Choose <strong>'Internet Site'</strong> and press enter. Use your server's external DNS for <strong>'mail name'</strong>, then press enter. If additional configuration screens appear, accept the defaults by pressing enter.</p>
<h2 id="heading-step-2-add-the-gitlab-package-repository-and-install-gitlab">Step 2: Add the GitLab Package Repository and Install GitLab</h2>
<p>To install GitLab, first add the GitLab package repository:</p>
<pre><code class="lang-plaintext">curl https://packages.gitlab.com/install/repositories/gitlab/gitlab-ee/script.deb.sh | sudo bash
</code></pre>
<p>Then, install GitLab with the following command. Be sure to replace <code>https://gitlab.example.com</code> with your desired GitLab URL:</p>
<pre><code class="lang-plaintext">sudo EXTERNAL_URL="https://gitlab.example.com" apt-get install gitlab-ee
</code></pre>
<p>If you wish to specify a particular version of GitLab, use:</p>
<pre><code class="lang-plaintext"># List available versions:
apt-cache madison gitlab-ee

# Install a specific version:
sudo EXTERNAL_URL="https://gitlab.example.com" apt-get install gitlab-ee=16.2.3-ee.0

# Pin the installed version to prevent auto-updates:
sudo apt-mark hold gitlab-ee

# Show pinned versions:
sudo apt-mark showhold
</code></pre>
<p>i use this for installing GitLab on <code>gitlab.hassandevops.site</code>, use:</p>
<pre><code class="lang-plaintext">sudo EXTERNAL_URL="https://gitlab.hassandevops.site" apt-get install gitlab-ee

# List available versions:
apt-cache madison gitlab-ee

# Install a specific version:
sudo EXTERNAL_URL="https://gitlab.hassandevops.site" apt-get install gitlab-ee=16.2.3-ee.0

# Pin the installed version:
sudo apt-mark hold gitlab-ee

# Show pinned versions:
sudo apt-mark showhold
</code></pre>
<h2 id="heading-step-3-access-gitlab-and-log-in">Step 3: Access GitLab and Log In</h2>
<p>Once installation is complete, navigate to your GitLab URL in a browser.</p>
<p>If you did not specify a custom administrator password, a randomly generated password will be stored in:</p>
<pre><code class="lang-plaintext">/etc/gitlab/initial_root_password
</code></pre>
<p>Use this password along with the username <strong>root</strong> to log in.</p>
<hr />
<p>With GitLab installed, you can now configure your repositories, CI/CD pipelines, and user management. For further customization and security enhancements, check out the <a target="_blank" href="https://docs.gitlab.com/ee/install/">official GitLab documentation</a>.</p>
<h3 id="heading-gitlab-access-url">GitLab Access URL:</h3>
<p><a target="_blank" href="https://gitlab.hassandevops.site">https://gitlab.hassandevops.site</a></p>
]]></content:encoded></item><item><title><![CDATA[Context-switching is the main productivity killer for developers]]></title><description><![CDATA[Disruptive Nature of Interruptions

Unplanned breaks in workflow can negatively impact productivity.

Our brains aren’t like computers: It takes time to load and switch tasks, and each shift forces your brain to refocus.

Each interruption causes you...]]></description><link>https://hassandevops.com/context-switching-is-the-main-productivity-killer-for-developers</link><guid isPermaLink="true">https://hassandevops.com/context-switching-is-the-main-productivity-killer-for-developers</guid><dc:creator><![CDATA[Muhammad Hassan]]></dc:creator><pubDate>Mon, 10 Feb 2025 13:12:59 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1739192946857/c1b22b29-e08c-49c2-a7d6-6970328463bb.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h3 id="heading-disruptive-nature-of-interruptions"><strong>Disruptive Nature of Interruptions</strong></h3>
<ul>
<li><p><strong>Unplanned breaks in workflow</strong> can negatively impact productivity.</p>
</li>
<li><p><strong>Our brains aren’t like computers</strong>: It takes time to load and switch tasks, and each shift forces your brain to <strong>refocus</strong>.</p>
</li>
<li><p>Each interruption causes you to <strong>sort through memory</strong> to figure out where you were.</p>
</li>
<li><p><strong>Context-switching</strong> is borrowed from <strong>operating systems (OS)</strong> where it refers to switching between tasks or processes.</p>
</li>
<li><p>With <strong>too many inputs</strong> (emails, chats, open tabs), it's easy to get distracted.</p>
</li>
<li><p>During <strong>complex tasks</strong>, our brains handle multiple pieces of information, but only up to <strong>7 items in short-term memory</strong>.</p>
</li>
<li><p>Interruptions <strong>shatter</strong> this mental model.</p>
</li>
<li><p>Developers need an <strong>average of 23 minutes</strong> to fully rebuild focus after an interruption.</p>
</li>
<li><p><strong>Mental energy reduction</strong>: Developers facing frequent interruptions show signs of <strong>mental fatigue</strong> much earlier, leading to <strong>more errors</strong> later in the day.</p>
</li>
<li><p><strong>Code quality suffers</strong> due to the impact on focus and mental energy.</p>
</li>
</ul>
<hr />
<h3 id="heading-flow-state"><strong>Flow State</strong></h3>
<ul>
<li><p><strong>Flow state</strong> is when work feels <strong>effortless</strong>, and time seems to disappear.</p>
</li>
<li><p>This state is <strong>fragile</strong>, and a <strong>single notification</strong> can instantly break it.</p>
</li>
</ul>
<hr />
<h3 id="heading-strategies-to-prevent-context-switching"><strong>Strategies to Prevent Context Switching</strong></h3>
<h4 id="heading-for-developers"><strong>For Developers</strong></h4>
<ol>
<li><p><strong>Set clear goals</strong>: Know what needs to be accomplished.</p>
</li>
<li><p><strong>Capture tasks on a TODO list</strong>: Have a record of tasks to reduce mental load.</p>
</li>
<li><p><strong>Prioritize tasks</strong>: Focus on high-priority work first.</p>
</li>
<li><p><strong>Deep work blocks</strong>: Schedule <strong>90-minute blocks</strong> for uninterrupted focus.</p>
</li>
<li><p><strong>Parking lot technique</strong>: Keep a list of non-urgent tasks to deal with later.</p>
</li>
<li><p><strong>Interruptible workflow</strong>: Leave comments in code so you can pick up where you left off.</p>
</li>
<li><p><strong>Minimize distractions</strong>: Turn off notifications or use noise-canceling headphones.</p>
</li>
<li><p><strong>Don’t multitask</strong>: Focus on one task at a time for better results.</p>
</li>
<li><p><strong>Ergonomics</strong>: Set up your desk and monitor for comfort to reduce physical strain.</p>
</li>
<li><p><strong>Organized environment</strong>: Keep your workspace tidy to minimize cognitive load.</p>
</li>
<li><p><strong>Regular breaks</strong>: Take short breaks to recharge.</p>
</li>
<li><p><strong>Be intentionally responsive</strong>: Decide when and how to engage with others.</p>
</li>
<li><p><strong>Plan your day strategically</strong>: Structure your time for maximum focus.</p>
</li>
<li><p><strong>Take proper rest</strong>: Ensure adequate sleep and downtime.</p>
</li>
</ol>
<hr />
<h4 id="heading-for-teams"><strong>For Teams</strong></h4>
<ol>
<li><p><strong>Interruption protocols</strong>: Define which tasks can be interrupted and which cannot.</p>
</li>
<li><p><strong>Focus time agreements</strong>: Set specific times for deep work (e.g., no meetings in the afternoon).</p>
</li>
<li><p><strong>Asynchronous communication</strong>: Use messages and emails instead of immediate calls or chats.</p>
</li>
<li><p><strong>Flexible working hours</strong>: Allow team members to work when they are most productive.</p>
</li>
<li><p><strong>Normalize saying NO</strong>: Empower the team to refuse non-essential interruptions.</p>
</li>
<li><p><strong>Make meetings meaningful</strong>: Ensure meetings are purposeful and efficient.</p>
</li>
</ol>
<hr />
<h3 id="heading-tracking-and-measuring-disruptions"><strong>Tracking and Measuring Disruptions</strong></h3>
<ol>
<li><p><strong>Unplanned interruptions</strong>: Track how many occur each day.</p>
</li>
<li><p><strong>Duration of uninterrupted coding sessions</strong>: Monitor increases over time.</p>
</li>
<li><p><strong>Code quality metrics</strong>: Check bug rates and review feedback for quality insights.</p>
</li>
<li><p><strong>Team satisfaction scores</strong>: Survey the team regularly to gauge satisfaction.</p>
</li>
<li><p><strong>Sprint velocity trends</strong>: Monitor if velocity improves after reducing interruptions.</p>
</li>
</ol>
<hr />
<p>This organization provides a clear view of both the issues and strategies involved in reducing context-switching for developers, helping to maintain productivity and code quality.</p>
]]></content:encoded></item><item><title><![CDATA[Comparing AI Model Pricing: Meta-Llama 3.1-8B vs. DeepSeek LLM Models]]></title><description><![CDATA[TASK
1. Deepseek API's2. ChatGPT for education API's3. https://www.khanmigo.ai/

DeepSeek API: We can use the DeepSeek LLM Chat 67B and DeepSeek-V3 models within Together AI. For other models, we need to create an account on DeepSeek and purchase the...]]></description><link>https://hassandevops.com/comparing-ai-model-pricing-meta-llama-31-8b-vs-deepseek-llm-models</link><guid isPermaLink="true">https://hassandevops.com/comparing-ai-model-pricing-meta-llama-31-8b-vs-deepseek-llm-models</guid><dc:creator><![CDATA[Muhammad Hassan]]></dc:creator><pubDate>Tue, 21 Jan 2025 12:56:59 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1737464190815/9b84856f-56c2-4493-9086-156587dfe2d4.avif" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>TASK</p>
<p>1. Deepseek API's<br />2. ChatGPT for education API's<br />3. <a target="_blank" href="https://www.khanmigo.ai/">https://www.khanmigo.ai/</a></p>
<ul>
<li><p><strong>DeepSeek API</strong>: We can use the <strong>DeepSeek LLM Chat 67B</strong> and <strong>DeepSeek-V3</strong> models within Together AI. For other models, we need to create an account on DeepSeek and purchase the API separately.</p>
</li>
<li><p><strong>ChatGPT for Education API</strong>: This API is designed for large organizations, such as universities, and uses GPT-4. Pricing is available upon request, but GPT-4 can also be accessed through Together AI.</p>
</li>
<li><p><strong>Khanmigo</strong>: Khanmigo is a SaaS product focused on educational support and is not suitable for large-scale API integrations or embedding.</p>
</li>
</ul>
<div class="hn-table">
<table>
<thead>
<tr>
<td><a target="_blank" href="https://www.khanmigo.ai/"><strong>Model</strong></a></td><td><a target="_blank" href="https://www.khanmigo.ai/"><strong>Size</strong></a></td><td><a target="_blank" href="https://www.khanmigo.ai/"><strong>Pri</strong></a><strong>ce (per 1M Tokens)</strong></td><td><strong>Type</strong></td><td></td></tr>
</thead>
<tbody>
<tr>
<td><strong>DeepSeek Models</strong></td><td></td><td></td><td></td><td></td></tr>
<tr>
<td>DeepSeek-V3</td><td></td><td>$1.25</td><td>General-purpose</td><td></td></tr>
<tr>
<td>DeepSeek LLM Chat 67B</td><td></td><td></td><td>$0.90</td><td>Chat model</td></tr>
<tr>
<td><strong>Llama Models</strong></td><td></td><td></td><td></td><td></td></tr>
<tr>
<td>Up to 3B</td><td></td><td>$0.06</td><td>Text</td><td></td></tr>
<tr>
<td>8B</td><td>Lite</td><td>$0.10</td><td>Text</td><td></td></tr>
<tr>
<td>8B</td><td>Turbo</td><td>$0.18</td><td>Text</td><td></td></tr>
<tr>
<td>8B</td><td>Reference</td><td>$0.20</td><td>Text</td><td></td></tr>
<tr>
<td>11B</td><td></td><td>$0.18</td><td>Text</td><td></td></tr>
<tr>
<td>70B</td><td>Lite</td><td>$0.54</td><td>Text</td><td></td></tr>
<tr>
<td>70B</td><td>Turbo</td><td>$0.88</td><td>Text</td><td></td></tr>
<tr>
<td>70B</td><td>Reference</td><td>$0.90</td><td>Text</td><td></td></tr>
<tr>
<td>90B (Vision)</td><td></td><td>$1.20</td><td>Vision</td><td></td></tr>
<tr>
<td>405B</td><td></td><td>$3.50</td><td>Text</td><td></td></tr>
<tr>
<td><strong>GPT Models</strong></td><td></td><td></td><td></td><td></td></tr>
<tr>
<td>GPT-4O (All versions)</td><td>Input</td><td>$2.50</td><td>Text</td><td></td></tr>
<tr>
<td>GPT-4O (All versions)</td><td>Input (cached)</td><td>$1.25</td><td>Text</td><td></td></tr>
<tr>
<td>GPT-4O (All versions)</td><td>Output</td><td>$10.00</td><td>Text</td><td></td></tr>
<tr>
<td>GPT-4O (All versions)</td><td>Output (cached)</td><td>$5.00</td><td>Text</td></tr>
</tbody>
</table>
</div><p>Khanmigo, developed by Khan Academy, is an AI tutor focused on helping students across various subjects. While it provides educational support and guidance, it is not designed for business or advanced AI embedding use cases like those of DeepSeek or ChatGPT Education.</p>
]]></content:encoded></item><item><title><![CDATA[16: Kubernetes Cluster Management: Upgrading and Backing Up Your Cluster]]></title><description><![CDATA[Managing a Kubernetes (K8s) cluster involves routine upgrades to maintain security, compatibility, and new features, as well as reliable backup strategies to ensure data integrity. This blog will guide you through upgrading your Kubernetes cluster an...]]></description><link>https://hassandevops.com/16-kubernetes-cluster-management-upgrading-and-backing-up-your-cluster</link><guid isPermaLink="true">https://hassandevops.com/16-kubernetes-cluster-management-upgrading-and-backing-up-your-cluster</guid><category><![CDATA[k8s]]></category><dc:creator><![CDATA[Muhammad Hassan]]></dc:creator><pubDate>Fri, 06 Dec 2024 05:46:15 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1733401601181/7131b50a-12eb-44c1-b3c1-74046d29b582.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Managing a Kubernetes (K8s) cluster involves routine upgrades to maintain security, compatibility, and new features, as well as reliable backup strategies to ensure data integrity. This blog will guide you through <strong>upgrading your Kubernetes cluster</strong> and implementing robust backup mechanisms with built-in and third-party tools.</p>
<hr />
<h2 id="heading-upgrading-your-kubernetes-cluster"><strong>Upgrading Your Kubernetes Cluster</strong></h2>
<p>Upgrading your cluster involves updating <code>kubeadm</code>, applying the upgrade to the control plane, and ensuring nodes and components align with the new version. Below are the detailed steps:</p>
<h3 id="heading-steps-to-upgrade-the-cluster"><strong>Steps to Upgrade the Cluster</strong></h3>
<ol>
<li><p><strong>Check the Nodes in the Cluster:</strong></p>
<pre><code class="lang-plaintext"> kubectl get nodes
</code></pre>
<p> This command lists all nodes in the cluster and their current status.</p>
</li>
<li><p><strong>Update the System Package Index:</strong></p>
<pre><code class="lang-plaintext"> sudo apt update
</code></pre>
</li>
<li><p><strong>Check Available Versions of</strong> <code>kubeadm</code>:</p>
<pre><code class="lang-plaintext"> sudo apt-cache madison kubeadm
</code></pre>
<p> Identify the version of <code>kubeadm</code> you want to install. Replace <code>1.30.x</code> with the desired version.</p>
</li>
<li><p><strong>Install the New Version of</strong> <code>kubeadm</code>:</p>
<pre><code class="lang-plaintext"> sudo apt-mark unhold kubeadm &amp;&amp; \
 sudo apt-get update &amp;&amp; sudo apt-get install -y kubeadm=1.30.x-* &amp;&amp; \
 sudo apt-mark hold kubeadm
</code></pre>
</li>
<li><p><strong>Verify the Installed</strong> <code>kubeadm</code> Version:</p>
<pre><code class="lang-plaintext"> kubeadm version
</code></pre>
</li>
<li><p><strong>Plan the Upgrade:</strong></p>
<pre><code class="lang-plaintext"> sudo kubeadm upgrade plan
</code></pre>
<p> This command shows the current cluster state, available upgrades, and a step-by-step guide for applying the upgrade.</p>
</li>
<li><p><strong>Apply the Upgrade:</strong></p>
<pre><code class="lang-plaintext"> sudo kubeadm upgrade apply v1.30.x
</code></pre>
<p> Replace <code>v1.30.x</code> with the target version. This updates the control plane components.</p>
</li>
<li><p><strong>Upgrade the Nodes:</strong> After upgrading the control plane, update the nodes by following similar steps, ensuring <code>kubelet</code> and <code>kubectl</code> versions match the control plane.</p>
</li>
</ol>
<hr />
<h2 id="heading-backing-up-your-kubernetes-cluster"><strong>Backing Up Your Kubernetes Cluster</strong></h2>
<p>Reliable backups are critical for disaster recovery and cluster restoration. Here are two popular backup methods:</p>
<h3 id="heading-1-built-in-etcd-backup"><strong>1. Built-in ETCD Backup</strong></h3>
<p>ETCD is the primary datastore for Kubernetes and stores all cluster state information. To back it up:</p>
<ol>
<li><p><strong>Use</strong> <code>etcdctl</code> for Backup:</p>
<pre><code class="lang-plaintext"> ETCDCTL_API=3 etcdctl --endpoints=https://127.0.0.1:2379 \
   --cacert=/etc/kubernetes/pki/etcd/ca.crt \
   --cert=/etc/kubernetes/pki/etcd/server.crt \
   --key=/etc/kubernetes/pki/etcd/server.key \
   snapshot save /path/to/backup/etcd-snapshot.db
</code></pre>
<p> Replace <code>/path/to/backup/etcd-snapshot.db</code> with the desired backup location. Ensure you provide the correct certificate paths (usually located in <code>/etc/kubernetes/pki/etcd/</code>).</p>
</li>
<li><p><strong>Verify the Backup:</strong></p>
<pre><code class="lang-plaintext"> ETCDCTL_API=3 etcdctl snapshot status /path/to/backup/etcd-snapshot.db
</code></pre>
</li>
</ol>
<h3 id="heading-2-velero-for-production-backups"><strong>2. Velero for Production Backups</strong></h3>
<p>Velero is a widely-used third-party tool for backing up and restoring Kubernetes clusters. It is particularly useful for production environments.</p>
<ol>
<li><p><strong>Install Velero:</strong> Follow the official Velero documentation to install it in your cluster.</p>
</li>
<li><p><strong>Create a Backup:</strong></p>
<pre><code class="lang-plaintext"> velero backup create &lt;backup-name&gt; --include-namespaces=&lt;namespace&gt;
</code></pre>
<p> Replace <code>&lt;backup-name&gt;</code> with a descriptive name and <code>&lt;namespace&gt;</code> with the desired namespace (or use <code>--all-namespaces</code>).</p>
</li>
<li><p><strong>Verify Backups:</strong></p>
<pre><code class="lang-plaintext"> velero backup get
</code></pre>
</li>
<li><p><strong>Restore from Backup:</strong></p>
<pre><code class="lang-plaintext"> velero restore create --from-backup &lt;backup-name&gt;
</code></pre>
</li>
</ol>
<hr />
<h2 id="heading-conclusion"><strong>Conclusion</strong></h2>
<p>Regularly upgrading and backing up your Kubernetes cluster ensures stability, security, and disaster recovery readiness.</p>
<h3 id="heading-key-notes"><strong>Key Notes:</strong></h3>
<ul>
<li><p>Always test upgrades in a staging environment before applying them to production.</p>
</li>
<li><p>For built-in ETCD backups, validate the snapshot's integrity.</p>
</li>
<li><p>Velero provides a flexible, production-ready solution with cloud storage support.</p>
</li>
</ul>
<p>By following the above methods, you can confidently maintain your Kubernetes infrastructure and mitigate risks effectively.</p>
]]></content:encoded></item><item><title><![CDATA[15: Mastering Helm, YAML Validation, Monitoring, and Security]]></title><description><![CDATA[Kubernetes (K8s) is an essential tool for managing containerized applications. To simplify operations, tools like Helm and Kubernetes-native monitoring solutions like Prometheus and Grafana are indispensable. This blog will guide you through:

Helm: ...]]></description><link>https://hassandevops.com/15-mastering-helm-yaml-validation-monitoring-and-security</link><guid isPermaLink="true">https://hassandevops.com/15-mastering-helm-yaml-validation-monitoring-and-security</guid><category><![CDATA[k8s]]></category><dc:creator><![CDATA[Muhammad Hassan]]></dc:creator><pubDate>Thu, 05 Dec 2024 07:51:03 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1733384331787/d48e7b7e-cb91-4636-bc3a-dacc93b77b93.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Kubernetes (K8s) is an essential tool for managing containerized applications. To simplify operations, tools like Helm and Kubernetes-native monitoring solutions like Prometheus and Grafana are indispensable. This blog will guide you through:</p>
<ul>
<li><p><strong>Helm: Kubernetes Package Manager</strong></p>
</li>
<li><p><strong>YAML Validation and Best Practices</strong></p>
</li>
<li><p><strong>Monitoring Kubernetes Clusters</strong></p>
</li>
<li><p><strong>Enhancing Cluster Security</strong></p>
</li>
</ul>
<hr />
<h2 id="heading-1-helm-simplifying-kubernetes-package-management"><strong>1. Helm: Simplifying Kubernetes Package Management</strong></h2>
<h3 id="heading-what-is-helm"><strong>What is Helm?</strong></h3>
<p>Helm is a package manager for Kubernetes that makes deploying and managing applications easier by using <em>charts</em>—a collection of pre-configured Kubernetes resources. Instead of writing complex YAML files for deployments, Helm allows you to deploy applications like Apache servers or Prometheus in minutes.</p>
<h3 id="heading-installing-helm"><strong>Installing Helm</strong></h3>
<p>To get started with Helm, follow these steps:</p>
<pre><code class="lang-plaintext">curl https://baltocdn.com/helm/signing.asc | gpg --dearmor | sudo tee /usr/share/keyrings/helm.gpg &gt; /dev/null  
sudo apt-get install apt-transport-https --yes  
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/helm.gpg] https://baltocdn.com/helm/stable/debian/ all main" | sudo tee /etc/apt/sources.list.d/helm-stable-debian.list  
sudo apt-get update  
sudo apt-get install helm
</code></pre>
<h3 id="heading-using-helm-charts"><strong>Using Helm Charts</strong></h3>
<p>Helm charts simplify deployments:</p>
<ol>
<li><p>Search for a chart:</p>
<pre><code class="lang-plaintext"> helm search hub apache
</code></pre>
</li>
<li><p>View chart details:</p>
<pre><code class="lang-plaintext"> helm show chart &lt;chart-name&gt;
</code></pre>
</li>
<li><p>Install a chart (e.g., Apache server):</p>
<pre><code class="lang-plaintext"> helm install my-apache bitnami/apache
</code></pre>
</li>
<li><p>Customize a deployment using your values file:</p>
<pre><code class="lang-plaintext"> helm install my-apache bitnami/apache --values apache-custom.yaml
</code></pre>
</li>
<li><p>List installed releases:</p>
<pre><code class="lang-plaintext"> helm ls
</code></pre>
</li>
<li><p>Uninstall a release:</p>
<pre><code class="lang-plaintext"> helm uninstall my-apache
</code></pre>
</li>
</ol>
<h3 id="heading-deploying-prometheus-and-grafana-with-helm"><strong>Deploying Prometheus and Grafana with Helm</strong></h3>
<p>Let’s deploy a monitoring stack with Helm:</p>
<h4 id="heading-step-1-add-the-helm-repository"><strong>Step 1: Add the Helm Repository</strong></h4>
<pre><code class="lang-plaintext">helm repo add prometheus-community https://prometheus-community.github.io/helm-charts  
helm repo update
</code></pre>
<h4 id="heading-step-2-install-prometheus-grafana-stack"><strong>Step 2: Install Prometheus-Grafana Stack</strong></h4>
<pre><code class="lang-plaintext">kubectl create ns monitoring  
helm install prometheus --namespace monitoring prometheus-community/kube-prometheus-stack
</code></pre>
<h4 id="heading-step-3-access-the-grafana-dashboard"><strong>Step 3: Access the Grafana Dashboard</strong></h4>
<ol>
<li><p>Check running pods and services:</p>
<pre><code class="lang-plaintext"> kubectl get pods -n monitoring  
 kubectl get svc -n monitoring
</code></pre>
</li>
<li><p>Port-forward Grafana for local access:</p>
<pre><code class="lang-plaintext"> kubectl port-forward -n monitoring service/prometheus-grafana 3000:80
</code></pre>
</li>
<li><p>Access Grafana in your browser:</p>
<ul>
<li>URL: <a target="_blank" href="http://localhost:3000"><code>http://localhost:3000</code></a></li>
</ul>
</li>
</ol>
<hr />
<h2 id="heading-2-validating-yaml-files-in-kubernetes"><strong>2. Validating YAML Files in Kubernetes</strong></h2>
<h3 id="heading-why-validate-yaml"><strong>Why Validate YAML?</strong></h3>
<p>A minor syntax error can break your Kubernetes deployment. Tools like <code>kubeval</code> and <code>kube-score</code> ensure your YAML files are correctly configured and optimized.</p>
<h3 id="heading-yaml-validation-tools"><strong>YAML Validation Tools</strong></h3>
<ol>
<li><p><strong>kubeval</strong>:</p>
<pre><code class="lang-plaintext"> kubeval deployment.yaml
</code></pre>
</li>
<li><p><strong>kube-score</strong>:</p>
<pre><code class="lang-plaintext"> kube-score score deployment.yaml
</code></pre>
</li>
</ol>
<h3 id="heading-using-environment-variables-in-yaml"><strong>Using Environment Variables in YAML</strong></h3>
<p>You can use tools like <code>envsubst</code> to inject variables into your YAML files dynamically:</p>
<pre><code class="lang-plaintext">export APP_NAME=my-app  
envsubst &lt; deployment-template.yaml &gt; deployment.yaml
</code></pre>
<hr />
<h2 id="heading-3-multi-cluster-management-and-security"><strong>3. Multi-Cluster Management and Security</strong></h2>
<h3 id="heading-multi-cluster-deployment"><strong>Multi-Cluster Deployment</strong></h3>
<p>Helm supports deploying to multiple clusters by configuring kubeconfig files and specifying the target cluster:</p>
<pre><code class="lang-plaintext">export KUBECONFIG=/path/to/kubeconfig  
kubectl config use-context &lt;cluster-name&gt;
</code></pre>
<h3 id="heading-ingress-in-kubernetes"><strong>Ingress in Kubernetes</strong></h3>
<p>Ingress resources expose HTTP and HTTPS routes from outside the cluster to services within it. A sample ingress YAML:</p>
<pre><code class="lang-plaintext">apiVersion: networking.k8s.io/v1  
kind: Ingress  
metadata:  
  name: example-ingress  
spec:  
  rules:  
    - host: example.com  
      http:  
        paths:  
          - path: /  
            pathType: Prefix  
            backend:  
              service:  
                name: example-service  
                port:  
                  number: 80
</code></pre>
<hr />
<h2 id="heading-4-enhancing-security-in-kubernetes"><strong>4. Enhancing Security in Kubernetes</strong></h2>
<h3 id="heading-cluster-scanning-with-kubescape"><strong>Cluster Scanning with Kubescape</strong></h3>
<p>Kubescape is a Kubernetes-native tool for scanning clusters for vulnerabilities:</p>
<pre><code class="lang-plaintext">kubescape scan --include-namespace dev
</code></pre>
<h3 id="heading-decode-kubernetes-secrets"><strong>Decode Kubernetes Secrets</strong></h3>
<p>Secrets in Kubernetes are base64-encoded. To decode them:</p>
<pre><code class="lang-plaintext">kubectl get secret &lt;secret-name&gt; -n &lt;namespace&gt; -o jsonpath='{.data.&lt;key&gt;}' | base64 --decode
</code></pre>
<hr />
<h2 id="heading-5-upgrading-kubernetes-clusters"><strong>5. Upgrading Kubernetes Clusters</strong></h2>
<p>Upgrading clusters ensures you get the latest features and security patches. General steps:</p>
<ol>
<li><p>Upgrade the control plane components (e.g., <code>kube-apiserver</code>, <code>kube-scheduler</code>).</p>
</li>
<li><p>Upgrade node components (e.g., <code>kubelet</code>, <code>kubectl</code>).</p>
</li>
<li><p>Verify cluster functionality post-upgrade.</p>
</li>
</ol>
<hr />
<h3 id="heading-conclusion">Conclusion</h3>
<p>Helm simplifies Kubernetes deployments, YAML validation ensures robustness, and monitoring and security tools help maintain a healthy cluster. Mastering these tools will empower you to manage Kubernetes environments effectively.</p>
<p>Happy K8s journey!</p>
]]></content:encoded></item><item><title><![CDATA[14: Role-Based Access Control (RBAC) in Kubernetes with Practical Examples]]></title><description><![CDATA[Role-Based Access Control (RBAC) is a Kubernetes mechanism to control and restrict access to resources based on user roles and permissions. In this blog, we'll explore RBAC concepts, configuration steps, and examples to clarify how it works.

What is...]]></description><link>https://hassandevops.com/14-role-based-access-control-rbac-in-kubernetes-with-practical-examples</link><guid isPermaLink="true">https://hassandevops.com/14-role-based-access-control-rbac-in-kubernetes-with-practical-examples</guid><category><![CDATA[k8s]]></category><dc:creator><![CDATA[Muhammad Hassan]]></dc:creator><pubDate>Wed, 04 Dec 2024 11:21:41 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1733311108730/f5031ba9-dbf5-4b74-93c2-30544d17497b.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Role-Based Access Control (RBAC) is a Kubernetes mechanism to control and restrict access to resources based on user roles and permissions. In this blog, we'll explore RBAC concepts, configuration steps, and examples to clarify how it works.</p>
<hr />
<h2 id="heading-what-is-rbac"><strong>What is RBAC?</strong></h2>
<p>RBAC allows administrators to assign specific permissions to users or groups. This ensures users only have access to the resources they need, limiting potential security risks. Here’s a breakdown:</p>
<ol>
<li><p><strong>Role</strong>: Defines permissions for specific resources in a namespace.<br /> Example: A role allowing a user to create and delete pods in the <code>dev</code> namespace.</p>
</li>
<li><p><strong>ClusterRole</strong>: Similar to a Role but not namespace-specific, granting access to resources cluster-wide.</p>
</li>
<li><p><strong>RoleBinding</strong>: Associates a Role with a user or group within a namespace.</p>
</li>
<li><p><strong>ClusterRoleBinding</strong>: Associates a ClusterRole with a user or group across the cluster.</p>
</li>
</ol>
<hr />
<h2 id="heading-rbac-workflow-example"><strong>RBAC Workflow Example</strong></h2>
<p>We’ll demonstrate how to create a user named <strong>Hassan</strong>, set up their credentials, and assign them a role with limited permissions in the <code>dev</code> namespace.</p>
<hr />
<h3 id="heading-step-1-user-creates-an-openssl-key-and-csr"><strong>Step 1: User Creates an OpenSSL Key and CSR</strong></h3>
<p>On Hassan's workstation, generate a private key and a certificate signing request (CSR).</p>
<pre><code class="lang-plaintext"># Generate a private key
openssl genrsa -out user.key 2048

# Create a CSR (replace "username" with the actual username)
openssl req -new -key user.key -out user.csr -subj "/CN=hassan"
</code></pre>
<hr />
<h3 id="heading-step-2-submit-csr-to-the-manager"><strong>Step 2: Submit CSR to the Manager</strong></h3>
<p>Hassan submits the key and CSR to the manager (or CA).</p>
<pre><code class="lang-plaintext"># Transfer files to the manager
scp user.key user.csr login@manager:
</code></pre>
<hr />
<h3 id="heading-step-3-manager-issues-a-certificate"><strong>Step 3: Manager Issues a Certificate</strong></h3>
<p>The manager (Root CA) signs the CSR and sends the certificate back to Hassan.</p>
<pre><code class="lang-plaintext"># Sign the CSR with the Kubernetes Root CA
openssl x509 -req -in user.csr -CA /etc/kubernetes/pki/ca.crt -CAkey /etc/kubernetes/pki/ca.key \
  -CAcreateserial -out user.crt -days 365

# Return the certificate to Hassan
scp user.crt login@workstation:
</code></pre>
<hr />
<h3 id="heading-step-4-set-up-kubernetes-configuration-on-user-workstation"><strong>Step 4: Set Up Kubernetes Configuration on User Workstation</strong></h3>
<p>Hassan creates a <code>.kube</code> directory and configures <code>kubectl</code>.</p>
<ol>
<li><p><strong>Create the configuration directory:</strong></p>
<pre><code class="lang-plaintext"> mkdir -p ~/.kube
</code></pre>
</li>
<li><p><strong>Copy the necessary config file from the manager</strong> (without root credentials).</p>
</li>
<li><p><strong>Install</strong> <code>kubectl</code> on the workstation:</p>
<pre><code class="lang-plaintext"> sudo snap install kubectl --classic
</code></pre>
</li>
<li><p><strong>Set user credentials in the Kubernetes context:</strong></p>
<pre><code class="lang-plaintext"> kubectl config set-credentials hassan --client-certificate=user.crt --client-key=user.key
 kubectl config set-context hassan-context --cluster=kubernetes --namespace=dev --user=hassan
</code></pre>
</li>
</ol>
<hr />
<h3 id="heading-step-5-assign-a-role-to-the-user"><strong>Step 5: Assign a Role to the User</strong></h3>
<h4 id="heading-role-example-allow-pod-management-in-the-dev-namespace"><strong>Role Example: Allow Pod Management in the</strong> <code>dev</code> Namespace</h4>
<ol>
<li><p>Create a YAML file defining the Role:</p>
<pre><code class="lang-plaintext"> apiVersion: rbac.authorization.k8s.io/v1
 kind: Role
 metadata:
   namespace: dev
   name: pod-manager
 rules:
 - apiGroups: [""] # "" indicates the core API group
   resources: ["pods"]
   verbs: ["create", "delete"]
</code></pre>
</li>
<li><p>Apply the Role:</p>
<pre><code class="lang-plaintext"> kubectl apply -f role.yaml
</code></pre>
</li>
</ol>
<hr />
<h3 id="heading-step-6-bind-the-role-to-the-user"><strong>Step 6: Bind the Role to the User</strong></h3>
<p>Create a RoleBinding to associate Hassan with the <code>pod-manager</code> Role:</p>
<pre><code class="lang-plaintext">apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: bind-hassan
  namespace: dev
subjects:
- kind: User
  name: hassan
  apiGroup: ""
roleRef:
  kind: Role
  name: pod-manager
  apiGroup: ""
</code></pre>
<p>Apply the RoleBinding:</p>
<pre><code class="lang-plaintext">kubectl apply -f rolebinding.yaml
</code></pre>
<hr />
<h3 id="heading-step-7-verify-permissions"><strong>Step 7: Verify Permissions</strong></h3>
<p>Hassan can check their permissions using:</p>
<pre><code class="lang-plaintext"># Check if Hassan can delete pods in the `test` namespace
kubectl auth can-i delete pods -n test
</code></pre>
<p>Managers can verify Hassan's permissions:</p>
<pre><code class="lang-plaintext"># Verify as Hassan
kubectl auth can-i delete pods --as hassan -n dev

# List roles in the `dev` namespace
kubectl get roles -n dev
</code></pre>
<hr />
<h3 id="heading-important-notes"><strong>Important Notes</strong></h3>
<ol>
<li><p><strong>Kubeconfig for Users</strong>: Avoid sharing kubeconfig files with root credentials. Create a dedicated configuration for each user with minimal permissions.</p>
</li>
<li><p><strong>Root Access</strong>: Assigning a user to the <code>cluster-admin</code> role grants unrestricted access. Use it cautiously.</p>
</li>
<li><p><strong>Advanced Environments</strong>: In larger setups, integrate Kubernetes with services like Active Directory for streamlined authentication.</p>
</li>
</ol>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1733311223725/8c353d8f-c4f4-451a-af33-35e36a09e941.png" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1733311236706/0845eb3b-2e38-44d0-bf85-d6d757515b5f.png" alt class="image--center mx-auto" /></p>
<hr />
<h2 id="heading-conclusion"><strong>Conclusion</strong></h2>
<p>RBAC is an essential security practice for Kubernetes clusters, ensuring users and applications only access what they need. By following the steps and examples above, you can implement RBAC effectively in your organization.</p>
]]></content:encoded></item><item><title><![CDATA[13: Kubernetes Secrets and ConfigMaps: A Complete Guide with Examples]]></title><description><![CDATA[In this blog, we'll explore Kubernetes Secrets and ConfigMaps, their purpose, differences, and how to use them effectively with examples. We'll also clarify any misconceptions and highlight best practices.

What Are Kubernetes Secrets?
Secrets in Kub...]]></description><link>https://hassandevops.com/13-kubernetes-secrets-and-configmaps-a-complete-guide-with-examples</link><guid isPermaLink="true">https://hassandevops.com/13-kubernetes-secrets-and-configmaps-a-complete-guide-with-examples</guid><category><![CDATA[k8s]]></category><dc:creator><![CDATA[Muhammad Hassan]]></dc:creator><pubDate>Tue, 03 Dec 2024 12:13:33 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1733227978795/eaaf7208-726d-42e3-b083-4f8bdfcfd4f7.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In this blog, we'll explore <strong>Kubernetes Secrets</strong> and <strong>ConfigMaps</strong>, their purpose, differences, and how to use them effectively with examples. We'll also clarify any misconceptions and highlight best practices.</p>
<hr />
<h2 id="heading-what-are-kubernetes-secrets">What Are Kubernetes Secrets?</h2>
<p><strong>Secrets</strong> in Kubernetes are used to store sensitive and confidential information such as passwords, API keys, and SSH keys. They prevent sensitive data from being hardcoded into your application or configuration files.</p>
<h3 id="heading-key-characteristics">Key Characteristics:</h3>
<ul>
<li><p><strong>Encoded, not encrypted</strong>: Secrets are base64-encoded, not encrypted by default. While encoding helps obfuscate data, it doesn't protect it from being exposed.</p>
</li>
<li><p><strong>Data in etcd</strong>: By default, secrets are stored in etcd as plaintext, meaning data at rest isn't encrypted unless you enable encryption at the etcd layer.</p>
</li>
</ul>
<h3 id="heading-examples-of-sensitive-data-for-secrets">Examples of Sensitive Data for Secrets:</h3>
<ul>
<li><p>SSH keys</p>
</li>
<li><p>Database usernames and passwords</p>
</li>
<li><p>API tokens</p>
</li>
</ul>
<h4 id="heading-difference-between-encoding-and-encryption">Difference Between Encoding and Encryption:</h4>
<ul>
<li><p><strong>Encoding</strong>: Transforms data into a different format (e.g., base64) for transmission or storage but is reversible without a key.</p>
</li>
<li><p><strong>Encryption</strong>: Secures data using algorithms and requires a key to decrypt.</p>
</li>
</ul>
<hr />
<h3 id="heading-creating-and-using-secrets">Creating and Using Secrets</h3>
<p>Secrets can be created using <strong>imperative</strong> or <strong>declarative</strong> methods.</p>
<h4 id="heading-1-imperative-method">1. <strong>Imperative Method</strong></h4>
<pre><code class="lang-plaintext">kubectl create secret generic my-secret \
  --from-literal=username=admin \
  --from-literal=password=secret123
</code></pre>
<h4 id="heading-2-declarative-method-yaml">2. <strong>Declarative Method (YAML)</strong></h4>
<p>Define a <code>Secret</code> in a YAML file:</p>
<pre><code class="lang-plaintext">apiVersion: v1
kind: Secret
metadata:
  name: my-secret
type: Opaque
data:
  username: YWRtaW4= # Base64-encoded value of 'admin'
  password: c2VjcmV0MTIz # Base64-encoded value of 'secret123'
</code></pre>
<p>Apply the configuration:</p>
<pre><code class="lang-plaintext">kubectl apply -f secret.yaml
</code></pre>
<h4 id="heading-using-secrets-in-a-deployment">Using Secrets in a Deployment</h4>
<pre><code class="lang-plaintext">apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
spec:
  replicas: 1
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app
    spec:
      containers:
      - name: my-container
        image: nginx
        env:
        - name: DB_USERNAME
          valueFrom:
            secretKeyRef:
              name: my-secret
              key: username
        - name: DB_PASSWORD
          valueFrom:
            secretKeyRef:
              name: my-secret
              key: password
</code></pre>
<hr />
<h2 id="heading-what-are-configmaps">What Are ConfigMaps?</h2>
<p><strong>ConfigMaps</strong> store non-sensitive data in key-value pairs or configuration files. They allow you to decouple configuration details from your application code.</p>
<h3 id="heading-key-use-cases">Key Use Cases:</h3>
<ul>
<li><p>Application configuration files (e.g., <code>httpd.conf</code> for Apache).</p>
</li>
<li><p>Environment-specific variables to control application behavior.</p>
</li>
</ul>
<h3 id="heading-creating-and-using-configmaps">Creating and Using ConfigMaps</h3>
<h4 id="heading-1-imperative-method-1">1. <strong>Imperative Method</strong></h4>
<pre><code class="lang-plaintext">kubectl create configmap devapache --from-file=httpd.conf
</code></pre>
<h4 id="heading-2-declarative-method-yaml-1">2. <strong>Declarative Method (YAML)</strong></h4>
<p>Define a <code>ConfigMap</code> in a YAML file:</p>
<pre><code class="lang-plaintext">apiVersion: v1
kind: ConfigMap
metadata:
  name: devapache
data:
  httpd.conf: |
    ServerName localhost
    Listen 8080
</code></pre>
<h4 id="heading-using-configmaps-in-a-deployment">Using ConfigMaps in a Deployment</h4>
<pre><code class="lang-plaintext">apiVersion: apps/v1
kind: Deployment
metadata:
  name: apache-app
spec:
  replicas: 1
  selector:
    matchLabels:
      app: apache-app
  template:
    metadata:
      labels:
        app: apache-app
    spec:
      containers:
      - name: apache-container
        image: httpd
        volumeMounts:
        - name: config-volume
          mountPath: /usr/local/apache2/conf
          subPath: httpd.conf
      volumes:
      - name: config-volume
        configMap:
          name: devapache
</code></pre>
<p><strong>Important Note</strong>: In the <code>volumeMounts</code> section:</p>
<ul>
<li>Use the <strong>directory name</strong> (not the filename) in the <code>mountPath</code> where the ConfigMap data should be placed inside the container.</li>
</ul>
<hr />
<h2 id="heading-comparison-secrets-vs-configmaps">Comparison: Secrets vs. ConfigMaps</h2>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Feature</td><td>Secrets</td><td>ConfigMaps</td></tr>
</thead>
<tbody>
<tr>
<td><strong>Purpose</strong></td><td>Store sensitive data</td><td>Store non-sensitive configuration</td></tr>
<tr>
<td><strong>Data Encoding</strong></td><td>Base64-encoded</td><td>Plaintext</td></tr>
<tr>
<td><strong>Use Case</strong></td><td>API keys, passwords, credentials</td><td>Configuration files, environment variables</td></tr>
<tr>
<td><strong>Storage</strong></td><td>etcd (plaintext by default)</td><td>etcd (plaintext)</td></tr>
</tbody>
</table>
</div><hr />
<h2 id="heading-conclusion">Conclusion</h2>
<p>Secrets and ConfigMaps are essential tools for managing configuration and sensitive data in Kubernetes. While Secrets provide an additional layer of security through obfuscation, ConfigMaps allow seamless application configuration. Remember to:</p>
<ol>
<li><p>Enable encryption at rest for etcd to secure Secrets.</p>
</li>
<li><p>Avoid embedding sensitive data directly into YAML files.</p>
</li>
<li><p>Use declarative approaches for better version control.</p>
</li>
</ol>
<p>By combining these resources effectively, you can build a secure and configurable Kubernetes-based application.</p>
]]></content:encoded></item></channel></rss>