<?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: Chinaza Otumba</title>
    <description>The latest articles on DEV Community by Chinaza Otumba (@otumba).</description>
    <link>https://dev.to/otumba</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%2F695367%2Ffdd89e0f-ba8e-4f59-8bf1-e968545aa5cd.png</url>
      <title>DEV Community: Chinaza Otumba</title>
      <link>https://dev.to/otumba</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/otumba"/>
    <language>en</language>
    <item>
      <title>How to Create Your First API with Python, Flask and Azure</title>
      <dc:creator>Chinaza Otumba</dc:creator>
      <pubDate>Mon, 03 Feb 2025 05:02:30 +0000</pubDate>
      <link>https://dev.to/otumba/how-to-create-your-first-api-with-python-flask-and-azure-1bef</link>
      <guid>https://dev.to/otumba/how-to-create-your-first-api-with-python-flask-and-azure-1bef</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;APIs (&lt;a href="https://www.ibm.com/topics/api" rel="noopener noreferrer"&gt;Application Programming Interfaces&lt;/a&gt;) are the backbone of modern software development, enabling different applications to communicate with each other efficiently. They allow seamless data exchange between systems, automating processes that would otherwise require manual intervention. From fetching real-time weather data to processing payments and integrating third-party services, APIs are essential tools for developers.&lt;/p&gt;

&lt;p&gt;In this beginner-friendly guide, we will create a simple API using &lt;a href="https://www.python.org/" rel="noopener noreferrer"&gt;Python&lt;/a&gt; and &lt;a href="https://flask.palletsprojects.com/" rel="noopener noreferrer"&gt;Flask&lt;/a&gt; a lightweight and easy-to-use web framework for Python that allows developers to create APIs and web applications quickly. This API will take a number as input and return some basic properties, such as whether it is &lt;strong&gt;even or odd&lt;/strong&gt;, and its &lt;strong&gt;square&lt;/strong&gt;. We will also deploy the API so that it can be accessed from anywhere.&lt;/p&gt;




&lt;h2&gt;
  
  
  Understanding APIs
&lt;/h2&gt;

&lt;p&gt;Before diving into the implementation, let’s take a step back and understand APIs at a higher level.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is an API?
&lt;/h2&gt;

&lt;p&gt;An API acts as a bridge between different software applications, allowing them to communicate with each other. It acts as a middleman, handling requests and responses between a client (like your phone or a website) and a server (where data or services live). For &lt;a href="https://www.postman.com/what-is-an-api/#real-world-examples-of-apis:~:text=What%20are%20some%20real%2Dworld%20examples%20of%20APIs%3F" rel="noopener noreferrer"&gt;example&lt;/a&gt;, you walk into a coffee shop and order a latte. You don’t go behind the counter and make it yourself—you just tell the barista what you want.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Here’s how an API works in this scenario:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You (the client) order a latte.&lt;/li&gt;
&lt;li&gt;The barista (API) takes your order and communicates it to the kitchen (server).&lt;/li&gt;
&lt;li&gt;The kitchen (server) makes your latte.&lt;/li&gt;
&lt;li&gt;The barista (API) brings it back to you.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You don’t need to know how the coffee is brewed or what machine they use—you just get your latte.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How This Relates to APIs:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The barista is the API—they handle requests and deliver responses.&lt;/li&gt;
&lt;li&gt;The kitchen is the backend server where all the work happens.&lt;/li&gt;
&lt;li&gt;The customer (you) is the client making a request.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;APIs help different apps and services interact without knowing the complex inner workings—just like you don’t need to be a barista to order coffee!&lt;/p&gt;

&lt;h2&gt;
  
  
  API architectural styles
&lt;/h2&gt;

&lt;p&gt;APIs often use &lt;strong&gt;JSON&lt;/strong&gt; or &lt;strong&gt;XML&lt;/strong&gt; format to send and receive data and APIs can be categorized into various &lt;a href="https://www.postman.com/what-is-an-api/#api-architectural-styles:~:text=What%20are%20the%20most%20common%20API%20architectural%20styles%3F" rel="noopener noreferrer"&gt;architectural styles&lt;/a&gt;, including &lt;strong&gt;RESTful APIs&lt;/strong&gt;, &lt;strong&gt;GraphQL APIs&lt;/strong&gt;, and &lt;strong&gt;SOAP APIs&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;They also follow a set of rules called HTTP methods, such as::&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;GET&lt;/code&gt; – Retrieve data.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;POST&lt;/code&gt; – Send data to create a new resource.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;PUT&lt;/code&gt; – Update an existing resource.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;DELETE&lt;/code&gt; – Remove a resource.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In this guide, we will use the &lt;code&gt;GET&lt;/code&gt; method to allow users to request information about a number.&lt;/p&gt;




&lt;h2&gt;
  
  
  Project Overview
&lt;/h2&gt;

&lt;p&gt;Our API will:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Accept a number as input via a &lt;strong&gt;GET&lt;/strong&gt; request.&lt;/li&gt;
&lt;li&gt;Check if the number is &lt;strong&gt;even or odd&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Calculate the &lt;strong&gt;square&lt;/strong&gt; of the number.&lt;/li&gt;
&lt;li&gt;Return results in &lt;strong&gt;JSON format&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Be deployed online using &lt;strong&gt;&lt;a href="https://azure.microsoft.com/en-us/products/app-service/" rel="noopener noreferrer"&gt;Azure App Services&lt;/a&gt;&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;




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

&lt;p&gt;Before starting, ensure you have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://www.python.org/downloads/" rel="noopener noreferrer"&gt;Python 3+&lt;/a&gt;&lt;/strong&gt; installed.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://flask.palletsprojects.com/en/2.0.x/installation/" rel="noopener noreferrer"&gt;Flask&lt;/a&gt;&lt;/strong&gt; installed (&lt;code&gt;pip install flask&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;&lt;a href="https://github.com/" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;&lt;/strong&gt; account to host the project.&lt;/li&gt;
&lt;li&gt;An &lt;strong&gt;&lt;a href="https://azure.microsoft.com/" rel="noopener noreferrer"&gt;Azure&lt;/a&gt;&lt;/strong&gt; account for deployment.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Step 1: Setting Up the Project
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt; Create a project directory:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   &lt;span class="nb"&gt;mkdir &lt;/span&gt;simple-api &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;cd &lt;/span&gt;simple-api
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt; Install Flask:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   pip &lt;span class="nb"&gt;install &lt;/span&gt;flask
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Step 2: Implementing the API
&lt;/h2&gt;

&lt;p&gt;Create a Python file (&lt;code&gt;app.py&lt;/code&gt;) and add the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;flask&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Flask&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;jsonify&lt;/span&gt;

&lt;span class="n"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Flask&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;__name__&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nd"&gt;@app.route&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;/api/number-info&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;methods&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;GET&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;number_info&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="n"&gt;num&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;number&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;num&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;num&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;isdigit&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;jsonify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;error&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Invalid input. Please provide a valid number.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}),&lt;/span&gt; &lt;span class="mi"&gt;400&lt;/span&gt;

    &lt;span class="n"&gt;num&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;num&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;number&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;num&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;even_or_odd&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;even&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;num&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;odd&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;square&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;num&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;jsonify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;__main__&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;host&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;0.0.0.0&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;5000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Step 3: Running the API Locally
&lt;/h2&gt;

&lt;p&gt;Save the file and start the API:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python app.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsfj0d0hq8cuq9u0uifcy.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%2Fsfj0d0hq8cuq9u0uifcy.png" alt="local" width="519" height="178"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Test it using:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="s2"&gt;"http://127.0.0.1:5000/api/number-info?number=4"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expected Response:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"number"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"even_or_odd"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"even"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"square"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjvc6yludhjfz315yk1d0.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%2Fjvc6yludhjfz315yk1d0.png" alt="Result" width="553" height="243"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 4: Deploying the API to Azure
&lt;/h2&gt;

