<?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: Patricio Díaz </title>
    <description>The latest articles on DEV Community by Patricio Díaz  (@padiazg).</description>
    <link>https://dev.to/padiazg</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%2F209074%2F900fb752-46d4-435e-8882-6b9083fb12d5.jpeg</url>
      <title>DEV Community: Patricio Díaz </title>
      <link>https://dev.to/padiazg</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/padiazg"/>
    <language>en</language>
    <item>
      <title>Numerical Root-Finding Algorithms: Foundations, Theory, and Advanced Methods. Part 1</title>
      <dc:creator>Patricio Díaz </dc:creator>
      <pubDate>Sun, 01 Dec 2024 02:22:02 +0000</pubDate>
      <link>https://dev.to/padiazg/numerical-root-finding-algorithms-foundations-theory-and-advanced-methods-part-1-1f31</link>
      <guid>https://dev.to/padiazg/numerical-root-finding-algorithms-foundations-theory-and-advanced-methods-part-1-1f31</guid>
      <description>&lt;p&gt;Root-finding is one of the core problems in computational mathematics. Whether you're solving equations, optimizing functions, or modeling real-world phenomena, the need to find the roots of functions is ubiquitous. This article explores the foundations of root-finding algorithms, their mathematical principles, convergence properties, and real-world applications. Additionally, we will dive into advanced techniques, such as the Secant Method and Brent’s Method, which extend and improve upon traditional approaches.&lt;/p&gt;




&lt;h3&gt;
  
  
  1. Introduction to Root-Finding Problems
&lt;/h3&gt;

&lt;p&gt;In computational mathematics, finding the root of a function 

&lt;span class="katex-element"&gt;
  &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;f(x)=0f(x)=0&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;f&lt;/span&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord mathnormal"&gt;x&lt;/span&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;0&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;
 is essential across a range of fields, from physics and engineering to economics and computer science. A root is simply a value where the function evaluates to zero, and root-finding algorithms are designed to approximate these values when exact solutions are not easily obtainable.&lt;/p&gt;

&lt;p&gt;Root-finding problems arise in many contexts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Solving Equations&lt;/strong&gt;: For instance, finding the point where the gravitational force equals zero in physics or determining the intersection points of curves in geometry.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Optimization&lt;/strong&gt;: Algorithms find prices that optimize supply and demand in economics or optimal control points in engineering.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Computer Graphics&lt;/strong&gt;: Root-finding methods are used in rendering techniques like ray tracing, where finding the intersection of a light ray with 3D surfaces is crucial.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Root-finding algorithms are powerful tools in computational science, particularly when exact analytical solutions to nonlinear equations are unavailable.&lt;/p&gt;




&lt;h3&gt;
  
  
  2. Fundamental Algorithms Comparison
&lt;/h3&gt;

&lt;h4&gt;
  
  
  2.1 Bisection Method
&lt;/h4&gt;

&lt;p&gt;The &lt;strong&gt;Bisection Method&lt;/strong&gt; is one of the most basic and reliable root-finding algorithms. It is based on the intermediate value theorem, which states that if a continuous function 
&lt;span class="katex-element"&gt;
  &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;f(x)f(x)&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;f&lt;/span&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord mathnormal"&gt;x&lt;/span&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;
 changes sign over an interval 
&lt;span class="katex-element"&gt;
  &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;[a,b][a,b]&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mopen"&gt;[&lt;/span&gt;&lt;span class="mord mathnormal"&gt;a&lt;/span&gt;&lt;span class="mpunct"&gt;,&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;b&lt;/span&gt;&lt;span class="mclose"&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;
, then there exists at least one root in the interval.&lt;/p&gt;

&lt;h5&gt;
  
  
  Mathematical Principles
&lt;/h5&gt;

&lt;p&gt;The method works by repeatedly bisecting the interval and selecting the subinterval that contains the root. The midpoint of the interval, 
&lt;span class="katex-element"&gt;
  &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;m=a+b2m = \frac{a + b}{2}&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;m&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mopen nulldelimiter"&gt;&lt;/span&gt;&lt;span class="mfrac"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mtight"&gt;2&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="frac-line"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;a&lt;/span&gt;&lt;span class="mbin mtight"&gt;+&lt;/span&gt;&lt;span class="mord mathnormal mtight"&gt;b&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mclose nulldelimiter"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;
​, is computed, and the sign of 
&lt;span class="katex-element"&gt;
  &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;f(m)f(m)&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;f&lt;/span&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord mathnormal"&gt;m&lt;/span&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;
 is checked. If 
&lt;span class="katex-element"&gt;
  &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;f(a)⋅f(m)&amp;lt;0f(a) \cdot f(m) &amp;lt; 0&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;f&lt;/span&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord mathnormal"&gt;a&lt;/span&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;⋅&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;f&lt;/span&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord mathnormal"&gt;m&lt;/span&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;&amp;lt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;0&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;
, the root lies between 
&lt;span class="katex-element"&gt;
  &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;aa&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;a&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;
 and 
&lt;span class="katex-element"&gt;
  &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;mm&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;m&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;
, and the interval is updated to 
&lt;span class="katex-element"&gt;
  &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;[a,m][a, m]&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mopen"&gt;[&lt;/span&gt;&lt;span class="mord mathnormal"&gt;a&lt;/span&gt;&lt;span class="mpunct"&gt;,&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;m&lt;/span&gt;&lt;span class="mclose"&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;
. If 
&lt;span class="katex-element"&gt;
  &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;f(m)⋅f(b)&amp;lt;0f(m) \cdot f(b) &amp;lt; 0&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;f&lt;/span&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord mathnormal"&gt;m&lt;/span&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;⋅&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;f&lt;/span&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord mathnormal"&gt;b&lt;/span&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;&amp;lt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;0&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;
, the root lies between 
&lt;span class="katex-element"&gt;
  &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;mm&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;m&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;
 and 
&lt;span class="katex-element"&gt;
  &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;bb&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;b&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;
, and the interval is updated to 
&lt;span class="katex-element"&gt;
  &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;[m,b][m,b]&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mopen"&gt;[&lt;/span&gt;&lt;span class="mord mathnormal"&gt;m&lt;/span&gt;&lt;span class="mpunct"&gt;,&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;b&lt;/span&gt;&lt;span class="mclose"&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;
.&lt;/p&gt;

&lt;h5&gt;
  
  
  Convergence Characteristics
&lt;/h5&gt;

&lt;p&gt;The Bisection Method is &lt;strong&gt;guaranteed to converge&lt;/strong&gt; provided the function is continuous on the interval and the initial guesses are correctly chosen. The convergence is &lt;strong&gt;linear&lt;/strong&gt;, meaning each step reduces the interval size by half.&lt;/p&gt;

&lt;h5&gt;
  
  
  Pros and Cons
&lt;/h5&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Pros&lt;/strong&gt;: Simple to implement, guaranteed convergence if the initial interval is chosen correctly.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cons&lt;/strong&gt;: Slow convergence, requiring many iterations to achieve a high degree of accuracy.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  2.2 Newton-Raphson Method
&lt;/h4&gt;

&lt;p&gt;The &lt;strong&gt;Newton-Raphson Method&lt;/strong&gt; is a widely used root-finding technique that offers much faster convergence than the Bisection Method, especially when an initial guess is close to the true root. It uses the concept of linear approximation to refine the root estimate.&lt;/p&gt;

&lt;h5&gt;
  
  
  Mathematical Derivation
&lt;/h5&gt;

&lt;p&gt;The method uses the derivative of the function to find a tangent line at the current approximation. Given an initial guess 
&lt;span class="katex-element"&gt;
  &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;x0x_0&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;x&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;0&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;
​, the iterative formula is:&lt;br&gt;

&lt;/p&gt;
&lt;div class="katex-element"&gt;
  &lt;span class="katex-display"&gt;&lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;xn+1=xn−f(xn)f′(xn)
x_{n+1} = x_n - \frac{f(x_n)}{f'(x_n)}
&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;x&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;n&lt;/span&gt;&lt;span class="mbin mtight"&gt;+&lt;/span&gt;&lt;span class="mord mtight"&gt;1&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;x&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;n&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;−&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mopen nulldelimiter"&gt;&lt;/span&gt;&lt;span class="mfrac"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;f&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mtight"&gt;′&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;x&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;n&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="frac-line"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;f&lt;/span&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;x&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;n&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mclose nulldelimiter"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;
&lt;br&gt;
This process continues until the difference between successive approximations is smaller than a specified tolerance.

&lt;h5&gt;
  
  
  Convergence Speed
&lt;/h5&gt;

&lt;p&gt;Newton-Raphson has &lt;strong&gt;quadratic convergence&lt;/strong&gt;, meaning that the number of correct digits approximately doubles with each iteration when starting from a sufficiently close guess.&lt;/p&gt;

&lt;h5&gt;
  
  
  Computational Complexity
&lt;/h5&gt;

&lt;p&gt;The method requires calculating both the function and its derivative at each step, making it computationally expensive compared to methods like Bisection.&lt;/p&gt;

&lt;h5&gt;
  
  
  Pros and Cons
&lt;/h5&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Pros&lt;/strong&gt;: Fast convergence (quadratic), efficient for well-behaved functions with a good initial guess.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cons&lt;/strong&gt;: Requires the derivative of the function, can fail or diverge if the derivative is zero or the guess is poor.&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  3. Advanced Root-Finding Algorithms
&lt;/h3&gt;

&lt;p&gt;While the &lt;strong&gt;Bisection&lt;/strong&gt; and &lt;strong&gt;Newton-Raphson&lt;/strong&gt; methods are foundational, they have limitations in certain situations, such as poor initial guesses or the inability to compute derivatives. This has led to the development of more advanced algorithms, such as the &lt;strong&gt;Secant Method&lt;/strong&gt; and &lt;strong&gt;Brent’s Method&lt;/strong&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  3.1 Secant Method
&lt;/h4&gt;

&lt;p&gt;The &lt;strong&gt;Secant Method&lt;/strong&gt; is an improvement on the Newton-Raphson method that does not require the derivative of the function. Instead, it approximates the derivative by using two successive points.&lt;/p&gt;

&lt;h5&gt;
  
  
  Mathematical Principles
&lt;/h5&gt;

&lt;p&gt;The Secant Method iteratively refines guesses using the following formula:&lt;br&gt;

&lt;/p&gt;
&lt;div class="katex-element"&gt;
  &lt;span class="katex-display"&gt;&lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;xn+1=xn−f(xn)⋅(xn−xn−1)f(xn)−f(xn−1)
x_{n+1} = x_n - \frac{f(x_n) \cdot (x_n - x_{n-1})}{f(x_n) - f(x_{n-1})}
&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;x&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;n&lt;/span&gt;&lt;span class="mbin mtight"&gt;+&lt;/span&gt;&lt;span class="mord mtight"&gt;1&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;x&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;n&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;−&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mopen nulldelimiter"&gt;&lt;/span&gt;&lt;span class="mfrac"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;f&lt;/span&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;x&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;n&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;−&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;f&lt;/span&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;x&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;n&lt;/span&gt;&lt;span class="mbin mtight"&gt;−&lt;/span&gt;&lt;span class="mord mtight"&gt;1&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="frac-line"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;f&lt;/span&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;x&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;n&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;⋅&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;x&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;n&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;−&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;x&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;n&lt;/span&gt;&lt;span class="mbin mtight"&gt;−&lt;/span&gt;&lt;span class="mord mtight"&gt;1&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mclose nulldelimiter"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;
&lt;br&gt;
Here, the approximation of the derivative is made using the slope of the secant line through 
&lt;span class="katex-element"&gt;
  &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;(xn,f(xn))(x_n, f(x_n))&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;x&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;n&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mpunct"&gt;,&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;f&lt;/span&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;x&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;n&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mclose"&gt;))&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;
 and 
