<?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>The Ops Community ⚙️: Divine Odazie</title>
    <description>The latest articles on The Ops Community ⚙️ by Divine Odazie (@kikiodazie).</description>
    <link>https://community.ops.io/kikiodazie</link>
    <image>
      <url>https://community.ops.io/images/jyCliI1dudM2iCtbx6VQXDTWGQ0vgNozFxZ7J65aoJU/rs:fill:90:90/g:sm/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL3Vz/ZXIvcHJvZmlsZV9p/bWFnZS8yNTMvMTgy/YTNiOTMtYzRiYS00/OGI5LWI2OTMtZTM4/NWQ5MjM4ZDExLmpw/ZWc</url>
      <title>The Ops Community ⚙️: Divine Odazie</title>
      <link>https://community.ops.io/kikiodazie</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://community.ops.io/feed/kikiodazie"/>
    <language>en</language>
    <item>
      <title>How to Set Environment Variables on a Linux Machine</title>
      <dc:creator>Divine Odazie</dc:creator>
      <pubDate>Wed, 14 Sep 2022 15:43:11 +0000</pubDate>
      <link>https://community.ops.io/kikiodazie/how-to-set-environment-variables-on-a-linux-machine-591h</link>
      <guid>https://community.ops.io/kikiodazie/how-to-set-environment-variables-on-a-linux-machine-591h</guid>
      <description>&lt;p&gt;This article was originally posted on &lt;a href="https://everythingdevops.dev/how-to-set-environment-variables-on-a-linux-machine/"&gt;Everything DevOps&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;When building software, you start in a development environment (your local computer). You then move to another environment(s) (Staging, QA, etc.), and finally, the production environment where users can use the application. &lt;/p&gt;

&lt;p&gt;While moving through each of these environments, there may be some configuration options that will be different. For example, in development, you may want to test &lt;a href="https://en.wikipedia.org/wiki/Create,_read,_update_and_delete"&gt;CRUD&lt;/a&gt; operations with a dummy database with varying configuration values to the live database with real user data. &lt;/p&gt;

&lt;p&gt;To ensure a seamless workflow and not have to regularly change the database configurations in code when moving to different environments, you can set environment variables for each. &lt;/p&gt;

&lt;p&gt;In this tutorial, you will learn:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What environment variables are, and&lt;/li&gt;
&lt;li&gt;How to set environment variables on a Linux machine. &lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Prerequisite
&lt;/h1&gt;

&lt;p&gt;To follow along in this tutorial, you must have the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Basic knowledge of the terminal.&lt;/li&gt;
&lt;li&gt;Access to a Linux machine — This article uses &lt;a href="https://ubuntu.com/blog/ubuntu-22-04-lts-released"&gt;Ubuntu 22.04 (LTS) x64&lt;/a&gt; distribution.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  What are environment variables?
&lt;/h1&gt;

&lt;p&gt;Environment variables are variables whose values are set outside the code of an application. They are typically set through the built-in functionality of an operating system. Environment variables are made up of name and value pairs, and you can create as many as you wish to be available for reference at a point in time.&lt;/p&gt;

&lt;h1&gt;
  
  
  Setting environment variables on a Linux machine
&lt;/h1&gt;

&lt;p&gt;To set environment variables on a Linux machine, normally, in the shell session of your terminal, you would run the &lt;code&gt;export&lt;/code&gt; command on each environment variable’s name and value like the following:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export ENVIRONMENT_VARIABLE_NAME = &amp;lt;value&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;But doing so, if and when the particular shell session ends, all the environment variables will be lost. All the environment variables will be lost because the &lt;code&gt;export&lt;/code&gt; command exports variables to the shell session’s environment, not the Linux machine environment.  &lt;/p&gt;

&lt;p&gt;To persist environment variables on a Linux machine, in any directory aside from your application’s directory, create an environment file with the vi editor using the following command:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ vi .env
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The above command will create and open a &lt;code&gt;.env&lt;/code&gt; file, then to edit the file using the vi editor, press &lt;code&gt;i&lt;/code&gt; and add your environment variables like in the image below. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/wbLBOUtaVJMRtrfipgYxCRzJe6W928goG9eMbRmy1zM/w:880/mb:500000/ar:1/aHR0cHM6Ly9wYXBl/ci1hdHRhY2htZW50/cy5kcm9wYm94LmNv/bS9zXzg1QkQ1QTgx/N0Y5NEE1QjJEOUI4/ODhFMUY4QjMxOEFB/RkJBM0YwNzk1NTI2/ODNEMjU1REQ4QUI5/QzE0NDhEQTFfMTY2/MDYwMzc5OTgxMV9T/Y3JlZW5zaG90KzIw/MjItMDgtMTUrYXQr/MjMuNDkuNTYucG5n" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/wbLBOUtaVJMRtrfipgYxCRzJe6W928goG9eMbRmy1zM/w:880/mb:500000/ar:1/aHR0cHM6Ly9wYXBl/ci1hdHRhY2htZW50/cy5kcm9wYm94LmNv/bS9zXzg1QkQ1QTgx/N0Y5NEE1QjJEOUI4/ODhFMUY4QjMxOEFB/RkJBM0YwNzk1NTI2/ODNEMjU1REQ4QUI5/QzE0NDhEQTFfMTY2/MDYwMzc5OTgxMV9T/Y3JlZW5zaG90KzIw/MjItMDgtMTUrYXQr/MjMuNDkuNTYucG5n" alt="" width="880" height="418"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After adding your environment variables, to save the file, press &lt;code&gt;esc&lt;/code&gt;, then type &lt;code&gt;:wq&lt;/code&gt; and press &lt;code&gt;enter&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/13qr9dTUdurxpGgDbE1_mxJw7rBDGXq9e9LRHr0KD5A/w:880/mb:500000/ar:1/aHR0cHM6Ly9wYXBl/ci1hdHRhY2htZW50/cy5kcm9wYm94LmNv/bS9zXzg1QkQ1QTgx/N0Y5NEE1QjJEOUI4/ODhFMUY4QjMxOEFB/RkJBM0YwNzk1NTI2/ODNEMjU1REQ4QUI5/QzE0NDhEQTFfMTY2/MDYwMzk1NjMzOV9h/bm5vdGVseV9pbWFn/ZSs0OC5wbmc" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/13qr9dTUdurxpGgDbE1_mxJw7rBDGXq9e9LRHr0KD5A/w:880/mb:500000/ar:1/aHR0cHM6Ly9wYXBl/ci1hdHRhY2htZW50/cy5kcm9wYm94LmNv/bS9zXzg1QkQ1QTgx/N0Y5NEE1QjJEOUI4/ODhFMUY4QjMxOEFB/RkJBM0YwNzk1NTI2/ODNEMjU1REQ4QUI5/QzE0NDhEQTFfMTY2/MDYwMzk1NjMzOV9h/bm5vdGVseV9pbWFn/ZSs0OC5wbmc" alt="" width="880" height="418"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After saving the file, in the root directory of your Linux machine, run &lt;code&gt;$ ls -la&lt;/code&gt; to view all files, including hidden ones, which should show you a &lt;code&gt;.profile&lt;/code&gt; as in the image below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/won78MaQxr5RtrnLGefBgovBi2zKOJFsFBlywfZk4jY/w:880/mb:500000/ar:1/aHR0cHM6Ly9wYXBl/ci1hdHRhY2htZW50/cy5kcm9wYm94LmNv/bS9zXzg1QkQ1QTgx/N0Y5NEE1QjJEOUI4/ODhFMUY4QjMxOEFB/RkJBM0YwNzk1NTI2/ODNEMjU1REQ4QUI5/QzE0NDhEQTFfMTY2/MDYwMjkyNjc5OV9h/bm5vdGVseV9pbWFn/ZSs0NS5wbmc" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/won78MaQxr5RtrnLGefBgovBi2zKOJFsFBlywfZk4jY/w:880/mb:500000/ar:1/aHR0cHM6Ly9wYXBl/ci1hdHRhY2htZW50/cy5kcm9wYm94LmNv/bS9zXzg1QkQ1QTgx/N0Y5NEE1QjJEOUI4/ODhFMUY4QjMxOEFB/RkJBM0YwNzk1NTI2/ODNEMjU1REQ4QUI5/QzE0NDhEQTFfMTY2/MDYwMjkyNjc5OV9h/bm5vdGVseV9pbWFn/ZSs0NS5wbmc" alt="" width="880" height="220"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Open up the profile file with &lt;code&gt;$ vi .profile&lt;/code&gt;,  press &lt;code&gt;i&lt;/code&gt; to edit the file, and at the end of the file, add the following configuration:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;set -o allexport; source /&amp;lt;path_to_the_directory_of_.env_file&amp;gt;/.env; set +o allexport
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The above configuration will loop through all the environment variables you added to the &lt;code&gt;.env&lt;/code&gt; file and set them on the Linux machine.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/iFWcPSnrqZzXLB8BzW-syaQ9xDhkncyBAKLEfG0wFmk/w:880/mb:500000/ar:1/aHR0cHM6Ly9wYXBl/ci1hdHRhY2htZW50/cy5kcm9wYm94LmNv/bS9zXzg1QkQ1QTgx/N0Y5NEE1QjJEOUI4/ODhFMUY4QjMxOEFB/RkJBM0YwNzk1NTI2/ODNEMjU1REQ4QUI5/QzE0NDhEQTFfMTY2/MDYwMzQxODY4N19h/bm5vdGVseV9pbWFn/ZSs0Ny5wbmc" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/iFWcPSnrqZzXLB8BzW-syaQ9xDhkncyBAKLEfG0wFmk/w:880/mb:500000/ar:1/aHR0cHM6Ly9wYXBl/ci1hdHRhY2htZW50/cy5kcm9wYm94LmNv/bS9zXzg1QkQ1QTgx/N0Y5NEE1QjJEOUI4/ODhFMUY4QjMxOEFB/RkJBM0YwNzk1NTI2/ODNEMjU1REQ4QUI5/QzE0NDhEQTFfMTY2/MDYwMzQxODY4N19h/bm5vdGVseV9pbWFn/ZSs0Ny5wbmc" alt="" width="880" height="419"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To save the configuration, press &lt;code&gt;esc&lt;/code&gt;, then type &lt;code&gt;:wq&lt;/code&gt; and press &lt;code&gt;enter&lt;/code&gt; as you did previously.&lt;/p&gt;

&lt;p&gt;To confirm that the configuration took effect and your environment variables have been set, log out of your current shell session, log back in and then run:&lt;/p&gt;

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

&lt;/div&gt;

&lt;p&gt;After running the above command, you should see your environment variables, as shown in the image below. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/YJ0J8CpHNIQxIuT7FfSEN6-Bpv5ts3D90-pV79vAXC8/w:880/mb:500000/ar:1/aHR0cHM6Ly9wYXBl/ci1hdHRhY2htZW50/cy5kcm9wYm94LmNv/bS9zXzg1QkQ1QTgx/N0Y5NEE1QjJEOUI4/ODhFMUY4QjMxOEFB/RkJBM0YwNzk1NTI2/ODNEMjU1REQ4QUI5/QzE0NDhEQTFfMTY2/MDYwNzQ1OTk4Ml9h/bm5vdGVseV9pbWFn/ZSs1MC5wbmc" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/YJ0J8CpHNIQxIuT7FfSEN6-Bpv5ts3D90-pV79vAXC8/w:880/mb:500000/ar:1/aHR0cHM6Ly9wYXBl/ci1hdHRhY2htZW50/cy5kcm9wYm94LmNv/bS9zXzg1QkQ1QTgx/N0Y5NEE1QjJEOUI4/ODhFMUY4QjMxOEFB/RkJBM0YwNzk1NTI2/ODNEMjU1REQ4QUI5/QzE0NDhEQTFfMTY2/MDYwNzQ1OTk4Ml9h/bm5vdGVseV9pbWFn/ZSs1MC5wbmc" alt="" width="880" height="448"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;This tutorial explained environment variables and taught how to set them on a Linux machine. There is more to learn about environment variables in Linux. To learn more, check out the following resources:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.geeksforgeeks.org/environment-variables-in-linux-unix/"&gt;Environment Variables in Linux/Unix&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://linuxize.com/post/how-to-set-and-list-environment-variables-in-linux/"&gt;How to Set and List Environment Variables in Linux&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.guru99.com/linux-environment-variables.html"&gt;List of Environment Variables in Linux/Unix&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>devops</category>
      <category>tutorials</category>
    </item>
    <item>
      <title>How to avoid merge commits when syncing a fork</title>
      <dc:creator>Divine Odazie</dc:creator>
      <pubDate>Mon, 22 Aug 2022 01:21:26 +0000</pubDate>
      <link>https://community.ops.io/kikiodazie/how-to-avoid-merge-commits-when-syncing-a-fork-e9l</link>
      <guid>https://community.ops.io/kikiodazie/how-to-avoid-merge-commits-when-syncing-a-fork-e9l</guid>
      <description>&lt;p&gt;This article was originally posted on &lt;a href="https://everythingdevops.dev/how-to-avoid-merge-commits-when-syncing-a-fork/"&gt;Everything DevOps&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Whenever you work on open source projects, you usually maintain your copy (a &lt;a href="https://docs.github.com/en/get-started/quickstart/fork-a-repo"&gt;fork&lt;/a&gt;) of the original codebase. To propose changes, you open up a &lt;a href="https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/about-pull-requests"&gt;Pull Request (PR)&lt;/a&gt;. After you create a PR, there are chances that during its review process, commits will be made to the original codebase, which will require you to sync your fork. &lt;/p&gt;

&lt;p&gt;To sync your fork with the original codebase, ideally, you would use the web UI provided by your Git hosting service or run a &lt;code&gt;git fetch&lt;/code&gt; and &lt;code&gt;git merge&lt;/code&gt; in your terminal, as indicated in this &lt;a href="https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks/syncing-a-fork"&gt;Github tutorial&lt;/a&gt;. But with a PR open, syncing your fork that way will introduce an unwanted merge commit to your PR. &lt;/p&gt;

&lt;p&gt;In this article, you will learn what merge commits are and how to avoid them with &lt;code&gt;git rebase&lt;/code&gt; when syncing a fork with an original codebase. &lt;/p&gt;

&lt;h2&gt;
  
  
  What is a merge commit?
&lt;/h2&gt;

&lt;p&gt;A merge commit is just like any other commit, it is the state of a repository at a point in time plus the history it evolved from. But there is one thing unique about a merge commit: it has at least two parent commits. &lt;/p&gt;

&lt;p&gt;When you create a merge commit, Git automatically merges the histories of two separate commits. This merge commit can cause conflicts and mess up a project’s Git history if present in a merged PR.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/CbFbuv40j3TA5sLIcnTN6vAiAXVFfvATxZmjO4J_ZMQ/w:880/mb:500000/ar:1/aHR0cHM6Ly9wYXBl/ci1hdHRhY2htZW50/cy5kcm9wYm94LmNv/bS9zXzQwMzhFMjdF/QkI4M0ZDMDYxNTNG/MzE0MjVGRTgzNTIx/OUE3RDA0MTlGNDFB/NjNBMUIyNzgzNkIx/MkVGOTRBMTNfMTY1/OTYzMDU4NTczNV9h/bm5vdGVseV9pbWFn/ZSs0Mi5wbmc" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/CbFbuv40j3TA5sLIcnTN6vAiAXVFfvATxZmjO4J_ZMQ/w:880/mb:500000/ar:1/aHR0cHM6Ly9wYXBl/ci1hdHRhY2htZW50/cy5kcm9wYm94LmNv/bS9zXzQwMzhFMjdF/QkI4M0ZDMDYxNTNG/MzE0MjVGRTgzNTIx/OUE3RDA0MTlGNDFB/NjNBMUIyNzgzNkIx/MkVGOTRBMTNfMTY1/OTYzMDU4NTczNV9h/bm5vdGVseV9pbWFn/ZSs0Mi5wbmc" alt="" width="880" height="66"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The annotated section in the image above shows a merge commit of two parent commits. Here is the &lt;a href="https://github.com/cilium/cilium/commit/fcc7837499b630df4e576396fd28d44007f77db1"&gt;link to the merge commit&lt;/a&gt; to the image.&lt;/p&gt;

&lt;p&gt;Now you know what a merge commit is. Next, you will learn how to avoid it when syncing your fork with an original codebase.  &lt;/p&gt;