&lt;p&gt;You can deploy this API using &lt;a href="https://learn.microsoft.com/en-us/azure/app-service/quickstart-python?tabs=flask" rel="noopener noreferrer"&gt;Azure App Services&lt;/a&gt; by following these steps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Install Azure CLI:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   pip &lt;span class="nb"&gt;install &lt;/span&gt;azure-cli
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Log in to Azure:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   az login
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Create a resource group (if not already created):
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   az group create &lt;span class="nt"&gt;--name&lt;/span&gt; myResourceGroup &lt;span class="nt"&gt;--location&lt;/span&gt; eastus
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Deploy the API directly:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   az webapp up &lt;span class="nt"&gt;--name&lt;/span&gt; simple-api &lt;span class="nt"&gt;--resource-group&lt;/span&gt; myResourceGroup &lt;span class="nt"&gt;--runtime&lt;/span&gt; PYTHON:3.8
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5uhpmj3ttvgbm0l88v4d.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%2F5uhpmj3ttvgbm0l88v4d.png" alt="Azure deployment" width="716" height="578"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Test it using the URL provided:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="s2"&gt;"http://127.0.0.1:5000/api/number-info?number=4"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F510g0fb04ftjk355ptxk.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%2F510g0fb04ftjk355ptxk.png" alt="Azure URL result" width="556" height="296"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;(Optional) If using GitHub, push your code to a repository(replace my repo URL with yours):
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"# pythonapi1"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; README.md
   git init
   git add README.md
   git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"first commit"&lt;/span&gt;
   git branch &lt;span class="nt"&gt;-M&lt;/span&gt; main
   git remote add origin https://github.com/Obs3rve/pythonapi1.git
   git push &lt;span class="nt"&gt;-u&lt;/span&gt; origin main
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






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

&lt;p&gt;This guide introduced the fundamentals of building an API using Python and Flask. We created a simple API that accepts a number, determines if it is even or odd, and calculates its square. Finally, we deployed it on Azure.&lt;/p&gt;

&lt;p&gt;In the next guide, we will enhance this API by allowing it to analyze numbers in more depth. The API will not only check if a number is prime but also return additional interesting mathematical properties about it, along with a fun fact.&lt;/p&gt;

&lt;p&gt;Stay tuned for the next guide! 🚀&lt;/p&gt;

</description>
      <category>python</category>
      <category>api</category>
      <category>tutorial</category>
      <category>azure</category>
    </item>
    <item>
      <title>Setting Up an NGINX Web Server on Azure: My DevOps HNG Stage 0 Experience</title>
      <dc:creator>Chinaza Otumba</dc:creator>
      <pubDate>Mon, 03 Feb 2025 02:56:35 +0000</pubDate>
      <link>https://dev.to/otumba/setting-up-an-nginx-web-server-on-azure-my-devops-hng-stage-0-experience-1i0k</link>
      <guid>https://dev.to/otumba/setting-up-an-nginx-web-server-on-azure-my-devops-hng-stage-0-experience-1i0k</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;As part of the HNG DevOps internship, I completed &lt;strong&gt;Stage 0: NGINX Configuration&lt;/strong&gt; by installing and configuring an NGINX web server on an Ubuntu machine. This blog post provides a guide, detailing my approach, challenges faced, solutions implemented, and key takeaways from this task.&lt;/p&gt;

&lt;h2&gt;
  
  
  Task Overview
&lt;/h2&gt;

&lt;p&gt;The objective of this task was to:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Install and configure NGINX on an Ubuntu server.&lt;/li&gt;
&lt;li&gt;Replace the default NGINX page with a custom HTML file displaying:
&lt;code&gt;
Welcome to DevOps Stage 0 - [Your Name]/[SlackName]
&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Ensure the page is accessible via a public IP address.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Step-by-Step Approach
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1️⃣ Setting Up the Ubuntu Server on Azure
&lt;/h3&gt;

&lt;p&gt;Since the task required a fresh Ubuntu instance, I deployed an &lt;strong&gt;Ubuntu 22.04&lt;/strong&gt; virtual machine on &lt;strong&gt;Microsoft Azure&lt;/strong&gt; following these steps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Logged into the &lt;a href="https://portal.azure.com/" rel="noopener noreferrer"&gt;Azure Portal&lt;/a&gt;. &lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdpvpgomfvcwsoqno4njh.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%2Fdpvpgomfvcwsoqno4njh.png" alt="Azure portal" width="800" height="409"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Navigated to &lt;strong&gt;Virtual Machines&lt;/strong&gt; and selected &lt;strong&gt;Create &amp;gt; Azure Virtual Machine&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2zlc0apotdjv11ouvh6s.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%2F2zlc0apotdjv11ouvh6s.png" alt="Virtual machine" width="800" height="407"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Selected &lt;strong&gt;Ubuntu 22.04 LTS&lt;/strong&gt; as the OS and Configured the machine.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdv5uds9bowfzzjo6rlbs.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%2Fdv5uds9bowfzzjo6rlbs.png" alt="Creating virtual machine in azure portal" width="800" height="413"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Configured &lt;strong&gt;Inbound Port Rules&lt;/strong&gt;, initially allowing only SSH (port 22), which later caused accessibility issues.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkcyyx96rmczovdwdgbo2.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%2Fkcyyx96rmczovdwdgbo2.png" alt="inbound port" width="800" height="282"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;After deployment, copied the &lt;strong&gt;Public IP Address&lt;/strong&gt; and connected via SSH:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   ssh username@my-server-ip
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2️⃣ Updating the System
&lt;/h3&gt;

&lt;p&gt;Before installing any software, I updated the system to ensure the latest security patches and package versions:&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;sudo &lt;/span&gt;apt update &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;sudo &lt;/span&gt;apt upgrade &lt;span class="nt"&gt;-y&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm5l88a8rg8xfrhzde4ou.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%2Fm5l88a8rg8xfrhzde4ou.png" alt="system update" width="715" height="384"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  3️⃣ Installing NGINX
&lt;/h3&gt;

&lt;p&gt;To install and verify NGINX:&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;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;nginx &lt;span class="nt"&gt;-y&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl status nginx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the service isn't running, start it manually but in case I didn't need to do this:&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;sudo &lt;/span&gt;systemctl start nginx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To ensure NGINX starts automatically at boot, enable the service:&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;sudo &lt;/span&gt;systemctl &lt;span class="nb"&gt;enable &lt;/span&gt;nginx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe9e6ojhoxugzo6vxcra0.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%2Fe9e6ojhoxugzo6vxcra0.png" alt="NGINX status" width="642" height="260"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  4️⃣ Configuring the Custom Web Page
&lt;/h3&gt;

&lt;p&gt;To meet the task requirements, I modified the &lt;strong&gt;index.html&lt;/strong&gt; file:&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;sudo &lt;/span&gt;nano /var/www/html/index.html
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Replaced the default content with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;html&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;title&amp;gt;&lt;/span&gt;Welcome&lt;span class="nt"&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;h1&amp;gt;&lt;/span&gt;Welcome to DevOps Stage 0 - [Your Name]/[SlackName]&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After saving the file, I restarted NGINX:&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;sudo &lt;/span&gt;systemctl restart nginx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx9x135z5pjzthq4twfec.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%2Fx9x135z5pjzthq4twfec.png" alt="custom html" width="651" height="175"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  5️⃣ Configuring Inbound Port Rules on Azure
&lt;/h3&gt;

&lt;p&gt;Initially, I couldn't access the web page due to inbound rule restrictions. I resolved this by allowing HTTP (port 80) traffic.&lt;/p&gt;

&lt;h4&gt;
  
  
  Using the Azure Portal:
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;Navigated to &lt;strong&gt;Virtual Machines&lt;/strong&gt; &amp;gt; Selected my VM &amp;gt; &lt;strong&gt;Networking&lt;/strong&gt; &amp;gt; Network settins. &lt;/li&gt;
&lt;li&gt;Clicked &lt;strong&gt;Create port rule&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Set &lt;strong&gt;Destination Port&lt;/strong&gt; to &lt;code&gt;80&lt;/code&gt;, &lt;strong&gt;Protocol&lt;/strong&gt; to &lt;code&gt;TCP&lt;/code&gt;, and &lt;strong&gt;Action&lt;/strong&gt; to &lt;code&gt;Allow&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Save the changes.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6h3ruc0km5m4zq13i235.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%2F6h3ruc0km5m4zq13i235.png" alt="port rule" width="800" height="1095"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  6️⃣ Testing the Web Page
&lt;/h3&gt;

&lt;p&gt;I confirmed the setup by opening a browser and visiting:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;http://my-server-ip:80
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The custom message successfully displayed, indicating a successful configuration. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7hddjijw1tmlhtxnqkrb.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%2F7hddjijw1tmlhtxnqkrb.png" alt="custom HTML on browser" width="800" height="309"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Challenges &amp;amp; Solutions
&lt;/h2&gt;

