<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Houssam Bourkane</title>
    <description>The latest articles on DEV Community by Houssam Bourkane (@houssambourkane).</description>
    <link>https://dev.to/houssambourkane</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F876998%2F5f3e1ca7-f292-48bc-abce-459c287cf634.jpeg</url>
      <title>DEV Community: Houssam Bourkane</title>
      <link>https://dev.to/houssambourkane</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/houssambourkane"/>
    <language>en</language>
    <item>
      <title>Exposing Kubernetes Metrics: Adding Metrics Server to Your Local Cluster</title>
      <dc:creator>Houssam Bourkane</dc:creator>
      <pubDate>Fri, 16 May 2025 14:02:03 +0000</pubDate>
      <link>https://dev.to/houssambourkane/exposing-kubernetes-metrics-adding-metrics-server-to-your-local-cluster-1bd</link>
      <guid>https://dev.to/houssambourkane/exposing-kubernetes-metrics-adding-metrics-server-to-your-local-cluster-1bd</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;This guide is the second part of the "Build a Kubernetes Lab with Vagrant &amp;amp; Ansible" series. In this article, we’ll add resource usage monitoring to your cluster by installing the Kubernetes Metrics Server.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Table of Contents
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Prerequisites&lt;/li&gt;
&lt;li&gt;Step 1: Install Metrics Server&lt;/li&gt;
&lt;li&gt;
Step 2: Patch the Deployment &lt;/li&gt;
&lt;li&gt;
Step 3: Verify Installation &lt;/li&gt;
&lt;li&gt;Step 4: Use the Metrics API&lt;/li&gt;
&lt;li&gt;What's Next?&lt;/li&gt;
&lt;li&gt;Useful links&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  📌 Prerequisite: Your Local Cluster Must Be Running
&lt;/h2&gt;

&lt;p&gt;This article assumes you have already completed the first part of the series, where we created a local Kubernetes cluster using Vagrant and Ansible. If not, go back and follow &lt;a href="https://dev.to/houssambourkane/kubernetes-at-home-set-up-your-own-cluster-using-vagrant-ansible-4c8a"&gt;Part 1: Build Your Local Kubernetes Cluster&lt;/a&gt; first.&lt;/p&gt;

&lt;p&gt;Reminder: You should have exported your Kubernetes configuration locally with the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vagrant ssh kubmaster &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s2"&gt;"sudo cat /etc/kubernetes/admin.conf"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; ~/kubeconfig-vagrant.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Set this file as your config path:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;KUBECONFIG&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;~/kubeconfig-vagrant.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Step 1: Install Metrics Server
&lt;/h2&gt;

&lt;p&gt;We’ll use the official manifest from the Kubernetes SIG repository to install the Metrics Server:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;KUBECONFIG&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$KUBECONFIG&lt;/span&gt; kubectl apply &lt;span class="nt"&gt;-f&lt;/span&gt; https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml &amp;amp;&amp;gt; /dev/null
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;This deploys the &lt;code&gt;metrics-server&lt;/code&gt; in the &lt;code&gt;kube-system&lt;/code&gt; namespace. However, some environments (like local or self-hosted) require additional flags to work properly.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Step 2: Patch the Deployment
&lt;/h2&gt;

&lt;p&gt;By default, the metrics server may not collect metrics correctly in local environments due to self-signed certificates or insecure Kubelet connections.&lt;/p&gt;

&lt;p&gt;To fix that, apply the following patch to the deployment:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;KUBECONFIG&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$KUBECONFIG&lt;/span&gt; kubectl patch deployment metrics-server &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-n&lt;/span&gt; kube-system &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'json'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-p&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'[
    {
      "op": "add",
      "path": "/spec/template/spec/containers/0/command",
      "value": [
        "/metrics-server",
        "--kubelet-insecure-tls",
        "--kubelet-preferred-address-types=InternalIP"
      ]
    }
  ]'&lt;/span&gt; &amp;amp;&amp;gt; /dev/null
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This tells the metrics server to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ignore TLS errors from kubelet (safe for local)&lt;/li&gt;
&lt;li&gt;Prefer InternalIP when communicating with nodes&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Step 3: Verify Installation
&lt;/h2&gt;

&lt;p&gt;Once installed and patched, verify that everything is working:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;KUBECONFIG&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$KUBECONFIG&lt;/span&gt; kubectl get deployment metrics-server &lt;span class="nt"&gt;-n&lt;/span&gt; kube-system
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If it shows &lt;code&gt;READY&lt;/code&gt; and &lt;code&gt;AVAILABLE&lt;/code&gt;, you're good to go!&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 4: Use the Metrics API
&lt;/h2&gt;

&lt;p&gt;You can now query live resource usage data:&lt;/p&gt;

&lt;h3&gt;
  
  
  View Node Metrics
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;KUBECONFIG&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$KUBECONFIG&lt;/span&gt; kubectl top nodes
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  View Pod Metrics (All Namespaces)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;KUBECONFIG&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$KUBECONFIG&lt;/span&gt; kubectl top pods &lt;span class="nt"&gt;-A&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You now have visibility into CPU and memory usage across your cluster.&lt;/p&gt;




&lt;h2&gt;
  
  
  What's Next?
&lt;/h2&gt;

&lt;p&gt;With your metrics server up and running, you're ready to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Explore Kubernetes Horizontal Pod Autoscaling (HPA)&lt;/li&gt;
&lt;li&gt;Set up resource dashboards like Lens or K9s&lt;/li&gt;
&lt;li&gt;Monitor cluster health trends locally&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In the next part of the series, we’ll configure the NGINX Ingress Controller to manage external traffic to your services.&lt;/p&gt;




&lt;h2&gt;
  
  
  Resources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/kubernetes-sigs/metrics-server" rel="noopener noreferrer"&gt;Metrics Server GitHub&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://kubernetes.io/docs/tasks/debug/debug-cluster/resource-metrics-pipeline/" rel="noopener noreferrer"&gt;Metrics Server Docs&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>devops</category>
      <category>kubernetes</category>
      <category>metrics</category>
      <category>automation</category>
    </item>
    <item>
      <title>Kubernetes at Home: Set Up Your Own Cluster Using Vagrant &amp; Ansible</title>
      <dc:creator>Houssam Bourkane</dc:creator>
      <pubDate>Thu, 15 May 2025 23:30:03 +0000</pubDate>
      <link>https://dev.to/houssambourkane/kubernetes-at-home-set-up-your-own-cluster-using-vagrant-ansible-4c8a</link>
      <guid>https://dev.to/houssambourkane/kubernetes-at-home-set-up-your-own-cluster-using-vagrant-ansible-4c8a</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; Learn how to build a lightweight Kubernetes cluster on your local machine using Vagrant, Ansible, and VMware Fusion. Perfect for ARM-based Mac users looking to experiment with Kubernetes in a reproducible environment.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Why This Guide?