&lt;h2&gt;
  
  
  How to avoid merge commits when syncing a fork in Git.
&lt;/h2&gt;

&lt;p&gt;**&lt;br&gt;
To avoid merge commits, you need to &lt;a href="http://git-scm.com/book/en/Git-Branching-Rebasing"&gt;rebase&lt;/a&gt; the changes from the original remote codebase in your local fork before pushing them to your remote fork by following the steps below.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1:&lt;/strong&gt;&lt;br&gt;
Create a link with the original remote repository to track and get the changes from the codebase with the command below:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ git remote add upstream https://github.com/com/original/original.git
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;After running the above command, you will now have two remotes. One for your fork and one for the original codebase. If you run &lt;code&gt;$ git remote -v&lt;/code&gt;, you will see the following:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;origin https://github.com/your_username/your_fork.git (fetch)
origin https://github.com/your_username/your_fork.git (push)
upstream https://github.com/original/original.git (fetch)
upstream https://github.com/original/original.git (push)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;In the above, &lt;code&gt;upstream&lt;/code&gt; refers to the original repository from which you created the fork.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2:&lt;/strong&gt;&lt;br&gt;
In this step, you fetch all the branches of the remote upstream with:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ git fetch upstream
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Step 3:&lt;/strong&gt;&lt;br&gt;
Next, you rewrite your fork’s master with the upstream’s master using &lt;code&gt;git rebase&lt;/code&gt;.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ git rebase upstream/master
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Step 4:&lt;/strong&gt;&lt;br&gt;
Then finally, push the updates to your remote fork. You may need to force the push with “&lt;code&gt;--force&lt;/code&gt;.” &lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ git push origin master --force
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; &lt;br&gt;
You can skip the &lt;code&gt;git fetch&lt;/code&gt; step by using &lt;code&gt;git pull&lt;/code&gt; which is &lt;code&gt;git fetch&lt;/code&gt; + &lt;code&gt;git merge&lt;/code&gt; but with the &lt;code&gt;--&lt;/code&gt;&lt;code&gt;rebase&lt;/code&gt;  flag to override the &lt;code&gt;git merge&lt;/code&gt;. The pull command will be:&lt;/p&gt;



&lt;br&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ git pull --rebase upstream master&lt;br&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
&lt;br&gt;
  &lt;br&gt;
  &lt;br&gt;
  Conclusion&lt;br&gt;
&lt;/h2&gt;

&lt;p&gt;In this article, you learned about merge commits and how you can avoid them when syncing your fork in Git using &lt;code&gt;git rebase&lt;/code&gt;. There is a lot more to learn about &lt;code&gt;git rebase&lt;/code&gt;. To learn more, check out the following resources:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://git-scm.com/docs/git-rebase"&gt;Git rebase official documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.simplilearn.com/what-is-git-rebase-command-article"&gt;What is Git Rebase, and How Do You Use It?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.baeldung.com/git-merge-vs-rebase"&gt;Difference Between git merge and rebase&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>github</category>
      <category>tutorials</category>
    </item>
    <item>
      <title>Building x86 Images on an Apple M1 Chip</title>
      <dc:creator>Divine Odazie</dc:creator>
      <pubDate>Tue, 16 Aug 2022 14:59:07 +0000</pubDate>
      <link>https://community.ops.io/kikiodazie/building-x86-images-on-an-apple-m1-chip-5f93</link>
      <guid>https://community.ops.io/kikiodazie/building-x86-images-on-an-apple-m1-chip-5f93</guid>
      <description>&lt;p&gt;This article was originally posted on &lt;a href="https://everythingdevops.dev/building-x86-images-on-an-apple-m1-chip/"&gt;Everything DevOps&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;A few months ago, while deploying an application in Amazon Elastic Kubernetes Service (EKS), my pods crashed with a  &lt;code&gt;standard_init_linux.go:228: exec user process caused: exec format error&lt;/code&gt; error.&lt;/p&gt;

&lt;p&gt;After a bit of research, I found out that the error tends to happen when the architecture an image is built on differs from the architecture it is running on. I then remembered that I was building the image on a MacBook with Apple M1 Chip which is based on &lt;a href="https://en.wikipedia.org/wiki/ARM_architecture_family"&gt;ARM64&lt;/a&gt; architecture, and the worker nodes in the EKS cluster I deployed on are based on &lt;a href="https://en.wikipedia.org/wiki/X86"&gt;x86&lt;/a&gt; architecture. &lt;/p&gt;

&lt;p&gt;I had two options to fix the error: create new ARM-based worker nodes or build the image on x86 architecture. I couldn’t create new worker nodes for obvious reasons, so I had to figure out how to build x86 images on my Apple M1 chip.&lt;/p&gt;

&lt;p&gt;In this article, I will walk you through how I built my application’s Docker image with x86 architecture on an Apple M1 chip using &lt;a href="https://docs.docker.com/build/buildx/"&gt;Docker Buildx&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Docker Buildx?
&lt;/h2&gt;

&lt;p&gt;Docker Buildx is a CLI plugin that extends the docker command. Docker Buildx provides the same user experience as &lt;code&gt;docker build&lt;/code&gt; with many new features like the ability to specify the target architecture for which Docker should build the image. These new features are made possible with the help of the &lt;a href="https://github.com/moby/buildkit"&gt;Moby BuildKit&lt;/a&gt; builder toolkit.&lt;/p&gt;

&lt;p&gt;Before you can build x86-64 images on an Apple M1 chip with Docker Buildx, you first need to install Docker Buildx.&lt;/p&gt;

&lt;h2&gt;
  
  
  Installing Docker Buildx
&lt;/h2&gt;

&lt;p&gt;If you use &lt;a href="https://docs.docker.com/desktop/"&gt;Docker Desktop&lt;/a&gt; or have Docker version 20.x, Docker Buildx is already included in it, and you don’t need a separate installation. Verify that you have Docker Buildx with:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker buildx version
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;But if you are like me that use another tool to get the Docker runtime, install Docker Buildx through the binary with the following commands:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ ARCH=arm64
$ VERSION=v0.8.2 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The above commands set temporary environment variables for the architecture and version of the Docker Buildx binary you will download. See the Docker Buildx &lt;a href="https://github.com/docker/buildx/releases/latest"&gt;releases page on GitHub&lt;/a&gt; for the latest version. &lt;/p&gt;

&lt;p&gt;After setting the temporary environment variables, download the binary with:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ curl -LO https://github.com/docker/buildx/releases/download/${VERSION}/buildx-${VERSION}.darwin-${ARCH}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;After downloading the binary, create a folder in your home directory to hold Docker CLI plugins with:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ mkdir -p ~/.docker/cli-plugins
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Then move the binary to the Docker CLI plugins folder with:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ mv buildx-${VERSION}.darwin-${ARCH} ~/.docker/cli-plugins/docker-buildx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;After that, make the binary executable with:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ chmod +x ~/.docker/cli-plugins/docker-buildx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;To verify the installation, run:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ docker buildx version 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
  
  
  Building x86-64 images on an Apple M1 chip with Docker Buildx
&lt;/h2&gt;

&lt;p&gt;After installing Docker Buildx, you can now easily build your application image to x86-64 on an Apple M1 chip with this command:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ docker buildx build --platform=linux/amd64 -t &amp;lt;image-name&amp;gt; .
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;In the above command:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;buildx&lt;/code&gt; builds the image using the BuildKit engine and does not require the &lt;code&gt;DOCKER_BUILDKIT=1&lt;/code&gt; environment variable to start the builds.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;--platform&lt;/code&gt; flag specifies the target architecture (platform) to build the image for. In this case, &lt;code&gt;linux/amd64&lt;/code&gt;, which is of x86 architecture.&lt;/li&gt;
&lt;li&gt;And the &lt;code&gt;&amp;lt;image-name&amp;gt;&lt;/code&gt; is a placeholder for putting an image tag.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/usmoaKPqL76yKhkQf_IEwfVDE4LGKNY2td9KVUKk_i8/w:880/mb:500000/ar:1/aHR0cHM6Ly9wYXBl/ci1hdHRhY2htZW50/cy5kcm9wYm94LmNv/bS9zXzdDNTA5MUZE/NjA5NkI3Q0Q4RjEz/QzA3MzZDQTQwQUM1/MThEN0U5N0ZBOTIy/MzY4MDFFOUNGMDVF/OEJFRkRBRENfMTY1/OTAyOTg1ODQ4NV9h/bm5vdGVseV9pbWFn/ZSs0MC5wbmc" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/usmoaKPqL76yKhkQf_IEwfVDE4LGKNY2td9KVUKk_i8/w:880/mb:500000/ar:1/aHR0cHM6Ly9wYXBl/ci1hdHRhY2htZW50/cy5kcm9wYm94LmNv/bS9zXzdDNTA5MUZE/NjA5NkI3Q0Q4RjEz/QzA3MzZDQTQwQUM1/MThEN0U5N0ZBOTIy/MzY4MDFFOUNGMDVF/OEJFRkRBRENfMTY1/OTAyOTg1ODQ4NV9h/bm5vdGVseV9pbWFn/ZSs0MC5wbmc" alt="building the image with buildx" width="880" height="551"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To verify that Docker built the image to &lt;code&gt;linux/amd64&lt;/code&gt;, use the &lt;code&gt;docker image inspect &amp;lt;image_name&amp;gt;&lt;/code&gt; command as you can see annotated screenshot above. &lt;/p&gt;

&lt;p&gt;The inspect command will display detailed information about the image in JSON format. Scroll down, and you should see the &lt;code&gt;Architecture&lt;/code&gt; and &lt;code&gt;Os&lt;/code&gt; information as in the image below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/DEvhMgpY9-i_DqFyGMxRo7ScbJxzpRST8CbeLKF9FK8/w:880/mb:500000/ar:1/aHR0cHM6Ly9wYXBl/ci1hdHRhY2htZW50/cy5kcm9wYm94LmNv/bS9zXzdDNTA5MUZE/NjA5NkI3Q0Q4RjEz/QzA3MzZDQTQwQUM1/MThEN0U5N0ZBOTIy/MzY4MDFFOUNGMDVF/OEJFRkRBRENfMTY1/OTAzMDI0MzE0N19h/bm5vdGVseV9pbWFn/ZSs0MS5wbmc" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/DEvhMgpY9-i_DqFyGMxRo7ScbJxzpRST8CbeLKF9FK8/w:880/mb:500000/ar:1/aHR0cHM6Ly9wYXBl/ci1hdHRhY2htZW50/cy5kcm9wYm94LmNv/bS9zXzdDNTA5MUZE/NjA5NkI3Q0Q4RjEz/QzA3MzZDQTQwQUM1/MThEN0U5N0ZBOTIy/MzY4MDFFOUNGMDVF/OEJFRkRBRENfMTY1/OTAzMDI0MzE0N19h/bm5vdGVseV9pbWFn/ZSs0MS5wbmc" alt="Showing image architecture" width="880" height="551"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;This article explored building images based on x86 architecture on an Apple M1 chip using Docker Buildx. There is so much more to learn about Docker Buildx. To learn more, check out the following resources:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://kubesimplify.com/the-secret-gems-behind-building-container-images-enter-buildkit-and-docker-buildx"&gt;The secret gems behind building container images, Enter: BuildKit &amp;amp; Docker Buildx&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://medium.com/@artur.klauser/building-multi-architecture-docker-images-with-buildx-27d80f7e2408"&gt;Building Multi-Architecture Docker Images With Buildx&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.circleci.com/hc/en-us/articles/360058095471-How-To-Use-Docker-Buildx-in-Remote-Docker-"&gt;How To Use Docker Buildx in Remote Docker?&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>devops</category>
      <category>tutorials</category>
      <category>docker</category>
      <category>cloudops</category>
    </item>
    <item>
      <title>Kubernetes Architecture Explained: Worker Nodes in a Cluster</title>
      <dc:creator>Divine Odazie</dc:creator>
      <pubDate>Mon, 08 Aug 2022 19:14:09 +0000</pubDate>
      <link>https://community.ops.io/kikiodazie/kubernetes-architecture-explained-worker-nodes-in-a-cluster-15ej</link>
      <guid>https://community.ops.io/kikiodazie/kubernetes-architecture-explained-worker-nodes-in-a-cluster-15ej</guid>
      <description>&lt;p&gt;This article was originally posted on &lt;a href="https://everythingdevops.dev/kubernetes-architecture-explained-worker-nodes-in-a-cluster/"&gt;Everything DevOps&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;When you deploy Kubernetes, you get a cluster. And the cluster you get upon deployment would consist of one or more worker machines (virtual or physical) called nodes for you to run your containerized applications in pods.&lt;/p&gt;

&lt;p&gt;For each worker node to run containerized applications, it must contain a &lt;strong&gt;container runtime&lt;/strong&gt; for running the containers, a &lt;strong&gt;kubelet&lt;/strong&gt; to ensure everything runs, and the &lt;strong&gt;kube-proxy&lt;/strong&gt; for handling networking. &lt;/p&gt;

&lt;p&gt;In this article, you will learn more about what each of the above components does to enable the running of containerized applications in a Kubernetes cluster. &lt;/p&gt;

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

&lt;p&gt;To properly understand this article, you should have an understanding of the Kubernetes control plane.&lt;/p&gt;

&lt;h2&gt;
  
  
  Container runtime
&lt;/h2&gt;

&lt;p&gt;The &lt;strong&gt;container runtime&lt;/strong&gt; in a worker node is responsible for running containers. The &lt;strong&gt;container runtime&lt;/strong&gt; is also responsible for pulling container images from a repository, monitoring local system resources, isolating system resources for the use of a container, and managing the container lifecycle. &lt;/p&gt;

&lt;p&gt;In Kubernetes, there is support for container runtimes such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://containerd.io/"&gt;containerd&lt;/a&gt;: An industry-standard container runtime with an emphasis on simplicity, robustness, and portability.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://cri-o.io/"&gt;CRI-O&lt;/a&gt;: A lightweight container runtime specifically built for Kubernetes.&lt;/li&gt;
&lt;li&gt;And any other implementation of the &lt;a href="https://github.com/kubernetes/community/blob/master/contributors/devel/sig-node/container-runtime-interface.md"&gt;Kubernetes Container Runtime Interface (CRI)&lt;/a&gt; —  a plugin enabling the kubelet to use other container runtimes without recompiling.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You may wonder why you didn’t see Docker (a major container runtime) in the list above. Docker isn’t there because of the &lt;a href="https://kubernetes.io/blog/2022/02/17/dockershim-faq/"&gt;removal of dockershim&lt;/a&gt; — the component that allows use of Docker as a container runtime — in Kubernetes release v1.24. &lt;/p&gt;

&lt;p&gt;But not to worry, you can still use Docker as a container runtime in Kubernetes using the &lt;a href="https://github.com/Mirantis/cri-dockerd"&gt;cri-dockerd&lt;/a&gt; adapter. cri-dockerd provides a &lt;a href="https://stackoverflow.com/questions/2116142/what-is-a-shim"&gt;shim&lt;/a&gt; for Docker Engine that lets you control Docker via the Kubernetes CRI. ****&lt;/p&gt;

&lt;h2&gt;
  
  
  kubelet
&lt;/h2&gt;