&lt;span class="katex-element"&gt;
  &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;(xn−1,f(xn−1))(x_{n-1}, f(x_{n-1}))&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;x&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;n&lt;/span&gt;&lt;span class="mbin mtight"&gt;−&lt;/span&gt;&lt;span class="mord mtight"&gt;1&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mpunct"&gt;,&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;f&lt;/span&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;x&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;n&lt;/span&gt;&lt;span class="mbin mtight"&gt;−&lt;/span&gt;&lt;span class="mord mtight"&gt;1&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mclose"&gt;))&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;
.

&lt;h5&gt;
  
  
  Convergence Speed
&lt;/h5&gt;

&lt;p&gt;The Secant Method exhibits &lt;strong&gt;superlinear convergence&lt;/strong&gt;, meaning it converges faster than the Bisection Method but slower than Newton-Raphson.&lt;/p&gt;

&lt;h5&gt;
  
  
  Pros and Cons
&lt;/h5&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Pros&lt;/strong&gt;: Does not require the derivative, faster convergence than the Bisection Method.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cons&lt;/strong&gt;: Can fail if the two initial guesses are too far apart or if the function behaves erratically.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  3.2 Brent’s Method
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;Brent’s Method&lt;/strong&gt; is a hybrid algorithm that combines the strengths of the &lt;strong&gt;Bisection&lt;/strong&gt;, &lt;strong&gt;Secant&lt;/strong&gt;, and &lt;strong&gt;inverse quadratic interpolation&lt;/strong&gt; methods. It dynamically selects the most appropriate strategy based on the situation, ensuring robustness and efficiency.&lt;/p&gt;

&lt;h5&gt;
  
  
  Mathematical Principles
&lt;/h5&gt;

&lt;p&gt;Brent’s Method switches between the following strategies:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Bisection&lt;/strong&gt;: When the other methods are unreliable.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Secant Method&lt;/strong&gt;: For faster convergence when appropriate.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Inverse Quadratic Interpolation&lt;/strong&gt;: Fits a quadratic to three points and solves for its root.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This combination allows the algorithm to reliably find roots even in difficult cases.&lt;/p&gt;

&lt;h5&gt;
  
  
  Convergence Speed
&lt;/h5&gt;

&lt;p&gt;Brent’s Method generally exhibits &lt;strong&gt;superlinear convergence&lt;/strong&gt; and performs well in a wide range of problems.&lt;/p&gt;

&lt;h5&gt;
  
  
  Pros and Cons
&lt;/h5&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Pros&lt;/strong&gt;: Extremely robust, combines the best features of multiple methods, guarantees convergence.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cons&lt;/strong&gt;: More complex to implement than simpler methods like Bisection.&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  4. Real-World Applications of Root-Finding Methods
&lt;/h3&gt;

&lt;p&gt;Root-finding algorithms are crucial in solving real-world computational problems, and the &lt;strong&gt;Newton-Raphson Method&lt;/strong&gt;, with its quadratic convergence, is often the preferred choice when speed and efficiency are required. Its fast convergence makes it highly valuable in many practical applications, particularly where high precision is needed and an initial guess can be reasonably made.&lt;/p&gt;

&lt;h4&gt;
  
  
  Engineering and Physics: Solving Nonlinear Equations
&lt;/h4&gt;

&lt;p&gt;In fields like &lt;strong&gt;engineering&lt;/strong&gt; and &lt;strong&gt;physics&lt;/strong&gt;, many problems involve solving nonlinear equations to model dynamic systems, equilibrium points, or interactions. For example, in &lt;strong&gt;structural engineering&lt;/strong&gt;, solving for the points at which forces balance within a system often leads to nonlinear equations. Newton-Raphson's rapid convergence makes it ideal for solving such problems where the function is well-behaved, and a good starting guess is available.&lt;/p&gt;

&lt;p&gt;In contrast, the &lt;strong&gt;Bisection Method&lt;/strong&gt; is sometimes used in situations where the function is not differentiable or its derivative is hard to compute, but its slower linear convergence can make it impractical when speed is important.&lt;/p&gt;

&lt;h4&gt;
  
  
  Computer Graphics: Ray Tracing and Geometric Calculations
&lt;/h4&gt;

&lt;p&gt;In &lt;strong&gt;computer graphics&lt;/strong&gt;, where accuracy and speed are essential for rendering, the &lt;strong&gt;Newton-Raphson Method&lt;/strong&gt; is commonly employed for root-finding in 3D rendering algorithms like &lt;strong&gt;ray tracing&lt;/strong&gt;. When computing intersections between light rays and surfaces, for example, Newton-Raphson can quickly hone in on the root, providing the intersection point in a minimal number of iterations, especially when the function is smooth and differentiable.&lt;/p&gt;

&lt;p&gt;Though &lt;strong&gt;Brent’s Method&lt;/strong&gt; and the &lt;strong&gt;Secant Method&lt;/strong&gt; can offer reliable solutions in more complex scenarios, when you know the derivative and can make an initial guess, &lt;strong&gt;Newton-Raphson&lt;/strong&gt; will typically outperform them, achieving results in far fewer iterations.&lt;/p&gt;

&lt;h4&gt;
  
  
  Economics: Solving Market Equilibrium Problems
&lt;/h4&gt;

&lt;p&gt;In &lt;strong&gt;economics&lt;/strong&gt;, finding market equilibrium involves solving nonlinear equations that represent supply and demand curves. The &lt;strong&gt;Newton-Raphson Method&lt;/strong&gt; is often used here for its speed in iteratively refining the estimate of the equilibrium price and quantity, especially when good initial guesses are available. For example, finding the point where supply equals demand often involves solving nonlinear equations that describe complex economic systems.&lt;/p&gt;

&lt;p&gt;On the other hand, if the function is difficult to differentiate, or if you're uncertain about the initial guess, the &lt;strong&gt;Bisection Method&lt;/strong&gt; can be a useful fallback, but it is slower, requiring more iterations to arrive at an accurate solution.&lt;/p&gt;




&lt;h3&gt;
  
  
  5. Choosing the Right Method: Linear vs. Quadratic Convergence
&lt;/h3&gt;

&lt;p&gt;When deciding between the &lt;strong&gt;Bisection Method&lt;/strong&gt; and the &lt;strong&gt;Newton-Raphson Method&lt;/strong&gt;, the key distinction lies in their &lt;strong&gt;convergence behavior&lt;/strong&gt; and the trade-offs between &lt;strong&gt;reliability&lt;/strong&gt; and &lt;strong&gt;speed&lt;/strong&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;Bisection Method: Guaranteed Convergence but Slow&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;The &lt;strong&gt;Bisection Method&lt;/strong&gt; is a &lt;strong&gt;reliable, guaranteed converging method&lt;/strong&gt;. As long as you can identify an interval where the function changes sign (i.e., 
&lt;span class="katex-element"&gt;
  &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;f(a)⋅f(b)&amp;lt;0f(a) \cdot f(b) &amp;lt; 0&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;f&lt;/span&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord mathnormal"&gt;a&lt;/span&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;⋅&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;f&lt;/span&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord mathnormal"&gt;b&lt;/span&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;&amp;lt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;0&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;
), the method will always converge to a root, provided the function is continuous. However, the &lt;strong&gt;rate of convergence is linear&lt;/strong&gt;, meaning that each step only reduces the error by a constant factor, typically halving the interval at each iteration. For a function with a relatively simple form and when you don't have access to the derivative, this method can be quite useful.&lt;/p&gt;