&lt;h3&gt;
  
  
  🔴 Challenge 1: Choosing the Right Server and Public IP Availability
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;issue&lt;/strong&gt;: The first challenge I faced was deciding which server to use for this project. Initially, I considered using my &lt;a href="https://everythingdevops.dev/step-by-step-guide-creating-a-kubernetes-cluster-on-raspberry-pi-5-with-k3s/" rel="noopener noreferrer"&gt;Raspberry Pi&lt;/a&gt;, but I encountered difficulties with obtaining a stable public IP address due to ISP restrictions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution:&lt;/strong&gt; To overcome this, I opted for Microsoft Azure, which provides a reliable public IP by default, ensuring seamless deployment and accessibility.&lt;/p&gt;

&lt;h3&gt;
  
  
  🔴 Challenge 2: Configuring Inbound Ports on Azure
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Issue:&lt;/strong&gt; I initially allowed only SSH traffic, preventing access to NGINX.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution:&lt;/strong&gt; I modified the network security group settings to allow inbound traffic on port 80 via both the Azure portal and CLI. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi8prtxsrtgrnihgq90k7.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%2Fi8prtxsrtgrnihgq90k7.png" alt="Port rule" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Key Takeaways
&lt;/h2&gt;

&lt;p&gt;This project provided invaluable hands-on experience with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Cloud Infrastructure&lt;/strong&gt;: Setting up an Ubuntu VM on &lt;strong&gt;Azure&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Linux Server Management&lt;/strong&gt;: Handling SSH connections and package management.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Web Server Configuration&lt;/strong&gt;: Installing and managing &lt;strong&gt;NGINX&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Networking &amp;amp; Security&lt;/strong&gt;: Configuring inbound rules to allow web traffic.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Troubleshooting&lt;/strong&gt;: Debugging issues related to firewall rules and NGINX status.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How This Task Helps My DevOps Journey
&lt;/h2&gt;

&lt;p&gt;Completing this task gave me practical experience in &lt;strong&gt;Linux system administration&lt;/strong&gt;, &lt;strong&gt;networking&lt;/strong&gt;, and &lt;strong&gt;troubleshooting&lt;/strong&gt;—fundamental DevOps skills. I also improved my ability to document configurations and resolve real-world deployment challenges.&lt;/p&gt;

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

&lt;p&gt;This experience improved my ability to &lt;strong&gt;set up, configure, and troubleshoot&lt;/strong&gt; web servers while reinforcing best practices for cloud security and networking. Looking forward to more HNG tasks! 💪&lt;/p&gt;

</description>
      <category>devops</category>
      <category>nginx</category>
      <category>azure</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Beginners Guide to ReactJS — Data handling Using Props and State</title>
      <dc:creator>Chinaza Otumba</dc:creator>
      <pubDate>Sun, 04 Feb 2024 10:08:00 +0000</pubDate>
      <link>https://dev.to/otumba/beginners-guide-to-reactjs-data-handling-using-props-and-state-2mgf</link>
      <guid>https://dev.to/otumba/beginners-guide-to-reactjs-data-handling-using-props-and-state-2mgf</guid>
      <description>&lt;h3&gt;
  
  
  Data Handling in React
&lt;/h3&gt;

&lt;p&gt;If you’re reading this, you’ve already done your homework and are probably interested in understanding more about &lt;strong&gt;Reactjs&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;So let’s cut to the chase: how can data be handled in react using &lt;strong&gt;Props&lt;/strong&gt; and &lt;strong&gt;States?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;ReactJS is one of the most popular JavaScript libraries for building user interfaces and it was created by Facebook.&lt;/p&gt;

&lt;p&gt;There are two major ways data can be managed or handled in React and they are Prop and State. Understanding how they both work will be a huge leap toward learning React.&lt;/p&gt;

&lt;p&gt;In this article, we are going to discuss&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; Briefly about components.&lt;/li&gt;
&lt;li&gt; The characteristics of both prop and state.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Before diving into this let’s briefly discuss a key part of react, Components.&lt;/p&gt;

&lt;h3&gt;
  
  
  What are Components?
&lt;/h3&gt;

&lt;p&gt;A component in react lets you split the elements or sections of your UI into independent, reusable pieces, and think about each piece separately.&lt;/p&gt;

&lt;p&gt;An example would be if we were to develop Instagram, the like button, the comments, the share, the feed all would be individual components.&lt;/p&gt;

&lt;p&gt;The components of React will get rendered or displayed if there is any change in state or props. Every component has a state and it’s only used to store values while Props are used to pass data from parent component to child component.&lt;/p&gt;

&lt;h3&gt;
  
  
  Parent and Child
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1663998449654%2FD8h9c9G-I.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1663998449654%2FD8h9c9G-I.jpeg" alt="Photo by nappy from Pexels"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You’ve probably heard people say things like you look so much like your dad, mom or even your grandparents. This is cause the child inherited their parent’s features such as hair color, complexion, etc.&lt;/p&gt;

&lt;p&gt;I don’t think you’ve heard someone say the parent inherited some features from the child.&lt;/p&gt;

&lt;p&gt;Now let’s relate it to this article.&lt;/p&gt;

&lt;p&gt;As mentioned earlier data in Reactjs flows from parent to child as parents can’t inherit from their children&lt;/p&gt;

&lt;p&gt;The parent passes the information down as “props”, (the properties) to the child file.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Keep reading, props are discussed better later in the article.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Functional Component
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;function Mango() {&lt;/p&gt;

&lt;p&gt;return &lt;/p&gt;
&lt;h1&gt;Hello, I love Mangos.&lt;/h1&gt;;

&lt;p&gt;}&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;These types of components are called “function components or functional components” because they are JavaScript functions.&lt;/p&gt;

&lt;p&gt;Functional components are shorter and the implementation of setState() in functional-based components is shorter, easier, and with less boilerplate code. They are also easier to understand.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;More on setState() later in the article&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Class Component
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;import React from “react”;&lt;/p&gt;

&lt;p&gt;class Mango extends React.Component {&lt;/p&gt;

&lt;p&gt;render() {&lt;/p&gt;

&lt;p&gt;return &lt;/p&gt;
&lt;h1&gt;Hello, I love Mangos.&lt;/h1&gt;;

&lt;p&gt;}&lt;/p&gt;

&lt;p&gt;}&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;As seen in the above code all class components must include the extends React.Component statement. This statement creates an inheritance to React.Component, and gives your component access to React.Component’s functions.&lt;/p&gt;

&lt;p&gt;Now we understand what components are, let us get into Props.&lt;/p&gt;

&lt;h3&gt;
  
  
  What are Props?
&lt;/h3&gt;

&lt;p&gt;Props simply mean properties and they are generally used to pass data from one component to another or from one parent component to its child component.&lt;/p&gt;

&lt;h3&gt;
  
  
  Characteristics of Props:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt; Props pass from parent to child component as React’s data flow between components is uni-directional.&lt;/li&gt;
&lt;li&gt; Props are set for the children.&lt;/li&gt;
&lt;li&gt; Props are read-only.&lt;/li&gt;
&lt;li&gt; Props are used in both functional and class components.&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  “Props are Read-Only”
&lt;/h4&gt;

&lt;p&gt;Props are immutable. Meaning once props are set they can not be changed or modified.&lt;/p&gt;

&lt;p&gt;A component must never modify its own prop even if it was declared as a function or a class.&lt;/p&gt;

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

&lt;blockquote&gt;
&lt;p&gt;Consider this &lt;em&gt;sum&lt;/em&gt; function:&lt;/p&gt;

&lt;p&gt;function sum(a, b) {&lt;/p&gt;

&lt;p&gt;. return a + b;&lt;/p&gt;

&lt;p&gt;}&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Functions similar to the above are called “pure” because they do not attempt to change their inputs, and always return the same result for the same inputs.&lt;/p&gt;

&lt;h3&gt;
  
  
  State
&lt;/h3&gt;

&lt;p&gt;State is only used to store the internal values or property of a component, which affects that component only. When the state changes the component had to render again. Unlike prop, state can be modified but they cannot be passed from one component to the other. State should not be modified directly, it is modified with a special method called setState( ).&lt;/p&gt;

&lt;p&gt;Using the this.state.propertyname syntax you can refer to &lt;em&gt;state&lt;/em&gt; anywhere in the component.&lt;/p&gt;

&lt;p&gt;Characteristics of State:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; State is initialized inside the component’s constructor method.&lt;/li&gt;
&lt;li&gt; State typically can only be used in class components but with the introduction of React hooks can be used in functional components as well.&lt;/li&gt;
&lt;li&gt; State can not be accessed from outside of the component but the value can be passed via props.&lt;/li&gt;
&lt;/ol&gt;

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