&lt;/h2&gt;

&lt;p&gt;Setting up a Kubernetes cluster manually can be complex and time-consuming. But with the power of &lt;strong&gt;Vagrant&lt;/strong&gt; for managing virtual machines and &lt;strong&gt;Ansible&lt;/strong&gt; for automating setup tasks, you can spin up a local cluster with minimal effort and maximum reproducibility. This tutorial walks you through building a two-node cluster on macOS with ARM chips (e.g., M1/M2), but it's adaptable to other setups.&lt;/p&gt;




&lt;h2&gt;
  
  
  Table of Contents
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Prerequisites&lt;/li&gt;
&lt;li&gt;Project Structure&lt;/li&gt;
&lt;li&gt;Step 1: Configure Vagrant&lt;/li&gt;
&lt;li&gt;
Step 2: Configure Ansible &lt;/li&gt;
&lt;li&gt;
Step 3: Ansible Playbook for Kubernetes Setup &lt;/li&gt;
&lt;li&gt;Step 4: Test and Deploy the Cluster&lt;/li&gt;
&lt;li&gt;What's Next?&lt;/li&gt;
&lt;li&gt;Useful links&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;Before we start, ensure you have the following installed:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://developer.hashicorp.com/vagrant/install" rel="noopener noreferrer"&gt;Vagrant&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.ansible.com/ansible/latest/installation_guide/intro_installation.html" rel="noopener noreferrer"&gt;Ansible&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://knowledge.broadcom.com/external/article/315638/download-and-install-vmware-fusion.html" rel="noopener noreferrer"&gt;VMware Fusion Tech Preview&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;For macOS ARM users, refer to this special setup guide: &lt;a href="https://dev.to/houssambourkane/run-vagrant-vms-in-a-m1m2m3-macos-chip-2p3l"&gt;Run Vagrant VMs in a M1/M2/M3 Apple Sillicon Chip&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Project Structure
&lt;/h2&gt;

&lt;p&gt;Create a project directory and replicate the following structure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;.&lt;/span&gt;
├── ansible
│   ├── ansible.cfg
│   ├── inventory.ini
│   └── k8s-cluster-setup.yml
└── Vagrantfile
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Step 1: Configure Vagrant
&lt;/h2&gt;

&lt;p&gt;Install the VMware Desktop plugin:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vagrant plugin &lt;span class="nb"&gt;install &lt;/span&gt;vagrant-vmware-desktop
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, reserve &lt;strong&gt;two static private IPs&lt;/strong&gt; from your LAN. Scan your local network using:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;nmap &lt;span class="nt"&gt;-sn&lt;/span&gt; 192.168.1.0/24
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Replace &lt;code&gt;192.168.1.0&lt;/code&gt; with you LAN network IP&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Update your &lt;code&gt;Vagrantfile&lt;/code&gt; with something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="no"&gt;Vagrant&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;configure&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"2"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;vm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;define&lt;/span&gt; &lt;span class="s2"&gt;"kubmaster"&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;kub&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
    &lt;span class="n"&gt;kub&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;vm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;box&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"spox/ubuntu-arm"&lt;/span&gt;
    &lt;span class="n"&gt;kub&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;vm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;box_version&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"1.0.0"&lt;/span&gt;
    &lt;span class="n"&gt;kub&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;vm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;hostname&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'kubmaster'&lt;/span&gt;
    &lt;span class="n"&gt;kub&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;vm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;provision&lt;/span&gt; &lt;span class="s2"&gt;"docker"&lt;/span&gt;
    &lt;span class="n"&gt;kub&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;vm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;network&lt;/span&gt; &lt;span class="s2"&gt;"public_network"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;ip: &lt;/span&gt;&lt;span class="s2"&gt;"192.168.1.101"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;bridge: &lt;/span&gt;&lt;span class="s2"&gt;"en0: Wifi"&lt;/span&gt;
    &lt;span class="n"&gt;kub&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;vm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;provider&lt;/span&gt; &lt;span class="s2"&gt;"vmware_desktop"&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
      &lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;allowlist_verified&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;true&lt;/span&gt;
      &lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;gui&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;false&lt;/span&gt;
      &lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;vmx&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"memsize"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"4096"&lt;/span&gt;
      &lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;vmx&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"numvcpus"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"2"&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;vm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;define&lt;/span&gt; &lt;span class="s2"&gt;"kubnode1"&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;kubnode&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
    &lt;span class="n"&gt;kubnode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;vm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;box&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"spox/ubuntu-arm"&lt;/span&gt;
    &lt;span class="n"&gt;kubnode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;vm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;box_version&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"1.0.0"&lt;/span&gt;
    &lt;span class="n"&gt;kubnode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;vm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;hostname&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'kubnode1'&lt;/span&gt;
    &lt;span class="n"&gt;kubnode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;vm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;provision&lt;/span&gt; &lt;span class="s2"&gt;"docker"&lt;/span&gt;
    &lt;span class="n"&gt;kubnode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;vm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;network&lt;/span&gt; &lt;span class="s2"&gt;"public_network"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;ip: &lt;/span&gt;&lt;span class="s2"&gt;"192.168.1.102"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;bridge: &lt;/span&gt;&lt;span class="s2"&gt;"en0: Wifi"&lt;/span&gt;
    &lt;span class="n"&gt;kubnode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;vm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;provider&lt;/span&gt; &lt;span class="s2"&gt;"vmware_desktop"&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
      &lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;allowlist_verified&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;true&lt;/span&gt;
      &lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;gui&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;false&lt;/span&gt;
      &lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;vmx&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"memsize"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"4096"&lt;/span&gt;
      &lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;vmx&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"numvcpus"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"2"&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Replace the IPs with ones that match your LAN.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now bring up the VMs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vagrant up
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Step 2: Configure Ansible
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;ansible/inventory.ini&lt;/code&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ini"&gt;&lt;code&gt;&lt;span class="nn"&gt;[master]&lt;/span&gt;
&lt;span class="err"&gt;kubmaster&lt;/span&gt; &lt;span class="py"&gt;ansible_host&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;192.168.1.101 ansible_ssh_private_key_file=.vagrant/machines/kubmaster/vmware_desktop/private_key&lt;/span&gt;