&lt;p&gt;However, in scenarios where the precision and speed are paramount (such as real-time computations in engineering, economics, or graphics), &lt;strong&gt;Bisection’s slow convergence can become a bottleneck&lt;/strong&gt;. It requires a larger number of iterations to achieve the same level of accuracy compared to faster methods like &lt;strong&gt;Newton-Raphson&lt;/strong&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;Newton-Raphson Method: Rapid Convergence for Smooth Functions&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;The &lt;strong&gt;Newton-Raphson Method&lt;/strong&gt; is favored in many applications where &lt;strong&gt;faster convergence is required&lt;/strong&gt;. Its &lt;strong&gt;quadratic convergence&lt;/strong&gt; means that with each iteration, the error is roughly squared (or halved at an exponentially faster rate). This makes it an &lt;strong&gt;extremely fast method&lt;/strong&gt; when the initial guess is close to the true root, as the number of correct digits roughly doubles with each step.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Example of Speed&lt;/strong&gt;: If the error after 5 iterations is 0.1, after 6 iterations, the error may drop to 0.01, and after 7 iterations, it could be reduced to 0.0001. This rapid convergence is why Newton-Raphson is preferred for solving equations in fields like &lt;strong&gt;engineering&lt;/strong&gt;, where quick, precise solutions are necessary.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;However, for the Newton-Raphson Method to work optimally, the function must be &lt;strong&gt;smooth&lt;/strong&gt; and &lt;strong&gt;differentiable&lt;/strong&gt;, and a &lt;strong&gt;good initial guess&lt;/strong&gt; is required. If these conditions are met, the method can vastly outperform slower methods like Bisection.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Caveat&lt;/strong&gt;: Newton-Raphson can fail or diverge if the initial guess is too far from the root, or if the derivative is small or zero. This is a limitation compared to Bisection, which guarantees convergence but at a slower pace.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;When to Choose Which Method&lt;/strong&gt;
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Choose the Bisection Method&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;When the function is continuous but not differentiable.&lt;/li&gt;
&lt;li&gt;When you don’t have access to the derivative.&lt;/li&gt;
&lt;li&gt;When you can find an initial interval where the function changes sign.&lt;/li&gt;
&lt;li&gt;When guaranteed, albeit slow, convergence is necessary.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Choose the Newton-Raphson Method&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;When you have access to the derivative and a reasonable initial guess.&lt;/li&gt;
&lt;li&gt;When rapid convergence and efficiency are required.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  - When dealing with smooth, well-behaved functions that allow for reliable derivative computation.
&lt;/h2&gt;


&lt;/li&gt;

&lt;/ul&gt;

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

&lt;p&gt;In this article, we have examined the core principles of &lt;strong&gt;root-finding algorithms&lt;/strong&gt;, focusing on two of the most fundamental methods: the &lt;strong&gt;Bisection Method&lt;/strong&gt; and the &lt;strong&gt;Newton-Raphson Method&lt;/strong&gt;. While the &lt;strong&gt;Bisection Method&lt;/strong&gt; is simple, reliable, and guarantees convergence, its &lt;strong&gt;linear convergence&lt;/strong&gt; makes it slow, especially in cases where speed is critical. On the other hand, the &lt;strong&gt;Newton-Raphson Method&lt;/strong&gt; offers &lt;strong&gt;quadratic convergence&lt;/strong&gt;, allowing it to find roots far more quickly and efficiently, provided the function is smooth and a good initial guess is available.&lt;/p&gt;

&lt;p&gt;In real-world applications across fields like &lt;strong&gt;engineering&lt;/strong&gt;, &lt;strong&gt;computer graphics&lt;/strong&gt;, and &lt;strong&gt;economics&lt;/strong&gt;, the &lt;strong&gt;Newton-Raphson Method&lt;/strong&gt; is often the preferred choice due to its superior speed and precision. However, the &lt;strong&gt;Bisection Method&lt;/strong&gt; still holds value in scenarios where reliability and guaranteed convergence are more important than speed.&lt;/p&gt;

&lt;p&gt;As we move forward in this series, we will explore some real world use cases with their corresponding example code. &lt;/p&gt;

&lt;p&gt;Originally posted at&lt;a href="https://padiazg.github.io/posts/numerical-root-finding-part1/" rel="noopener noreferrer"&gt;Numerical root-finding algorithms: Foundations, theory, and advanced methods. Part 1&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Setting up a local Kubernetes environment with Multipass and bridge networking</title>
      <dc:creator>Patricio Díaz </dc:creator>
      <pubDate>Wed, 13 Nov 2024 03:13:27 +0000</pubDate>
      <link>https://dev.to/padiazg/setting-up-a-local-kubernetes-environment-with-multipass-and-bridge-networking-4cpa</link>
      <guid>https://dev.to/padiazg/setting-up-a-local-kubernetes-environment-with-multipass-and-bridge-networking-4cpa</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Preparing for the Certified Kubernetes Application Developer (CKAD) certification requires a reliable environment for hands-on practice. While cloud providers are often recommended, setting up a local environment can be more cost-effective and provide valuable learning opportunities. In this guide, I'll walk you through creating a robust local Kubernetes environment using Ubuntu's Multipass and bridge networking.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Local Setup?
&lt;/h2&gt;

&lt;p&gt;When I started preparing for my CKAD certification, I wanted an environment that would:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Provide consistent networking between nodes&lt;/li&gt;
&lt;li&gt;Allow full control over the infrastructure&lt;/li&gt;
&lt;li&gt;Minimize costs compared to cloud solutions&lt;/li&gt;
&lt;li&gt;Offer flexibility for experimentation&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Hardware Requirements
&lt;/h2&gt;

&lt;p&gt;Before getting started, ensure your system meets these minimum requirements:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Minimum Requirements:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;CPU: 4 cores (8 threads recommended)&lt;/li&gt;
&lt;li&gt;RAM: 16GB minimum, 32GB recommended&lt;/li&gt;
&lt;li&gt;Storage: 100GB free space (SSD recommended)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;My Test Environment:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;CPU: AMD Ryzen 5 3600 (6 cores, 12 threads)&lt;/li&gt;
&lt;li&gt;RAM: 64GB DDR4&lt;/li&gt;
&lt;li&gt;Storage: 1TB SSD + 1TB HDD + 750GB HDD&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Note: While you can run this setup on lower specifications, you might experience performance issues when running multiple containers and services.&lt;/p&gt;

&lt;h2&gt;
  
  
  System Compatibility
&lt;/h2&gt;

&lt;p&gt;This guide has been tested on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ubuntu 24.10 (host system)&lt;/li&gt;
&lt;li&gt;Ubuntu 22.04 LTS (Jammy) for VMs&lt;/li&gt;
&lt;li&gt;Multipass 1.14.1&lt;/li&gt;
&lt;li&gt;LXD 5.21.2 LTS&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;While the steps should work on other Ubuntu versions (20.04+), you might encounter slight differences in network interface names or default configurations. If you're using Ubuntu 22.04 or earlier, you may need to modify the networkd configuration syntax slightly.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Network Architecture
&lt;/h2&gt;

&lt;p&gt;Before we dive into the setup, let's understand the network architecture we'll be creating:&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%2F972ftbl5glnl5hkndtzm.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%2F972ftbl5glnl5hkndtzm.png" alt="practice-environment-network-diagram" width="800" height="395"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Our setup creates multiple network interfaces:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Bridge Network (br0): Primary network for Kubernetes communication&lt;/li&gt;
&lt;li&gt;Host Network (enp37s0): Connection to external network&lt;/li&gt;
&lt;li&gt;VM Networks: Each VM gets two interfaces

&lt;ul&gt;
&lt;li&gt;enp5s0: Multipass default network&lt;/li&gt;
&lt;li&gt;enp6s0: Bridge network interface&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;
  
  
  Setting Up the Network Bridge
&lt;/h2&gt;

&lt;p&gt;Our first task is creating a dedicated network bridge for our Kubernetes nodes. We'll use &lt;code&gt;systemd-networkd&lt;/code&gt; for this purpose, which provides a robust and modern networking stack.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Preparing the Network Environment
&lt;/h3&gt;

&lt;p&gt;First, we need to disable NetworkManager and enable systemd-networkd:&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="c"&gt;# Disable NetworkManager&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl stop NetworkManager
&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl disable NetworkManager

&lt;span class="c"&gt;# Enable systemd-networkd&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl &lt;span class="nb"&gt;enable &lt;/span&gt;systemd-networkd 
&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl start systemd-networkd 

&lt;span class="c"&gt;# Configure DNS resolution&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl &lt;span class="nb"&gt;enable &lt;/span&gt;systemd-resolved
&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl start systemd-resolved
&lt;span class="nb"&gt;sudo rm&lt;/span&gt; /etc/resolv.conf 
&lt;span class="nb"&gt;sudo ln&lt;/span&gt; &lt;span class="nt"&gt;-s&lt;/span&gt; /run/systemd/resolve/resolv.conf /etc/resolv.conf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Configuring the Bridge
&lt;/h3&gt;

&lt;p&gt;We'll create a bridge network with the following specifications:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Network: 172.19.180.0/24&lt;/li&gt;
&lt;li&gt;Gateway: 172.19.180.254&lt;/li&gt;
&lt;li&gt;DHCP Range: 172.19.180.1 - 172.19.180.253&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Create two configuration files in &lt;code&gt;/etc/systemd/network&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;Bridge device definition (&lt;code&gt;50-br0.netdev&lt;/code&gt;):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ini"&gt;&lt;code&gt;&lt;span class="nn"&gt;[NetDev]&lt;/span&gt;
&lt;span class="py"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;br0&lt;/span&gt;
&lt;span class="py"&gt;Kind&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;bridge&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Bridge network configuration (&lt;code&gt;51-br0-bind.network&lt;/code&gt;):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ini"&gt;&lt;code&gt;&lt;span class="nn"&gt;[Match]&lt;/span&gt;
&lt;span class="py"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;br0&lt;/span&gt;

&lt;span class="nn"&gt;[Network]&lt;/span&gt;
&lt;span class="py"&gt;Address&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;172.19.180.254/24&lt;/span&gt;
&lt;span class="py"&gt;IPForward&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;yes&lt;/span&gt;
&lt;span class="py"&gt;ConfigureWithoutCarrier&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;yes&lt;/span&gt;
&lt;span class="py"&gt;DHCPServer&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;yes&lt;/span&gt;