&lt;p&gt;The &lt;strong&gt;kubelet&lt;/strong&gt; is the primary Kubernetes node agent. The &lt;strong&gt;kubelet&lt;/strong&gt; is responsible for running the containers for the pods scheduled to its node. The &lt;strong&gt;kubelet&lt;/strong&gt; runs on every machine (control plane, too) in the cluster. &lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;kubelet&lt;/strong&gt; for each node keeps a watch on pod resources in the control plane’s &lt;strong&gt;kube-apiserver.&lt;/strong&gt; Whenever the &lt;strong&gt;kube-scheduler&lt;/strong&gt; assigns a pod to a node, the &lt;strong&gt;kubelet&lt;/strong&gt; for that node reads the PodSpec (a YAML or JSON object that describes a pod) and instructs the container runtime using the CRI to spin up containers to satisfy that spec. The &lt;strong&gt;container runtime&lt;/strong&gt; will then pull the container images if they aren’t present in the node and start them. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/QOebb25RabH1BqLGbWYie9sJuFzCQ737RVnkM_FIQuY/w:880/mb:500000/ar:1/aHR0cHM6Ly9wYXBl/ci1hdHRhY2htZW50/cy5kcm9wYm94LmNv/bS9zX0VFQzBEMDE4/MEJDNkYxODZDMDRE/OEQyRkE3MEJBNzQy/QkE2OTlFMzlFNDRD/MTI0MUIxODcxNDQy/MDA5RjlEMkRfMTY1/ODI2NDc5MDYxN19T/Y3JlZW5zaG90KzIw/MjItMDctMTkrYXQr/MjIuMDYuMjUucG5n" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/QOebb25RabH1BqLGbWYie9sJuFzCQ737RVnkM_FIQuY/w:880/mb:500000/ar:1/aHR0cHM6Ly9wYXBl/ci1hdHRhY2htZW50/cy5kcm9wYm94LmNv/bS9zX0VFQzBEMDE4/MEJDNkYxODZDMDRE/OEQyRkE3MEJBNzQy/QkE2OTlFMzlFNDRD/MTI0MUIxODcxNDQy/MDA5RjlEMkRfMTY1/ODI2NDc5MDYxN19T/Y3JlZW5zaG90KzIw/MjItMDctMTkrYXQr/MjIuMDYuMjUucG5n" alt="kubelet working" width="880" height="436"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It is important to note that the &lt;strong&gt;kubelet&lt;/strong&gt; is a Kubernetes component that does not run in a container. The &lt;strong&gt;kubelet,&lt;/strong&gt; along with the &lt;strong&gt;container runtime,&lt;/strong&gt; are installed and run directly on the machine that forms the node in the cluster, and that’s why they are responsible for managing the containerized workloads. &lt;/p&gt;

&lt;h2&gt;
  
  
  kube-proxy
&lt;/h2&gt;

&lt;p&gt;Like the &lt;strong&gt;kubelet&lt;/strong&gt;, &lt;strong&gt;kube-proxy&lt;/strong&gt; runs on every node in the cluster, but unlike the kubelet, kube-proxy typically runs in a Kubernetes pod as a part of a Kubernetes &lt;a href="https://kubernetes.io/docs/concepts/workloads/controllers/daemonset/"&gt;DaemonSet&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;kube-proxy&lt;/strong&gt; implements essential functionalities for Kubernetes services.  &lt;strong&gt;kube-proxy&lt;/strong&gt; maintains network rules that allow communication to your Pods from network sessions inside or outside your cluster.&lt;/p&gt;

&lt;p&gt;To dig deep into kube-proxy’s role, you must understand how &lt;strong&gt;Service&lt;/strong&gt; resources work in Kubernetes. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Service in Kubernetes&lt;/strong&gt;&lt;br&gt;
A &lt;strong&gt;Service&lt;/strong&gt; provides a stable IP address for connecting to pods. There are &lt;strong&gt;Service&lt;/strong&gt; resources in Kubernetes because without them:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;When a client application needs to connect to server pods in a cluster, it would need to retrieve and maintain a list of each pod’s IP address, which will burden the client.&lt;/li&gt;
&lt;li&gt;And also, it will be hard to maintain those connections, seeing that in Kubernetes, pods will come and go due to scaling, update or hardware failure.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/7aVx3RcL6v2hyIHVv4dWcdUZALWec_wsy_Pllu67S3U/w:880/mb:500000/ar:1/aHR0cHM6Ly9wYXBl/ci1hdHRhY2htZW50/cy5kcm9wYm94LmNv/bS9zX0VFQzBEMDE4/MEJDNkYxODZDMDRE/OEQyRkE3MEJBNzQy/QkE2OTlFMzlFNDRD/MTI0MUIxODcxNDQy/MDA5RjlEMkRfMTY1/ODI3MjExNTQ4Ml9T/Y3JlZW5zaG90KzIw/MjItMDctMjArYXQr/MDAuMDguMjgucG5n" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/7aVx3RcL6v2hyIHVv4dWcdUZALWec_wsy_Pllu67S3U/w:880/mb:500000/ar:1/aHR0cHM6Ly9wYXBl/ci1hdHRhY2htZW50/cy5kcm9wYm94LmNv/bS9zX0VFQzBEMDE4/MEJDNkYxODZDMDRE/OEQyRkE3MEJBNzQy/QkE2OTlFMzlFNDRD/MTI0MUIxODcxNDQy/MDA5RjlEMkRfMTY1/ODI3MjExNTQ4Ml9T/Y3JlZW5zaG90KzIw/MjItMDctMjArYXQr/MDAuMDguMjgucG5n" alt="Service working" width="880" height="466"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With the above setup using a &lt;strong&gt;Service&lt;/strong&gt; resource, the client will just need the address of the &lt;strong&gt;Service,&lt;/strong&gt; and the rest is taken care of for you automatically. &lt;/p&gt;

&lt;p&gt;And how that’s taken care of automatically is that when you create a &lt;strong&gt;Service&lt;/strong&gt; with a &lt;code&gt;selector&lt;/code&gt; that references a &lt;code&gt;label&lt;/code&gt; applied to a set of pods, the &lt;strong&gt;Endpoints controller&lt;/strong&gt; in the &lt;strong&gt;kube-controller-manager&lt;/strong&gt; will create an &lt;strong&gt;Endpoints&lt;/strong&gt; resource with the pods IP addresses. In the &lt;strong&gt;Endpoints&lt;/strong&gt; resource, the addresses are maintained and if they change, they will be updated automatically and the client’s requests routed accordingly. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/CiAl4Q7p71mDOQkqBcnCnQxd4hhs_0dr6V4ie7Vg6Ko/w:880/mb:500000/ar:1/aHR0cHM6Ly9wYXBl/ci1hdHRhY2htZW50/cy5kcm9wYm94LmNv/bS9zX0VFQzBEMDE4/MEJDNkYxODZDMDRE/OEQyRkE3MEJBNzQy/QkE2OTlFMzlFNDRD/MTI0MUIxODcxNDQy/MDA5RjlEMkRfMTY1/ODI3NTM4MTE5NF9T/Y3JlZW5zaG90KzIw/MjItMDctMjArYXQr/MDEuMDIuNTQucG5n" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/CiAl4Q7p71mDOQkqBcnCnQxd4hhs_0dr6V4ie7Vg6Ko/w:880/mb:500000/ar:1/aHR0cHM6Ly9wYXBl/ci1hdHRhY2htZW50/cy5kcm9wYm94LmNv/bS9zX0VFQzBEMDE4/MEJDNkYxODZDMDRE/OEQyRkE3MEJBNzQy/QkE2OTlFMzlFNDRD/MTI0MUIxODcxNDQy/MDA5RjlEMkRfMTY1/ODI3NTM4MTE5NF9T/Y3JlZW5zaG90KzIw/MjItMDctMjArYXQr/MDEuMDIuNTQucG5n" alt="Endpoints controller working" width="880" height="426"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the above image, you might get the impression that a &lt;strong&gt;Service&lt;/strong&gt; is a literal proxy that load balances requests to backends like Nginx. But that’s almost not the case in modern Kubernetes clusters. &lt;/p&gt;

&lt;p&gt;Now with your understanding of &lt;strong&gt;Service&lt;/strong&gt; resources, let’s dig into how &lt;strong&gt;kube-proxy&lt;/strong&gt; implements essential functionalities for Kubernetes services.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How kube-proxy implements functionalities for Kubernetes Service resources.&lt;/strong&gt;&lt;br&gt;
There is an &lt;strong&gt;Endpoints controller&lt;/strong&gt; in the &lt;strong&gt;kube-controller-manager&lt;/strong&gt; that manages the endpoint resources. The &lt;strong&gt;Endpoints controller&lt;/strong&gt; also manages the associations between services and pods. &lt;/p&gt;

&lt;p&gt;With the &lt;strong&gt;kube-proxy&lt;/strong&gt; running on each node in the cluster, it watches &lt;strong&gt;Service&lt;/strong&gt; and &lt;strong&gt;Endpoint&lt;/strong&gt; resources. So when a change that needs updating occurs, the &lt;strong&gt;kube-proxy&lt;/strong&gt; will update the rules in iptables. iptables is a network packet filtering utility that allows rules to be set in the network stack of the Linux kernel. &lt;/p&gt;

&lt;p&gt;Now, when a client pod sends a request to a &lt;strong&gt;Service’s&lt;/strong&gt; IP, the Linux kernel routes the request to one of the pod’s IP according to the rule &lt;strong&gt;kube-proxy&lt;/strong&gt; sets.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: kube-proxy supports alternatives to using iptables to manage network packet routing. But iptables is the most common and suitable for the majority of installations.&lt;/p&gt;

&lt;p&gt;Also, note that with iptables, the pod selection will be random. It would not be &lt;a href="https://avinetworks.com/glossary/round-robin-load-balancing/"&gt;round robin&lt;/a&gt; or other common load balancing strategies. For load balancing, you will need to use IPVS (IP Virtual Server), an alternative to iptables that implements a layer for load balancing in the Linux kernel. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/A3AkxqXt7xakdfQngBFnAquVKWH_Uq8TSs5ft1D6Re4/w:880/mb:500000/ar:1/aHR0cHM6Ly9wYXBl/ci1hdHRhY2htZW50/cy5kcm9wYm94LmNv/bS9zX0VFQzBEMDE4/MEJDNkYxODZDMDRE/OEQyRkE3MEJBNzQy/QkE2OTlFMzlFNDRD/MTI0MUIxODcxNDQy/MDA5RjlEMkRfMTY1/ODMyMDU4NzMzOV9T/Y3JlZW5zaG90KzIw/MjItMDctMjArYXQr/MTMuMzYuMTYucG5n" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/A3AkxqXt7xakdfQngBFnAquVKWH_Uq8TSs5ft1D6Re4/w:880/mb:500000/ar:1/aHR0cHM6Ly9wYXBl/ci1hdHRhY2htZW50/cy5kcm9wYm94LmNv/bS9zX0VFQzBEMDE4/MEJDNkYxODZDMDRE/OEQyRkE3MEJBNzQy/QkE2OTlFMzlFNDRD/MTI0MUIxODcxNDQy/MDA5RjlEMkRfMTY1/ODMyMDU4NzMzOV9T/Y3JlZW5zaG90KzIw/MjItMDctMjArYXQr/MTMuMzYuMTYucG5n" alt="kube-proxy working" width="880" height="613"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Also, It is important to point out that a &lt;strong&gt;Service’s&lt;/strong&gt; IP is a “virtual IP”, so if you try to ping that IP, you won’t get a response the way you usually would if you ping a pod’s IP, which is an actual endpoint on the network. &lt;/p&gt;

&lt;p&gt;A &lt;strong&gt;Service’s&lt;/strong&gt; IP is essentially a key in the rules set by iptables that gives network packet routing instructions to the host’s kernel. But the important part is that a client pod can use the &lt;strong&gt;Service&lt;/strong&gt; IP like it usually would and get the expected behavior as if it were calling an actual pod IP.&lt;/p&gt;

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

&lt;p&gt;This article explained the roles of the &lt;strong&gt;container runtime&lt;/strong&gt;, &lt;strong&gt;kubelet&lt;/strong&gt;, and &lt;strong&gt;kube-proxy&lt;/strong&gt; components in a Kubernetes worker node. There is so much more to learn about these three node components. &lt;/p&gt;

&lt;p&gt;To learn more, check out the following resources:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.aquasec.com/cloud-native-academy/container-security/container-runtime/"&gt;3 Types of Container Runtime and the Kubernetes Connection&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.mo4tech.com/kubelet-create-pod-principle-in-depth-analysis.html"&gt;Kubelet create pod principle in-depth analysis&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://betterprogramming.pub/k8s-a-closer-look-at-kube-proxy-372c4e8b090"&gt;K8s: A Closer Look at Kube-Proxy&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>devops</category>
      <category>kubernetes</category>
      <category>docker</category>
      <category>cloudops</category>
    </item>
    <item>
      <title>How to run Minikube on an Apple M1 chip without Docker Desktop</title>
      <dc:creator>Divine Odazie</dc:creator>
      <pubDate>Fri, 29 Jul 2022 19:33:36 +0000</pubDate>
      <link>https://community.ops.io/kikiodazie/how-to-run-minikube-on-an-apple-m1-chip-without-docker-desktop-14p5</link>
      <guid>https://community.ops.io/kikiodazie/how-to-run-minikube-on-an-apple-m1-chip-without-docker-desktop-14p5</guid>
      <description>&lt;p&gt;This article was originally posted on &lt;a href="https://everythingdevops.dev/how-to-run-minikube-on-apple-m1-chip-without-docker-desktop/"&gt;Everything DevOps&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Docker Desktop failed me, and at the time (13th July 2022) of writing this article, Hyperkit, VirtualBox, and other hypervisors specified &lt;a href="https://minikube.sigs.k8s.io/docs/drivers/#macos"&gt;here&lt;/a&gt; don’t work on the Apple M1 chip.&lt;/p&gt;

&lt;p&gt;Weeks ago, while using Docker Desktop, it suddenly got stuck in a &lt;a href="https://github.com/docker/for-mac/issues/6136"&gt;start-stop loop&lt;/a&gt;. I spent hours trying to resolve it, combed through GitHub issues and stackoverflow, and even downloaded older versions of Docker Desktop but to no avail. &lt;/p&gt;

&lt;p&gt;I then started searching for an alternative to Docker Desktop. And oh, did I see so many! But though they were alternatives, most didn’t work seamlessly on the M1 chip until I found &lt;a href="https://github.com/abiosoft/colima"&gt;Colima&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;This article will teach you how to run minikube on an Apple M1 chip without Docker Desktop using Colima.&lt;/p&gt;

&lt;h1&gt;
  
  
  Prerequisite
&lt;/h1&gt;

&lt;p&gt;To follow along with this article, you should have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;minikube installed on your machine. Learn how to &lt;a href="https://minikube.sigs.k8s.io/docs/start/"&gt;here&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Docker Desktop uninstalled. It’s important to note that &lt;a href="https://github.com/abiosoft/colima/blob/main/docs/FAQ.md#can-it-run-alongside-docker-for-mac"&gt;Colima from v0.3.0 upwards can run alongside Docker Desktop&lt;/a&gt;.
# How to run Minikube without Docker Desktop&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With your current M1 minikube installation, if you run just &lt;code&gt;$ minikube start&lt;/code&gt;, it will fail (see image below). And this is because minikube needs a container or virtual machine manager to run, which ideally, Docker desktop (VM + container), hyperKit, etc., would provide.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/tqO_D-HcOip4vJa4ZStM2HR4Hw7nABRCkyucyjK6yKs/w:880/mb:500000/ar:1/aHR0cHM6Ly9wYXBl/ci1hdHRhY2htZW50/cy5kcm9wYm94LmNv/bS9zXzdGN0M5MjhG/RUMwN0VBOUE4RkJE/RTk0QTg1MzJCRjVF/MkRCNDg4MzVDNTg1/MTFGRUZDRTYyQkI5/MkYwRTJFQUJfMTY1/NzcxMjM2ODA5NV9T/Y3JlZW5zaG90KzIw/MjItMDctMTMrYXQr/MTIuMzkuMjIucG5n" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/tqO_D-HcOip4vJa4ZStM2HR4Hw7nABRCkyucyjK6yKs/w:880/mb:500000/ar:1/aHR0cHM6Ly9wYXBl/ci1hdHRhY2htZW50/cy5kcm9wYm94LmNv/bS9zXzdGN0M5MjhG/RUMwN0VBOUE4RkJE/RTk0QTg1MzJCRjVF/MkRCNDg4MzVDNTg1/MTFGRUZDRTYyQkI5/MkYwRTJFQUJfMTY1/NzcxMjM2ODA5NV9T/Y3JlZW5zaG90KzIw/MjItMDctMTMrYXQr/MTIuMzkuMjIucG5n" alt="" width="880" height="191"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;But since you are having issues or don’t want to use Docker Desktop and can’t use other hypervisors on the M1 chip. You can replace Docker Desktop with Colima reducing the process to run minikube to &lt;code&gt;$ colima start&lt;/code&gt; and then &lt;code&gt;$ minikube start&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Colima?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/abiosoft/colima"&gt;Colima&lt;/a&gt; is an open-source project that provides container runtimes on macOS with minimal setup. The name Colima means containers in &lt;a href="https://github.com/lima-vm/lima"&gt;Lima&lt;/a&gt; — Linux virtual machines on macOS. &lt;/p&gt;