&lt;blockquote&gt;
&lt;p&gt;class GreetingComponent extends React.Component {&lt;/p&gt;

&lt;p&gt;constructor(props) {&lt;/p&gt;

&lt;p&gt;super(props);&lt;/p&gt;

&lt;p&gt;this.state = { name: “Olajumoke” };&lt;/p&gt;

&lt;p&gt;}&lt;/p&gt;

&lt;p&gt;render() {&lt;/p&gt;

&lt;p&gt;return &lt;/p&gt;
&lt;h1&gt;Hello, {this.state.name}&lt;/h1&gt;;

&lt;p&gt;}&lt;/p&gt;

&lt;p&gt;}&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Let’s update the state variable using setState()&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;class GreetingComponent extends React.Component {&lt;/p&gt;

&lt;p&gt;constructor(props) {&lt;/p&gt;

&lt;p&gt;super(props);&lt;/p&gt;

&lt;p&gt;this.state = { name: “Olajumoke” };&lt;/p&gt;

&lt;p&gt;}&lt;/p&gt;

&lt;p&gt;componentDidMount() {&lt;/p&gt;

&lt;p&gt;// following code updates the state&lt;/p&gt;

&lt;p&gt;// your component will call the render method&lt;/p&gt;

&lt;p&gt;// so that your changes can be seen in your dom&lt;/p&gt;

&lt;p&gt;this.setState({ name: “Laurel” });&lt;/p&gt;

&lt;p&gt;}&lt;/p&gt;

&lt;p&gt;render() {&lt;/p&gt;

&lt;p&gt;return &lt;/p&gt;
&lt;h1&gt;Hello, {this.state.name}&lt;/h1&gt;;

&lt;p&gt;}&lt;/p&gt;

&lt;p&gt;}&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Quick Summary
&lt;/h3&gt;

&lt;p&gt;So far we have learnt a lot about &lt;em&gt;props&lt;/em&gt; and &lt;em&gt;states.&lt;/em&gt; We now know that &lt;em&gt;props&lt;/em&gt; cannot be changed while &lt;em&gt;states&lt;/em&gt; on the other hand can be changed using a special method called setState().&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>react</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Implementation of a Prototype Kubernetes-Based Cluster for Scalable Web-Based WordPress Deployment using K3s on Raspberry Pis</title>
      <dc:creator>Chinaza Otumba</dc:creator>
      <pubDate>Sun, 04 Feb 2024 09:19:54 +0000</pubDate>
      <link>https://dev.to/otumba/implementation-of-a-prototype-kubernetes-based-cluster-for-scalable-web-based-wordpress-deployment-using-k3s-on-raspberry-pis-1goe</link>
      <guid>https://dev.to/otumba/implementation-of-a-prototype-kubernetes-based-cluster-for-scalable-web-based-wordpress-deployment-using-k3s-on-raspberry-pis-1goe</guid>
      <description>&lt;p&gt;Welcome to an exhilarating journey where we unlock the secrets of building a scalable infrastructure using Kubernetes. In this comprehensive guide, we'll navigate the nuances of setting up a robust cluster to host a WordPress site. Buckle up as we explore the implementation process using five Raspberry Pis, a router, and a switch, with the lightweight K3s as our chosen Kubernetes distribution.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5svz6u8f9cjcfgw1uf27.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5svz6u8f9cjcfgw1uf27.jpeg" alt="PI Cluster Image" width="800" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting the Stage: Objectives
&lt;/h2&gt;

&lt;p&gt;Our primary goal is crystal clear – to create a powerhouse infrastructure that effortlessly scales to host a WordPress site. This guide will walk you through every twist and turn, from the initial Raspberry Pi setup to deploying and scaling your WordPress application.&lt;/p&gt;