&lt;span class="nn"&gt;[workers]&lt;/span&gt;
&lt;span class="err"&gt;kubnode1&lt;/span&gt; &lt;span class="py"&gt;ansible_host&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;192.168.1.102 ansible_ssh_private_key_file=.vagrant/machines/kubnode1/vmware_desktop/private_key&lt;/span&gt;

&lt;span class="nn"&gt;[all:vars]&lt;/span&gt;
&lt;span class="py"&gt;ansible_user&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;vagrant&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Make sure to replace the IP addresses&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;ansible/ansible.cfg&lt;/code&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ini"&gt;&lt;code&gt;&lt;span class="nn"&gt;[defaults]&lt;/span&gt;
&lt;span class="py"&gt;inventory&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;inventory.ini&lt;/span&gt;
&lt;span class="py"&gt;host_key_checking&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;False&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Step 3: Ansible Playbook for Kubernetes Setup
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;ansible/k8s-cluster-setup.yml&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;This playbook performs the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Prepares all nodes: disables swap, installs required packages, configures kernel modules, adds K8s repositories, installs &lt;code&gt;kubeadm&lt;/code&gt;, &lt;code&gt;kubelet&lt;/code&gt;, and &lt;code&gt;kubectl&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Initializes the master node and stores the cluster join command.&lt;/li&gt;
&lt;li&gt;Sets up Flannel CNI for networking.&lt;/li&gt;
&lt;li&gt;Joins worker nodes using the generated join command.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Prepare Kubernetes Nodes&lt;/span&gt;
  &lt;span class="na"&gt;hosts&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;all&lt;/span&gt;
  &lt;span class="na"&gt;become&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;yes&lt;/span&gt;

  &lt;span class="na"&gt;tasks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;  

    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Disable swap (runtime)&lt;/span&gt;
      &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;swapoff -a&lt;/span&gt;
      &lt;span class="na"&gt;when&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ansible_swaptotal_mb &amp;gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;

    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Comment out swap line in /etc/fstab&lt;/span&gt;
      &lt;span class="na"&gt;lineinfile&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/etc/fstab&lt;/span&gt;
        &lt;span class="na"&gt;regexp&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;^\s*([^#]\S*\s+\S+\s+swap\s+\S+)\s*$'&lt;/span&gt;
        &lt;span class="na"&gt;line&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;#&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;\1'&lt;/span&gt;
        &lt;span class="na"&gt;backrefs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;yes&lt;/span&gt;

    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Apply mount changes&lt;/span&gt;
      &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;mount -a&lt;/span&gt;

    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Stop AppArmor&lt;/span&gt;
      &lt;span class="na"&gt;systemd&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;apparmor&lt;/span&gt;
        &lt;span class="na"&gt;state&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;stopped&lt;/span&gt;
        &lt;span class="na"&gt;enabled&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;no&lt;/span&gt;

    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Restart containerd&lt;/span&gt;
      &lt;span class="na"&gt;systemd&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;containerd&lt;/span&gt;
        &lt;span class="na"&gt;state&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;restarted&lt;/span&gt;

    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Configure sysctl for Kubernetes&lt;/span&gt;
      &lt;span class="na"&gt;copy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;dest&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/etc/sysctl.d/kubernetes.conf&lt;/span&gt;
        &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
          &lt;span class="s"&gt;net.bridge.bridge-nf-call-ip6tables = 1&lt;/span&gt;
          &lt;span class="s"&gt;net.bridge.bridge-nf-call-iptables = 1&lt;/span&gt;

    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Apply sysctl settings&lt;/span&gt;
      &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;sysctl --system&lt;/span&gt;

    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Install transport and curl&lt;/span&gt;
      &lt;span class="na"&gt;apt&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;apt-transport-https&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;curl&lt;/span&gt;
        &lt;span class="na"&gt;update_cache&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;yes&lt;/span&gt;
        &lt;span class="na"&gt;state&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;present&lt;/span&gt;

    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Add Kubernetes APT key&lt;/span&gt;
      &lt;span class="na"&gt;shell&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
        &lt;span class="s"&gt;curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.33/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg&lt;/span&gt;
      &lt;span class="na"&gt;args&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;creates&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/etc/apt/keyrings/kubernetes-apt-keyring.gpg&lt;/span&gt;

    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Add Kubernetes APT repository&lt;/span&gt;
      &lt;span class="na"&gt;apt_repository&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;repo&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;deb&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;[signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg]&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;https://pkgs.k8s.io/core:/stable:/v1.33/deb/&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;/"&lt;/span&gt;
        &lt;span class="na"&gt;filename&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;kubernetes"&lt;/span&gt;
        &lt;span class="na"&gt;state&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;present&lt;/span&gt;

    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Install Kubernetes components&lt;/span&gt;
      &lt;span class="na"&gt;apt&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;kubelet&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;kubeadm&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;kubectl&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;kubernetes-cni&lt;/span&gt;
        &lt;span class="na"&gt;update_cache&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;yes&lt;/span&gt;
        &lt;span class="na"&gt;state&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;present&lt;/span&gt;

    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Enable kubelet service&lt;/span&gt;
      &lt;span class="na"&gt;systemd&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;kubelet&lt;/span&gt;
        &lt;span class="na"&gt;enabled&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;yes&lt;/span&gt;

&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Initialize Kubernetes Master&lt;/span&gt;
  &lt;span class="na"&gt;hosts&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;master&lt;/span&gt;
  &lt;span class="na"&gt;become&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;yes&lt;/span&gt;
  &lt;span class="na"&gt;vars&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;pod_cidr&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;10.244.0.0/16"&lt;/span&gt;

  &lt;span class="na"&gt;tasks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;

    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Remove default containerd config&lt;/span&gt;
      &lt;span class="na"&gt;file&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/etc/containerd/config.toml&lt;/span&gt;
        &lt;span class="na"&gt;state&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;absent&lt;/span&gt;

    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Restart containerd&lt;/span&gt;
      &lt;span class="na"&gt;systemd&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;containerd&lt;/span&gt;
        &lt;span class="na"&gt;state&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;restarted&lt;/span&gt;
        &lt;span class="na"&gt;enabled&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;yes&lt;/span&gt;

    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Wait for containerd socket to be available&lt;/span&gt;
      &lt;span class="na"&gt;wait_for&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/run/containerd/containerd.sock&lt;/span&gt;
        &lt;span class="na"&gt;state&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;present&lt;/span&gt;
        &lt;span class="na"&gt;timeout&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;20&lt;/span&gt;

    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Initialize Kubernetes control plane&lt;/span&gt;
      &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;kubeadm init --apiserver-advertise-address={{ ansible_host }} --node-name {{ inventory_hostname }} --pod-network-cidr={{ pod_cidr }}&lt;/span&gt;
      &lt;span class="na"&gt;register&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;kubeadm_output&lt;/span&gt;
      &lt;span class="na"&gt;args&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;creates&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/etc/kubernetes/admin.conf&lt;/span&gt;

    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Extract join command&lt;/span&gt;
      &lt;span class="na"&gt;shell&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
        &lt;span class="s"&gt;kubeadm token create --print-join-command&lt;/span&gt;
      &lt;span class="na"&gt;register&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;join_command&lt;/span&gt;
      &lt;span class="na"&gt;changed_when&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;

    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Set join command fact&lt;/span&gt;
      &lt;span class="na"&gt;set_fact&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;kube_join_command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;{{&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;join_command.stdout&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;}}"&lt;/span&gt;

    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Create .kube directory for vagrant user&lt;/span&gt;
      &lt;span class="na"&gt;become_user&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;vagrant&lt;/span&gt;
      &lt;span class="na"&gt;file&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/home/vagrant/.kube&lt;/span&gt;
        &lt;span class="na"&gt;state&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;directory&lt;/span&gt;
        &lt;span class="na"&gt;mode&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0755&lt;/span&gt;

    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Copy Kubernetes admin config to vagrant user&lt;/span&gt;
      &lt;span class="na"&gt;copy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;src&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/etc/kubernetes/admin.conf&lt;/span&gt;
        &lt;span class="na"&gt;dest&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/home/vagrant/.kube/config&lt;/span&gt;
        &lt;span class="na"&gt;remote_src&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;yes&lt;/span&gt;
        &lt;span class="na"&gt;owner&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;vagrant&lt;/span&gt;
        &lt;span class="na"&gt;group&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;vagrant&lt;/span&gt;
        &lt;span class="na"&gt;mode&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0644&lt;/span&gt;

&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Configure networking&lt;/span&gt;
  &lt;span class="na"&gt;hosts&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;all&lt;/span&gt;
  &lt;span class="na"&gt;become&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;yes&lt;/span&gt;

  &lt;span class="na"&gt;tasks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;

    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Ensure br_netfilter loads at boot&lt;/span&gt;
      &lt;span class="na"&gt;copy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;dest&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/etc/modules-load.d/k8s.conf&lt;/span&gt;
        &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
          &lt;span class="s"&gt;br_netfilter&lt;/span&gt;

    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Load br_netfilter kernel module now&lt;/span&gt;
      &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;modprobe br_netfilter&lt;/span&gt;

    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Configure sysctl for Kubernetes networking&lt;/span&gt;
      &lt;span class="na"&gt;copy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;dest&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/etc/sysctl.d/k8s.conf&lt;/span&gt;
        &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
          &lt;span class="s"&gt;net.bridge.bridge-nf-call-iptables = 1&lt;/span&gt;
          &lt;span class="s"&gt;net.bridge.bridge-nf-call-ip6tables = 1&lt;/span&gt;

    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Apply sysctl settings&lt;/span&gt;
      &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;sysctl --system&lt;/span&gt;

&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Configure flannel&lt;/span&gt;
  &lt;span class="na"&gt;hosts&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;master&lt;/span&gt;
  &lt;span class="na"&gt;become&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;yes&lt;/span&gt;

  &lt;span class="na"&gt;tasks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;

    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Apply Flannel CNI plugin&lt;/span&gt;
      &lt;span class="na"&gt;become_user&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;vagrant&lt;/span&gt;
      &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;kubectl apply -f https://raw.githubusercontent.com/flannel-io/flannel/master/Documentation/kube-flannel.yml&lt;/span&gt;
      &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;KUBECONFIG&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/home/vagrant/.kube/config&lt;/span&gt;


&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Join worker nodes to cluster&lt;/span&gt;
  &lt;span class="na"&gt;hosts&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;workers&lt;/span&gt;
  &lt;span class="na"&gt;become&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;yes&lt;/span&gt;
  &lt;span class="na"&gt;vars&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;kube_join_command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;{{&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;hostvars['kubmaster']['kube_join_command']&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;}}"&lt;/span&gt;

  &lt;span class="na"&gt;tasks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Remove default containerd config&lt;/span&gt;
      &lt;span class="na"&gt;file&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/etc/containerd/config.toml&lt;/span&gt;
        &lt;span class="na"&gt;state&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;absent&lt;/span&gt;

    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Restart containerd&lt;/span&gt;
      &lt;span class="na"&gt;systemd&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;containerd&lt;/span&gt;
        &lt;span class="na"&gt;state&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;restarted&lt;/span&gt;
        &lt;span class="na"&gt;enabled&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;yes&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Wait until the Kubernetes API server is reachable&lt;/span&gt;
      &lt;span class="na"&gt;wait_for&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;host&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;{{&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;hostvars['kubmaster']['ansible_host']&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;}}"&lt;/span&gt;
        &lt;span class="na"&gt;port&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;6443&lt;/span&gt;
        &lt;span class="na"&gt;delay&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;10&lt;/span&gt;
        &lt;span class="na"&gt;timeout&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;120&lt;/span&gt;
        &lt;span class="na"&gt;state&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;started&lt;/span&gt;

    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Join the node to Kubernetes cluster&lt;/span&gt;
      &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;{{&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;kube_join_command&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;}}"&lt;/span&gt;
      &lt;span class="na"&gt;args&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;creates&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/etc/kubernetes/kubelet.conf&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Step 4: Test and Deploy the Cluster
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Test Ansible SSH connectivity:
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ansible all &lt;span class="nt"&gt;-m&lt;/span&gt; ping &lt;span class="nt"&gt;-i&lt;/span&gt; ansible/inventory.ini
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Run the full cluster setup:
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ansible-playbook &lt;span class="nt"&gt;-i&lt;/span&gt; ansible/inventory.ini ansible/k8s-cluster-setup.yml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Retrieve the kubeconfig file locally:
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vagrant ssh kubmaster &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s2"&gt;"sudo cat /etc/kubernetes/admin.conf"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; ~/kubeconfig-vagrant.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Test your cluster:
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;KUBECONFIG&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;~/kubeconfig-vagrant.yaml kubectl get nodes
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should see both the master and worker nodes in &lt;code&gt;Ready&lt;/code&gt; status.&lt;/p&gt;




&lt;h2&gt;
  
  
  What's Next?
&lt;/h2&gt;

&lt;p&gt;You now have a fully functioning local Kubernetes cluster on ARM-based hardware, with everything automated and reproducible. You can now:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Experiment with Helm charts&lt;/li&gt;
&lt;li&gt;Try GitOps with ArgoCD&lt;/li&gt;
&lt;li&gt;Deploy sample apps&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Stay tuned for the next part of this series!&lt;/p&gt;




&lt;h2&gt;
  
  
  Useful Links
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Vagrant: &lt;a href="https://developer.hashicorp.com/vagrant/install" rel="noopener noreferrer"&gt;https://developer.hashicorp.com/vagrant/install&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Ansible: &lt;a href="https://docs.ansible.com/ansible/latest/installation_guide/intro_installation.html" rel="noopener noreferrer"&gt;https://docs.ansible.com/ansible/latest/installation_guide/intro_installation.html&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;VMware Fusion Tech Preview: &lt;a href="https://knowledge.broadcom.com/external/article/315638/download-and-install-vmware-fusion.html" rel="noopener noreferrer"&gt;https://knowledge.broadcom.com/external/article/315638/download-and-install-vmware-fusion.html&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;ARM-specific setup guide: &lt;a href="https://dev.to/houssambourkane/run-vagrant-vms-in-a-m1m2m3-macos-chip-2p3l"&gt;https://dev.to/houssambourkane/run-vagrant-vms-in-a-m1m2m3-macos-chip-2p3l&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Vagrant VMware utility: &lt;a href="https://developer.hashicorp.com/vagrant/docs/providers/vmware/vagrant-vmware-utility" rel="noopener noreferrer"&gt;https://developer.hashicorp.com/vagrant/docs/providers/vmware/vagrant-vmware-utility&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>devops</category>
      <category>kubernetes</category>
      <category>vagrant</category>
      <category>ansible</category>
    </item>
    <item>
      <title>Run Vagrant VMs in a M1/M2/M3 Apple Sillicon Chip</title>
      <dc:creator>Houssam Bourkane</dc:creator>
      <pubDate>Sun, 18 Feb 2024 00:01:02 +0000</pubDate>
      <link>https://dev.to/houssambourkane/run-vagrant-vms-in-a-m1m2m3-macos-chip-2p3l</link>
      <guid>https://dev.to/houssambourkane/run-vagrant-vms-in-a-m1m2m3-macos-chip-2p3l</guid>
      <description>&lt;p&gt;If you're a Mac user equipped with an Apple Silicon chip (M1/M2/M3...) and facing challenges setting up a Vagrant infrastructure due to the lack of supported hypervisors, this tutorial is tailored for you. It will guide you through configuring Vagrant to run using VMware Fusion technology as a hypervisor. Simply follow the steps outlined, and should you encounter any issues along the way, feel free to reach out to me for assistance.&lt;/p&gt;

&lt;h4&gt;
  
  
  Step 1: Install Rosetta
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/usr/sbin/softwareupdate --install-rosetta --agree-to-license
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Step 2: Install VMware Fusion tech (you will have to create a VMware account)
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://customerconnect.vmware.com/downloads/get-download?downloadGroup=FUS-TP2023
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You may also need to provide a license key, you can opt for the free one.&lt;/p&gt;

&lt;h4&gt;
  
  
  Step 3: Create a symbolic link
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ln -s /Applications/VMWare\ Fusion\ Tech\ Preview.app /Applications/VMWare\ Fusion.app
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Step 4: Install vagrant (on MacOS)
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;brew tap hashicorp/tap
brew install hashicorp/tap/hashicorp-vagrant
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Step 5: Install vagrant vmware utility
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://releases.hashicorp.com/vagrant-vmware-utility/1.0.22/vagrant-vmware-utility_1.0.22_darwin_amd64.dmg
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Step 6: Install vagrant plugin
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;vagrant plugin install vagrant-vmware-desktop
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Step 7: Create a Vagrantfile
&lt;/h4&gt;

&lt;p&gt;&lt;em&gt;This configuration will create 2 VMs (master and slave)&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mkdir vagrant-project
cd vagrant-project
touch Vagrantfile
cat &amp;lt;&amp;lt; EOF &amp;gt; Vagrantfile
Vagrant.configure("2") do |config|
    config.vm.define "master" do |master|
        master.vm.box = "spox/ubuntu-arm" 
        master.vm.box_version = "1.0.0"
        master.vm.hostname = 'master'
        master.vm.provision "docker"

        master.vm.network :private_network, ip: "192.168.56.101"

        master.vm.provider "vmware_desktop" do |v|
            v.allowlist_verified = true
            v.gui = false
            v.vmx["memsize"] = "2048"
            v.vmx["numvcpus"] = "2"
      end
    end

    config.vm.define "slave" do |slave|
        slave.vm.box = "spox/ubuntu-arm" 
        slave.vm.box_version = "1.0.0"
        slave.vm.hostname = 'slave'
        slave.vm.provision "docker"

        slave.vm.network :private_network, ip: "192.168.56.102"

        slave.vm.provider "vmware_desktop" do |v|
            v.allowlist_verified = true
            v.gui = false
            v.vmx["memsize"] = "2048"
            v.vmx["numvcpus"] = "2"
      end
    end
  end
EOF
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Note: gui parameter is mandatory&lt;/strong&gt; &lt;/p&gt;

&lt;h4&gt;
  
  
  Step 8: Now you can run the vagrant program
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;vagrant up
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Additional commands
&lt;/h4&gt;

&lt;h5&gt;
  
  
  Check the status of the VMs
&lt;/h5&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;vagrant status
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h5&gt;
  
  
  Connect to the VMs
&lt;/h5&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;vagrant ssh &amp;lt;hostname&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In our example we can use either&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;vagrant ssh master
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;vagrant ssh slave
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h5&gt;
  
  
  Stop the VMs
&lt;/h5&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;vagrant halt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h5&gt;
  
  
  Delete the VMs
&lt;/h5&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;vagrant destroy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>vagrant</category>
      <category>hashicorp</category>
      <category>mac</category>
      <category>vmware</category>
    </item>
    <item>
      <title>How DNS works - Part 2</title>
      <dc:creator>Houssam Bourkane</dc:creator>
      <pubDate>Sat, 06 Jan 2024 22:30:20 +0000</pubDate>
      <link>https://dev.to/houssambourkane/how-dns-works-part-2-446a</link>
      <guid>https://dev.to/houssambourkane/how-dns-works-part-2-446a</guid>
      <description>&lt;ol&gt;
&lt;li&gt;
Records

&lt;ul&gt;
&lt;li&gt;A record&lt;/li&gt;
&lt;li&gt;AAAA record&lt;/li&gt;
&lt;li&gt;CNAME record&lt;/li&gt;
&lt;li&gt;MX record&lt;/li&gt;
&lt;li&gt;NS record&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
Useful shell commands

&lt;ul&gt;
&lt;li&gt;nslookup&lt;/li&gt;
&lt;li&gt;dig&lt;/li&gt;
&lt;li&gt;whois&lt;/li&gt;
&lt;li&gt;host&lt;/li&gt;
&lt;li&gt;ping&lt;/li&gt;
&lt;li&gt;traceroute or tracert&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Useful links&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Records
&lt;/h2&gt;

&lt;p&gt;DNS records (aka zone files) are instructions that live in authoritative DNS servers and provide information about a domain including what IP address is associated with that domain and how to handle requests for that domain. These records consist of a series of text files written in what is known as DNS syntax. DNS syntax is just a string of characters used as commands that tell the DNS server what to do. All DNS records also have a ‘TTL’, which stands for time-to-live, and indicates how often a DNS server will refresh that record.&lt;/p&gt;

&lt;h3&gt;
  
  
  A record
&lt;/h3&gt;

&lt;p&gt;The "A" stands for "address" and this is the most fundamental type of DNS record: it indicates the IP address of a given domain.&lt;/p&gt;

&lt;p&gt;Here is an example of an A record:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;example.com&lt;/th&gt;
&lt;th&gt;record type&lt;/th&gt;
&lt;th&gt;value&lt;/th&gt;
&lt;th&gt;TTL&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;@&lt;/td&gt;
&lt;td&gt;A&lt;/td&gt;
&lt;td&gt;192.0.2.1&lt;/td&gt;
&lt;td&gt;14400&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The "@" symbol in this example indicates that this is a record for the &lt;strong&gt;&lt;u&gt;root domain&lt;/u&gt;&lt;/strong&gt;, and the "14400" value is the TTL (time to live), listed in seconds. The default TTL for A records is 14,400 seconds. This means that if an A record gets updated, it takes 240 minutes (14,400 seconds) to take effect.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm7rsjg72n65lk91bnvm2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm7rsjg72n65lk91bnvm2.png" alt="what is a root domain name" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  AAAA record
&lt;/h3&gt;

&lt;p&gt;Here is an example of an AAAA record:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;example.com&lt;/th&gt;
&lt;th&gt;record type:&lt;/th&gt;
&lt;th&gt;value:&lt;/th&gt;
&lt;th&gt;TTL&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;@&lt;/td&gt;
&lt;td&gt;AAAA&lt;/td&gt;
&lt;td&gt;2001:0db8:85a3:0000:  &lt;br&gt;0000:8a2e:0370:7334&lt;/td&gt;
&lt;td&gt;14400&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;
&lt;h3&gt;
  
  
  CNAME record
&lt;/h3&gt;

&lt;p&gt;A "canonical name" (CNAME) record points from an alias domain to a "canonical" domain. A CNAME record is used in lieu of an A record, when a domain or subdomain is an alias of another domain. &lt;strong&gt;All CNAME records must point to a domain, never to an IP address&lt;/strong&gt;. Imagine a scavenger hunt where each clue points to another clue, and the final clue points to the treasure. A domain with a CNAME record is like a clue that can point you to another clue (another domain with a CNAME record) or to the treasure (a domain with an A record).&lt;/p&gt;

&lt;p&gt;For example, suppose blog.example.com has a CNAME record with a value of "example.com" (without the "blog"). This means when a DNS server hits the DNS records for blog.example.com, it actually triggers another DNS lookup to example.com, returning example.com’s IP address via its A record. In this case we would say that example.com is the canonical name (or true name) of blog.example.com.&lt;/p&gt;

&lt;p&gt;Oftentimes, when sites have subdomains such as blog.example.com or shop.example.com, those subdomains will have CNAME records that point to a root domain (example.com). This way if the IP address of the host changes, only the DNS A record for the root domain needs to be updated and all the CNAME records will follow along with whatever changes are made to the root.&lt;/p&gt;

&lt;p&gt;Example of a CNAME record:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;blog.example.com&lt;/th&gt;
&lt;th&gt;record type:&lt;/th&gt;
&lt;th&gt;value:&lt;/th&gt;
&lt;th&gt;TTL&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;@&lt;/td&gt;
&lt;td&gt;CNAME&lt;/td&gt;
&lt;td&gt;is an alias of example.com&lt;/td&gt;
&lt;td&gt;32600&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;In this example you can see that blog.example.com points to example.com, and assuming it is based on our example A record we know that it will eventually resolve to the IP address 192.0.2.1.&lt;/p&gt;
&lt;h3&gt;
  
  
  MX record
&lt;/h3&gt;

&lt;p&gt;An MX (Mail Exchange) record in DNS guides email to a specific mail server. It specifies the route for email messages based on the Simple Mail Transfer Protocol (SMTP), the standard protocol for email. Similar to CNAME records, an MX record always points to a different domain.&lt;br&gt;
Example of an MX record:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;example.com&lt;/th&gt;
&lt;th&gt;record type:&lt;/th&gt;
&lt;th&gt;priority:&lt;/th&gt;
&lt;th&gt;value:&lt;/th&gt;
&lt;th&gt;TTL&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;@&lt;/td&gt;
&lt;td&gt;MX&lt;/td&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;td&gt;mailhost1.example.com&lt;/td&gt;
&lt;td&gt;45000&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;@&lt;/td&gt;
&lt;td&gt;MX&lt;/td&gt;
&lt;td&gt;20&lt;/td&gt;
&lt;td&gt;mailhost2.example.com&lt;/td&gt;
&lt;td&gt;45000&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The 'priority' numbers before the domains for these MX records indicate preference; the lower 'priority' value is preferred. The server will always try mailhost1 first because 10 is lower than 20. In the result of a message send failure, the server will default to mailhost2.&lt;/p&gt;

&lt;p&gt;The email service could also configure this MX record so that both servers have equal priority and receive an equal amount of mail:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;example.com&lt;/th&gt;
&lt;th&gt;record type:&lt;/th&gt;
&lt;th&gt;priority:&lt;/th&gt;
&lt;th&gt;value:&lt;/th&gt;
&lt;th&gt;TTL&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;@&lt;/td&gt;
&lt;td&gt;MX&lt;/td&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;td&gt;mailhost1.example.com&lt;/td&gt;
&lt;td&gt;45000&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;@&lt;/td&gt;
&lt;td&gt;MX&lt;/td&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;td&gt;mailhost2.example.com&lt;/td&gt;
&lt;td&gt;45000&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;This configuration enables the email provider to equally balance the load between the two servers.&lt;/p&gt;
&lt;h3&gt;
  
  
  NS record
&lt;/h3&gt;

&lt;p&gt;NS stands for ‘nameserver,’ and the nameserver record indicates which DNS server is authoritative for that domain (i.e. which server contains the actual DNS records. Basically, NS records tell the Internet where to go to find out a domain's IP address. A domain often has multiple NS records which can indicate primary and secondary nameservers for that domain. Without properly configured NS records, users will be unable to load a website or application.&lt;/p&gt;

&lt;p&gt;Here is an example of an NS record:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;example.com&lt;/th&gt;
&lt;th&gt;record type:&lt;/th&gt;
&lt;th&gt;value:&lt;/th&gt;
&lt;th&gt;TTL&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;@&lt;/td&gt;
&lt;td&gt;NS&lt;/td&gt;
&lt;td&gt;ns1.exampleserver.com&lt;/td&gt;
&lt;td&gt;21600&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Note that NS records can never point to a canonical name (CNAME) record&lt;/strong&gt;&lt;br&gt;
When NS records are updated, it may take several hours for the changes to be replicated throughout the DNS.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;There are other DNS records that i didn't cover which will be included in the links below.&lt;/em&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Useful shell commands
&lt;/h2&gt;

&lt;p&gt;You may need to install network utils and packages before running the commands below.&lt;/p&gt;
&lt;h3&gt;
  
  
  nslookup
&lt;/h3&gt;

&lt;p&gt;A network tool for querying DNS to obtain information about domain names and IP addresses. While it's older and less feature-rich than dig, it's available on many systems and provides basic DNS lookup capabilities.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;nslookup - brings the intera­ctive mode
&amp;gt; [domain] - query dns server for domain
&amp;gt; [ip_ad­dress] - reverse dns lookup
&amp;gt; set type=x - determines the type of DNS record that the DNS server will use to answer the query (x = DNS record type)
&amp;gt; set recursive - query other DNS servers if the default server does not have the inform­ation
&amp;gt; ls -a domain - list all canonical (true) names and aliases in domain
&amp;gt; ls -d domain - list all available records for domain.
&amp;gt; ls -t [type] domain - list all DNS TYPE records for domain
&amp;gt; exit - quit the intera­ctive mode
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Example
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ nslookup # Open nslookup interactive mode
&amp;gt; google.com
Server:     172.20.10.1
Address:    172.20.10.1#53

Non-authoritative answer:
Name:   google.com
Address: 172.217.20.174

&amp;gt; set type=AAAA # Set AAAA type for next queries (IPv6)
&amp;gt; google.com
Server:     172.20.10.1
Address:    172.20.10.1#53

Non-authoritative answer:
google.com  has AAAA address 2a00:1450:4007:80c::200e
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  dig
&lt;/h3&gt;

&lt;p&gt;A versatile DNS (Domain Name System) tool for querying DNS information, providing detailed responses, and supporting various query types. It offers extensive options and is commonly used for troubleshooting and DNS analysis.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;dig [domain] - query dns server for name
dig +short [domain] - short form of query output
dig [DNS_r­ecord] [domain] - query dns for given DNS record
dig -x [ip_ad­dress] - reverse dns lookup
dig @names­erver [domain] - query different name server
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Example
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ dig @8.8.8.8 +short google.com
&amp;gt;&amp;gt; 216.58.214.174
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  whois
&lt;/h3&gt;

&lt;p&gt;Checks inform­ation about ownership of a domain name&lt;br&gt;
&lt;code&gt;whois [domain] - querying databases that store the registered users or assignees, such as a domain name, an IP addresses&lt;/code&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  host
&lt;/h3&gt;

&lt;p&gt;A simple command-line utility for DNS lookups, capable of translating domain names to IP addresses and vice versa. It provides basic DNS information in a straightforward format, suitable for quick queries and basic troubleshooting.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;host [domain] - query dns server for domain
host [ip_ad­dress] - reverse dns lookup
host -t [DNS_r­ecord] [domain] - query dns for given DNS record
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Example
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ host youtube.com
&amp;gt;&amp;gt; youtube.com has address 142.250.201.174
   youtube.com has IPv6 address 2a00:1450:4007:80e::200e
   youtube.com mail is handled by 0 smtp.google.com.

$ host -t A youtube.com
&amp;gt;&amp;gt; youtube.com has address 216.58.214.174

$ host -t NS youtube.com
&amp;gt;&amp;gt; youtube.com name server ns2.google.com.
   youtube.com name server ns4.google.com.
   youtube.com name server ns1.google.com.
   youtube.com name server ns3.google.com.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  ping
&lt;/h3&gt;

&lt;p&gt;A ping measures the latency of a connection for a target location. For demonstration purposes, I’ll run a ping test using 8.8.8.8, Google’s public DNS address.&lt;/p&gt;

&lt;h4&gt;
  
  
  Example
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ ping 8.8.8.8
PING 8.8.8.8 (8.8.8.8): 56 data bytes
64 bytes from 8.8.8.8: icmp_seq=0 ttl=116 time=90.834 ms
64 bytes from 8.8.8.8: icmp_seq=1 ttl=116 time=48.649 ms
64 bytes from 8.8.8.8: icmp_seq=2 ttl=116 time=47.372 ms
--- 8.8.8.8 ping statistics ---
3 packets transmitted, 3 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 47.372/62.285/90.834/20.194 ms
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  traceroute or tracert
&lt;/h3&gt;

&lt;p&gt;A traceroute traces a packet’s path, from the starting point to the destination.&lt;/p&gt;

&lt;h4&gt;
  
  
  Example
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ traceroute google.com
&amp;gt;&amp;gt; traceroute to google.com (142.250.178.142), 64 hops max, 52 byte packets
 1  172.20.10.1 (172.20.10.1)  6.461 ms  3.192 ms  2.537 ms
 2  * * *
 3  * 192.168.4.30 (192.168.4.30)  62.968 ms  34.551 ms
 4  192.168.255.19 (192.168.255.19)  43.909 ms  33.963 ms  40.175 ms
 5  194.149.185.144 (194.149.185.144)  24.554 ms  33.511 ms  39.744 ms
 6  194.149.173.32 (194.149.173.32)  39.917 ms  48.690 ms  32.094 ms
 7  * * 194.149.166.22 (194.149.166.22)  63.474 ms
 8  194.149.166.62 (194.149.166.62)  29.755 ms  38.763 ms  40.086 ms
 9  72.14.221.62 (72.14.221.62)  41.002 ms  41.752 ms
    72.14.211.26 (72.14.211.26)  47.443 ms
10  108.170.245.1 (108.170.245.1)  38.538 ms
    108.170.244.193 (108.170.244.193)  54.826 ms  36.586 ms
11  142.251.64.131 (142.251.64.131)  39.879 ms  34.754 ms
    142.251.64.129 (142.251.64.129)  38.454 ms
12  142.251.64.129 (142.251.64.129)  42.599 ms
    142.251.64.131 (142.251.64.131)  31.373 ms
    108.170.244.241 (108.170.244.241)  45.710 ms
13  par21s22-in-f14.1e100.net (142.250.178.142)  29.977 ms
    209.85.251.179 (209.85.251.179)  32.639 ms
    par21s22-in-f14.1e100.net (142.250.178.142)  38.448 ms
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;The packet has gone through 13 routers in order to reach the final destination&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Useful links
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;a href="https://howdns.works/" rel="noopener noreferrer"&gt;Simplified explanation of how DNS works animated&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://constellix.com/other/dns-records-cheat-sheet" rel="noopener noreferrer"&gt;DNS Records cheatsheet&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://networkwalks.com/wp-content/uploads/2020/03/DNS-part-1-notes-cheatsheet-network-walks.pdf" rel="noopener noreferrer"&gt;DNS Mechanism cheatsheet&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://cheatography.com/janek/cheat-sheets/dns/" rel="noopener noreferrer"&gt;DNS cheatsheet&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.cloudflare.com/learning/dns/what-is-dns/" rel="noopener noreferrer"&gt;DNS Overview&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

</description>
    </item>
    <item>
      <title>How DNS works - Part 1</title>
      <dc:creator>Houssam Bourkane</dc:creator>
      <pubDate>Wed, 27 Dec 2023 15:13:27 +0000</pubDate>
      <link>https://dev.to/houssambourkane/how-dns-works-part-1-1bcg</link>
      <guid>https://dev.to/houssambourkane/how-dns-works-part-1-1bcg</guid>
      <description>&lt;p&gt;The Domain Name System (DNS) functions as the Internet's equivalent of a phonebook. When humans seek information online, they use domain names such as nytimes.com. However, web browsers communicate with &lt;strong&gt;Internet Protocol (IP) addresses&lt;/strong&gt;. DNS plays a crucial role by translating domain names into corresponding IP addresses. The DNS lookup takes place seamlessly in the background for the web browser, requiring no user interaction beyond the initial request from the computer. But let's see how it works.&lt;/p&gt;

&lt;h3&gt;
  
  
  How DNS works in the background
&lt;/h3&gt;

&lt;p&gt;When you type a domain name in the browser, the first thing that your DNS resolver look for before reaching DNS servers is checking if there is a match in your :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Browser DNS cache&lt;/strong&gt; : for example in chrome you can check the DNS cache on &lt;em&gt;chrome://net-internals/#dns&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Host file&lt;/strong&gt; : located in &lt;em&gt;/etc/hosts&lt;/em&gt; on Linux and macOS.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If no match is found, it will try to resolve the domain name through a &lt;strong&gt;DNS lookup&lt;/strong&gt;, there are 4 DNS servers involved :&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;DNS Recursor&lt;/strong&gt;: Imagine the DNS recursor as a helpful librarian in a library. When you ask this librarian (server) to find a specific book (IP address) for you, it gets queries from your computer (through applications like web browsers). The librarian, or DNS recursor, then makes additional requests to fulfill your request for information.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Root Nameserver&lt;/strong&gt;: Think of the root server as the first guide in a library that helps you find the right section of books. It's like an index pointing to different racks of books. The root server is the starting point for translating human-readable names (like website addresses) into IP addresses.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;TLD Nameserver&lt;/strong&gt;: Picture the top-level domain (TLD) server as a specific section of books in a library. It's like a particular rack. This server is the next step in the search for a specific IP address, and it handles the last part of a website address (like "com" in example.com).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Authoritative Nameserver&lt;/strong&gt;: Envision the authoritative nameserver as a dictionary in a library, where a specific name (hostname) can be translated into its definition (IP address). This nameserver is the final stop in the query. If it has the information you're looking for, it returns the IP address to the DNS recursor (the librarian) that initially made the request.&lt;/p&gt;

&lt;h2&gt;
  
  
  The 8 steps in a DNS lookup:
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;A user types ‘example.com’ into a web browser and the query travels into the Internet and is received by a &lt;strong&gt;DNS recursive resolver&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;The resolver then queries a &lt;strong&gt;DNS root nameserver&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;The root server then responds to the resolver with the address of a &lt;strong&gt;Top Level Domain (TLD) DNS server&lt;/strong&gt; (such as .com or .net), which stores the information for its domains. When searching for example.com, our request is pointed toward the .com TLD.&lt;/li&gt;
&lt;li&gt;The resolver then makes a request to the .com TLD.&lt;/li&gt;
&lt;li&gt;The TLD server then responds with the IP address of the &lt;strong&gt;Authoritative nameserver&lt;/strong&gt;, example.com.&lt;/li&gt;
&lt;li&gt;Lastly, the recursive resolver sends a query to the &lt;strong&gt;Authoritative nameserver&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;The IP address for example.com is then returned to the resolver from the &lt;strong&gt;Authoritative nameserver&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;The DNS resolver then responds to the web browser with the IP address of the domain requested initially.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Once the 8 steps of the DNS lookup have returned the IP address for example.com, the browser is able to make the request for the web page:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The browser makes a HTTP request to the IP address.&lt;/li&gt;
&lt;li&gt;The server at that IP returns the webpage to be rendered in the browser.&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>dns</category>
      <category>networking</category>
      <category>devops</category>
    </item>
  </channel>
</rss>