&lt;p&gt;Aside from the minimal setup, Colima offers the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Simple CLI interface&lt;/li&gt;
&lt;li&gt;Docker and Containerd support&lt;/li&gt;
&lt;li&gt;Port Forwarding&lt;/li&gt;
&lt;li&gt;Volume mounts&lt;/li&gt;
&lt;li&gt;Kubernetes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As this article is to run minikube, you will use Colima with Docker runtime without enabling its Kubernetes feature.&lt;/p&gt;

&lt;h2&gt;
  
  
  Installing Colima to run Docker containers on macOS
&lt;/h2&gt;

&lt;p&gt;As minikube (with Docker driver) will create a docker container, you must install Docker’s CLI alongside Colima.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Installing Colima&lt;/strong&gt; &lt;br&gt;
The fastest way to install Colima is through Homebrew. There are other installation options; check &lt;a href="https://github.com/abiosoft/colima/blob/main/docs/INSTALL.md"&gt;here&lt;/a&gt; to see them.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ brew install colima
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;To check your installation, run:&lt;/p&gt;

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

&lt;/div&gt;

&lt;p&gt;And ensure you get a help message similar to the image below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/7yM6qLq-Hcu8UDIQXOFbeYoyE2xktNDOiaKtBX22PM0/w:880/mb:500000/ar:1/aHR0cHM6Ly9wYXBl/ci1hdHRhY2htZW50/cy5kcm9wYm94LmNv/bS9zXzdGN0M5MjhG/RUMwN0VBOUE4RkJE/RTk0QTg1MzJCRjVF/MkRCNDg4MzVDNTg1/MTFGRUZDRTYyQkI5/MkYwRTJFQUJfMTY1/NzY3NDU2MDc3OV9T/Y3JlZW5zaG90KzIw/MjItMDctMTMrYXQr/MDIuMDkuMTcucG5n" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/7yM6qLq-Hcu8UDIQXOFbeYoyE2xktNDOiaKtBX22PM0/w:880/mb:500000/ar:1/aHR0cHM6Ly9wYXBl/ci1hdHRhY2htZW50/cy5kcm9wYm94LmNv/bS9zXzdGN0M5MjhG/RUMwN0VBOUE4RkJE/RTk0QTg1MzJCRjVF/MkRCNDg4MzVDNTg1/MTFGRUZDRTYyQkI5/MkYwRTJFQUJfMTY1/NzY3NDU2MDc3OV9T/Y3JlZW5zaG90KzIw/MjItMDctMTMrYXQr/MDIuMDkuMTcucG5n" alt="" width="880" height="371"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Installing Docker’s CLI&lt;/strong&gt;&lt;br&gt;
After Colima installs, install Docker and Docker Compose.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ brew install docker docker-compose
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;After the above installation, configure &lt;code&gt;docker-compose&lt;/code&gt; as a Docker plugin so you can use the &lt;code&gt;docker compose&lt;/code&gt; command instead of the legacy &lt;code&gt;docker-compose&lt;/code&gt; script. To do that, first create a folder in your home directory to hold Docker CLI plugins:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ mkdir -p ~/.docker/cli-plugins
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Then symlink &lt;code&gt;docker-compose&lt;/code&gt; into that folder with:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ ln -sfn $(brew --prefix)/opt/docker-compose/bin/docker-compose ~/.docker/cli-plugins/docker-compose
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;And to test, run:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ docker compose
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Then ensure you get an output similar to the image below. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/ZZnQzHAD1--D7UTZlB_rUPtvqXxyOf04Ktt3rErCG5k/w:880/mb:500000/ar:1/aHR0cHM6Ly9wYXBl/ci1hdHRhY2htZW50/cy5kcm9wYm94LmNv/bS9zXzdGN0M5MjhG/RUMwN0VBOUE4RkJE/RTk0QTg1MzJCRjVF/MkRCNDg4MzVDNTg1/MTFGRUZDRTYyQkI5/MkYwRTJFQUJfMTY1/NzY3MjEwMjY1MF9T/Y3JlZW5zaG90KzIw/MjItMDctMTMrYXQr/MDEuMjguMTgucG5n" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/ZZnQzHAD1--D7UTZlB_rUPtvqXxyOf04Ktt3rErCG5k/w:880/mb:500000/ar:1/aHR0cHM6Ly9wYXBl/ci1hdHRhY2htZW50/cy5kcm9wYm94LmNv/bS9zXzdGN0M5MjhG/RUMwN0VBOUE4RkJE/RTk0QTg1MzJCRjVF/MkRCNDg4MzVDNTg1/MTFGRUZDRTYyQkI5/MkYwRTJFQUJfMTY1/NzY3MjEwMjY1MF9T/Y3JlZW5zaG90KzIw/MjItMDctMTMrYXQr/MDEuMjguMTgucG5n" alt="" width="880" height="382"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now that you have Colima installed on your machine, you will create a virtual machine instance with Colima. minikube will use the VM instance, which provides the Docker runtime to start.&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating a virtual machine instance with Colima
&lt;/h2&gt;

&lt;p&gt;To create a virtual machine with Colima, run:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ colima start
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The above command will create a VM with the default configuration of 2 CPUs, 2GiB memory, and 60GiB storage which should be enough for moderate use. But if you’d like, you can customize your VM by passing additional flags such as &lt;code&gt;--cpu&lt;/code&gt;, &lt;code&gt;--memory&lt;/code&gt;, &lt;code&gt;--disk&lt;/code&gt;, etc., to &lt;code&gt;colima start&lt;/code&gt;. Or by editing the config file with &lt;code&gt;colima start --edit&lt;/code&gt;. To learn more, check &lt;a href="https://github.com/abiosoft/colima#customizing-the-vm"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;After you run the start command, you will see the following output as Colima downloads the image required the create the VM and then boots the VM:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/lgS-V8pAroI15k_t5TztRwYYRosmsPkwgtD7Js2T5oY/w:880/mb:500000/ar:1/aHR0cHM6Ly9wYXBl/ci1hdHRhY2htZW50/cy5kcm9wYm94LmNv/bS9zXzdGN0M5MjhG/RUMwN0VBOUE4RkJE/RTk0QTg1MzJCRjVF/MkRCNDg4MzVDNTg1/MTFGRUZDRTYyQkI5/MkYwRTJFQUJfMTY1/NzcxNDU0NDc3Nl9T/Y3JlZW5zaG90KzIw/MjItMDctMTMrYXQr/MTMuMTQuNTcucG5n" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/lgS-V8pAroI15k_t5TztRwYYRosmsPkwgtD7Js2T5oY/w:880/mb:500000/ar:1/aHR0cHM6Ly9wYXBl/ci1hdHRhY2htZW50/cy5kcm9wYm94LmNv/bS9zXzdGN0M5MjhG/RUMwN0VBOUE4RkJE/RTk0QTg1MzJCRjVF/MkRCNDg4MzVDNTg1/MTFGRUZDRTYyQkI5/MkYwRTJFQUJfMTY1/NzcxNDU0NDc3Nl9T/Y3JlZW5zaG90KzIw/MjItMDctMTMrYXQr/MTMuMTQuNTcucG5n" alt="" width="880" height="306"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once the download and boot process finishes, you will see an output showing that Colima is ready for use.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/UCJY0e_vIxT29xh-5m7ENzUmRWm_ReAZxyxOdEx__Tw/w:880/mb:500000/ar:1/aHR0cHM6Ly9wYXBl/ci1hdHRhY2htZW50/cy5kcm9wYm94LmNv/bS9zXzdGN0M5MjhG/RUMwN0VBOUE4RkJE/RTk0QTg1MzJCRjVF/MkRCNDg4MzVDNTg1/MTFGRUZDRTYyQkI5/MkYwRTJFQUJfMTY1/NzcxNDcwNzUwMV9T/Y3JlZW5zaG90KzIw/MjItMDctMTMrYXQr/MTMuMTguMjMucG5n" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/UCJY0e_vIxT29xh-5m7ENzUmRWm_ReAZxyxOdEx__Tw/w:880/mb:500000/ar:1/aHR0cHM6Ly9wYXBl/ci1hdHRhY2htZW50/cy5kcm9wYm94LmNv/bS9zXzdGN0M5MjhG/RUMwN0VBOUE4RkJE/RTk0QTg1MzJCRjVF/MkRCNDg4MzVDNTg1/MTFGRUZDRTYyQkI5/MkYwRTJFQUJfMTY1/NzcxNDcwNzUwMV9T/Y3JlZW5zaG90KzIw/MjItMDctMTMrYXQr/MTMuMTguMjMucG5n" alt="" width="880" height="173"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To confirm, you can run &lt;code&gt;$ colima list&lt;/code&gt; or &lt;code&gt;$ colima status&lt;/code&gt; to see the Colima running and with the default Docker  runtime which minikube will use to start. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/F5MHAuQOOZ-0mO8p4J5x2tA1BY_jWyNliYF9uz1SEaI/w:880/mb:500000/ar:1/aHR0cHM6Ly9wYXBl/ci1hdHRhY2htZW50/cy5kcm9wYm94LmNv/bS9zXzdGN0M5MjhG/RUMwN0VBOUE4RkJE/RTk0QTg1MzJCRjVF/MkRCNDg4MzVDNTg1/MTFGRUZDRTYyQkI5/MkYwRTJFQUJfMTY1/NzcxNDk4MDkwMV9h/bm5vdGVseV9pbWFn/ZSszNC5wbmc" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/F5MHAuQOOZ-0mO8p4J5x2tA1BY_jWyNliYF9uz1SEaI/w:880/mb:500000/ar:1/aHR0cHM6Ly9wYXBl/ci1hdHRhY2htZW50/cy5kcm9wYm94LmNv/bS9zXzdGN0M5MjhG/RUMwN0VBOUE4RkJE/RTk0QTg1MzJCRjVF/MkRCNDg4MzVDNTg1/MTFGRUZDRTYyQkI5/MkYwRTJFQUJfMTY1/NzcxNDk4MDkwMV9h/bm5vdGVseV9pbWFn/ZSszNC5wbmc" alt="" width="880" height="167"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now with Colima running, you can efficiently run minikube without specifying any driver. &lt;/p&gt;

&lt;h2&gt;
  
  
  Starting minikube
&lt;/h2&gt;

&lt;p&gt;With Colima running, run the &lt;code&gt;$ minikube start&lt;/code&gt; command to create your minikube cluster.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/DGoQ-PPhAS5HldK6fEEpHfE7Zhu625S8IM2KDZsxioo/w:880/mb:500000/ar:1/aHR0cHM6Ly9wYXBl/ci1hdHRhY2htZW50/cy5kcm9wYm94LmNv/bS9zXzdGN0M5MjhG/RUMwN0VBOUE4RkJE/RTk0QTg1MzJCRjVF/MkRCNDg4MzVDNTg1/MTFGRUZDRTYyQkI5/MkYwRTJFQUJfMTY1/NzcxNTYxMDcwOV9T/Y3JlZW5zaG90KzIw/MjItMDctMTMrYXQr/MTMuMzEuNTAucG5n" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/DGoQ-PPhAS5HldK6fEEpHfE7Zhu625S8IM2KDZsxioo/w:880/mb:500000/ar:1/aHR0cHM6Ly9wYXBl/ci1hdHRhY2htZW50/cy5kcm9wYm94LmNv/bS9zXzdGN0M5MjhG/RUMwN0VBOUE4RkJE/RTk0QTg1MzJCRjVF/MkRCNDg4MzVDNTg1/MTFGRUZDRTYyQkI5/MkYwRTJFQUJfMTY1/NzcxNTYxMDcwOV9T/Y3JlZW5zaG90KzIw/MjItMDctMTMrYXQr/MTMuMzEuNTAucG5n" alt="" width="880" height="379"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, run &lt;code&gt;$ docker ps&lt;/code&gt;. You will see the minikube container running on your machine with the image created on the first &lt;code&gt;$ minikube start&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/bghF-dmtu_OY2XZQjTMsC-usyM2b9JPhTZGadJZ3pA0/w:880/mb:500000/ar:1/aHR0cHM6Ly9wYXBl/ci1hdHRhY2htZW50/cy5kcm9wYm94LmNv/bS9zXzdGN0M5MjhG/RUMwN0VBOUE4RkJE/RTk0QTg1MzJCRjVF/MkRCNDg4MzVDNTg1/MTFGRUZDRTYyQkI5/MkYwRTJFQUJfMTY1/NzcxNzMzMDA4N19T/Y3JlZW5zaG90KzIw/MjItMDctMTMrYXQr/MTQuMDIuMDQucG5n" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/bghF-dmtu_OY2XZQjTMsC-usyM2b9JPhTZGadJZ3pA0/w:880/mb:500000/ar:1/aHR0cHM6Ly9wYXBl/ci1hdHRhY2htZW50/cy5kcm9wYm94LmNv/bS9zXzdGN0M5MjhG/RUMwN0VBOUE4RkJE/RTk0QTg1MzJCRjVF/MkRCNDg4MzVDNTg1/MTFGRUZDRTYyQkI5/MkYwRTJFQUJfMTY1/NzcxNzMzMDA4N19T/Y3JlZW5zaG90KzIw/MjItMDctMTMrYXQr/MTQuMDIuMDQucG5n" alt="" width="880" height="153"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;This article taught you how to run minikube on an Apple silicon without Docker Desktop and other hypervisors using Colima. Colima is a great tool and has made my life easier since I started using the Apple M1 chip. To learn more about Colima, see &lt;a href="https://github.com/abiosoft/colima/blob/main/docs/FAQ.md"&gt;answers to some frequently asked questions&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>devops</category>
      <category>docker</category>
      <category>kubernetes</category>
      <category>tutorials</category>
    </item>
    <item>
      <title>How to create and apply a Git patch file with git diff and git apply commands</title>
      <dc:creator>Divine Odazie</dc:creator>
      <pubDate>Sat, 09 Jul 2022 11:27:10 +0000</pubDate>
      <link>https://community.ops.io/kikiodazie/how-to-create-and-apply-a-git-patch-file-with-git-diff-and-git-apply-commands-57ej</link>
      <guid>https://community.ops.io/kikiodazie/how-to-create-and-apply-a-git-patch-file-with-git-diff-and-git-apply-commands-57ej</guid>
      <description>&lt;p&gt;This article was originally posted on &lt;a href="https://everythingdevops.dev/how-to-create-and-apply-a-git-patch-with-git-diff-and-git-apply-commands/"&gt;Everything DevOps&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;An engineer just joined their first company. While debugging an issue, their co-worker shared a &lt;strong&gt;patch&lt;/strong&gt; (also known as &lt;strong&gt;diff&lt;/strong&gt;) file to apply changes listed in the file to their local branch of the same Git repository.&lt;/p&gt;

&lt;p&gt;The engineer could go line by line to retype and apply the changes, but doing so, will subject the code to human error. How can that engineer apply the changes easily?&lt;/p&gt;

&lt;p&gt;In this article, you will learn:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;what a patch file is, &lt;/li&gt;
&lt;li&gt;how the co-worker created the patch file with the &lt;code&gt;git diff&lt;/code&gt; command, and &lt;/li&gt;
&lt;li&gt;how the engineer can apply the changes using &lt;code&gt;git apply&lt;/code&gt; command. &lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  GitHub repository
&lt;/h2&gt;

&lt;p&gt;This article will show screenshots of commands run on a cloned Git repository. Here is the &lt;a href="https://github.com/Kikiodazie/demo-for-git-apply"&gt;GitHub repository&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is a patch file?
&lt;/h2&gt;

&lt;p&gt;A patch file is a file that contains changes to be applied to another file or files. A patch file records all the way files are different from each other. Patch files are sometimes called diff files and use &lt;code&gt;.patch&lt;/code&gt; or &lt;code&gt;.diff&lt;/code&gt; extension. &lt;/p&gt;

&lt;h2&gt;
  
  
  The &lt;code&gt;git diff&lt;/code&gt; command and its use cases:
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;git diff&lt;/code&gt; command works by outputting the changes between two sources inside a Git repository. The sources can be two different files, commits, branches, etc. &lt;/p&gt;