&lt;p&gt;Before diving into the implementation, ensure you have the following:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Hardware:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Five Raspberry Pis(You can follow along with one Raspberry PI A similar setup can be found in this &lt;a href="https://youtu.be/X9fSMGkjtug?si=uO4kdF_pWGnpcUSu"&gt;youtube video&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Router and Switch&lt;/li&gt;
&lt;li&gt;SD Cards for Raspberry Pis&lt;/li&gt;
&lt;li&gt;Ethernet Cables&lt;/li&gt;
&lt;li&gt;Power Supply for Raspberry Pis&lt;/li&gt;
&lt;li&gt;External Drive (for storing disk images)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Software:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Win32 Disk Imager (for disk imaging)&lt;/li&gt;
&lt;li&gt;K3s binary for ARM architecture (compatible with Raspberry Pi)&lt;/li&gt;
&lt;li&gt;Raspberry Pi OS Lite 64-bit&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Knowledge:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Basic understanding of Linux environments&lt;/li&gt;
&lt;li&gt;Basic understanding of Kubernetes with essential commands&lt;/li&gt;
&lt;li&gt;Fundamental networking knowledge&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

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

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Setting Up Raspberry Pis&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;1.1 Hardware Preparation
&lt;/li&gt;
&lt;li&gt;1.2 Operating System Installation
&lt;/li&gt;
&lt;li&gt;1.3 Configuring Network Settings
&lt;/li&gt;
&lt;li&gt;1.4 Enabling SSH Access
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Configuring the Master Node&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;2.1 Installing K3s on the Master Node
&lt;/li&gt;
&lt;li&gt;2.2 Verifying K3s Installation
&lt;/li&gt;
&lt;li&gt;2.3 Configuring Master Node Components
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Setting Up Worker Nodes&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;3.1 Installing K3s on Worker Nodes
&lt;/li&gt;
&lt;li&gt;3.2 Joining Worker Nodes to the Cluster
&lt;/li&gt;
&lt;li&gt;3.3 Verifying Worker Node Status
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Network Configuration&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;4.1 Configuring Raspberry Pi Networking
&lt;/li&gt;
&lt;li&gt;4.2 Ensuring Network Connectivity
&lt;/li&gt;
&lt;li&gt;4.3 Troubleshooting Network Issues
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Persistent Volume Implementation&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;5.1 Creating Persistent Volumes
&lt;/li&gt;
&lt;li&gt;5.2 Configuring Persistent Volume Claims
&lt;/li&gt;
&lt;li&gt;5.3 Testing Persistent Volumes
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Deploying WordPress on Kubernetes&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;6.1 Creating WordPress Deployment YAML
&lt;/li&gt;
&lt;li&gt;6.2 Configuring Service for WordPress
&lt;/li&gt;
&lt;li&gt;6.3 Verifying WordPress Deployment
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Scaling the WordPress Deployment&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;7.1 Horizontal Pod Autoscaling
&lt;/li&gt;
&lt;li&gt;7.2 Testing Autoscaling
&lt;/li&gt;
&lt;li&gt;7.3 Analyzing Scalability
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Monitoring and Observability&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;8.1 Implementing Prometheus for Monitoring
&lt;/li&gt;
&lt;li&gt;8.2 Grafana Dashboard Configuration
&lt;/li&gt;
&lt;li&gt;8.3 Observing Cluster Metrics
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  1. Setting Up Raspberry Pis
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1.1 Hardware Preparation
&lt;/h3&gt;

&lt;p&gt;Before we dive into the technical details, let's ensure that we have everything ready. Power up your Raspberry Pis and ensure they are properly connected to the network.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcjudeg9fw793pc74njko.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcjudeg9fw793pc74njko.jpg" alt="PI Cluster showing the set up" width="800" height="1181"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  1.2 Operating System Installation
&lt;/h3&gt;

&lt;p&gt;The first step is to get the Raspberry Pi OS up and running. To do this, follow these steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Download the &lt;a href="https://www.raspberrypi.org/software/"&gt;Raspberry Pi Imager&lt;/a&gt; and install it on your computer.&lt;/li&gt;
&lt;li&gt;Insert the SD card into your computer using an SD card reader.&lt;/li&gt;
&lt;li&gt;Open the Raspberry Pi Imager and choose the Raspberry Pi OS Lite 64-bit version.&lt;/li&gt;
&lt;li&gt;Select the inserted SD card as the storage location.&lt;/li&gt;
&lt;li&gt;Click on "Write" to start the installation process.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Once the process is complete, eject the SD card safely and insert it into the Raspberry Pi.&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkmmcncc1wx6uxe3r6uj6.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkmmcncc1wx6uxe3r6uj6.jpeg" alt="Raspberry Pi Imager software" width="800" height="600"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  1.3 Configuring Raspberry Pi Networking
&lt;/h3&gt;

&lt;p&gt;Now, let's configure the network settings on each Raspberry Pi:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Boot up the Raspberry Pi:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Connect a monitor, keyboard, and mouse to the Raspberry Pi.&lt;/li&gt;
&lt;li&gt;Power it up and follow the on-screen instructions to set up the Raspberry Pi OS.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Open the Terminal:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Once the Raspberry Pi OS is booted, open the terminal.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Configure Network Settings:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use the following command to edit the network configuration file:
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt; &lt;span class="nb"&gt;sudo &lt;/span&gt;nano /etc/network/interfaces
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Update the file with your desired network settings. For example:&lt;br&gt;
&lt;/p&gt;

&lt;pre class="highlight shell"&gt;&lt;code&gt; auto eth0
 iface eth0 inet static
 address 192.168.1.2
 netmask 255.255.255.0
 gateway 192.168.1.1
&lt;/code&gt;&lt;/pre&gt;




&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Save and Exit:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Save the changes by pressing &lt;code&gt;Ctrl + X&lt;/code&gt;, then &lt;code&gt;Y&lt;/code&gt; to confirm, and finally &lt;code&gt;Enter&lt;/code&gt; to exit.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Restart the Network:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Restart the network interface to apply the changes:
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt; &lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl restart networking
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  1.4 Enabling SSH Access
&lt;/h3&gt;

&lt;p&gt;Enabling SSH on each Raspberry Pi is essential for remote access. Here's how you can do it:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Open the Raspberry Pi Configuration:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Run the following command:
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt; &lt;span class="nb"&gt;sudo &lt;/span&gt;raspi-config
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;Navigate to &lt;code&gt;Interfacing Options&lt;/code&gt; and enable &lt;code&gt;SSH&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Restart the Raspberry Pi:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;After enabling SSH, restart the Raspberry Pi to apply the changes:
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt; &lt;span class="nb"&gt;sudo &lt;/span&gt;reboot
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;With these steps completed, you've successfully set up the Raspberry Pis for further configuration.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Configuring the Master Node
&lt;/h2&gt;

&lt;h3&gt;
  
  
  2.1 Installing K3s on the Master Node
&lt;/h3&gt;

&lt;p&gt;Now, let's move on to configuring the master node. Follow these steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Log into the Master Pi:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Open a terminal or use SSH to log into the master Raspberry Pi.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Download and Install K3s:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use the following command to download and install K3s:
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt; curl &lt;span class="nt"&gt;-sfL&lt;/span&gt; https://get.k3s.io | sh -
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Verify K3s Installation:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Once the installation is&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;complete, verify that K3s is running:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; ```bash
 sudo k3s kubectl get nodes
 ```
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;During installation, I got this error&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbaqcmv0hotge4wfqkmdk.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbaqcmv0hotge4wfqkmdk.jpeg" alt="Error Screenshot" width="800" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Kubernetes requires “cgroup_memory=1 cgroup_enabled=memory” added to the cmdline.txt file of my pi’s for the installation to work. As this is missing the installation initially failed.&lt;/p&gt;

&lt;p&gt;After adding this, I was able to install Kubernetes on the master node&lt;/p&gt;

&lt;p&gt;￼&lt;/p&gt;

&lt;h3&gt;
  
  
  2.2 Configuring Master Node Components
&lt;/h3&gt;

&lt;p&gt;With K3s installed, configure the master node components:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Export Kubeconfig:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Export the Kubeconfig file to enable kubectl commands:
&lt;/li&gt;
&lt;/ul&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;/etc/rancher/k3s/k3s.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Check Nodes:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ensure that the master node is ready:
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt; &lt;span class="nb"&gt;sudo &lt;/span&gt;k3s kubectl get nodes
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx6rz9owc7an4tom239o1.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx6rz9owc7an4tom239o1.jpeg" alt="kubectl get nodes screenshot" width="800" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Install Helm:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Helm is a package manager for Kubernetes. Install Helm using:
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt; &lt;span class="nb"&gt;sudo &lt;/span&gt;snap &lt;span class="nb"&gt;install &lt;/span&gt;helm &lt;span class="nt"&gt;--classic&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Initialize Helm:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt; helm init
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Verify the Helm installation:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt; helm version
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With the master node configured, you're ready to proceed to the next stage.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Setting Up Worker Nodes
&lt;/h2&gt;

&lt;h3&gt;
  
  
  3.1 Installing K3s on Worker Nodes
&lt;/h3&gt;

&lt;p&gt;Expand your cluster by setting up worker nodes. Here's how:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Log into Each Worker Pi:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use SSH to log into each worker Raspberry Pi.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Download and Install K3s:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Similar to the master node, install K3s on each worker node:
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt; curl &lt;span class="nt"&gt;-sfL&lt;/span&gt; https://get.k3s.io | &lt;span class="nv"&gt;K3S_URL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;https://&amp;lt;master-node-ip&amp;gt;:6443 &lt;span class="nv"&gt;K3S_TOKEN&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&amp;lt;node-token&amp;gt; sh -
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Replace &lt;code&gt;&amp;lt;master-node-ip&amp;gt;&lt;/code&gt; with the IP of your master node and &lt;code&gt;&amp;lt;node-token&amp;gt;&lt;/code&gt; with the token obtained from the master node:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt; &lt;span class="nb"&gt;sudo cat&lt;/span&gt; /var/lib/rancher/k3s/server/node-token
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3.2 Joining Worker Nodes to the Cluster
&lt;/h3&gt;

&lt;p&gt;After installing K3s on each worker node, join them to the cluster:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Obtain Master Node Token:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;On the master node, retrieve the token:
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt; &lt;span class="nb"&gt;sudo cat&lt;/span&gt; /var/lib/rancher/k3s/server/node-token
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Join Worker to Cluster:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;On each worker node, join the cluster using the token:
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt; curl &lt;span class="nt"&gt;-sfL&lt;/span&gt; https://get.k3s.io | &lt;span class="nv"&gt;K3S_URL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;https://&amp;lt;master-node-ip&amp;gt;:6443 &lt;span class="nv"&gt;K3S_TOKEN&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&amp;lt;node-token&amp;gt; sh -
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  3.3 Verifying Worker Node Status
&lt;/h3&gt;

&lt;p&gt;Check if the worker nodes have successfully joined the cluster:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;On the Master Node:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Run the following command to verify the status of worker nodes:
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt; &lt;span class="nb"&gt;sudo &lt;/span&gt;k3s kubectl get nodes
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;Ensure all nodes are in the 'Ready' state.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7t8wl64ptwqi97zr44qr.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7t8wl64ptwqi97zr44qr.jpeg" alt="Node status" width="800" height="243"&gt;&lt;/a&gt;&lt;br&gt;
With the worker nodes in place, your Kubernetes cluster is shaping up. Now, let's delve into network configuration.&lt;/p&gt;
&lt;h2&gt;
  
  
  4. Network Configuration
&lt;/h2&gt;
&lt;h3&gt;
  
  
  4.1 Configuring Raspberry Pi Networking
&lt;/h3&gt;

&lt;p&gt;A well-configured network is crucial for the seamless operation of your Kubernetes cluster. Follow these steps to ensure optimal network settings:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Check Network Interfaces:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Verify the available network interfaces on each Raspberry Pi:
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt; ip a
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;Identify the primary network interface (e.g., eth0) for configuration.&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Edit Network Configuration File:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Open the network configuration file for editing:
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt; &lt;span class="nb"&gt;sudo &lt;/span&gt;nano /etc/network/interfaces
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Configure Static IP Address:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Add the following lines to set a static IP address (adjust values based on your network):
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; auto eth0
 iface eth0 inet static
 address 192.168.1.2
 netmask 255.255.255.0
 gateway 192.168.1.1
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;Save and exit the editor (press &lt;code&gt;Ctrl + X&lt;/code&gt;, then &lt;code&gt;Y&lt;/code&gt;, and &lt;code&gt;Enter&lt;/code&gt;).&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Restart Networking:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Apply the changes by restarting the network service:
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt; &lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl restart networking
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This can also be set up on your router. Irrespective of how you set the Static IPs this step is important as a change of IP while working can prevent the nodes from communicating with each other.&lt;/p&gt;

&lt;p&gt;The screenshot below shows a change in the status of my pods with this being the cause.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5fd6mev0craqz4m3ewzl.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5fd6mev0craqz4m3ewzl.jpeg" alt="Status error" width="800" height="159"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Using this command helped me to see the cause of this issue&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;sudo &lt;/span&gt;kubectl describe pod &amp;lt;pod_name&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4.2 Ensuring Network Connectivity
&lt;/h3&gt;

&lt;p&gt;Verify that each Raspberry Pi can communicate with others in the network:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Ping Test:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;From one Raspberry Pi, ping another using their static IP addresses:
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt; ping 192.168.1.3
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;Replace the IP address with the actual address of the target Raspberry Pi.&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;SSH Connectivity:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ensure SSH connectivity between Raspberry Pis:
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt; ssh pi@192.168.1.3
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;Use the IP address of the target Raspberry Pi.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  4.3 Troubleshooting Network Issues
&lt;/h3&gt;

&lt;p&gt;If you encounter network issues, consider the following troubleshooting steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Check Configuration Files:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Review the network configuration files on each Raspberry Pi.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Firewall Settings:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ensure that firewalls on Raspberry Pis are not blocking necessary ports.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Router Configuration:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Check router settings to ensure it allows communication between devices.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Node Discovery:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Verify that each node can discover others in the cluster.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;With a well-configured network, your Kubernetes cluster is ready to conquer the world. In the next section, we'll explore persistent volume implementation.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Persistent Volume Implementation
&lt;/h2&gt;

&lt;p&gt;To ensure data persistence and availability, we'll set up persistent volumes (PVs) in our Kubernetes cluster.&lt;/p&gt;

&lt;h3&gt;
  
  
  5.1 Creating Persistent Volumes
&lt;/h3&gt;

&lt;p&gt;On the master node, create persistent volumes for data storage:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Create PV YAML File:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create a YAML file (e.g., pv.yaml) with the PV configuration. Here's an example for a local storage PV:
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt; &lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;v1&lt;/span&gt;
 &lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;PersistentVolume&lt;/span&gt;
 &lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
   &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;pv-local&lt;/span&gt;
 &lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
   &lt;span class="na"&gt;capacity&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
     &lt;span class="na"&gt;storage&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;1Gi&lt;/span&gt;
   &lt;span class="na"&gt;accessModes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
     &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;ReadWriteOnce&lt;/span&gt;
   &lt;span class="na"&gt;hostPath&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="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/mnt/data"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Apply the PV Configuration:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Apply the configuration to create the PV:
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt; &lt;span class="nb"&gt;sudo &lt;/span&gt;k3s kubectl apply &lt;span class="nt"&gt;-f&lt;/span&gt; pv.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  5.2 Configuring Persistent Volume Claims
&lt;/h3&gt;

&lt;p&gt;Now, let's configure persistent volume claims (PVCs) for your WordPress deployment:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Create PVC YAML File:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create a YAML file (e.g., pvc.yaml) with the PVC configuration. Here's an example:
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt; &lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;v1&lt;/span&gt;
 &lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;PersistentVolumeClaim&lt;/span&gt;
 &lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
   &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;pvc-local&lt;/span&gt;
 &lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
   &lt;span class="na"&gt;accessModes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
     &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;ReadWriteOnce&lt;/span&gt;
   &lt;span class="na"&gt;resources&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
     &lt;span class="na"&gt;requests&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
       &lt;span class="na"&gt;storage&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;1Gi&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Apply the PVC Configuration:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Apply the configuration to create the PVC:
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt; &lt;span class="nb"&gt;sudo &lt;/span&gt;k3s kubectl apply &lt;span class="nt"&gt;-f&lt;/span&gt; pvc.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  5.3 Testing Persistent Volumes
&lt;/h3&gt;

&lt;p&gt;Verify that persistent volumes are functioning as expected:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Check PV Status:&lt;/strong&gt;
-&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Verify the status of the persistent volume:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; ```bash
 sudo k3s kubectl get pv
 ```
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Ensure that the PV is in the 'Bound' state.&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Check PVC Status:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Verify the status of the persistent volume claim:
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt; &lt;span class="nb"&gt;sudo &lt;/span&gt;k3s kubectl get pvc
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;Ensure that the PVC is in the 'Bound' state.&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Test Data Persistence:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Deploy a test pod that uses the persistent volume:
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt; &lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;v1&lt;/span&gt;
 &lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Pod&lt;/span&gt;
 &lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
   &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;test-pod&lt;/span&gt;
 &lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
   &lt;span class="na"&gt;containers&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
     &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;test-container&lt;/span&gt;
       &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;busybox&lt;/span&gt;
       &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/bin/sh"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;-c"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;echo&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Hello&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Kubernetes!&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;/mnt/data/test-file&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;sleep&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;3600"&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
       &lt;span class="na"&gt;volumeMounts&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
         &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;storage&lt;/span&gt;
           &lt;span class="na"&gt;mountPath&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/mnt/data"&lt;/span&gt;
   &lt;span class="na"&gt;volumes&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;storage&lt;/span&gt;
       &lt;span class="na"&gt;persistentVolumeClaim&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
         &lt;span class="na"&gt;claimName&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;pvc-local&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;Check if the test pod is running and verify the contents of the persistent volume.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With persistent volumes in place, your Kubernetes cluster is now equipped with reliable storage capabilities. The next step is to deploy WordPress on Kubernetes.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Deploying WordPress on Kubernetes
&lt;/h2&gt;

&lt;p&gt;Let's dive into the exciting phase of deploying WordPress on your Kubernetes cluster.&lt;/p&gt;

&lt;h3&gt;
  
  
  6.1 Creating WordPress Deployment YAML
&lt;/h3&gt;

&lt;p&gt;Create a YAML file (e.g., wordpress.yaml) to define the WordPress deployment:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;apps/v1&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Deployment&lt;/span&gt;
&lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;wordpress&lt;/span&gt;
&lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;replicas&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;
  &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;matchLabels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;wordpress&lt;/span&gt;
  &lt;span class="na"&gt;template&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;labels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;wordpress&lt;/span&gt;
    &lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;containers&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;wordpress&lt;/span&gt;
          &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;wordpress:latest&lt;/span&gt;
          &lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;WORDPRESS_DB_HOST&lt;/span&gt;
              &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;mysql-service&lt;/span&gt;
            &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;WORDPRESS_DB_PASSWORD&lt;/span&gt;
              &lt;span class="na"&gt;valueFrom&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
                &lt;span class="na"&gt;secretKeyRef&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;mysql-secret&lt;/span&gt;
                  &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;password&lt;/span&gt;
          &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;containerPort&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;80&lt;/span&gt;
&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;v1&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Service&lt;/span&gt;
&lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;wordpress-service&lt;/span&gt;
&lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;wordpress&lt;/span&gt;
  &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;protocol&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;TCP&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;80&lt;/span&gt;
      &lt;span class="na"&gt;targetPort&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;80&lt;/span&gt;
  &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;LoadBalancer&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Apply the configuration to create the WordPress 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="nb"&gt;sudo &lt;/span&gt;k3s kubectl apply &lt;span class="nt"&gt;-f&lt;/span&gt; wordpress.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  6.2 Configuring Service for WordPress
&lt;/h3&gt;

&lt;p&gt;Expose the WordPress service to the external world:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Check Service Status:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Verify that the WordPress service is running:
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt; &lt;span class="nb"&gt;sudo &lt;/span&gt;k3s kubectl get services
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;Note the external IP assigned to the service.&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Access WordPress:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Open a web browser and navigate to the external IP of the WordPress service.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;Complete the WordPress installation steps.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  6.3 Verifying WordPress Deployment
&lt;/h3&gt;

&lt;p&gt;Confirm the successful deployment of WordPress:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Check Deployment Status:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Verify the status of the WordPress deployment:
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt; &lt;span class="nb"&gt;sudo &lt;/span&gt;k3s kubectl get deployments
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;Ensure the desired number of replicas is running.&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Verify Pods:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Check the pods associated with the WordPress deployment:
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt; &lt;span class="nb"&gt;sudo &lt;/span&gt;k3s kubectl get pods
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;Ensure the pods are in the 'Running' state.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With WordPress up and running, it's time to explore how to scale your deployment for increased traffic.&lt;/p&gt;

&lt;h2&gt;
  
  
  7. Scaling the WordPress Deployment
&lt;/h2&gt;

&lt;p&gt;Kubernetes makes scaling a breeze. Let's explore how to scale your WordPress deployment dynamically.&lt;/p&gt;

&lt;h3&gt;
  
  
  7.1 Horizontal Pod Autoscaling
&lt;/h3&gt;

&lt;p&gt;Enable horizontal pod autoscaling for the WordPress deployment:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Create HPA YAML File:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create a YAML file (e.g., hpa.yaml) for the horizontal pod autoscaler:
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt; &lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;autoscaling/v2beta2&lt;/span&gt;
 &lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;HorizontalPodAutoscaler&lt;/span&gt;
 &lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
   &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;wordpress-hpa&lt;/span&gt;
 &lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
   &lt;span class="na"&gt;scaleTargetRef&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
     &lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;apps/v1&lt;/span&gt;
     &lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Deployment&lt;/span&gt;
     &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;wordpress&lt;/span&gt;
   &lt;span class="na"&gt;minReplicas&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;
   &lt;span class="na"&gt;maxReplicas&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;5&lt;/span&gt;
   &lt;span class="na"&gt;metrics&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
     &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Resource&lt;/span&gt;
       &lt;span class="na"&gt;resource&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;cpu&lt;/span&gt;
         &lt;span class="na"&gt;targetAverageUtilization&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;80&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Apply the HPA Configuration:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Apply the configuration to create the horizontal pod autoscaler:
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt; &lt;span class="nb"&gt;sudo &lt;/span&gt;k3s kubectl apply &lt;span class="nt"&gt;-f&lt;/span&gt; hpa.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  7.2 Testing Autoscaling
&lt;/h3&gt;

&lt;p&gt;Simulate increased load on your WordPress site to trigger autoscaling:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Generate Load:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use a tool like Apache Benchmark to simulate increased traffic:
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt; ab &lt;span class="nt"&gt;-n&lt;/span&gt; 10000 &lt;span class="nt"&gt;-c&lt;/span&gt; 10 http://&amp;lt;wordpress-service-ip&amp;gt;/
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;Replace &lt;code&gt;&amp;lt;wordpress-service-ip&amp;gt;&lt;/code&gt; with the IP of your WordPress service.&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Monitor Autoscaling:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Check the status of the horizontal pod autoscaler:
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt; &lt;span class="nb"&gt;sudo &lt;/span&gt;k3s kubectl get hpa
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;Monitor the number of replicas based on the defined metrics.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  7.3 Analyzing Scalability
&lt;/h3&gt;

&lt;p&gt;Review metrics and logs to analyze the scalability of your WordPress deployment:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Check Metrics:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Examine the metrics gathered by the horizontal pod autoscaler:
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt; &lt;span class="nb"&gt;sudo &lt;/span&gt;k3s kubectl describe hpa wordpress-hpa
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Review Logs:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Analyze logs for individual pods to identify any performance issues:
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt; &lt;span class="nb"&gt;sudo &lt;/span&gt;k3s kubectl logs &amp;lt;pod-name&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;Replace &lt;code&gt;&amp;lt;pod-name&amp;gt;&lt;/code&gt; with the name of a WordPress pod.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With autoscaling in place, your WordPress deployment can dynamically adapt to varying workloads. Let's now focus on monitoring and observability.&lt;/p&gt;

&lt;h2&gt;
  
  
  8. Monitoring and Observability
&lt;/h2&gt;

&lt;p&gt;A robust monitoring setup ensures that you stay informed about the health and performance of your Kubernetes cluster. Let's implement monitoring using Prometheus and visualize data with Grafana.&lt;/p&gt;

&lt;h3&gt;
  
  
  8.1 Implementing Prometheus for Monitoring
&lt;/h3&gt;

&lt;p&gt;Deploy Prometheus to gather and store cluster metrics:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Create Prometheus YAML File:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create a YAML file (e.g., prometheus.yaml) for Prometheus deployment:
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt; &lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;v1&lt;/span&gt;
 &lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Service&lt;/span&gt;
 &lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
   &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;prometheus-service&lt;/span&gt;
 &lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
   &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
     &lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;prometheus&lt;/span&gt;
   &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
     &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;protocol&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;TCP&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;9090&lt;/span&gt;
       &lt;span class="na"&gt;targetPort&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;9090&lt;/span&gt;
   &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;LoadBalancer&lt;/span&gt;
 &lt;span class="s"&gt;---&lt;/span&gt;
 &lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;apps/v1&lt;/span&gt;
 &lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Deployment&lt;/span&gt;
 &lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
   &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;prometheus&lt;/span&gt;
 &lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
   &lt;span class="na"&gt;replicas&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;
   &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
     &lt;span class="na"&gt;matchLabels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
       &lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;prometheus&lt;/span&gt;
   &lt;span class="na"&gt;template&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
     &lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
       &lt;span class="na"&gt;labels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
         &lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;prometheus&lt;/span&gt;
     &lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
       &lt;span class="na"&gt;containers&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
         &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;prometheus&lt;/span&gt;
           &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;prom/prometheus&lt;/span&gt;
           &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
             &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;containerPort&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;9090&lt;/span&gt;
           &lt;span class="na"&gt;args&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
             &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;--config.file=/etc/prometheus/prometheus.yml"&lt;/span&gt;
           &lt;span class="na"&gt;volumeMounts&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
             &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;prometheus-config&lt;/span&gt;
               &lt;span class="na"&gt;mountPath&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/etc/prometheus&lt;/span&gt;
       &lt;span class="na"&gt;volumes&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;prometheus-config&lt;/span&gt;
           &lt;span class="na"&gt;configMap&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;prometheus-config&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Apply the Prometheus Configuration:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Apply the configuration to create the Prometheus deployment:
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt; &lt;span class="nb"&gt;sudo &lt;/span&gt;k3s kubectl apply &lt;span class="nt"&gt;-f&lt;/span&gt; prometheus.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  8.2 Grafana Dashboard Configuration
&lt;/h3&gt;

&lt;p&gt;Set up Grafana to visualize Prometheus metrics:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Create Grafana YAML File:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create a YAML file (e.g., grafana.yaml) for Grafana deployment:
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt; &lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;v1&lt;/span&gt;
 &lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Service&lt;/span&gt;
 &lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
   &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;grafana-service&lt;/span&gt;
 &lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
   &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
     &lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;grafana&lt;/span&gt;
   &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
     &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;protocol&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;TCP&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;3000&lt;/span&gt;
       &lt;span class="na"&gt;targetPort&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;3000&lt;/span&gt;
   &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;LoadBalancer&lt;/span&gt;
 &lt;span class="s"&gt;---&lt;/span&gt;
 &lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;apps/v1&lt;/span&gt;
 &lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Deployment&lt;/span&gt;
 &lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
   &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;grafana&lt;/span&gt;
 &lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
   &lt;span class="na"&gt;replicas&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;
   &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
     &lt;span class="na"&gt;matchLabels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
       &lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;grafana&lt;/span&gt;
   &lt;span class="na"&gt;template&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
     &lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
       &lt;span class="na"&gt;labels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
         &lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;grafana&lt;/span&gt;
     &lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
       &lt;span class="na"&gt;containers&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
         &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;grafana&lt;/span&gt;
           &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;grafana/grafana&lt;/span&gt;
           &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
             &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;containerPort&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;3000&lt;/span&gt;
           &lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
             &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;GF_SECURITY_ADMIN_PASSWORD&lt;/span&gt;
               &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;admin"&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;GF_SECURITY_ADMIN_USER&lt;/span&gt;
               &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;admin"&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;GF_SECURITY_ALLOW_EMBEDDING&lt;/span&gt;
               &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;true"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Apply the Grafana Configuration:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Apply the configuration to create the Grafana deployment:
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt; &lt;span class="nb"&gt;sudo &lt;/span&gt;k3s kubectl apply &lt;span class="nt"&gt;-f&lt;/span&gt; grafana.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Access Grafana:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Access the Grafana dashboard using a web browser and the external IP of the Grafana service.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Configure Prometheus as a Data Source:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Log in to Grafana (default credentials: admin/admin).&lt;/li&gt;
&lt;li&gt;Add Prometheus as a data source with the URL: &lt;code&gt;http://prometheus-service:9090&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Import Kubernetes Dashboard:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Import the official Kubernetes dashboard for Grafana.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;With Prometheus and Grafana in place, your Kubernetes cluster is now equipped with powerful monitoring and visualization capabilities.&lt;/p&gt;

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

&lt;p&gt;Congratulations on completing the implementation of a prototype Kubernetes-based cluster for scalable web-based WordPress deployment. This journey covered everything from setting up Raspberry Pis to deploying, scaling, and monitoring your WordPress application.&lt;/p&gt;

&lt;p&gt;As you continue to explore the dynamic world of Kubernetes, remember that this guide serves as a solid foundation. Feel free to adapt and enhance your cluster based on evolving requirements. Embrace the scalability, flexibility, and resilience that Kubernetes brings to your web-based applications.&lt;/p&gt;

&lt;p&gt;May your Kubernetes journey be filled with seamless deployments, effortless scalability, and a robust infrastructure that stands the test of time. Happy clustering!&lt;/p&gt;

&lt;p&gt;Here are some resources I found helpful:&lt;br&gt;
&lt;a href="https://kubernetes.io/docs/tutorials/stateful-application/mysql-wordpress-persistent-volume/"&gt;https://kubernetes.io/docs/tutorials/stateful-application/mysql-wordpress-persistent-volume/&lt;/a&gt;&lt;br&gt;
&lt;a href="https://docs.k3s.io/storage"&gt;https://docs.k3s.io/storage&lt;/a&gt;&lt;br&gt;
YouTube playlist - &lt;a href="https://youtube.com/playlist?list=PL9ti0-HuCzGbI4MdxgODTbuzEs0RS12c2&amp;amp;si=34d3StsvzwqnHc0j"&gt;https://youtube.com/playlist?list=PL9ti0-HuCzGbI4MdxgODTbuzEs0RS12c2&amp;amp;si=34d3StsvzwqnHc0j&lt;/a&gt;&lt;/p&gt;

</description>
      <category>devops</category>
      <category>kubernetes</category>
      <category>k3s</category>
    </item>
    <item>
      <title>How to Install VPN on Kali Linux Using OpenVPN and VPNBook</title>
      <dc:creator>Chinaza Otumba</dc:creator>
      <pubDate>Thu, 22 Sep 2022 16:23:40 +0000</pubDate>
      <link>https://dev.to/otumba/how-to-install-vpn-on-kali-linux-using-openvpn-and-vpnbook-1k</link>
      <guid>https://dev.to/otumba/how-to-install-vpn-on-kali-linux-using-openvpn-and-vpnbook-1k</guid>
      <description>&lt;p&gt;Kali Linux, formerly known as &lt;strong&gt;BackTrack&lt;/strong&gt;, is synonymous with security and forensics. It is a Linux distro; based on Debian and built for cyber security experts, penetration testers, and white-hat hackers for digital forensics and penetration testing.&lt;/p&gt;

&lt;p&gt;Having a VPN on your Kali Linux increases invisibility (private mode) while you keep testing for vulnerabilities.&lt;/p&gt;

&lt;p&gt;In this article, we’ll show you how to install a VPN using OpenVPN and VPNBook on Kali Linux.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why do you need a VPN on your Kali Linux?
&lt;/h3&gt;

&lt;p&gt;Despite being built for digital forensics and penetration testing, Kali is just like every other Linux distro or operating system (OS), and as a user, you need to protect your activities while using it.&lt;/p&gt;

&lt;p&gt;Failure to do so is like using an umbrella with holes,you'll definitely get soaked when it rains.&lt;/p&gt;

&lt;p&gt;Installing a VPN helps cloak your IP address, bypass censorship/geographical limitations, and encrypt your network traffic. Or, in this case, you can view it as patching the umbrella.&lt;/p&gt;

&lt;p&gt;Please note that despite doing all the things stated above, you may still need more than a VPN to protect yourself, depending on the task.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why open-source VPN?
&lt;/h3&gt;

&lt;p&gt;This article will focus on an &lt;a href="https://www.makeuseof.com/tag/open-source-vpns-linux-windows/" rel="noopener noreferrer"&gt;open-source&lt;/a&gt; VPN, as they provide higher transparency compared to closed-source VPNs. Some closed-sourced VPNs even rely on open-source VPNs to function.&lt;/p&gt;

&lt;p&gt;The selected VPN for today is &lt;a href="https://www.makeuseof.com/what-is-openvpn/" rel="noopener noreferrer"&gt;OpenVPN&lt;/a&gt; because it is compatible with various OSes.&lt;/p&gt;

&lt;h3&gt;
  
  
  How to Install a VPN on Kali Linux?
&lt;/h3&gt;

&lt;p&gt;Let's assume you already have Kali Linux up and running (either on your &lt;a href="https://www.makeuseof.com/install-kali-linux-in-vmware/" rel="noopener noreferrer"&gt;virtual machine&lt;/a&gt; or you dual boot it on your machine).&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Next, open your terminal by navigating to your apps menu.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Then click the icon or use the command &lt;strong&gt;Ctrl + Alt + T&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;!&lt;br&gt;
&lt;a href="https://media.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%2F839cwmrkj965kzxe6rcv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F839cwmrkj965kzxe6rcv.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Type the command &lt;strong&gt;Sudo apt-get install OpenVPN&lt;/strong&gt; once the command line opens.&lt;/li&gt;
&lt;/ul&gt;

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

Sudo apt-get install OpenVPN


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

&lt;/div&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fswq8d3midqer6w1pjd8n.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fswq8d3midqer6w1pjd8n.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Depending on your setup, you might be asked to input your password.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;To confirm a correct installation after the download,, type the command &lt;strong&gt;Openvpn&lt;/strong&gt; into the terminal, “”.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

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

Openvpn


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

&lt;/div&gt;

&lt;p&gt;&lt;a href="https://media.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%2F7e6e51a9xl8dsleyj0j3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F7e6e51a9xl8dsleyj0j3.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Next, you'll need to get the required configuration files for your VPN to work properly. Open your browser and go to &lt;a href="http://www.vpnhooks.com" rel="noopener noreferrer"&gt;www.vpnhooks.com&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fb0zjfqmgtzrrjwt5fgue.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fb0zjfqmgtzrrjwt5fgue.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Then scroll down and select &lt;strong&gt;&lt;em&gt;OpenVPN&lt;/em&gt;&lt;/strong&gt; from the options available.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.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%2Flv1ou1jh58jn7flk74u7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Flv1ou1jh58jn7flk74u7.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Select the server you prefer and download the configuration file.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For the purpose of this guide, we will be using US1 Server.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fq6l3it38tmlu94c41065.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fq6l3it38tmlu94c41065.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;After downloading the configuration file, extract the files.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Configuring OpenVPN
&lt;/h3&gt;

&lt;p&gt;There are two ways to proceed with the configuration from this point. It’s either through the GUI or the Terminal.&lt;/p&gt;

&lt;h4&gt;
  
  
  Configuring OpenVPN with GUI (Graphical User Interface)
&lt;/h4&gt;

&lt;p&gt;Using the GUI option is typically easier, but the images provided could be slightly different on your version of Kali.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Go to settings and select network. Then click the plus sign(+) at the bottom&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fes6io1ug41za9dnh8up8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fes6io1ug41za9dnh8up8.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;From the pop-up, select &lt;strong&gt;&lt;em&gt;import saved VPN configuration&lt;/em&gt;&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.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%2F40qub9us84qsjyi8gsth.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F40qub9us84qsjyi8gsth.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Input the username and password found on the VPNBook website and click Save.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;After this, you're good to go!&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Congratulations! You have successfully installed OpenVPN on your Kali Linux using the GUI method.&lt;/p&gt;

&lt;h3&gt;
  
  
  Configuring OpenVPN from the Terminal
&lt;/h3&gt;

&lt;p&gt;Unlike the GUI method, the terminal stays the same on various Kali versions. Other Linux distros on the other hand would require different commands.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;For this method, simply right-click on the folder where you have extracted the configuration files&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.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%2Focmpubsryex4b7rd48e2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Focmpubsryex4b7rd48e2.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;And select open Terminal.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Then input the command, Sudo vpnbook-us2-tcp443.ovpn&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

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

Sudo vpnbook-us2-tcp443.ovpn


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

&lt;/div&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fh5q9ree3wkuaaorhhczs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fh5q9ree3wkuaaorhhczs.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Input the username and password when prompted.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.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%2F9p9l8xn04vrlvu5nx13e.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F9p9l8xn04vrlvu5nx13e.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You've now successfully installed OpenVPN on your Kali Linux using the terminal.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2F9qnxbbiv037s3cj0q6oy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F9qnxbbiv037s3cj0q6oy.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;We have successfully installed a VPN in our Kali through the GUI process and using the terminal.&lt;/p&gt;

&lt;p&gt;If you made it to the end, congratulations.&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