&lt;span class="nn"&gt;[DHCPServer]&lt;/span&gt;
&lt;span class="py"&gt;PoolSize&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;253&lt;/span&gt;
&lt;span class="py"&gt;EmitRouter&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;yes&lt;/span&gt;
&lt;span class="py"&gt;EmitDNS&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;yes&lt;/span&gt;
&lt;span class="py"&gt;DNS&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;8.8.8.8&lt;/span&gt;

&lt;span class="py"&gt;DefaultLeaseTimeSec&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;600&lt;/span&gt;
&lt;span class="py"&gt;MaxLeaseTimeSec&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;7200&lt;/span&gt;

&lt;span class="nn"&gt;[DHCPServerStaticLease]&lt;/span&gt;
&lt;span class="py"&gt;MACAddress&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;52:54:00:ab:cd:01&lt;/span&gt;
&lt;span class="py"&gt;Address&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;172.19.180.1&lt;/span&gt;

&lt;span class="nn"&gt;[DHCPServerStaticLease]&lt;/span&gt;
&lt;span class="py"&gt;MACAddress&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;52:54:00:ab:cd:02&lt;/span&gt;
&lt;span class="py"&gt;Address&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;172.19.180.2&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Enabling IP Forwarding
&lt;/h3&gt;

&lt;p&gt;To allow communication between nodes and the internet:&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="c"&gt;# enable IP forwarding in the kernel&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;sysctl &lt;span class="nt"&gt;-w&lt;/span&gt; net.ipv4.ip_forward&lt;span class="o"&gt;=&lt;/span&gt;1
&lt;span class="nv"&gt;$ &lt;/span&gt;sysctl &lt;span class="nt"&gt;-w&lt;/span&gt; net.ipv6.conf.default.forwarding&lt;span class="o"&gt;=&lt;/span&gt;1

&lt;span class="c"&gt;# check&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;sysctl net.ipv4.ip_forward
net.ipv4.ip_forward &lt;span class="o"&gt;=&lt;/span&gt; 1

&lt;span class="nv"&gt;$ &lt;/span&gt;sysctl net.ipv6.conf.default.forwarding
net.ipv6.conf.default.forwarding &lt;span class="o"&gt;=&lt;/span&gt; 1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Set forwarding rule for iptables&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="c"&gt;# Configure iptables to allow forwarding&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;iptables &lt;span class="nt"&gt;-P&lt;/span&gt; FORWARD ACCEPT
&lt;span class="c"&gt;# allow nat forwarding to our bridge&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;iptables &lt;span class="nt"&gt;-t&lt;/span&gt; nat &lt;span class="nt"&gt;-A&lt;/span&gt; POSTROUTING &lt;span class="nt"&gt;-o&lt;/span&gt; &amp;lt;host-nic&amp;gt; &lt;span class="nt"&gt;-j&lt;/span&gt; MASQUERADE
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Optional: Make it permanent
&lt;/h3&gt;

&lt;p&gt;Ubuntu comes with &lt;strong&gt;&lt;em&gt;ufw&lt;/em&gt;&lt;/strong&gt; installed by default but it adds lots of restrictions and issues with Multipass regarding DHCP and traffic forwarding so we are going to use plain iptables to manage the firewall rules and make it persistent.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Disclaimer: Follow this steps only if you are sure and did your research about how it will affect your system as they will change the firewall manager for your host. Take this as a suggestion if it works for you.&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# to persist the rules after restarts, it will uninstall ufw in the process and save the existing rules&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt-get &lt;span class="nb"&gt;install &lt;/span&gt;iptables-persistent

&lt;span class="c"&gt;# set default FOrWARD policy to ACCEPT&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;iptables &lt;span class="nt"&gt;-P&lt;/span&gt; FORWARD ACCEPT

&lt;span class="c"&gt;# allow nat forwarding for our brigde network. change enp37s0 with your host interface &lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;iptables &lt;span class="nt"&gt;-t&lt;/span&gt; nat &lt;span class="nt"&gt;-A&lt;/span&gt; POSTROUTING &lt;span class="nt"&gt;-o&lt;/span&gt; enp37s0 &lt;span class="nt"&gt;-j&lt;/span&gt; MASQUERADE

&lt;span class="c"&gt;# save the rules&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;netfilter-persistent save

&lt;span class="c"&gt;# check rules&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;iptables &lt;span class="nt"&gt;-L&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;iptables &lt;span class="nt"&gt;-t&lt;/span&gt; nat &lt;span class="nt"&gt;-L&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Creating Virtual Machines with Multipass
&lt;/h2&gt;

&lt;p&gt;Multipass provides a lightweight way to create Ubuntu VMs. We'll configure it to work with our bridge network.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Setting Up Multipass with LXD
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;snap &lt;span class="nb"&gt;install &lt;/span&gt;lxd
snap connect multipass:lxd lxd
multipass &lt;span class="nb"&gt;set &lt;/span&gt;local.driver&lt;span class="o"&gt;=&lt;/span&gt;lxd
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Launching Kubernetes Nodes
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Control plane node&lt;/span&gt;
multipass launch jammy &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--name&lt;/span&gt; ckad-cp &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--cpus&lt;/span&gt; 2 &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--memory&lt;/span&gt; 8G &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--disk&lt;/span&gt; 20G &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--network&lt;/span&gt; &lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;br0,mode&lt;span class="o"&gt;=&lt;/span&gt;auto,mac&lt;span class="o"&gt;=&lt;/span&gt;52:54:00:ab:cd:01

&lt;span class="c"&gt;# Worker node&lt;/span&gt;
multipass launch jammy &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--name&lt;/span&gt; ckad-wn0 &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--cpus&lt;/span&gt; 2 &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--memory&lt;/span&gt; 8G &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--disk&lt;/span&gt; 20G &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--network&lt;/span&gt; &lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;br0,mode&lt;span class="o"&gt;=&lt;/span&gt;auto,mac&lt;span class="o"&gt;=&lt;/span&gt;52:54:00:ab:cd:02
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Optimizing Network Configuration
&lt;/h3&gt;

&lt;p&gt;To ensure Kubernetes uses the correct network interface, we need to adjust the interface priorities on each node. Here's a quick way to do it using &lt;code&gt;yq&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Install yq&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;wget https://github.com/mikefarah/yq/releases/latest/download/yq_linux_amd64 &lt;span class="nt"&gt;-O&lt;/span&gt; /usr/bin/yq &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;sudo chmod&lt;/span&gt; +x /usr/bin/yq

&lt;span class="c"&gt;# Update netplan configuration&lt;/span&gt;
&lt;span class="nb"&gt;sudo cp&lt;/span&gt; /etc/netplan/50-cloud-init.yaml /etc/netplan/50-cloud-init.yaml.old
&lt;span class="nb"&gt;sudo &lt;/span&gt;yq &lt;span class="s1"&gt;'.network.ethernets.default.match.macaddress as $default | 
        .network.ethernets.extra0.match.macaddress as $extra | 
        .network.ethernets.default.match.macaddress = $extra | 
        .network.ethernets.extra0.match.macaddress = $default'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    /etc/netplan/50-cloud-init.yaml.old | 
    &lt;span class="nb"&gt;sudo tee&lt;/span&gt; /etc/netplan/50-cloud-init.yaml

&lt;span class="c"&gt;# Restart the node&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;reboot
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Troubleshooting Guide
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Common Issues and Solutions
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Bridge Network Not Coming Up&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   &lt;span class="c"&gt;# Check bridge status&lt;/span&gt;
   ip &lt;span class="nb"&gt;link &lt;/span&gt;show br0
   &lt;span class="c"&gt;# If DOWN, try:&lt;/span&gt;
   &lt;span class="nb"&gt;sudo &lt;/span&gt;ip &lt;span class="nb"&gt;link set &lt;/span&gt;br0 up
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;VMs Can't Reach Internet&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Verify IP forwarding:
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt; sysctl net.ipv4.ip_forward
&lt;/code&gt;&lt;/pre&gt;

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

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Check iptables rules:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt; &lt;span class="nb"&gt;sudo &lt;/span&gt;iptables &lt;span class="nt"&gt;-L&lt;/span&gt; &lt;span class="nt"&gt;-v&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Verify DNS resolution:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt; dig @8.8.8.8 google.com
&lt;/code&gt;&lt;/pre&gt;

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

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;DHCP Not Working on Bridge&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Check systemd-networkd logs:
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt; journalctl &lt;span class="nt"&gt;-u&lt;/span&gt; systemd-networkd
&lt;/code&gt;&lt;/pre&gt;

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

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Verify bridge configuration:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt; networkctl status br0
&lt;/code&gt;&lt;/pre&gt;

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

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;VM Network Priority Issues&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Verify interface metrics:
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt; ip route show
&lt;/code&gt;&lt;/pre&gt;

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

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Check netplan configuration:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt; &lt;span class="nb"&gt;cat&lt;/span&gt; /etc/netplan/50-cloud-init.yaml
&lt;/code&gt;&lt;/pre&gt;

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

&lt;h3&gt;
  
  
  Verification Steps
&lt;/h3&gt;