&lt;p&gt;To understand the above explanations better, below are common use cases of the &lt;code&gt;git diff&lt;/code&gt; command.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;$ git diff&lt;/strong&gt;&lt;br&gt;
When you run the &lt;code&gt;$ git diff&lt;/code&gt; command, it outputs all the modified changes which are you yet to add to Git.&lt;/p&gt;

&lt;p&gt;See the image of &lt;code&gt;$ git diff&lt;/code&gt; in use below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/VUYpHWHtXqhopu-gjBCtCq8iFyRweDx4_r3CD7a_XcY/w:880/mb:500000/ar:1/aHR0cHM6Ly9wYXBl/ci1hdHRhY2htZW50/cy5kcm9wYm94LmNv/bS9zXzM1NkVERTY5/NUNDNkU4NkIxOUE1/MEFGRjM0QUFBRjRE/OUEyRkE4QkQ2MDI2/MzVFRDFBNDgxQUEx/RTM0RDNGNjBfMTY1/Mzc2MDEzNjcwOF9T/Y3JlZW5zaG90KzIw/MjItMDUtMjgrYXQr/MTYuMjIuNDgucG5n" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/VUYpHWHtXqhopu-gjBCtCq8iFyRweDx4_r3CD7a_XcY/w:880/mb:500000/ar:1/aHR0cHM6Ly9wYXBl/ci1hdHRhY2htZW50/cy5kcm9wYm94LmNv/bS9zXzM1NkVERTY5/NUNDNkU4NkIxOUE1/MEFGRjM0QUFBRjRE/OUEyRkE4QkQ2MDI2/MzVFRDFBNDgxQUEx/RTM0RDNGNjBfMTY1/Mzc2MDEzNjcwOF9T/Y3JlZW5zaG90KzIw/MjItMDUtMjgrYXQr/MTYuMjIuNDgucG5n" alt="" width="880" height="395"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;$ git diff &lt;/strong&gt;&lt;br&gt;
When you run the &lt;code&gt;$ git diff &amp;lt;filename&amp;gt;&lt;/code&gt; command, it will output the changes of the file (&lt;code&gt;&amp;lt;filename&amp;gt;&lt;/code&gt;) to its previous committed state.&lt;/p&gt;

&lt;p&gt;See image of &lt;code&gt;$ git diff &amp;lt;filename&amp;gt;&lt;/code&gt; in use below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/MNbX4T2_kyaIJmDIHFkkhC3Daf0Dk8bY7il33abWjNs/w:880/mb:500000/ar:1/aHR0cHM6Ly9wYXBl/ci1hdHRhY2htZW50/cy5kcm9wYm94LmNv/bS9zXzM1NkVERTY5/NUNDNkU4NkIxOUE1/MEFGRjM0QUFBRjRE/OUEyRkE4QkQ2MDI2/MzVFRDFBNDgxQUEx/RTM0RDNGNjBfMTY1/Mzc1MjM1MjQyNl9T/Y3JlZW5zaG90KzIw/MjItMDUtMjgrYXQr/MTYuMzkuMDMucG5n" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/MNbX4T2_kyaIJmDIHFkkhC3Daf0Dk8bY7il33abWjNs/w:880/mb:500000/ar:1/aHR0cHM6Ly9wYXBl/ci1hdHRhY2htZW50/cy5kcm9wYm94LmNv/bS9zXzM1NkVERTY5/NUNDNkU4NkIxOUE1/MEFGRjM0QUFBRjRE/OUEyRkE4QkQ2MDI2/MzVFRDFBNDgxQUEx/RTM0RDNGNjBfMTY1/Mzc1MjM1MjQyNl9T/Y3JlZW5zaG90KzIw/MjItMDUtMjgrYXQr/MTYuMzkuMDMucG5n" alt="" width="880" height="445"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;$ git diff  &lt;/strong&gt;&lt;br&gt;
When you run &lt;code&gt;$ git diff &amp;lt;branch_1_name&amp;gt; &amp;lt;branch_2_name&amp;gt;&lt;/code&gt; command, it will output the modifications between the two branches. &lt;/p&gt;

&lt;p&gt;See image of &lt;code&gt;$ git diff &amp;lt;branch_1_name&amp;gt; &amp;lt;branch_2_name&amp;gt;&lt;/code&gt; in use below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/oe5iTR517oyRVgkTb5aTNX-zpTiSf3OaaTSVg09HMfM/w:880/mb:500000/ar:1/aHR0cHM6Ly9wYXBl/ci1hdHRhY2htZW50/cy5kcm9wYm94LmNv/bS9zXzM1NkVERTY5/NUNDNkU4NkIxOUE1/MEFGRjM0QUFBRjRE/OUEyRkE4QkQ2MDI2/MzVFRDFBNDgxQUEx/RTM0RDNGNjBfMTY1/Mzc1MjkyMDI0NF9T/Y3JlZW5zaG90KzIw/MjItMDUtMjgrYXQr/MTYuNDUuNTUucG5n" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/oe5iTR517oyRVgkTb5aTNX-zpTiSf3OaaTSVg09HMfM/w:880/mb:500000/ar:1/aHR0cHM6Ly9wYXBl/ci1hdHRhY2htZW50/cy5kcm9wYm94LmNv/bS9zXzM1NkVERTY5/NUNDNkU4NkIxOUE1/MEFGRjM0QUFBRjRE/OUEyRkE4QkQ2MDI2/MzVFRDFBNDgxQUEx/RTM0RDNGNjBfMTY1/Mzc1MjkyMDI0NF9T/Y3JlZW5zaG90KzIw/MjItMDUtMjgrYXQr/MTYuNDUuNTUucG5n" alt="" width="880" height="383"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Also, you can output the changes of your current branch to the mentioned branch to its previous committed state using just &lt;code&gt;$ git diff branch_name&lt;/code&gt;. See the example image below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/rq5swt2y7v4yvH5eZAQ6HBqGjfHnzAWRZMMw2fCTbsI/w:880/mb:500000/ar:1/aHR0cHM6Ly9wYXBl/ci1hdHRhY2htZW50/cy5kcm9wYm94LmNv/bS9zXzM1NkVERTY5/NUNDNkU4NkIxOUE1/MEFGRjM0QUFBRjRE/OUEyRkE4QkQ2MDI2/MzVFRDFBNDgxQUEx/RTM0RDNGNjBfMTY1/Mzc1MzE0ODAyNF9T/Y3JlZW5zaG90KzIw/MjItMDUtMjgrYXQr/MTYuNTIuMTgucG5n" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/rq5swt2y7v4yvH5eZAQ6HBqGjfHnzAWRZMMw2fCTbsI/w:880/mb:500000/ar:1/aHR0cHM6Ly9wYXBl/ci1hdHRhY2htZW50/cy5kcm9wYm94LmNv/bS9zXzM1NkVERTY5/NUNDNkU4NkIxOUE1/MEFGRjM0QUFBRjRE/OUEyRkE4QkQ2MDI2/MzVFRDFBNDgxQUEx/RTM0RDNGNjBfMTY1/Mzc1MzE0ODAyNF9T/Y3JlZW5zaG90KzIw/MjItMDUtMjgrYXQr/MTYuNTIuMTgucG5n" alt="" width="880" height="406"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;$ git diff --staged path/to/file&lt;/strong&gt;&lt;br&gt;
When you add changes to Git or move the change to staging, you will not be able to see the difference between the files. You can use the &lt;code&gt;git diff&lt;/code&gt; command with &lt;strong&gt;--staged or --cached&lt;/strong&gt; option to see the staged changes.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/lY02y5pmNjHmaF6q3-c400zt-QeNFOBHMIYoFih70ko/w:880/mb:500000/ar:1/aHR0cHM6Ly9wYXBl/ci1hdHRhY2htZW50/cy5kcm9wYm94LmNv/bS9zXzM1NkVERTY5/NUNDNkU4NkIxOUE1/MEFGRjM0QUFBRjRE/OUEyRkE4QkQ2MDI2/MzVFRDFBNDgxQUEx/RTM0RDNGNjBfMTY1/Mzc1MzczMDA2OF9T/Y3JlZW5zaG90KzIw/MjItMDUtMjgrYXQr/MTcuMDEuNTgucG5n" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/lY02y5pmNjHmaF6q3-c400zt-QeNFOBHMIYoFih70ko/w:880/mb:500000/ar:1/aHR0cHM6Ly9wYXBl/ci1hdHRhY2htZW50/cy5kcm9wYm94LmNv/bS9zXzM1NkVERTY5/NUNDNkU4NkIxOUE1/MEFGRjM0QUFBRjRE/OUEyRkE4QkQ2MDI2/MzVFRDFBNDgxQUEx/RTM0RDNGNjBfMTY1/Mzc1MzczMDA2OF9T/Y3JlZW5zaG90KzIw/MjItMDUtMjgrYXQr/MTcuMDEuNTgucG5n" alt="" width="880" height="381"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;$ git diff commit_id1 commit_id2&lt;/strong&gt;&lt;br&gt;
When you want to see the difference between any two commits, you can use the &lt;code&gt;$ git diff commit_id1 commit_id2&lt;/code&gt; command.&lt;/p&gt;

&lt;p&gt;To get the &lt;code&gt;id&lt;/code&gt;'s of the commits you want to see the difference in, use the &lt;code&gt;$ git log&lt;/code&gt; command to see the list of commits (starting from the latest commit) made in the Git repo and their respective commit ids.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/RPo8R79gXMAe49uLlQayygBLqu6dVE-sz2hW-P6UQIo/w:880/mb:500000/ar:1/aHR0cHM6Ly9wYXBl/ci1hdHRhY2htZW50/cy5kcm9wYm94LmNv/bS9zXzM1NkVERTY5/NUNDNkU4NkIxOUE1/MEFGRjM0QUFBRjRE/OUEyRkE4QkQ2MDI2/MzVFRDFBNDgxQUEx/RTM0RDNGNjBfMTY1/Mzc1NDU3MjM0OF9h/bm5vdGVseV9pbWFn/ZSs4LnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/RPo8R79gXMAe49uLlQayygBLqu6dVE-sz2hW-P6UQIo/w:880/mb:500000/ar:1/aHR0cHM6Ly9wYXBl/ci1hdHRhY2htZW50/cy5kcm9wYm94LmNv/bS9zXzM1NkVERTY5/NUNDNkU4NkIxOUE1/MEFGRjM0QUFBRjRE/OUEyRkE4QkQ2MDI2/MzVFRDFBNDgxQUEx/RTM0RDNGNjBfMTY1/Mzc1NDU3MjM0OF9h/bm5vdGVseV9pbWFn/ZSs4LnBuZw" alt="" width="880" height="529"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Creating a Git patch file with &lt;code&gt;git diff&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;For the co-worker to create the Git patch file they shared with the engineer, they used any &lt;code&gt;git diff&lt;/code&gt; commands you saw above to get the changes. And then save the changes to a patch file using &lt;code&gt;&amp;gt;&lt;/code&gt;, as you can see below.&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;git diff &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; patch_file.diff
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;git diff commit_id1 commit_id2 &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; patch_file.diff
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;git diff &amp;lt;filename&amp;gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; patch_file.diff
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;, etc.&lt;/p&gt;

&lt;p&gt;The above command will create the patch file in the current working directory, as seen in the image below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/Tl-42g3F7kB38wh_ctVyUKMIWkoiINkEoUJPnV0w0NE/w:880/mb:500000/ar:1/aHR0cHM6Ly9wYXBl/ci1hdHRhY2htZW50/cy5kcm9wYm94LmNv/bS9zXzM1NkVERTY5/NUNDNkU4NkIxOUE1/MEFGRjM0QUFBRjRE/OUEyRkE4QkQ2MDI2/MzVFRDFBNDgxQUEx/RTM0RDNGNjBfMTY1/Mzc1NTk3NjQ4OF9h/bm5vdGVseV9pbWFn/ZSs5LnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/Tl-42g3F7kB38wh_ctVyUKMIWkoiINkEoUJPnV0w0NE/w:880/mb:500000/ar:1/aHR0cHM6Ly9wYXBl/ci1hdHRhY2htZW50/cy5kcm9wYm94LmNv/bS9zXzM1NkVERTY5/NUNDNkU4NkIxOUE1/MEFGRjM0QUFBRjRE/OUEyRkE4QkQ2MDI2/MzVFRDFBNDgxQUEx/RTM0RDNGNjBfMTY1/Mzc1NTk3NjQ4OF9h/bm5vdGVseV9pbWFn/ZSs5LnBuZw" alt="" width="880" height="73"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Also, remember that the file can also have a &lt;code&gt;.patch&lt;/code&gt; extension.&lt;/p&gt;

&lt;h2&gt;
  
  
  Applying a Git patch file using &lt;code&gt;git apply&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;After the created patch file has been shared with the engineer, they can apply it in the directory of the Git repository that requires the change using the command below.&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;git apply patch_file.diff
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For more information about the &lt;code&gt;git apply&lt;/code&gt;, check out &lt;a href="http://www.kernel.org/pub/software/scm/git/docs/git-apply.html"&gt;its man page&lt;/a&gt;.&lt;/p&gt;

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

&lt;p&gt;This article showed you how Git patch files are created using &lt;code&gt;git diff&lt;/code&gt; and how the patch changes can be applied using &lt;code&gt;git apply&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;There are other ways to apply changes from a patch file. To learn more about them, check out this conversation on &lt;a href="https://stackoverflow.com/questions/12320863/how-do-you-take-a-git-diff-file-and-apply-it-to-a-local-branch-that-is-a-copy-o"&gt;stackoverflow&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>github</category>
      <category>tutorials</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Persisting Data in Kubernetes with Volumes</title>
      <dc:creator>Divine Odazie</dc:creator>
      <pubDate>Sat, 09 Jul 2022 11:25:11 +0000</pubDate>
      <link>https://community.ops.io/kikiodazie/persisting-data-in-kubernetes-with-volumes-5fbb</link>
      <guid>https://community.ops.io/kikiodazie/persisting-data-in-kubernetes-with-volumes-5fbb</guid>
      <description>&lt;p&gt;Persisting Data in Kubernetes is complex. And this is because though Pods have readable and writable disk space, the disk space still depends on the &lt;a href="https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/"&gt;Pod’s lifecycle&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;When building applications on Kubernetes, there are use cases where developers would want storage for their Pods that doesn’t depend on a Pod’s lifecycle, is available for all nodes, and can survive cluster crashes. &lt;/p&gt;

&lt;p&gt;To meet those use cases, Kubernetes provides developers with &lt;a href="https://kubernetes.io/docs/concepts/storage/persistent-volumes/"&gt;PersistentVolumes&lt;/a&gt;, which are volume plugins like volumes that have a lifecycle independent of any individual Pod that uses it. &lt;/p&gt;

&lt;p&gt;In this article, with the help of this &lt;a href="https://kubernetes.io/docs/tasks/configure-pod-container/configure-persistent-volume-storage/"&gt;Kubernetes docs demo example&lt;/a&gt;, you will learn what PersistentVolumes are and how to configure a Pod to use a PersistentVolume for storage. &lt;/p&gt;

&lt;h1&gt;
  
  
  Prerequisite
&lt;/h1&gt;

&lt;p&gt;To follow this article, you would need a single Node Kubernetes cluster with the kubectl command-line tool configured to communicate with the cluster. &lt;/p&gt;

&lt;p&gt;If you don’t have a single Node cluster, you can create one by using &lt;a href="https://minikube.sigs.k8s.io/docs/"&gt;Minikube&lt;/a&gt; — which this article uses.&lt;/p&gt;

&lt;h1&gt;
  
  
  What are Persistent Volumes?
&lt;/h1&gt;

&lt;p&gt;PersistentVolumes (PVs) are units of storage in a Kubernetes cluster that an administrator has provisioned. As a Node is a cluster resource, a PersistentVolume is a resource in the cluster.&lt;/p&gt;

&lt;p&gt;A PersistentVolume provides storage in a Kubernetes cluster through an API object that captures the details of the actual storage implementation, be that NFS, iSCSI, or a cloud-provider-specific storage system.&lt;/p&gt;

&lt;h1&gt;
  
  
  How to use PersistentVolume for storage
&lt;/h1&gt;

&lt;p&gt;To use a PersistentVolume, you must request it through PersistentVolumeClaims (PVC). A PersistentVolumeClaim is a request for storage used to mount a PersistentVolume into a Pod.&lt;/p&gt;

