<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Ashish Nair</title>
    <description>The latest articles on DEV Community by Ashish Nair (@ashish_nair_d9b10ba4f8126).</description>
    <link>https://dev.to/ashish_nair_d9b10ba4f8126</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2176306%2F7d07f10c-0efc-4f5d-a8cd-a6ed1a06b7ec.png</url>
      <title>DEV Community: Ashish Nair</title>
      <link>https://dev.to/ashish_nair_d9b10ba4f8126</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ashish_nair_d9b10ba4f8126"/>
    <language>en</language>
    <item>
      <title>Deploying OpenShift IPI on KVM (Baremetal Simulation with Redfish &amp; Sushy)</title>
      <dc:creator>Ashish Nair</dc:creator>
      <pubDate>Tue, 07 Apr 2026 19:04:42 +0000</pubDate>
      <link>https://dev.to/ashish_nair_d9b10ba4f8126/deploying-openshift-ipi-on-kvm-baremetal-simulation-with-redfish-sushy-2o60</link>
      <guid>https://dev.to/ashish_nair_d9b10ba4f8126/deploying-openshift-ipi-on-kvm-baremetal-simulation-with-redfish-sushy-2o60</guid>
      <description>&lt;p&gt;If the article gave you a "Yet Another Openshift Setup Guide"(Sorry YAML, I stole some letters) feel, I don't blame you!(This is an indication of how much free time i have, lol!) While this isn't a typical How-To guide (I lied!) ,I'll tell you why this is different - Openshift doesn't support IPI method of installation on KVM (ironical huh? not supporting their own siblings) but there's a hack that allows you to do it(ofcourse! you can only use it for labs!!)&lt;/p&gt;

&lt;h2&gt;
  
  
  The Layout (okay! Architecture diagram)
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fipu0xxo9pdclj6qgi7ro.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fipu0xxo9pdclj6qgi7ro.png" alt=" "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The components
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;A KVM host(Our protagonist!)&lt;/li&gt;
&lt;li&gt;DNSmasq built-in with KVM A.K.A our Antagonist!&lt;/li&gt;
&lt;li&gt;Sushy (not the dish, this is a Redfish emulator)&lt;/li&gt;
&lt;li&gt;VM's (The masters and the Workers)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  A note on prerequisites and Hardware requirements
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;you can check the H/W requirements for openshift in Redhat's or OKD's official documentation &lt;a href="https://docs.okd.io/latest/installing/installing_bare_metal/ipi/ipi-install-prerequisites.html#installation-minimum-resource-requirements_ipi-install-prerequisites" rel="noopener noreferrer"&gt;here&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  1. Assembling components for the Virtual Machines
&lt;/h3&gt;

&lt;h2&gt;
  
  
  Adding disks to our Masters and Slaves.
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;qemu-img create &lt;span class="nt"&gt;-f&lt;/span&gt; qcow2 /var/lib/libvirt/images/master-1.qcow2 120G
qemu-img create &lt;span class="nt"&gt;-f&lt;/span&gt; qcow2 /var/lib/libvirt/images/master-2.qcow2 120G
qemu-img create &lt;span class="nt"&gt;-f&lt;/span&gt; qcow2 /var/lib/libvirt/images/master-3.qcow2 120G
qemu-img create &lt;span class="nt"&gt;-f&lt;/span&gt; qcow2 /var/lib/libvirt/images/worker-1.qcow2 120G
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Configuring a Network in Libvirt
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;This is the most &lt;strong&gt;critical&lt;/strong&gt; part of the setup. If this fails the install will &lt;strong&gt;fail&lt;/strong&gt; and frustrate you to the core!&lt;/li&gt;
&lt;li&gt;Save this into a file, probably default.xml&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs96dgztdxx2yzxd33cvo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs96dgztdxx2yzxd33cvo.png" alt=" "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Apply it
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;virsh net-define default.xml
virsh net-start default
virsh net-autostart default
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Creating the VM's
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;It's time to create the VM's using the KVM console but don't boot them yet! We will have our installer boot these machines for us via &lt;a href="https://github.com/openstack/sushy-tools" rel="noopener noreferrer"&gt;Redfish and Sushy&lt;/a&gt;. In other words, a poor man's iDrac/ILO but only for power management.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  setting up Sushy
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;create a virtual Environment to install python module
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python3 &lt;span class="nt"&gt;-m&lt;/span&gt; venv ~/sushy-env
&lt;span class="nb"&gt;source&lt;/span&gt; ~/sushy-env/bin/activate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Install the sushy module
&lt;/li&gt;
&lt;/ul&gt;

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

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;start sushy
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;sushy-emulator &lt;span class="nt"&gt;-i&lt;/span&gt; 192.168.122.1 &lt;span class="nt"&gt;--port&lt;/span&gt; 8000 &lt;span class="nt"&gt;--libvirt-uri&lt;/span&gt; qemu:///system
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Testing powering on/off the VM's using the tool we just installed.
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;validate the Redfish API
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl http://192.168.122.1:8000/redfish/v1/Systems
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The output will look something like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;sushy-emulator &lt;span class="nt"&gt;-i&lt;/span&gt; 192.168.122.1 &lt;span class="nt"&gt;--port&lt;/span&gt; 8000 &lt;span class="nt"&gt;--libvirt-uri&lt;/span&gt; qemu:///system
&lt;span class="go"&gt; * Serving Flask app 'sushy_tools.emulator.main'
 * Debug mode: off
WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
 * Running on http://192.168.122.1:8000