&lt;p&gt;After setup, verify your environment:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Network Connectivity&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   &lt;span class="c"&gt;# From VMs&lt;/span&gt;
   ping 172.19.180.254  &lt;span class="c"&gt;# Should reach bridge&lt;/span&gt;
   ping 8.8.8.8         &lt;span class="c"&gt;# Should reach internet&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Interface Priority&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   &lt;span class="c"&gt;# Should show bridge interface as priority&lt;/span&gt;
   ip route | &lt;span class="nb"&gt;grep &lt;/span&gt;default
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;DNS Resolution&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   &lt;span class="c"&gt;# Should resolve correctly&lt;/span&gt;
   nslookup kubernetes.io
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Performance Optimization Tips
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;VM Resource Allocation&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Don't overcommit CPU cores&lt;/li&gt;
&lt;li&gt;Leave at least 4GB RAM for host system&lt;/li&gt;
&lt;li&gt;Use SSD for VM storage when possible&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Network Performance&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Enable jumbo frames if your network supports it:
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt; &lt;span class="nb"&gt;sudo &lt;/span&gt;ip &lt;span class="nb"&gt;link set &lt;/span&gt;br0 mtu 9000
&lt;/code&gt;&lt;/pre&gt;

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

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Adjust network buffer sizes:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt; &lt;span class="nb"&gt;sudo &lt;/span&gt;sysctl &lt;span class="nt"&gt;-w&lt;/span&gt; net.core.rmem_max&lt;span class="o"&gt;=&lt;/span&gt;16777216
 &lt;span class="nb"&gt;sudo &lt;/span&gt;sysctl &lt;span class="nt"&gt;-w&lt;/span&gt; net.core.wmem_max&lt;span class="o"&gt;=&lt;/span&gt;16777216
&lt;/code&gt;&lt;/pre&gt;

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

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

&lt;p&gt;With this setup, you now have a robust local environment for CKAD preparation. The bridge network configuration ensures reliable communication between nodes, while Multipass provides easy VM management. This environment strikes a balance between functionality and resource efficiency, making it perfect for learning Kubernetes administration.&lt;/p&gt;

&lt;p&gt;Remember to monitor system resources during heavy testing, and consider adjusting VM resources based on your workload requirements. While this setup requires more initial configuration than cloud-based alternatives, it provides valuable hands-on experience with networking and system administration concepts that will serve you well in your Kubernetes journey.&lt;/p&gt;

&lt;p&gt;Next steps would be to install Kubernetes components and configure your cluster following the provided documentation by the course.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Happy practicing!&lt;/em&gt;&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://multipass.run/docs" rel="noopener noreferrer"&gt;Multipass Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.freedesktop.org/software/systemd/man/systemd-networkd.service.html" rel="noopener noreferrer"&gt;systemd-networkd Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/cncf/curriculum" rel="noopener noreferrer"&gt;CKAD Curriculum&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://kubernetes.io/docs/home/" rel="noopener noreferrer"&gt;Kubernetes Documentation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>kubernetes</category>
      <category>ubuntu</category>
      <category>virtualmachine</category>
      <category>networking</category>
    </item>
    <item>
      <title>How to sync your Obsidian vault using GitHub: A complete guide</title>
      <dc:creator>Patricio Díaz </dc:creator>
      <pubDate>Fri, 01 Nov 2024 02:44:56 +0000</pubDate>
      <link>https://dev.to/padiazg/how-to-sync-your-obsidian-vault-using-github-a-complete-guide-2l08</link>
      <guid>https://dev.to/padiazg/how-to-sync-your-obsidian-vault-using-github-a-complete-guide-2l08</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Obsidian has become a powerful tool for note-taking and personal knowledge management, but one question often comes up: "How can I sync my notes across devices?" While Obsidian offers a paid sync service, there's a robust alternative using GitHub that's both free and secure. In this guide, I'll walk you through setting up GitHub synchronization for your Obsidian vault, whether you're on desktop or mobile.&lt;/p&gt;

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