&lt;p&gt;One can summarize the entire process in the following three steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The cluster administrator creates a PersistentVolume backed by a physical storage. And they do not associate the volume with any Pod.&lt;/li&gt;
&lt;li&gt;The developer (cluster user) creates a PersistentVolumeClaim that is automatically bound to a suitable PersistentVolume.&lt;/li&gt;
&lt;li&gt;The developer then creates a Pod that uses the created PersistentVolumeClaim for storage. &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In this article, you will take the role of a cluster administrator and user to walk through the steps. &lt;/p&gt;

&lt;h1&gt;
  
  
  Configuring a Pod to use a PersistentVolume for storage
&lt;/h1&gt;

&lt;p&gt;In this article, you will create a &lt;a href="https://kubernetes.io/docs/concepts/storage/volumes/#hostpath"&gt;hostPath&lt;/a&gt; Persistent Volume. Kubernetes supports hostPath volumes for development and testing on a single Node cluster. A hostPath PersistentVolume uses a file or directory on the single Node to emulate network-attached storage. &lt;/p&gt;

&lt;p&gt;In a production cluster, it is not recommended you use hostPath as it presents many security risks. Instead, the cluster administrator would provision a network resource like an NFS share, a Google Compute Engine persistent disk, or an Amazon Elastic Block Store volume.&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating a file for the hostPath
&lt;/h2&gt;

&lt;p&gt;To create a file for the hostPath, open a shell to the single Node in your cluster. As this article uses Minikube, the terminal command will be:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;In the shell, create a directory for the file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    # This article assumes that your Node uses 'sudo' to run commands as the superuser
    $ sudo mkdir /mnt/tmp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the &lt;code&gt;/mnt/tmp&lt;/code&gt; directory, create an &lt;code&gt;index.html&lt;/code&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ sudo sh -c "echo 'Hello from a Kubernetes storage' &amp;gt; /mnt/tmp/index.html"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Test that the &lt;code&gt;index.html&lt;/code&gt; file exists:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ cat /mnt/tmp/index.html
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The output of the above command should be:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Hello from a Kubernetes storage
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, you can close the shell to your single Node. Next, you will create a PersistentVolume for the hostPath.&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating a hostPath PersistentVolume
&lt;/h2&gt;

&lt;p&gt;You use a YAML configuration file to create a PersistentVolume, like any Kubernetes component. &lt;/p&gt;

&lt;p&gt;Below is the YAML configuration file for a &lt;code&gt;hostPath&lt;/code&gt; PersistentVolume:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;apiVersion: v1
kind: PersistentVolume
metadata:
  name: learn-pv-volume
  labels:
    type: local
spec:
  storageClassName: manual
  capacity:
    storage: 10Gi
  accessModes:
    - ReadWriteOnce
  hostPath:
    path: "/mnt/tmp"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The YAML configuration file specifies that the volume is at &lt;code&gt;/mnt/tmp&lt;/code&gt; on the cluster's Node. The configuration also defines a storage of 10 gibibytes and an access mode of &lt;code&gt;ReadWriteOnce&lt;/code&gt;. The access mode of &lt;code&gt;ReadWriteOnce&lt;/code&gt; means the volume can be mounted as read-write by a single Node. The configuration file also defines the PersistentVolume &lt;a href="https://kubernetes.io/docs/concepts/storage/persistent-volumes/#class"&gt;StorageClassName&lt;/a&gt; as &lt;code&gt;manual&lt;/code&gt;, which Kubernetes will use to bind the PersistentVolumeClaim requests to this PersistentVolume.&lt;/p&gt;

&lt;p&gt;Create the hostPath PersistentVolume with the above configuration using the command below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ kubectl apply -f https://raw.githubusercontent.com/Kikiodazie/persisting-data-in-kubernetes-with-persistent-volumes/master/hostPathPersistentVolume.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Verify the creation of the PersistentVolume with the command below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    // learn-pv-volume is the pv name defined in the configuration file above
    $ kubectl get pv learn-pv-volume
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The above command will show the PersistentVolume &lt;code&gt;STATUS&lt;/code&gt; as &lt;code&gt;Available&lt;/code&gt;, which means the PersistentVolume is yet to be bound to a PersistentVolumeClaim.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/xfGdeaVX2OOBUWcG5avns-DLhLz4hI2w3A8UEBZsi8M/w:880/mb:500000/ar:1/aHR0cHM6Ly9wYXBl/ci1hdHRhY2htZW50/cy5kcm9wYm94LmNv/bS9zXzQwRDY0ODlG/ODM0NUI4MDUwRTAx/Rjk2NEMyQTAxMjk0/MDdDRUUxQzlGQkQw/QkRBMDU1OTVDREE4/REJBRjc0NDJfMTY1/NTQ4MDI1MDUyNF9T/Y3JlZW5zaG90KzIw/MjItMDYtMTcrYXQr/MTYuMzcuMTMucG5n" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/xfGdeaVX2OOBUWcG5avns-DLhLz4hI2w3A8UEBZsi8M/w:880/mb:500000/ar:1/aHR0cHM6Ly9wYXBl/ci1hdHRhY2htZW50/cy5kcm9wYm94LmNv/bS9zXzQwRDY0ODlG/ODM0NUI4MDUwRTAx/Rjk2NEMyQTAxMjk0/MDdDRUUxQzlGQkQw/QkRBMDU1OTVDREE4/REJBRjc0NDJfMTY1/NTQ4MDI1MDUyNF9T/Y3JlZW5zaG90KzIw/MjItMDYtMTcrYXQr/MTYuMzcuMTMucG5n" alt="Screenshot" width="880" height="86"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next, you will create a PersistentVolumeClaim to request the PersistentVolume you’ve created. &lt;/p&gt;

&lt;h2&gt;
  
  
  Creating a PersistentVolumeClaim
&lt;/h2&gt;

&lt;p&gt;Same with PersistentVolume, you use a YAML file. Below is a PersistentVolumeClaim configuration file that requests a volume of at least three gibibytes and can allow read-write access for at least one Node.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: learn-pv-claim
spec:
  storageClassName: manual
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 3Gi
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;To create a PersistentVolumeClaim with the above configurations, run the command below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ kubectl apply -f https://raw.githubusercontent.com/Kikiodazie/persisting-data-in-kubernetes-with-persistent-volumes/master/persistentVolumeClaim.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After running the above command, the Kubernetes control plane will look for a PersistentVolume that satisfies the claim's requirements. Supposed the control plane finds a suitable PersistentVolume with the same StorageClass, it binds the claim to that PersistentVolume.&lt;/p&gt;

&lt;p&gt;To confirm that the PersistentVolumeClaim binds to the PersistentVolume, get the PersistentVolume’s  &lt;code&gt;STATUS&lt;/code&gt; with the command below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ kubectl get pv learn-pv-volume
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The above command will show a &lt;code&gt;STATUS&lt;/code&gt; of &lt;code&gt;Bound&lt;/code&gt;, as shown in the screenshot below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/gfYGDtT-EsmuCjElhSrX-BErfVXjFcY-HlAbZYSFVj8/w:880/mb:500000/ar:1/aHR0cHM6Ly9wYXBl/ci1hdHRhY2htZW50/cy5kcm9wYm94LmNv/bS9zXzQwRDY0ODlG/ODM0NUI4MDUwRTAx/Rjk2NEMyQTAxMjk0/MDdDRUUxQzlGQkQw/QkRBMDU1OTVDREE4/REJBRjc0NDJfMTY1/NTQ4MDM0MzA2Ml9T/Y3JlZW5zaG90KzIw/MjItMDYtMTcrYXQr/MTYuMzguNTMucG5n" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/gfYGDtT-EsmuCjElhSrX-BErfVXjFcY-HlAbZYSFVj8/w:880/mb:500000/ar:1/aHR0cHM6Ly9wYXBl/ci1hdHRhY2htZW50/cy5kcm9wYm94LmNv/bS9zXzQwRDY0ODlG/ODM0NUI4MDUwRTAx/Rjk2NEMyQTAxMjk0/MDdDRUUxQzlGQkQw/QkRBMDU1OTVDREE4/REJBRjc0NDJfMTY1/NTQ4MDM0MzA2Ml9T/Y3JlZW5zaG90KzIw/MjItMDYtMTcrYXQr/MTYuMzguNTMucG5n" alt="Screenshot" width="880" height="55"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can also see that the PersistentVolumeClaim is bound to the PersistentVolume by looking at the PersistentVolumeClaim:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ kubectl get pvc learn-pv-claim
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://community.ops.io/images/1oEMMccsdJMgmww7QfeevO_WNh23nAqrfXMbznaOj48/w:880/mb:500000/ar:1/aHR0cHM6Ly9wYXBl/ci1hdHRhY2htZW50/cy5kcm9wYm94LmNv/bS9zXzQwRDY0ODlG/ODM0NUI4MDUwRTAx/Rjk2NEMyQTAxMjk0/MDdDRUUxQzlGQkQw/QkRBMDU1OTVDREE4/REJBRjc0NDJfMTY1/NTQ4MDM5MDA2OV9T/Y3JlZW5zaG90KzIw/MjItMDYtMTcrYXQr/MTYuMzkuNDAucG5n" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/1oEMMccsdJMgmww7QfeevO_WNh23nAqrfXMbznaOj48/w:880/mb:500000/ar:1/aHR0cHM6Ly9wYXBl/ci1hdHRhY2htZW50/cy5kcm9wYm94LmNv/bS9zXzQwRDY0ODlG/ODM0NUI4MDUwRTAx/Rjk2NEMyQTAxMjk0/MDdDRUUxQzlGQkQw/QkRBMDU1OTVDREE4/REJBRjc0NDJfMTY1/NTQ4MDM5MDA2OV9T/Y3JlZW5zaG90KzIw/MjItMDYtMTcrYXQr/MTYuMzkuNDAucG5n" alt="Screenshot" width="880" height="64"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next, you will create a Pod to use the PersistentVolumeClaim as a volume.&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating a Pod
&lt;/h2&gt;

&lt;p&gt;Below is the YAML configuration file for the Pod you will create:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;apiVersion: v1
kind: Pod
metadata:
  name: learn-pv-pod
spec:
  volumes:
    - name: learn-pv-storage
      persistentVolumeClaim:
        claimName: learn-pv-claim
  containers:
    - name: learn-pv-container
      image: nginx
      ports:
        - containerPort: 80
          name: "http-server"
      volumeMounts:
        - mountPath: "/usr/share/nginx/html"
          name: learn-pv-storage
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Looking at the above configuration file, you would notice that it specifies the PersistentVolumeClaim and not the PersistentVolume. This is because the claim is a volume from the Pod’s perspective.&lt;/p&gt;

&lt;p&gt;To create the Pod with the above configurations, run the command below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ kubectl apply -f 
https://raw.githubusercontent.com/Kikiodazie/persisting-data-in-kubernetes-with-persistent-volumes/master/persistentVolumePod.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To verify that the container (Ngnix) in the Pod is running, run the command below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ kubectl get pod learn-pv-pod
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://community.ops.io/images/-26bHQy0qkSfPPNggtJPWo0-gV30zd2R6BRkQyibHxQ/w:880/mb:500000/ar:1/aHR0cHM6Ly9wYXBl/ci1hdHRhY2htZW50/cy5kcm9wYm94LmNv/bS9zXzQwRDY0ODlG/ODM0NUI4MDUwRTAx/Rjk2NEMyQTAxMjk0/MDdDRUUxQzlGQkQw/QkRBMDU1OTVDREE4/REJBRjc0NDJfMTY1/NTQ4MDU0MzE3NF9T/Y3JlZW5zaG90KzIw/MjItMDYtMTcrYXQr/MTYuNDEuMDEucG5n" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/-26bHQy0qkSfPPNggtJPWo0-gV30zd2R6BRkQyibHxQ/w:880/mb:500000/ar:1/aHR0cHM6Ly9wYXBl/ci1hdHRhY2htZW50/cy5kcm9wYm94LmNv/bS9zXzQwRDY0ODlG/ODM0NUI4MDUwRTAx/Rjk2NEMyQTAxMjk0/MDdDRUUxQzlGQkQw/QkRBMDU1OTVDREE4/REJBRjc0NDJfMTY1/NTQ4MDU0MzE3NF9T/Y3JlZW5zaG90KzIw/MjItMDYtMTcrYXQr/MTYuNDEuMDEucG5n" alt="Screenshot" width="790" height="79"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next, you will confirm that the Pod has been configured to use the hostPath PersistentVolume as storage from the PersistentVolumeClaim.&lt;/p&gt;

&lt;h2&gt;
  
  
  Testing the configuration
&lt;/h2&gt;

&lt;p&gt;To test and confirm the configuration, you verify that the Nginx server is serving the &lt;code&gt;index.html&lt;/code&gt; file from the hostPath volume. &lt;/p&gt;

&lt;p&gt;To do so, enter the shell of the Nginx container running in your Pod with the command below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ kubectl exec -it learn-pv-pod -- /bin/bash
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the shell, run the commands below to install &lt;code&gt;curl&lt;/code&gt;, which you will use to serve the &lt;code&gt;index.html&lt;/code&gt; file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ apt update
$ apt install curl
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After installing &lt;code&gt;curl&lt;/code&gt;, use it to verify the configuration works with the command below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ curl http://localhost/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The above command will output the text you wrote to the &lt;code&gt;index.html&lt;/code&gt; file on the hostPath volume:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/TFvsshgXIjplu9W2hIldiwc2APL5ZnV3NbGMo2wmpzQ/w:880/mb:500000/ar:1/aHR0cHM6Ly9wYXBl/ci1hdHRhY2htZW50/cy5kcm9wYm94LmNv/bS9zXzQwRDY0ODlG/ODM0NUI4MDUwRTAx/Rjk2NEMyQTAxMjk0/MDdDRUUxQzlGQkQw/QkRBMDU1OTVDREE4/REJBRjc0NDJfMTY1/NTQ4MDY1ODM2NF9T/Y3JlZW5zaG90KzIw/MjItMDYtMTcrYXQr/MTYuNDQuMDQucG5n" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/TFvsshgXIjplu9W2hIldiwc2APL5ZnV3NbGMo2wmpzQ/w:880/mb:500000/ar:1/aHR0cHM6Ly9wYXBl/ci1hdHRhY2htZW50/cy5kcm9wYm94LmNv/bS9zXzQwRDY0ODlG/ODM0NUI4MDUwRTAx/Rjk2NEMyQTAxMjk0/MDdDRUUxQzlGQkQw/QkRBMDU1OTVDREE4/REJBRjc0NDJfMTY1/NTQ4MDY1ODM2NF9T/Y3JlZW5zaG90KzIw/MjItMDYtMTcrYXQr/MTYuNDQuMDQucG5n" alt="Screenshot" width="880" height="56"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, even if the Pod dies or restarts, upon recreation, it will have access to the same storage.&lt;/p&gt;