Press CTRL+C to quit
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Validate power control. The curl command we ran above will give you an id assigned to every system that might look like 58ec1279-e393-4dba-a7b4-e8ea37c0d6da, replace that id in the below command.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST http://192.168.122.1:8000/redfish/v1/Systems/&amp;lt;ID&amp;gt;/Actions/ComputerSystem.Reset &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"ResetType": "On"}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The system will be powered on if you check the KVM console. Power it off again!( I swear I'm not trying to irritate you!)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Redfish power operations require files under /usr/share/OVMF. My system had secure boot files missing so I had to create the below soft links.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo ln&lt;/span&gt; &lt;span class="nt"&gt;-s&lt;/span&gt; /usr/share/OVMF/OVMF_VARS_4M.fd /usr/share/OVMF/OVMF_VARS.fd
&lt;span class="nb"&gt;sudo ln&lt;/span&gt; &lt;span class="nt"&gt;-s&lt;/span&gt; /usr/share/OVMF/OVMF_CODE_4M.fd /usr/share/OVMF/OVMF_CODE.fd
&lt;span class="nb"&gt;sudo ln&lt;/span&gt; &lt;span class="nt"&gt;-s&lt;/span&gt; /usr/share/OVMF/OVMF_CODE_4M.secboot.fd /usr/share/OVMF/OVMF_CODE_4M.ms.fd
&lt;span class="nb"&gt;sudo ln&lt;/span&gt; &lt;span class="nt"&gt;-s&lt;/span&gt; /usr/share/OVMF/OVMF_CODE_4M.secboot.fd /usr/share/OVMF/OVMF_CODE.secboot.fd
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Building the installer
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Installing the tools to build the installer
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo apt install golang git make gcc g++ libvirt-dev pkg-config
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;br&gt;
plaintext&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;clone the repo
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git clone https://github.com/openshift/installer.git
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;&lt;br&gt;
shell&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;compile the installer with &lt;strong&gt;TAGS=libvirt hack/build.sh&lt;/strong&gt;. A.K.A - The Hack
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cd installer
make build
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;&lt;br&gt;
shell&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;copy the installer to /usr/local/bin
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo cp bin/openshift-install /usr/local/bin/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;&lt;br&gt;
markdown&lt;/p&gt;
&lt;h3&gt;
  
  
  3. The installation
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Create directories for the install
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mkdir ~/ocp-install
cd ~/ocp-install
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;&lt;br&gt;
yaml&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;create install-config.yaml
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;apiVersion: v1
baseDomain: lab
metadata:
  name: mycluster

controlPlane:
  name: master
  replicas: 3

compute:
- name: worker
  replicas: 2

networking:
  networkType: OVNKubernetes
  machineNetwork:
  - cidr: 192.168.122.0/24

platform:
  baremetal:
    externalBridge: "virbr0"
    apiVIP: 192.168.122.10
    ingressVIP: 192.168.122.11
    provisioningNetwork: "Disabled"

    hosts:
    - name: master
      role: master
      bmc:
        address: redfish-virtualmedia+http://192.168.122.1:8000/redfish/v1/Systems/&amp;lt;ID&amp;gt;
        username: admin
        password: password
      bootMACAddress: 52:54:00:3d:30:b5
      rootDeviceHints:
        deviceName: /dev/vda
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;&lt;br&gt;
plaintext&lt;br&gt;
Note: populate fields for all you masters and workers and Add the pull-config(from the Redhat Portal) and sshKey(ssh public key from your home directory).  fields and populate them. The ignition configs(RH core OS' Kickstart) will bake this into the RHCOS ISO and you should be able to login to your master/workers via ssh using core@master/worker using the key you entered above.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;kick-off the installation (while you're inside ~/ocp-install which also houses your install-config.yaml)
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;openshift-install create cluster --dir . --log-level=DEBUG
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;&lt;br&gt;
plaintext&lt;br&gt;
This will create a bootstrap node in KVM, then after the initial phase of install is complete it will remove it and boot your masters and workers(via sushy and Redfish) via RHCOS iso and continue with the install.  &lt;/p&gt;

&lt;p&gt;Note: you can change the --log-level parameter to INFO if detailing is not your thing(not judging you!)&lt;/p&gt;
&lt;h3&gt;
  
  
  The wait (And also the toughest part)
&lt;/h3&gt;

&lt;p&gt;Yes, This is the toughest part as the install takes around 1 hour or even more to complete based on the resources you have on your system. &lt;br&gt;
You can login to one of your nodes (core@master) and tail the bootkube logs and monitor the install.&lt;/p&gt;

&lt;p&gt;Once the Install is complete you should see something like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;INFO Waiting up to 1h0m0s (until 5:21PM IST) for the cluster at https://api.mycluster.lab:6443 to initialize... 
INFO Checking to see if there is a route at openshift-console/console... 
INFO Install complete!                            
INFO To access the cluster as the system:admin user when using 'oc', run 'export KUBECONFIG=/home/user/test/ocp-install2/auth/kubeconfig' 
INFO Access the OpenShift web-console here: https://console-openshift-console.apps.mycluster.lab 
INFO Login to the console with user: "kubeadmin", and password: "eI2ES-wtGQG-Lgwec-KUNum" 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;br&gt;
shell&lt;/p&gt;

&lt;p&gt;export the kubeconfig file and access your cluster API's:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export KUBECONFIG=./auth/kubeconfig
oc get nodes
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What a waste of my weekend!!&lt;/p&gt;

</description>
      <category>automation</category>
      <category>devops</category>
      <category>kubernetes</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