&lt;p&gt;Before we begin, you'll need:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;An Obsidian installation&lt;/li&gt;
&lt;li&gt;A GitHub account&lt;/li&gt;
&lt;li&gt;Basic familiarity with Git concepts (though I'll explain the essential commands)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Setting Up Your GitHub Repository
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Create a private GitHub repository to store your notes&lt;/li&gt;
&lt;li&gt;Generate a personal access token:

&lt;ul&gt;
&lt;li&gt;Navigate to GitHub &lt;em&gt;Settings&lt;/em&gt; → &lt;em&gt;Developer Settings&lt;/em&gt; → &lt;em&gt;Personal access tokens&lt;/em&gt; → &lt;em&gt;Fine-grained tokens&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;Set the following permissions:

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Read&lt;/strong&gt; access to metadata&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Read&lt;/strong&gt; and &lt;strong&gt;Write&lt;/strong&gt; access to code and commit statuses&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Pro Tip&lt;/strong&gt;: While classic tokens work too, fine-grained tokens offer better security through more precise permission control.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Creating Your Obsidian Vault
&lt;/h2&gt;

&lt;p&gt;To ensure a smooth setup, we'll start fresh:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create a new vault in Obsidian&lt;/li&gt;
&lt;li&gt;Choose your preferred name and location&lt;/li&gt;
&lt;li&gt;Remove any default files (like Welcome.md)&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Installing and Configuring the Git Plugin
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Enable community plugins in Obsidian:

&lt;ul&gt;
&lt;li&gt;Go to &lt;em&gt;Vault's setup&lt;/em&gt; → &lt;em&gt;Community plugins&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;Toggle "Turn on community plugins"&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Install the Git plugin by Vinzent:

&lt;ul&gt;
&lt;li&gt;Navigate to &lt;em&gt;Browse&lt;/em&gt; → search for "Git"&lt;/li&gt;
&lt;li&gt;Install and enable the plugin&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Don't worry if you see a message about not finding a valid Git repository—that's expected at this stage.&lt;/p&gt;

&lt;h2&gt;
  
  
  Repository Setup Methods
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Mobile Setup
&lt;/h3&gt;

&lt;p&gt;Mobile devices use a JavaScript implementation of Git called isomorphic-git, making the setup process slightly different:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;In Git plugin settings, scroll to &lt;strong&gt;Authentication/commit author&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Enter your GitHub username&lt;/li&gt;
&lt;li&gt;Paste your personal access token&lt;/li&gt;
&lt;li&gt;Use the command palette to find "git clone an existing remote repo"&lt;/li&gt;
&lt;li&gt;Enter your repository's HTTPS URL&lt;/li&gt;
&lt;li&gt;Select "Vault Root" as the clone directory&lt;/li&gt;
&lt;li&gt;Choose "NO" when asked about existing .obsidian directory&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Desktop Setup
&lt;/h3&gt;

&lt;p&gt;For desktop users, you can use terminal commands for a more traditional Git setup:&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;cd &lt;/span&gt;your/vault/folder
&lt;span class="nb"&gt;rm&lt;/span&gt; &lt;span class="k"&gt;*&lt;/span&gt;
git init
git branch &lt;span class="nt"&gt;-m&lt;/span&gt; master
git remote add origin https://&amp;lt;your-personal-token&amp;gt;@github.com/username/repo.git
git pull origin master
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Important: Managing .gitignore
&lt;/h2&gt;

&lt;p&gt;To prevent synchronization conflicts, create a .gitignore file with these entries:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.obsidian
.trash
.vscode
conflict-files-obsidian-git.md
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On mobile, use the "git edit .gitignore" command from the palette to add these entries.&lt;/p&gt;

&lt;h2&gt;
  
  
  Daily Synchronization Workflow
&lt;/h2&gt;

&lt;p&gt;Once everything is set up, syncing becomes straightforward:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open Git source control (via UI or command palette)&lt;/li&gt;
&lt;li&gt;Stage changed files using the + icon&lt;/li&gt;
&lt;li&gt;Commit changes with the check icon&lt;/li&gt;
&lt;li&gt;Push changes using the upload icon&lt;/li&gt;
&lt;li&gt;Pull updates using the download icon&lt;/li&gt;
&lt;li&gt;
For convenience, there's a "Commit-and-sync" button that combines staging, committing, and syncing into one action.&lt;/li&gt;
&lt;/ol&gt;

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

&lt;p&gt;Setting up GitHub synchronization for Obsidian might seem daunting at first, but it offers a powerful and free way to keep your notes in sync across devices. This setup not only provides version control for your notes but also gives you complete control over your data. With the workflow established here, you can focus on what matters most: capturing and developing your ideas in Obsidian while maintaining a reliable backup of your knowledge base.&lt;br&gt;
Remember to regularly sync your changes and keep your access token secure. Happy note-taking!&lt;/p&gt;

</description>
      <category>git</category>
      <category>github</category>
      <category>obsidian</category>
      <category>productivity</category>
    </item>
    <item>
      <title>From Pi to Sky: How My Kubernetes Cluster Evolved Beyond Raspberry</title>
      <dc:creator>Patricio Díaz </dc:creator>
      <pubDate>Wed, 18 Sep 2024 00:53:10 +0000</pubDate>
      <link>https://dev.to/padiazg/from-pi-to-sky-how-my-kubernetes-cluster-evolved-beyond-raspberry-nf2</link>
      <guid>https://dev.to/padiazg/from-pi-to-sky-how-my-kubernetes-cluster-evolved-beyond-raspberry-nf2</guid>
      <description>&lt;p&gt;Ever embarked on a project that seemed straightforward at first, only to find yourself tumbling down a rabbit hole of challenges and discoveries? That's exactly what happened when I decided to breathe new life into my ageing Kubernetes cluster. What began as a simple upgrade turned into an odyssey through the world of single-board computers, operating systems, and DIY ingenuity.&lt;br&gt;
It all started a few years ago with a Raspberry Pi 2, four Raspberry Pi Zeros, and a cluster hat from 8086.net. Little did I know that this modest setup would lead me on a journey spanning multiple hardware platforms, wrestling with ARM architectures, and ultimately crafting my own solutions to keep my cluster alive and kicking.&lt;br&gt;
In this post, I'll take you through the twists and turns of my cluster resurrection project. From the initial roadblocks of discontinued support to the thrill of discovering alternative hardware, and finally, to the satisfaction of creating custom solutions. Whether you're a fellow tinkerer, a Kubernetes enthusiast, or simply curious about the world of single-board computing, buckle up – this tale of perseverance and problem-solving might just inspire your next tech adventure.&lt;/p&gt;
&lt;h2&gt;
  
  
  A bit of history
&lt;/h2&gt;
&lt;h3&gt;
  
  
  The Initial Setup
&lt;/h3&gt;

&lt;p&gt;It all began a few years ago when I stumbled upon the cluster hats from 8086.net. Intrigued by the possibility of creating my own Kubernetes cluster, I decided to take the plunge. That old Raspberry Pi 2 Model B that had been gathering dust in a drawer finally would have a purpose!&lt;br&gt;
For the cluster nodes, there's nothing to think about, just got some Raspberry Pi Zeros. Little did I know that acquiring these tiny powerhouses would be my first hurdle. Due to their popularity and supply constraints, most suppliers had implemented a strict one-per-customer limit. Undeterred, I embarked on a quest that led me to four different suppliers just to obtain the necessary quartet of Zeros. &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%2Fxueymmm7mhrw8a5u243l.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%2Fxueymmm7mhrw8a5u243l.jpg" alt="cluster-hat-and-four-raspberry-pi-zeros" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With all the hardware in hand, I assembled my cluster. The Raspberry Pi 2 served as the controller, while the four Zeros, neatly arranged on the cluster hats, formed the nodes. I opted for K3s, a lightweight Kubernetes distribution perfect for my modest hardware. For a while, everything hummed along smoothly. My little cluster was up and running, handling tasks and teaching me the ins and outs of Kubernetes management.&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%2Fvkx0p02p89hcya55iy9k.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%2Fvkx0p02p89hcya55iy9k.jpg" alt="all-boards-assembled" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  The Fall of 32-bit and the Quest for Alternatives
&lt;/h3&gt;

&lt;p&gt;The bliss was short-lived. As technology marched forward, K8s and K3s made the decision to drop support for ARM 32-bit architectures. Suddenly, my trusty Raspberry Pi Zeros were obsolete for this purpose. I found myself at a crossroads – should I abandon the project or find a way to adapt?&lt;br&gt;
My first instinct was to look at the Raspberry Pi Zero 2 W, a 64-bit capable successor. However, I quickly ran into familiar problems: high prices and purchase limits. It was déjà vu all over again.&lt;/p&gt;
&lt;h3&gt;
  
  
  Enter the Banana Pi
&lt;/h3&gt;

&lt;p&gt;In my search for alternatives, I stumbled upon the Banana Pi M2 Zero. These boards were not only drop-in replacements with the same form factor and pinout as the Pi Zeros, but they also sported 64-bit processors. Best of all, they were significantly cheaper and had no quantity limitations. &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%2F8zh75e68zqar3wchcadf.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%2F8zh75e68zqar3wchcadf.jpg" alt="orange-pi-on-cluster-hat" width="800" height="756"&gt;&lt;/a&gt;&lt;br&gt;
Thanks to a helpful thread on the Cluster Hat's Google Groups page, I found pre-built images and enough information to get the Banana Pis up and running as nodes. My cluster was back in business, now with 64-bit capable nodes.&lt;/p&gt;
&lt;h3&gt;
  
  
  The Final Evolution: Orange Pi CM4
&lt;/h3&gt;

&lt;p&gt;Recently, I decided it was time for the controller board to join the 64-bit party. In the spirit of exploration (and, admittedly, for the fun of it), I opted for an Orange Pi CM4 with a base board to replace the ageing Raspberry Pi 2. The form factor and pinout matched, making it a perfect candidate.&lt;br&gt;
However, this final upgrade proved to be the most challenging. There were no pre-built images for using the Orange Pi as a controller with the cluster hat. I found myself diving deep into the differences between Raspbian/Raspberry Pi OS and the various operating systems available for the Orange Pi.&lt;/p&gt;
&lt;h3&gt;
  
  
  The Home Stretch: Custom Solutions
&lt;/h3&gt;

&lt;p&gt;Over the next couple of weeks, I immersed myself in learning the intricacies of operating systems for Orange Pi and Banana Pi. I spent countless hours refactoring and updating the original scripts provided by Cluster Hat. It was a journey of discovery, frustration, and ultimately, triumph.&lt;br&gt;
The result of this labor was the creation of two GitHub repositories containing scripts to smoothly create images for both the Orange Pi CM4 controller and the Banana Pi M2 Zero nodes. What started as a simple cluster project had evolved into a deep dive into single-board computing, operating systems, and custom software solutions.&lt;/p&gt;
&lt;h2&gt;
  
  
  Hands on!
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Controller board
&lt;/h3&gt;

&lt;p&gt;The main components used on the controller board:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www.aliexpress.us/item/3256805807016286.html" rel="noopener noreferrer"&gt;Orange Pi CM4 4G32G+CM4 Base Board&lt;/a&gt;: RK3566 CPU, 4G DDR4 RAM, 32G eMMC on-board storage&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.aliexpress.us/item/3256806166171564.html" rel="noopener noreferrer"&gt;A 128G 2242 M.2 NVME PCIe 3.0x4 SSD card&lt;/a&gt; (optional, I plan to use it for PVC provisioning on Kubernetes)&lt;/li&gt;
&lt;li&gt;3.5mm pitch screw terminal. For independently powering the hat, see &lt;a href="//3.5mm%20pitch%20screw%20terminal"&gt;here&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;
  
  
  Get the images
&lt;/h4&gt;
&lt;h5&gt;
  
  
  From the repo
&lt;/h5&gt;

&lt;p&gt;Download the images from  the &lt;a href="https://github.com/padiazg/clusterhat-orangepi-cm4/releases" rel="noopener noreferrer"&gt;releases&lt;/a&gt; page on the repo and skip to the Burn it section below&lt;/p&gt;
&lt;h5&gt;
  
  
  Build them yourself
&lt;/h5&gt;

&lt;p&gt;You might want to fine-tune or customize the images.&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="c"&gt;# clone the repo&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;git clone git@github.com:padiazg/clusterhat-orangepi-cm4.git
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;clusterhat-orangepi-cm4

&lt;span class="c"&gt;# create the required folders&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; build/dest build/img build/mnt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Download a base image from &lt;a href="http://www.orangepi.org/html/hardWare/computerAndMicrocontrollers/service-and-support/Orange-Pi-CM4-1.htm" rel="noopener noreferrer"&gt;here&lt;/a&gt; into the &lt;code&gt;build/img&lt;/code&gt; folder, I use the &lt;a href="https://drive.google.com/file/d/1Y4KED4elo9A2YaJaRleE6WL5iy5carfV/view?usp=drive_link" rel="noopener noreferrer"&gt;Ubuntu Jammy server&lt;/a&gt; image as it was the most updated and flawless from the options available.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I don't provide a shell example for it as there's no way, I think, to download a Google Drive file straightforwardly with wget or curl  &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Time to create the images&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;build

&lt;span class="c"&gt;# you need sudo because of losetup and mount used in the scripts&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;sudo&lt;/span&gt; ./create.sh Orangepicm4_1.0.6

&lt;span class="c"&gt;# once the script has finished the images should be in build/dest&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;ls&lt;/span&gt; &lt;span class="nt"&gt;-l&lt;/span&gt; dest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Burn it &lt;a&gt;&lt;/a&gt;
&lt;/h4&gt;

&lt;p&gt;Burn the image into an SD card by using any method you're comfortable with: Raspberry Pi Imager, Balena Etcher, dd&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="c"&gt;# list the block storages to find your SD&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;lsblk
AME          MAJ:MIN RM   SIZE RO TYPE  MOUNTPOINTS
sda             8:0    0 698,6G  0 disk  
└─sda1          8:1    0 698,6G  0 part  /home/pato/vaults/backup
sdb             8:16   0 931,5G  0 disk  
└─sdb1          8:17   0 931,5G  0 part  /home/pato/vaults/mis-cosas
sdc             8:32   1  29,7G  0 disk  
└─sdc1          8:33   1  29,4G  0 part  
zram0         251:0    0    16G  0 disk  &lt;span class="o"&gt;[&lt;/span&gt;SWAP]
nvme0n1       259:0    0 931,5G  0 disk  
├─nvme0n1p1   259:1    0  1022M  0 part  /boot/efi
├─nvme0n1p2   259:2    0     4G  0 part  /recovery
├─nvme0n1p3   259:3    0 922,5G  0 part  /
└─nvme0n1p4   259:4    0     4G  0 part  
  └─cryptswap 252:0    0     4G  0 crypt &lt;span class="o"&gt;[&lt;/span&gt;SWAP]


&lt;span class="c"&gt;# the SD is at /dev/sdc in this example &lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;umount /dev/sdc 
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;sudo dd &lt;/span&gt;&lt;span class="nv"&gt;bs&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;1M &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;build/dest/Orangepicm4_1.0.6-1-ubuntu_jammy_server_linux5.10.160-ClusterCTRL-CNAT.img &lt;span class="nv"&gt;of&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/dev/sdc &lt;span class="nv"&gt;status&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;progress
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Boot and access the controller
&lt;/h4&gt;

&lt;p&gt;Place the SD card into the board and power it. &lt;br&gt;
Find out what's the IP address assigned to the board, there are many ways but here's one:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;nmap &lt;span class="nt"&gt;-sS&lt;/span&gt; 192.168.1.0/24
...
Nmap scan report &lt;span class="k"&gt;for &lt;/span&gt;pi.hole &lt;span class="o"&gt;(&lt;/span&gt;192.168.1.100&lt;span class="o"&gt;)&lt;/span&gt;
Host is up &lt;span class="o"&gt;(&lt;/span&gt;0.00018s latency&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="nb"&gt;.&lt;/span&gt;
Not shown: 994 closed ports
PORT     STATE SERVICE
22/tcp   open  ssh
53/tcp   open  domain
80/tcp   open  http
81/tcp   open  hosts2-ns
443/tcp  open  https
8443/tcp open  https-alt
MAC Address: DC:A6:32:BB:97:30 &lt;span class="o"&gt;(&lt;/span&gt;Raspberry Pi Trading&lt;span class="o"&gt;)&lt;/span&gt;

Nmap scan report &lt;span class="k"&gt;for &lt;/span&gt;clusterhat-01.local.patodiaz.io &lt;span class="o"&gt;(&lt;/span&gt;192.168.1.110&lt;span class="o"&gt;)&lt;/span&gt;
Host is up &lt;span class="o"&gt;(&lt;/span&gt;0.00045s latency&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="nb"&gt;.&lt;/span&gt;
Not shown: 995 closed ports
PORT     STATE SERVICE
22/tcp   open  ssh
111/tcp  open  rpcbind
2049/tcp open  nfs
5555/tcp open  freeciv
8000/tcp open  http-alt
MAC Address: 00:00:A4:ED:A7:29 &lt;span class="o"&gt;(&lt;/span&gt;Acorn Computers Limited&lt;span class="o"&gt;)&lt;/span&gt;

Nmap scan report &lt;span class="k"&gt;for &lt;/span&gt;cnat.local &lt;span class="o"&gt;(&lt;/span&gt;192.168.1.235&lt;span class="o"&gt;)&lt;/span&gt;
Host is up &lt;span class="o"&gt;(&lt;/span&gt;0.00056s latency&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="nb"&gt;.&lt;/span&gt;
Not shown: 995 closed ports
PORT      STATE SERVICE
22/tcp    open  ssh
111/tcp   open  rpcbind
2049/tcp  open  nfs
5555/tcp  open  freeciv
49175/tcp open  unknown
MAC Address: 00:00:A4:FD:FF:FD &lt;span class="o"&gt;(&lt;/span&gt;Acorn Computers Limited&lt;span class="o"&gt;)&lt;/span&gt;
...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;I leverage Pi-hole's DHCP capabilities to implement MAC address-based static IP assignment for key devices within my local network. This approach allows for consistent addressing of critical nodes. Furthermore, I utilize Pi-hole's local DNS functionality to pair each of these static IP addresses with a corresponding domain name, facilitating easier identification and access to these devices across the network.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You should be able to access the controller now. The default username and password is "pi:clusterctrl"&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;ssh pi@192.168.1.213
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Boot from eMMC
&lt;/h4&gt;

&lt;p&gt;You might also want to use the eMMC storage, so you don't need a SD card to boot. In such a case, you still need the SD to boot the board and copy the OS to the eMMC. This procedure is described in the manual found &lt;a href="http://www.orangepi.org/html/hardWare/computerAndMicrocontrollers/service-and-support/Orange-Pi-CM4-1.html" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Create a bootable SD. Use any base image, or those you created or downloaded from the repo, as long as it can boot the board.&lt;br&gt;
Copy the image to the SD&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="c"&gt;# mount the SD card to copy the image&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;mount /dev/sdc /mnt/p2

&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;cp &lt;/span&gt;dest/Orangepicm4_1.0.6-1-ubuntu_jammy_server_linux5.10.160-ClusterCTRL-CNAT.img /mnt/p2/home/your_user
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Boot the board with the SD, then copy the image to the eMMC&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="c"&gt;# identify the eMMC device&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;ls&lt;/span&gt; /dev/mmcblk&lt;span class="k"&gt;*&lt;/span&gt;boot0 | &lt;span class="nb"&gt;cut&lt;/span&gt; &lt;span class="nt"&gt;-c1-12&lt;/span&gt;&lt;span class="k"&gt;**&lt;/span&gt;
/dev/mmcblk0

&lt;span class="c"&gt;# clear the device, use the device from the prior step&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;sudo dd &lt;/span&gt;&lt;span class="nv"&gt;bs&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;1M &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/dev/zero &lt;span class="nv"&gt;of&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/dev/mmcblk0 &lt;span class="nv"&gt;count&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;5000 &lt;span class="nv"&gt;status&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;progress

&lt;span class="c"&gt;# copy the image&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;sudo dd &lt;/span&gt;&lt;span class="nv"&gt;bs&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;1M &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;Orangepicm4_1.0.6-1-ubuntu_jammy_server_linux5.10.160-ClusterCTRL-CNAT.img &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nv"&gt;of&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/dev/mmcblk0 &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nv"&gt;status&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;progress

&lt;span class="c"&gt;# reboot&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;sync&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; reboot
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Unplug the SD to allow the board to boot from the eMMC.&lt;/p&gt;

&lt;h3&gt;
  
  
  The nodes
&lt;/h3&gt;

&lt;p&gt;As nodes, I'm using four &lt;a href="https://www.aliexpress.us/item/3256803540350120.html" rel="noopener noreferrer"&gt;Banana Pi M2 Zero&lt;/a&gt;. The reasons are that they are cheap, the CPU has four 64-bit cores, and there's no restriction on how many I can buy at once, amongst other improvements you can check on their &lt;a href="https://wiki.banana-pi.org/Banana_Pi_BPI-M2_ZERO" rel="noopener noreferrer"&gt;wiki&lt;/a&gt;&lt;br&gt;
The instructions for creating the images are pretty much the same as those for the controller, so I'll try not to make it longer.&lt;/p&gt;
&lt;h4&gt;
  
  
  Get the images
&lt;/h4&gt;
&lt;h5&gt;
  
  
  From the repo
&lt;/h5&gt;

&lt;p&gt;Download the images from  the &lt;a href="https://github.com/padiazg/clusterhat-bananapi-m2-zero/releases" rel="noopener noreferrer"&gt;releases&lt;/a&gt; page on the repo and skip to the Burn it section below&lt;/p&gt;
&lt;h5&gt;
  
  
  Build them yourself
&lt;/h5&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# clone the repo&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;git clone git@github.com:padiazg/clusterhat-orangepi-cm4.git
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;clusterhat-orangepi-cm4

&lt;span class="c"&gt;# create the required folders&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; build/dest build/img build/mnt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;To get a base image for the BPi M2 Zero that works well with the cluster hat is a bit trickier, mostly because of kernel support for usb-otg which is fundamental for the nodes.&lt;br&gt;
Download the Debian Bullseye base image from &lt;a href="https://github.com/TuryRx/Banana-pi-m2-zero-Images" rel="noopener noreferrer"&gt;here&lt;/a&gt; into the &lt;code&gt;build/img&lt;/code&gt; folder, here's a direct &lt;a href="https://www.mediafire.com/file/ahqfobon44htbud/Armbian_22.08.0-trunk_Bananapim2zero_bullseye_current_5.15.43_Server.rar/file" rel="noopener noreferrer"&gt;link&lt;/a&gt;. This one works as expected, and is the most updated I could successfully make it work.&lt;/p&gt;

&lt;p&gt;I use a custom setting to create images prepared to work with a CNAT controller because it is what I use in my infra. I'll explain later the differences between using a CNAT and a CBRIDGE controller.&lt;/p&gt;

&lt;p&gt;I create a &lt;em&gt;config-local.sh&lt;/em&gt; file next to the config.sh 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="c"&gt;#!/bin/sh&lt;/span&gt;
&lt;span class="nv"&gt;UPGRADE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;1
&lt;span class="nv"&gt;GROWLITE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"2G"&lt;/span&gt;
&lt;span class="nv"&gt;CNAT_IMAGES&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now create the images&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;build

&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;sudo&lt;/span&gt; ./create.sh Armbian_22.08.0  

&lt;span class="c"&gt;# the images should be in build/dest&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;ls&lt;/span&gt; &lt;span class="nt"&gt;-l&lt;/span&gt; dest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Burn it &lt;a&gt;&lt;/a&gt;
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# list the block storages to find your SD&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;lsblk

&lt;span class="c"&gt;# SD is at /dev/sdc for this example &lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;umount /dev/sdc 
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;sudo dd &lt;/span&gt;&lt;span class="nv"&gt;bs&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;1M &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;build/dest/Armbian_22.08.0-1-trunk_Bananapim2zero_bullseye_current_5.15.43-ClusterCTRL-p1-CNAT.img &lt;span class="nv"&gt;of&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/dev/sdc &lt;span class="nv"&gt;status&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;progress
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Boot and access the node
&lt;/h4&gt;

&lt;p&gt;Place the SD card into the node. To start the node we need to use the &lt;code&gt;clusterctrl&lt;/code&gt; tool.&lt;br&gt;
Please read the &lt;a href="https://clusterctrl.com/setup-control" rel="noopener noreferrer"&gt;cluster-hat control page&lt;/a&gt; to get familiarized with the basic tasks&lt;/p&gt;

&lt;p&gt;At the controller&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="c"&gt;# get some info about the cluster-hat&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;clusterctrl status

&lt;span class="c"&gt;# start the P1 node&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;clusterctrl on p1

&lt;span class="c"&gt;# stop the P1 node&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;clusterctrl off p1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's explain a bit the networking&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="c"&gt;## the network interfaces&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;ip &lt;span class="nb"&gt;link
&lt;/span&gt;1: lo: &amp;lt;LOOPBACK,UP,LOWER_UP&amp;gt; mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
    &lt;span class="nb"&gt;link&lt;/span&gt;/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: eth0: &amp;lt;BROADCAST,MULTICAST,UP,LOWER_UP&amp;gt; mtu 1500 qdisc mq state UP mode DEFAULT group default qlen 1000
    &lt;span class="nb"&gt;link&lt;/span&gt;/ether 00:00:a4:ed:a7:29 brd ff:ff:ff:ff:ff:ff
6: wlan0: &amp;lt;BROADCAST,MULTICAST&amp;gt; mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
    &lt;span class="nb"&gt;link&lt;/span&gt;/ether 54:78:c9:0d:8c:34 brd ff:ff:ff:ff:ff:ff
7: brint: &amp;lt;NO-CARRIER,BROADCAST,MULTICAST,UP&amp;gt; mtu 1500 qdisc noqueue state DOWN mode DEFAULT group default qlen 1000
    &lt;span class="nb"&gt;link&lt;/span&gt;/ether ce:90:04:cf:0c:74 brd ff:ff:ff:ff:ff:ff
11: br0: &amp;lt;BROADCAST,MULTICAST,UP,LOWER_UP&amp;gt; mtu 1500 qdisc noqueue state UP mode DEFAULT group default qlen 1000
    &lt;span class="nb"&gt;link&lt;/span&gt;/ether 00:00:a4:ed:a7:29 brd ff:ff:ff:ff:ff:ff
39: ethpi2: &amp;lt;BROADCAST,MULTICAST,UP,LOWER_UP&amp;gt; mtu 1500 qdisc fq_codel master br0 state UNKNOWN mode DEFAULT group default qlen 1000
    &lt;span class="nb"&gt;link&lt;/span&gt;/ether 00:22:82:ff:fe:02 brd ff:ff:ff:ff:ff:ff
41: ethpi3: &amp;lt;BROADCAST,MULTICAST,UP,LOWER_UP&amp;gt; mtu 1500 qdisc fq_codel master br0 state UNKNOWN mode DEFAULT group default qlen 1000
    &lt;span class="nb"&gt;link&lt;/span&gt;/ether 00:22:82:ff:fe:03 brd ff:ff:ff:ff:ff:ff
42: ethpi4: &amp;lt;BROADCAST,MULTICAST,UP,LOWER_UP&amp;gt; mtu 1500 qdisc fq_codel master br0 state UNKNOWN mode DEFAULT group default qlen 1000
    &lt;span class="nb"&gt;link&lt;/span&gt;/ether 00:22:82:ff:fe:04 brd ff:ff:ff:ff:ff:ff
...

&lt;span class="c"&gt;# the addresses assigned to each one&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;ip a
1: lo: &amp;lt;LOOPBACK,UP,LOWER_UP&amp;gt; mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    &lt;span class="nb"&gt;link&lt;/span&gt;/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: eth0: &amp;lt;BROADCAST,MULTICAST,UP,LOWER_UP&amp;gt; mtu 1500 qdisc mq state UP group default qlen 1000
    &lt;span class="nb"&gt;link&lt;/span&gt;/ether 00:00:a4:ed:a7:29 brd ff:ff:ff:ff:ff:ff
    inet 192.168.1.110/24 brd 192.168.1.255 scope global dynamic eth0
       valid_lft 80240sec preferred_lft 80240sec
    inet6 fe80::200:a4ff:feed:a729/64 scope &lt;span class="nb"&gt;link 
       &lt;/span&gt;valid_lft forever preferred_lft forever
3: brint: &amp;lt;NO-CARRIER,BROADCAST,MULTICAST,UP&amp;gt; mtu 1500 qdisc noqueue state DOWN group default qlen 1000
    &lt;span class="nb"&gt;link&lt;/span&gt;/ether ce:90:04:cf:0c:74 brd ff:ff:ff:ff:ff:ff
    inet 172.19.180.254/24 brd 172.19.180.255 scope global brint
       valid_lft forever preferred_lft forever
4: br0: &amp;lt;BROADCAST,MULTICAST,UP,LOWER_UP&amp;gt; mtu 1500 qdisc noqueue state UP group default qlen 1000
    &lt;span class="nb"&gt;link&lt;/span&gt;/ether 00:00:a4:ed:a7:29 brd ff:ff:ff:ff:ff:ff
    inet 172.19.181.254/24 brd 172.19.181.255 scope global br0
       valid_lft forever preferred_lft forever
    inet6 fe80::200:a4ff:feed:a729/64 scope &lt;span class="nb"&gt;link 
       &lt;/span&gt;valid_lft forever preferred_lft forever
5: ethpi1: &amp;lt;BROADCAST,MULTICAST,UP,LOWER_UP&amp;gt; mtu 1500 qdisc fq_codel master br0 state UNKNOWN group default qlen 1000
    &lt;span class="nb"&gt;link&lt;/span&gt;/ether 00:22:82:ff:fe:01 brd ff:ff:ff:ff:ff:ff
    inet6 fe80::222:82ff:feff:fe01/64 scope &lt;span class="nb"&gt;link 
       &lt;/span&gt;valid_lft forever preferred_lft forever
6: ethpi2: &amp;lt;BROADCAST,MULTICAST,UP,LOWER_UP&amp;gt; mtu 1500 qdisc fq_codel master br0 state UNKNOWN group default qlen 1000
    &lt;span class="nb"&gt;link&lt;/span&gt;/ether 00:22:82:ff:fe:02 brd ff:ff:ff:ff:ff:ff
    inet6 fe80::222:82ff:feff:fe02/64 scope &lt;span class="nb"&gt;link 
       &lt;/span&gt;valid_lft forever preferred_lft forever
7: ethpi3: &amp;lt;BROADCAST,MULTICAST,UP,LOWER_UP&amp;gt; mtu 1500 qdisc fq_codel master br0 state UNKNOWN group default qlen 1000
    &lt;span class="nb"&gt;link&lt;/span&gt;/ether 00:22:82:ff:fe:03 brd ff:ff:ff:ff:ff:ff
    inet6 fe80::222:82ff:feff:fe03/64 scope &lt;span class="nb"&gt;link 
       &lt;/span&gt;valid_lft forever preferred_lft forever
8: ethpi4: &amp;lt;BROADCAST,MULTICAST,UP,LOWER_UP&amp;gt; mtu 1500 qdisc fq_codel master br0 state UNKNOWN group default qlen 1000
    &lt;span class="nb"&gt;link&lt;/span&gt;/ether 00:22:82:ff:fe:04 brd ff:ff:ff:ff:ff:ff
    inet6 fe80::222:82ff:feff:fe04/64 scope &lt;span class="nb"&gt;link 
       &lt;/span&gt;valid_lft forever preferred_lft forever
...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;ethpix&lt;/code&gt; interfaces are added to the &lt;code&gt;br0&lt;/code&gt; bridge, they share the &lt;code&gt;171.19.181.0/24&lt;/code&gt; network:&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="c"&gt;# the controller&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;ping 172.19.181.254

&lt;span class="c"&gt;# the P1 node&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;ping 172.19.181.1

&lt;span class="c"&gt;# the P2 node&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;ping 172.19.181.2

&lt;span class="c"&gt;# the P3 node&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;ping 172.19.181.3

&lt;span class="c"&gt;# the P4 node&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;ping 172.19.181.4
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Worth mentioning that the mac-addresses of each node follow the pattern &lt;code&gt;00:22:82:ff:fe:0x&lt;/code&gt; where &lt;code&gt;x&lt;/code&gt; is a number between 1 and 4 matching the node number. This is very useful when assigning IP addresses based on the mac-addresses, especially if we are in a CBRIDGE configuration.&lt;/p&gt;

&lt;p&gt;You should be able to ssh any of the nodes using the info above&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;ssh pi@172.19.181.1 &lt;span class="c"&gt;# P1&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;ssh pi@172.19.181.2 &lt;span class="c"&gt;# P2&lt;/span&gt;
&lt;span class="c"&gt;# and so on&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Difference between CBRIDGE and CNAT
&lt;/h3&gt;

&lt;p&gt;The main difference between the two is how nodes get an IP address, and how the cluster components access the network.&lt;br&gt;
At both configurations the br0 network is configured and each node is assigned the internal ip addresses as mentioned before, but the main difference is how the traffic is routed to the rest of the network and other networks like the internet.&lt;/p&gt;

&lt;p&gt;In a CBRIDGE configuration the nodes get bridged through the controller network and access the network directly. Each node will get an ip address either manually or via an DHCP present in the network, as if it is a device directly connected to the network. &lt;br&gt;
In the other hand, in a CNAT configuration, the nodes traffic is nated and the controller acts as a router hiding the nodes from the outside.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion: Lessons Learned and the Road Ahead
&lt;/h2&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%2Fzpvcve8ukfyjuwj6c51z.png" 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%2Fzpvcve8ukfyjuwj6c51z.png" alt="Image description" width="646" height="161"&gt;&lt;/a&gt;&lt;br&gt;
As I sit back and reflect on this journey, from those first Raspberry Pi Zeros to the current setup with Banana Pi nodes and an Orange Pi controller, I'm struck by how much I've learned and how far this project has come.&lt;br&gt;
What started as a simple desire to build a Kubernetes cluster became a crash course in hardware compatibility, operating system intricacies, and the importance of community knowledge. Each obstacle - from supply constraints to architecture changes - pushed me to think creatively and expand my skillset.&lt;br&gt;
Perhaps the most valuable lesson was the reminder that in the world of technology, change is the only constant. The ability to adapt, whether it's finding alternative hardware or writing custom scripts, is crucial. This project also reinforced the power of open-source communities. Without the shared knowledge and pre-built images from other enthusiasts, many of the hurdles would have been much harder to overcome.&lt;br&gt;
The two GitHub repositories I've created for image creation are not just the end result of this project, but also my contribution back to the community that helped me along the way. I hope that other tinkerers and cluster enthusiasts will find them useful in their own journeys.&lt;br&gt;
Looking ahead, I'm excited about the possibilities this upgraded cluster opens up. With more powerful, 64-bit capable nodes and a controller, I can explore more complex Kubernetes deployments and perhaps even venture into edge computing scenarios. By the way, I already have two Orange Pi Zero 2W with 2GB RAM each, even more powerful than the Banana Pi M2 Zero,and also just saw there are some Radxa ZERO 3W with 4G of RAM, both of them bringing new challenges to this project.&lt;br&gt;
This project may have started with a handful of Pis and a dream, but it's grown into so much more. It's a testament to the joy of problem-solving, the power of perseverance, and the endless possibilities when you're willing to think outside the (Raspberry Pi) box.&lt;br&gt;
So, what's next? Who knows - but I'm certain it will involve more tinkering, learning, and pushing the boundaries of what's possible with these amazing single-board computers. The sky's the limit!&lt;/p&gt;

</description>
      <category>kubernetes</category>
      <category>raspberrypi</category>
      <category>sbc</category>
    </item>
  </channel>
</rss>