&lt;p&gt;To test it out, delete the Pod with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ kubectl delete pod learn-pv-pod
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And create it again with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ kubectl apply -f https://raw.githubusercontent.com/Kikiodazie/persisting-data-in-kubernetes-with-persistent-volumes/master/persistentVolumePod.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then get into the shell of the Pod and rerun the &lt;code&gt;curl&lt;/code&gt; command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ kubectl exec -it learn-pv-pod -- /bin/bash
$ curl http://localhost/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;br&gt;
&lt;code&gt;&lt;br&gt;
You will still get the output of the&lt;/code&gt;index.html` file.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/Lo-kIahhVf3yFMkh_gO5Sqs0NUV2BambBdkvka-1BTg/w:880/mb:500000/ar:1/aHR0cHM6Ly9wYXBl/ci1hdHRhY2htZW50/cy5kcm9wYm94LmNv/bS9zXzQwRDY0ODlG/ODM0NUI4MDUwRTAx/Rjk2NEMyQTAxMjk0/MDdDRUUxQzlGQkQw/QkRBMDU1OTVDREE4/REJBRjc0NDJfMTY1/NTQ4MTE3MDY4NF9T/Y3JlZW5zaG90KzIw/MjItMDYtMTcrYXQr/MTYuNDQuMDQucG5n" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/Lo-kIahhVf3yFMkh_gO5Sqs0NUV2BambBdkvka-1BTg/w:880/mb:500000/ar:1/aHR0cHM6Ly9wYXBl/ci1hdHRhY2htZW50/cy5kcm9wYm94LmNv/bS9zXzQwRDY0ODlG/ODM0NUI4MDUwRTAx/Rjk2NEMyQTAxMjk0/MDdDRUUxQzlGQkQw/QkRBMDU1OTVDREE4/REJBRjc0NDJfMTY1/NTQ4MTE3MDY4NF9T/Y3JlZW5zaG90KzIw/MjItMDYtMTcrYXQr/MTYuNDQuMDQucG5n" alt="Screenshot" width="880" height="56"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Cleaning up
&lt;/h2&gt;

&lt;p&gt;Clean up the entire setup by deleting the Pod, PersistentVolumeClaim, and the PersistentVolume with the commands below:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ kubectl delete pod learn-pv-pod
$ kubectl delete pvc learn-pv-claim
$ kubectl delete pv learn-pv-volume
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Also, delete the &lt;code&gt;index.html&lt;/code&gt; file and the directory by running the following commands in the Node shell:&lt;/p&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ sudo rm /mnt/tmp/index.html&lt;br&gt;
$ sudo rmdir /mnt/tmp&lt;br&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h1&gt;
&lt;br&gt;
  &lt;br&gt;
  &lt;br&gt;
  Conclusion&lt;br&gt;
&lt;/h1&gt;

&lt;p&gt;This article introduced you to PersistentVolumes in Kubernetes. It also showed you how to configure a Pod to use a PersistentVolume for storage. &lt;/p&gt;

&lt;p&gt;There is more to learn about persisting data in Kubernetes with volumes. To learn more, check out the following resources:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://kubernetes.io/docs/concepts/storage/persistent-volumes/"&gt;Kubernetes documentation on Persistent Volumes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://loft.sh/blog/kubernetes-persistent-volumes-examples-and-best-practices"&gt;Examples &amp;amp; best practices in using Persistent Volumes&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>devops</category>
      <category>kubernetes</category>
      <category>tutorials</category>
    </item>
    <item>
      <title>Linux background and foreground process management</title>
      <dc:creator>Divine Odazie</dc:creator>
      <pubDate>Thu, 26 May 2022 17:51:52 +0000</pubDate>
      <link>https://community.ops.io/kikiodazie/linux-background-and-foreground-process-management-4j1o</link>
      <guid>https://community.ops.io/kikiodazie/linux-background-and-foreground-process-management-4j1o</guid>
      <description>&lt;p&gt;This article was originally posted on &lt;a href="https://everythingdevops.dev/linux-background-and-foreground-process-management"&gt;Everything DevOps&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;There is support for background and foreground job processing in Linux-based operating systems. A job in this context is just a command launched from a terminal window. Any running command is a process. &lt;/p&gt;

&lt;p&gt;This tutorial will show you how to manage jobs in the foreground and background of your Linux terminal window. In the end, you would've learned: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Why you would manage jobs&lt;/li&gt;
&lt;li&gt;How to take a foreground job to the background with &lt;code&gt;&amp;amp;&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;How to bring a background job to the foreground with &lt;code&gt;fg&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;How to suspend a foreground job with &lt;code&gt;CTRL + Z&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;How to resume a suspended foreground job with &lt;code&gt;bg&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;The meaning of the &lt;code&gt;+&lt;/code&gt; and &lt;code&gt;-&lt;/code&gt; symbol on background jobs&lt;/li&gt;
&lt;li&gt;How to run job processes even after closing the terminal window&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why manage jobs?
&lt;/h2&gt;

&lt;p&gt;By default, all jobs in Linux execute in the foreground. Foreground jobs run directly from the shell. When you run one foreground job, you will have to wait for shell access until the job completes before you can run other jobs.&lt;/p&gt;

&lt;p&gt;Waiting for jobs to complete is fine when the jobs complete quickly. But in cases where the current job is going to take a long time (even several hours) to complete, it becomes a challenge, especially when you have a single terminal window (&lt;a href="https://en.wikipedia.org/wiki/Secure_Shell"&gt;SSH&lt;/a&gt; session, wconsole) to work with.&lt;/p&gt;

&lt;p&gt;In such cases, you can run the job in the background and free the shell for other jobs and tasks. When you run a Job in the background, it will execute at low priority, which will, in turn, allow typing of other commands in the terminal window while the job runs.&lt;/p&gt;

&lt;p&gt;Next, you will see how to manage jobs in the foreground and background.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisite
&lt;/h2&gt;

&lt;p&gt;To follow along on managing jobs in foreground and background in Linux, you need access to a Linux distribution terminal window. &lt;/p&gt;

&lt;p&gt;This tutorial uses an &lt;a href="https://en.wikipedia.org/wiki/Ubuntu"&gt;Ubuntu Linux distribution&lt;/a&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  Managing jobs in the foreground and background
&lt;/h1&gt;

&lt;p&gt;This tutorial will use the &lt;code&gt;sleep&lt;/code&gt; command to create dummy jobs for illustration purposes. The &lt;code&gt;sleep&lt;/code&gt; command, when run, delays the shell for a specified timeframe. To learn more about the &lt;code&gt;sleep&lt;/code&gt; command, check out this &lt;a href="https://www.geeksforgeeks.org/sleep-command-in-linux-with-examples/"&gt;article&lt;/a&gt;. &lt;/p&gt;

&lt;h2&gt;
  
  
  Taking a foreground job to the background with &lt;code&gt;&amp;amp;&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;To start, open up your terminal window and run:&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;sleep &lt;/span&gt;10000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After running the above command, it delays the shell for &lt;code&gt;10000&lt;/code&gt; seconds, making  it impossible to run any other command until after &lt;code&gt;10000&lt;/code&gt; seconds, as shown in the image below. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/kll58HKrHSiJc4i86hYEwfzrJK-yU7AAy_T-V9gN-BQ/w:880/mb:500000/ar:1/aHR0cHM6Ly9wYXBl/ci1hdHRhY2htZW50/cy5kcm9wYm94LmNv/bS9zXzA3NEZEQzNC/QTMwQjI0QkUyOUY2/RjQyNDE1NTkwQTZC/QkM4QTRGODdBOUZG/N0Y5MUYyRjAxNUUx/NERCRjk1MkFfMTY1/MTUxNzcxNjQ2MV9T/Y3JlZW5zaG90K2Zy/b20rMjAyMi0wNS0w/MisxOS01NC01NC5w/bmc" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/kll58HKrHSiJc4i86hYEwfzrJK-yU7AAy_T-V9gN-BQ/w:880/mb:500000/ar:1/aHR0cHM6Ly9wYXBl/ci1hdHRhY2htZW50/cy5kcm9wYm94LmNv/bS9zXzA3NEZEQzNC/QTMwQjI0QkUyOUY2/RjQyNDE1NTkwQTZC/QkM4QTRGODdBOUZG/N0Y5MUYyRjAxNUUx/NERCRjk1MkFfMTY1/MTUxNzcxNjQ2MV9T/Y3JlZW5zaG90K2Zy/b20rMjAyMi0wNS0w/MisxOS01NC01NC5w/bmc" alt="" width="880" height="156"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To run the above &lt;code&gt;sleep&lt;/code&gt; command in the background, after terminating the currently running job with &lt;code&gt;CTRL + C&lt;/code&gt;, run:&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;sleep &lt;/span&gt;10000 &amp;amp;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After running the above command, you will get an output similar to the image below and your shell back to run other commands. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/tvq-m9kDASpxD2GtPgias7OY3JsfJ5NA1SIjDrBC6kI/w:880/mb:500000/ar:1/aHR0cHM6Ly9wYXBl/ci1hdHRhY2htZW50/cy5kcm9wYm94LmNv/bS9zXzA3NEZEQzNC/QTMwQjI0QkUyOUY2/RjQyNDE1NTkwQTZC/QkM4QTRGODdBOUZG/N0Y5MUYyRjAxNUUx/NERCRjk1MkFfMTY1/MTUxNzc1ODc5MV9T/Y3JlZW5zaG90K2Zy/b20rMjAyMi0wNS0w/MisxOS01NS0zMy5w/bmc" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/tvq-m9kDASpxD2GtPgias7OY3JsfJ5NA1SIjDrBC6kI/w:880/mb:500000/ar:1/aHR0cHM6Ly9wYXBl/ci1hdHRhY2htZW50/cy5kcm9wYm94LmNv/bS9zXzA3NEZEQzNC/QTMwQjI0QkUyOUY2/RjQyNDE1NTkwQTZC/QkM4QTRGODdBOUZG/N0Y5MUYyRjAxNUUx/NERCRjk1MkFfMTY1/MTUxNzc1ODc5MV9T/Y3JlZW5zaG90K2Zy/b20rMjAyMi0wNS0w/MisxOS01NS0zMy5w/bmc" alt="" width="880" height="123"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the above image, the &lt;code&gt;sleep 10000 &amp;amp;&lt;/code&gt; is process &lt;code&gt;3647&lt;/code&gt; job number &lt;code&gt;1&lt;/code&gt;, and it is currently running in the background.&lt;/p&gt;

&lt;p&gt;To see the Job, run:&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;jobs&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The above command will show all the jobs in the background of your terminal session and their current state. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/BDfDLpT1o6yQUYQkYS7n2a9jO_x3JeP41sLkZagh3WM/w:880/mb:500000/ar:1/aHR0cHM6Ly9wYXBl/ci1hdHRhY2htZW50/cy5kcm9wYm94LmNv/bS9zXzA3NEZEQzNC/QTMwQjI0QkUyOUY2/RjQyNDE1NTkwQTZC/QkM4QTRGODdBOUZG/N0Y5MUYyRjAxNUUx/NERCRjk1MkFfMTY1/MTUxNzc5MTE5M19T/Y3JlZW5zaG90K2Zy/b20rMjAyMi0wNS0w/MisxOS01Ni0xNC5w/bmc" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/BDfDLpT1o6yQUYQkYS7n2a9jO_x3JeP41sLkZagh3WM/w:880/mb:500000/ar:1/aHR0cHM6Ly9wYXBl/ci1hdHRhY2htZW50/cy5kcm9wYm94LmNv/bS9zXzA3NEZEQzNC/QTMwQjI0QkUyOUY2/RjQyNDE1NTkwQTZC/QkM4QTRGODdBOUZG/N0Y5MUYyRjAxNUUx/NERCRjk1MkFfMTY1/MTUxNzc5MTE5M19T/Y3JlZW5zaG90K2Zy/b20rMjAyMi0wNS0w/MisxOS01Ni0xNC5w/bmc" alt="" width="880" height="78"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Bringing a background job to the foreground with &lt;code&gt;fg&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;In some cases, after taking a job to the background, you might want to do something with it; that’s where the &lt;code&gt;fg&lt;/code&gt; command comes in. You use the &lt;code&gt;fg&lt;/code&gt; to move a background job on your current Linux shell to the foreground. &lt;/p&gt;

&lt;p&gt;To bring back your current running job to the foreground, run:&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;fg&lt;/span&gt; %1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next to &lt;code&gt;%&lt;/code&gt; in the above command is the job number &lt;code&gt;1&lt;/code&gt;. After running the command, you will see it back in the foreground.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/eZ_-ZpoZ97Ul6akk9ONdWpkXtdEIbmsQZnhfQJUAGcE/w:880/mb:500000/ar:1/aHR0cHM6Ly9wYXBl/ci1hdHRhY2htZW50/cy5kcm9wYm94LmNv/bS9zXzA3NEZEQzNC/QTMwQjI0QkUyOUY2/RjQyNDE1NTkwQTZC/QkM4QTRGODdBOUZG/N0Y5MUYyRjAxNUUx/NERCRjk1MkFfMTY1/MTUxNzgyNDg2NV9T/Y3JlZW5zaG90K2Zy/b20rMjAyMi0wNS0w/MisxOS01Ni01MC5w/bmc" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/eZ_-ZpoZ97Ul6akk9ONdWpkXtdEIbmsQZnhfQJUAGcE/w:880/mb:500000/ar:1/aHR0cHM6Ly9wYXBl/ci1hdHRhY2htZW50/cy5kcm9wYm94LmNv/bS9zXzA3NEZEQzNC/QTMwQjI0QkUyOUY2/RjQyNDE1NTkwQTZC/QkM4QTRGODdBOUZG/N0Y5MUYyRjAxNUUx/NERCRjk1MkFfMTY1/MTUxNzgyNDg2NV9T/Y3JlZW5zaG90K2Zy/b20rMjAyMi0wNS0w/MisxOS01Ni01MC5w/bmc" alt="" width="880" height="113"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Suspending a foreground job with &lt;code&gt;CTRL + Z&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Let’s say you want to suspend the job for a while to run other commands; you can do that with &lt;code&gt;CTRL + Z&lt;/code&gt;. &lt;code&gt;CTRL + Z&lt;/code&gt; puts the job in a “stopped” mode and doesn’t terminate it. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/c2Q8T6jqS-QTCczYAstf47MO_IZfWteawZZzwcxEj1k/w:880/mb:500000/ar:1/aHR0cHM6Ly9wYXBl/ci1hdHRhY2htZW50/cy5kcm9wYm94LmNv/bS9zXzA3NEZEQzNC/QTMwQjI0QkUyOUY2/RjQyNDE1NTkwQTZC/QkM4QTRGODdBOUZG/N0Y5MUYyRjAxNUUx/NERCRjk1MkFfMTY1/MTUxNzg2NDk3M19T/Y3JlZW5zaG90K2Zy/b20rMjAyMi0wNS0w/MisxOS01Ny0yNi5w/bmc" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/c2Q8T6jqS-QTCczYAstf47MO_IZfWteawZZzwcxEj1k/w:880/mb:500000/ar:1/aHR0cHM6Ly9wYXBl/ci1hdHRhY2htZW50/cy5kcm9wYm94LmNv/bS9zXzA3NEZEQzNC/QTMwQjI0QkUyOUY2/RjQyNDE1NTkwQTZC/QkM4QTRGODdBOUZG/N0Y5MUYyRjAxNUUx/NERCRjk1MkFfMTY1/MTUxNzg2NDk3M19T/Y3JlZW5zaG90K2Zy/b20rMjAyMi0wNS0w/MisxOS01Ny0yNi5w/bmc" alt="" width="880" height="160"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Resuming a suspended foreground job with &lt;code&gt;bg&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;To resume the &lt;code&gt;sleep 10000&lt;/code&gt; process, you can use the &lt;code&gt;bg&lt;/code&gt; command. &lt;code&gt;bg&lt;/code&gt; will resume the job process and take it to the background. &lt;/p&gt;

&lt;p&gt;In the shell, run:&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;bg&lt;/span&gt; %1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://community.ops.io/images/iWCpcY7XVU_TUb-k_6d7Zm8aulYF2AEuSmMt-htE-io/w:880/mb:500000/ar:1/aHR0cHM6Ly9wYXBl/ci1hdHRhY2htZW50/cy5kcm9wYm94LmNv/bS9zXzA3NEZEQzNC/QTMwQjI0QkUyOUY2/RjQyNDE1NTkwQTZC/QkM4QTRGODdBOUZG/N0Y5MUYyRjAxNUUx/NERCRjk1MkFfMTY1/MTUxNzkxMDY1Nl9T/Y3JlZW5zaG90K2Zy/b20rMjAyMi0wNS0w/MisxOS01OC0xNS5w/bmc" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/iWCpcY7XVU_TUb-k_6d7Zm8aulYF2AEuSmMt-htE-io/w:880/mb:500000/ar:1/aHR0cHM6Ly9wYXBl/ci1hdHRhY2htZW50/cy5kcm9wYm94LmNv/bS9zXzA3NEZEQzNC/QTMwQjI0QkUyOUY2/RjQyNDE1NTkwQTZC/QkM4QTRGODdBOUZG/N0Y5MUYyRjAxNUUx/NERCRjk1MkFfMTY1/MTUxNzkxMDY1Nl9T/Y3JlZW5zaG90K2Zy/b20rMjAyMi0wNS0w/MisxOS01OC0xNS5w/bmc" alt="" width="880" height="119"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Meaning of the &lt;code&gt;+&lt;/code&gt; and &lt;code&gt;-&lt;/code&gt; symbol on background job processes
&lt;/h2&gt;

&lt;p&gt;If you’ve noticed throughout the screenshots, the &lt;code&gt;+&lt;/code&gt; symbol beside the job number, well, there’s also &lt;code&gt;-&lt;/code&gt; and they both have meanings, as you can see in the quote below:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;In output pertaining to jobs command), the current job is always flagged with a &lt;code&gt;+&lt;/code&gt;, and the previous job with a &lt;code&gt;-&lt;/code&gt;. — &lt;strong&gt;"JOB CONTROL" section on the bash manpage.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;To show the above quote, create two more dummy jobs in the background.&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;sleep &lt;/span&gt;10001 &amp;amp;
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;sleep &lt;/span&gt;10002 &amp;amp;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After running the above commands, run &lt;code&gt;$ jobs&lt;/code&gt; to see all the job processes:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/29JJ-JVgXUnjHZF9AWbsJNVT8PKZDUTb36syI0gbCb8/w:880/mb:500000/ar:1/aHR0cHM6Ly9wYXBl/ci1hdHRhY2htZW50/cy5kcm9wYm94LmNv/bS9zXzA3NEZEQzNC/QTMwQjI0QkUyOUY2/RjQyNDE1NTkwQTZC/QkM4QTRGODdBOUZG/N0Y5MUYyRjAxNUUx/NERCRjk1MkFfMTY1/MTUxNzYyMTk2NF9T/Y3JlZW5zaG90K2Zy/b20rMjAyMi0wNS0w/MisxOS01My0yMS5w/bmc" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/29JJ-JVgXUnjHZF9AWbsJNVT8PKZDUTb36syI0gbCb8/w:880/mb:500000/ar:1/aHR0cHM6Ly9wYXBl/ci1hdHRhY2htZW50/cy5kcm9wYm94LmNv/bS9zXzA3NEZEQzNC/QTMwQjI0QkUyOUY2/RjQyNDE1NTkwQTZC/QkM4QTRGODdBOUZG/N0Y5MUYyRjAxNUUx/NERCRjk1MkFfMTY1/MTUxNzYyMTk2NF9T/Y3JlZW5zaG90K2Zy/b20rMjAyMi0wNS0w/MisxOS01My0yMS5w/bmc" alt="" width="880" height="114"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you can see in the image above, the most recent just you created is flagged with the &lt;code&gt;+&lt;/code&gt; symbol and the previous with &lt;code&gt;-&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;So far, you’ve learned how to take foreground jobs to the background, bring them back to the foreground, suspend them and resume them. Doing all this helps you be more efficient when you have a single terminal window to work. &lt;/p&gt;

&lt;p&gt;Next, you will learn how to make your job run even after closing the terminal window.&lt;/p&gt;

&lt;h2&gt;
  
  
  Running jobs even after closing the terminal window
&lt;/h2&gt;

&lt;p&gt;When you have jobs running in the background or foreground, all the jobs will be terminated if you close the terminal window. The job termination is because they are associated with that particular terminal session. And upon exit, a &lt;a href="https://www.computerhope.com/unix/signals.htm"&gt;hang-up (HUP) signal&lt;/a&gt; is sent to all the processes it started.&lt;/p&gt;

&lt;p&gt;To practicalize this, if the previous jobs you created are still running, close the terminal window, open it back up and then run &lt;code&gt;$ jobs&lt;/code&gt;. You will see that no job process is running like in the image below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/YxBFnulK7gH-myDBahInfz1ufqDlwUlomOQQ0ot6JWk/w:880/mb:500000/ar:1/aHR0cHM6Ly9wYXBl/ci1hdHRhY2htZW50/cy5kcm9wYm94LmNv/bS9zXzA3NEZEQzNC/QTMwQjI0QkUyOUY2/RjQyNDE1NTkwQTZC/QkM4QTRGODdBOUZG/N0Y5MUYyRjAxNUUx/NERCRjk1MkFfMTY1/MTUwNzg3NTc3N19T/Y3JlZW5zaG90K2Zy/b20rMjAyMi0wNS0w/MisxNy0xMC01My5w/bmc" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/YxBFnulK7gH-myDBahInfz1ufqDlwUlomOQQ0ot6JWk/w:880/mb:500000/ar:1/aHR0cHM6Ly9wYXBl/ci1hdHRhY2htZW50/cy5kcm9wYm94LmNv/bS9zXzA3NEZEQzNC/QTMwQjI0QkUyOUY2/RjQyNDE1NTkwQTZC/QkM4QTRGODdBOUZG/N0Y5MUYyRjAxNUUx/NERCRjk1MkFfMTY1/MTUwNzg3NTc3N19T/Y3JlZW5zaG90K2Zy/b20rMjAyMi0wNS0w/MisxNy0xMC01My5w/bmc" alt="" width="880" height="120"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To make jobs continue running even after closing the terminal window, you can use &lt;code&gt;nohup&lt;/code&gt;, &lt;code&gt;disown&lt;/code&gt;, and other commands. This tutorial uses only &lt;code&gt;nohup&lt;/code&gt; and &lt;code&gt;disown&lt;/code&gt;. To learn about the other commands, check out these &lt;a href="https://askubuntu.com/questions/8653/how-to-keep-processes-running-after-ending-ssh-session"&gt;recommendations by other Linux users on askubuntu&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;When to use&lt;/strong&gt; &lt;code&gt;nohup&lt;/code&gt;? &lt;strong&gt;When to use&lt;/strong&gt; &lt;code&gt;disown&lt;/code&gt;?&lt;br&gt;
If you’re able to think ahead of time that you will close your terminal window and not want to hang up your running jobs, use &lt;code&gt;nohup&lt;/code&gt;. If not, use &lt;code&gt;disown&lt;/code&gt;, which allows you to disconnect a process from a terminal session after its already been created.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Using&lt;/strong&gt; &lt;code&gt;nohup&lt;/code&gt;&lt;br&gt;
To use &lt;code&gt;nohup&lt;/code&gt; and continue running jobs even after closing the terminal window, when creating the job, add &lt;code&gt;nohup&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;To practicalize, in your terminal window, create a dummy job with &lt;code&gt;nohup&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="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;nohup sleep &lt;/span&gt;10000 &amp;amp;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After running the above command, you will see a terminal output similar to the image below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/W-ePRBd4Nhm3aGwulrDtomvw2hnjKB0-MUf0FxQdwCc/w:880/mb:500000/ar:1/aHR0cHM6Ly9wYXBl/ci1hdHRhY2htZW50/cy5kcm9wYm94LmNv/bS9zXzA3NEZEQzNC/QTMwQjI0QkUyOUY2/RjQyNDE1NTkwQTZC/QkM4QTRGODdBOUZG/N0Y5MUYyRjAxNUUx/NERCRjk1MkFfMTY1/MTUxMTg0NDE1Nl9h/bm5vdGVseV9pbWFn/ZSsyNy5wbmc" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/W-ePRBd4Nhm3aGwulrDtomvw2hnjKB0-MUf0FxQdwCc/w:880/mb:500000/ar:1/aHR0cHM6Ly9wYXBl/ci1hdHRhY2htZW50/cy5kcm9wYm94LmNv/bS9zXzA3NEZEQzNC/QTMwQjI0QkUyOUY2/RjQyNDE1NTkwQTZC/QkM4QTRGODdBOUZG/N0Y5MUYyRjAxNUUx/NERCRjk1MkFfMTY1/MTUxMTg0NDE1Nl9h/bm5vdGVseV9pbWFn/ZSsyNy5wbmc" alt="" width="880" height="79"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The annotated terminal output above means that &lt;code&gt;nohup&lt;/code&gt; will append (add) any output from the job process &lt;code&gt;sleep 10000&lt;/code&gt; to a file called &lt;code&gt;nohup.out&lt;/code&gt;. You can find the &lt;code&gt;nohup.out&lt;/code&gt; file in your present working directory, as you can see in the image below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/m02shBIQvwox2G8EgcSREfoDSYpIVxIr7s3iRLttD4Y/w:880/mb:500000/ar:1/aHR0cHM6Ly9wYXBl/ci1hdHRhY2htZW50/cy5kcm9wYm94LmNv/bS9zXzA3NEZEQzNC/QTMwQjI0QkUyOUY2/RjQyNDE1NTkwQTZC/QkM4QTRGODdBOUZG/N0Y5MUYyRjAxNUUx/NERCRjk1MkFfMTY1/MTUxMzU1Mzc5N19h/bm5vdGVseV9pbWFn/ZSsyOC5wbmc" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/m02shBIQvwox2G8EgcSREfoDSYpIVxIr7s3iRLttD4Y/w:880/mb:500000/ar:1/aHR0cHM6Ly9wYXBl/ci1hdHRhY2htZW50/cy5kcm9wYm94LmNv/bS9zXzA3NEZEQzNC/QTMwQjI0QkUyOUY2/RjQyNDE1NTkwQTZC/QkM4QTRGODdBOUZG/N0Y5MUYyRjAxNUUx/NERCRjk1MkFfMTY1/MTUxMzU1Mzc5N19h/bm5vdGVseV9pbWFn/ZSsyOC5wbmc" alt="" width="880" height="290"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can also redirect a particular job output to a different file. To learn how to do that, check out this &lt;a href="https://unix.stackexchange.com/questions/45913/is-there-a-way-to-redirect-nohup-output-to-a-log-file-other-than-nohup-out"&gt;question and answer on Unix &amp;amp; Linux StackExchange&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Now, when you close your terminal and open it back up, you can still find your &lt;code&gt;sleep 10000&lt;/code&gt; job running. But this time, not with the &lt;code&gt;$ jobs&lt;/code&gt; command but with &lt;code&gt;$ ps -aux | grep sleep&lt;/code&gt; commands, as you can see in the image below. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/17sN4jlqOQwvT95axerrK1IxjUB0-rIvB0Drc2oblIY/w:880/mb:500000/ar:1/aHR0cHM6Ly9wYXBl/ci1hdHRhY2htZW50/cy5kcm9wYm94LmNv/bS9zXzA3NEZEQzNC/QTMwQjI0QkUyOUY2/RjQyNDE1NTkwQTZC/QkM4QTRGODdBOUZG/N0Y5MUYyRjAxNUUx/NERCRjk1MkFfMTY1/MTUxNDA5ODMyOF9h/bm5vdGVseV9pbWFn/ZSsyOS5wbmc" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/17sN4jlqOQwvT95axerrK1IxjUB0-rIvB0Drc2oblIY/w:880/mb:500000/ar:1/aHR0cHM6Ly9wYXBl/ci1hdHRhY2htZW50/cy5kcm9wYm94LmNv/bS9zXzA3NEZEQzNC/QTMwQjI0QkUyOUY2/RjQyNDE1NTkwQTZC/QkM4QTRGODdBOUZG/N0Y5MUYyRjAxNUUx/NERCRjk1MkFfMTY1/MTUxNDA5ODMyOF9h/bm5vdGVseV9pbWFn/ZSsyOS5wbmc" alt="" width="880" height="105"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The second &lt;code&gt;sleep&lt;/code&gt; process you see in the above terminal output was not started by you but by the &lt;code&gt;grep&lt;/code&gt; command. To learn why it is there, check out these answers on &lt;a href="https://stackoverflow.com/questions/6893714/why-does-ps-o-p-list-the-grep-process-after-the-pipe"&gt;stackoverflow&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;To terminate the job, run:&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;pkill &lt;span class="nb"&gt;sleep&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After running the command, you can still see the second process there like in the image below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/elBMZC9Vvrg_ciTWqRvfqiLxi1SRADsYrZHnmcR4hZs/w:880/mb:500000/ar:1/aHR0cHM6Ly9wYXBl/ci1hdHRhY2htZW50/cy5kcm9wYm94LmNv/bS9zXzA3NEZEQzNC/QTMwQjI0QkUyOUY2/RjQyNDE1NTkwQTZC/QkM4QTRGODdBOUZG/N0Y5MUYyRjAxNUUx/NERCRjk1MkFfMTY1/MTUxNDc3MDUzOF9T/Y3JlZW5zaG90K2Zy/b20rMjAyMi0wNS0w/MisxOS0wNS01Ni5w/bmc" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/elBMZC9Vvrg_ciTWqRvfqiLxi1SRADsYrZHnmcR4hZs/w:880/mb:500000/ar:1/aHR0cHM6Ly9wYXBl/ci1hdHRhY2htZW50/cy5kcm9wYm94LmNv/bS9zXzA3NEZEQzNC/QTMwQjI0QkUyOUY2/RjQyNDE1NTkwQTZC/QkM4QTRGODdBOUZG/N0Y5MUYyRjAxNUUx/NERCRjk1MkFfMTY1/MTUxNDc3MDUzOF9T/Y3JlZW5zaG90K2Zy/b20rMjAyMi0wNS0w/MisxOS0wNS01Ni5w/bmc" alt="" width="880" height="80"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Using&lt;/strong&gt; &lt;code&gt;disown&lt;/code&gt;&lt;br&gt;
Since all the jobs you’ve created are “stopped,” to learn about how to use &lt;code&gt;disown&lt;/code&gt;, create a new dummy job process:&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;sleep &lt;/span&gt;10000 &amp;amp;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then disconnect it from that particular terminal session with:&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;disown&lt;/span&gt; %1 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://community.ops.io/images/dZ3ARozyOyTtSeDxes-opJmjQH97P90OnkzGsF77SNY/w:880/mb:500000/ar:1/aHR0cHM6Ly9wYXBl/ci1hdHRhY2htZW50/cy5kcm9wYm94LmNv/bS9zXzA3NEZEQzNC/QTMwQjI0QkUyOUY2/RjQyNDE1NTkwQTZC/QkM4QTRGODdBOUZG/N0Y5MUYyRjAxNUUx/NERCRjk1MkFfMTY1/MTUxNzUwOTI3OV9T/Y3JlZW5zaG90K2Zy/b20rMjAyMi0wNS0w/MisxOS01MS0yNy5w/bmc" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/dZ3ARozyOyTtSeDxes-opJmjQH97P90OnkzGsF77SNY/w:880/mb:500000/ar:1/aHR0cHM6Ly9wYXBl/ci1hdHRhY2htZW50/cy5kcm9wYm94LmNv/bS9zXzA3NEZEQzNC/QTMwQjI0QkUyOUY2/RjQyNDE1NTkwQTZC/QkM4QTRGODdBOUZG/N0Y5MUYyRjAxNUUx/NERCRjk1MkFfMTY1/MTUxNzUwOTI3OV9T/Y3JlZW5zaG90K2Zy/b20rMjAyMi0wNS0w/MisxOS01MS0yNy5w/bmc" alt="" width="880" height="73"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, close the terminal window, open it up again, then run &lt;code&gt;$ ps -aux | grep sleep&lt;/code&gt; to see the job process running like in the image below &lt;/p&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/WQQqPgxIiMGUyYGh-DRQ2JYB9gG68tpdkfLWyXSYbTg/w:880/mb:500000/ar:1/aHR0cHM6Ly9wYXBl/ci1hdHRhY2htZW50/cy5kcm9wYm94LmNv/bS9zXzA3NEZEQzNC/QTMwQjI0QkUyOUY2/RjQyNDE1NTkwQTZC/QkM4QTRGODdBOUZG/N0Y5MUYyRjAxNUUx/NERCRjk1MkFfMTY1/MTUxNzQ1MzQxMl9h/bm5vdGVseV9pbWFn/ZSszMC5wbmc" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/WQQqPgxIiMGUyYGh-DRQ2JYB9gG68tpdkfLWyXSYbTg/w:880/mb:500000/ar:1/aHR0cHM6Ly9wYXBl/ci1hdHRhY2htZW50/cy5kcm9wYm94LmNv/bS9zXzA3NEZEQzNC/QTMwQjI0QkUyOUY2/RjQyNDE1NTkwQTZC/QkM4QTRGODdBOUZG/N0Y5MUYyRjAxNUUx/NERCRjk1MkFfMTY1/MTUxNzQ1MzQxMl9h/bm5vdGVseV9pbWFn/ZSszMC5wbmc" alt="" width="880" height="76"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;This tutorial taught you how to manage foreground and background job processes in a Linux terminal window. To learn more about managing processes in Linux, check out the following resources:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=Ip9P1XJt5PI"&gt;Linux Internals - Process Management&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://youtu.be/VC50SpHlkz8"&gt;How to use the Linux Screen program&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>devops</category>
      <category>tutorials</category>
    </item>
  </channel>
</rss>
