Deploy OKD 4.19 Single Node OpenShift di KVM menggunakan WSL2 - Complete Guide

Deploy OKD 4.19 Single Node OpenShift di KVM menggunakan WSL2 - Complete Guide

Blog Series

OpenShift & OKD Journey

Part 1 of 5

41 min read
4736 wordsCloud Engineering
openshiftokdkubernetes

Tutorial lengkap deploy OKD 4.19 Single Node OpenShift di KVM menggunakan WSL2. Dari setup environment hingga akses console web - perfect untuk learning environment dan development setup.

Intro

Halo temen-temen! Kali ini kita bakal bahas cara deploy OKD (OpenShift Kubernetes Distribution) versi 4.19 dalam mode Single Node. Buat yang belum tau, OKD itu basically versi open source dari Red Hat OpenShift yang bisa temen-temen pake gratis.

Perfect banget buat learning environment atau development setup yang ga butuh cluster penuh tapi tetap mau ngerasain fitur-fitur enterprise Kubernetes.

Spesifikasi & Requirements

Hardware yang Dipake

  • CPU: Intel i3-12100
  • RAM: 80GB DDR4 (yes, sebanyak itu karena kita bakal running OKD VMs)
  • Storage: SSD dengan space cukup buat VM images

Software Environment

  • Host OS: Windows dengan WSL2 Ubuntu
  • Virtualization: KVM/QEMU (sudah terinstall di WSL2)
  • Network: Custom bridge network

VM Architecture

okd-febryan-web-vm-architecture

Resource Monitoring

Resource PC Saat Installation/Bootstrapping via Windows Task Manager

okd-febryan-web-resource-bootstraping

  • CPU Usage: ~90-100%
  • RAM Usage: ~50-60GB
  • Disk I/O: High (baca ISO + write installation)

Setelah Installation (Idle State)

  • CPU Usage: ~40-65%
  • RAM Usage: ~45-50GB
  • Disk I/O: Low

Step-by-Step Installation

Pertama, temen-temen perlu siapin network dan server bastion/manager yang diperlukan sebagain penyedia berbagai service/layanan untuk node OKD nantinya.

Eksek di host KVM (WSL2 Ubuntu)

1. Setup KVM Network

okd-febryan-web-network-architecture

Kita butuh custom network buat isolasi VMs kita:

# Buat file network definition
cat > okd4.xml << 'EOF'
<network>
  <name>okd4</name>
  <uuid>7e122cdf-1c17-40f3-b445-e4a00c51da30</uuid>
  <forward mode='nat'>
    <nat>
      <port start='1024' end='65535'/>
    </nat>
  </forward>
  <bridge name='vbr-okd' stp='on' delay='0'/>
  <mac address='52:54:00:0f:49:45'/>
  <domain name='minhphupham.com'/>
  <ip address='192.168.101.1' netmask='255.255.255.0'>
  </ip>
</network>
EOF
 
# Define dan start network
sudo virsh net-define --file okd4.xml
sudo virsh net-autostart okd4
sudo virsh net-start okd4

2. Deploy Bastion Server

Bastion server ini bakal jadi NTP, DNS, DHCP server buat environment kita.

# Check available OS templates
sudo virt-builder -l
 
# Build CentOS Stream 9 image
sudo virt-builder centos-stream9 --format qcow2 \
  --size 20G -o /var/lib/libvirt/images/okd-bastion-server.qcow2 \
  --root-password password:rahasia
 
# Deploy VM
sudo virt-install \
  --name okd-bastion-server \
  --ram 4096 \
  --disk path=/var/lib/libvirt/images/okd-bastion-server.qcow2 \
  --vcpus 2 \
  --os-variant centos-stream9 \
  --network=bridge:vbr-okd,model=virtio \
  --graphics none \
  --serial pty \
  --console pty \
  --boot hd \
  --import
 
# Set autostart
sudo virsh autostart okd-bastion-server

Eksek di Server Bastion

3. Persiapan Release Files

Lalu siapkan tools yang diperlukan, download tools ini di dalam server bastion/manager. Dalam tutorial ini, kita bakal pake OKD versi 4.19.0-okd-scos.11:

# Download openshift-install dan oc client
wget https://github.com/okd-project/okd/releases/download/4.19.0-okd-scos.11/openshift-install-linux-4.19.0-okd-scos.11.tar.gz
wget https://github.com/okd-project/okd/releases/download/4.19.0-okd-scos.11/openshift-client-linux-4.19.0-okd-scos.11.tar.gz
 
# Extract tools
tar -xzf openshift-install-linux-4.19.0-okd-scos.11.tar.gz
tar -xzf openshift-client-linux-4.19.0-okd-scos.11.tar.gz
 
# Move to PATH
sudo mv openshift-install oc kubectl /usr/local/bin/

Pro tip: Buat upgrade toolsnya, temen-temen bisa pake command ini:

oc adm release extract --tools quay.io/okd/scos-release:4.19.0-okd-scos.15 
# sesuaikan versi terbaru

4. Configure Bastion Server

Connect ke bastion server dan setup networking:

sudo virsh console okd-bastion-server
# Login: root / rahasia
 
# Set static IP
nmcli con add type ethernet con-name enp1s0 ifname enp1s0 \
  connection.autoconnect yes ipv4.method manual \
  ipv4.address 192.168.101.254/24 ipv4.gateway 192.168.101.1 \
  ipv4.dns 8.8.8.8
 
# Test connectivity
ping 8.8.8.8
 
# Update system
dnf -y upgrade
dnf -y install git vim wget curl bash-completion tree tar libselinux-python3 firewalld
reboot

5. Configure NTP (Network Time Protocol)

Time synchronization sangat penting untuk OKD cluster. Kita akan setup NTP server di bastion dan configure client di SNO node.

Setup NTP Server di Bastion

# Install dan enable chronyd
dnf -y install chrony
systemctl enable --now chronyd
 
# Edit konfigurasi chrony untuk Indonesia NTP servers
vim /etc/chrony.conf

Edit /etc/chrony.conf dengan konfigurasi berikut:

# Indonesia NTP Pool servers
server 0.id.pool.ntp.org iburst
server 1.id.pool.ntp.org iburst
server 2.id.pool.ntp.org iburst
server 3.id.pool.ntp.org iburst
 
# Allow clients dari network OKD
allow 192.168.101.0/24
 
# Standard chrony configuration
sourcedir /run/chrony-dhcp
driftfile /var/lib/chrony/drift
makestep 1.0 3
rtcsync
leapsectz right/UTC
logdir /var/log/chrony
 
# Disable local stratum untuk fail-fast behavior
# local stratum 10   # <- commented out untuk production best practice
# Restart chronyd service
systemctl restart chronyd
 
# Verify NTP sources
chronyc sources -v
chronyc tracking
 
# Check firewall untuk NTP
firewall-cmd --permanent --add-service=ntp
firewall-cmd --reload

Verify NTP pada SNO Node (setelah deployment node OKD selesai nantinya)

Setelah SNO node running, verify time sync:

# Connect ke SNO node
ssh core@192.168.101.20
 
# Check chrony sources
sudo chronyc sources -v
 
# Check system time status
timedatectl
 
# Verify time sync dengan bastion
date && ssh 192.168.101.254 date

Expected output menunjukkan time difference < 1 second antara bastion dan SNO node.

6. Setup DHCP Server

# Install DHCP server
dnf -y install dhcp-server
systemctl enable --now dhcpd
mv /etc/dhcp/dhcpd.conf /etc/dhcp/dhcpd.conf.bak
 
# Create DHCP config
cat > /etc/dhcp/dhcpd.conf << 'EOF'
authoritative;
ddns-update-style interim;
default-lease-time 14400;
max-lease-time 14400;
 
# Global options
option routers                  192.168.101.1;
option broadcast-address        192.168.101.255;
option subnet-mask              255.255.255.0;
option domain-name-servers      192.168.101.254, 8.8.8.8, 1.1.1.1;
option domain-name              "okd4.minhphupham.com";
option domain-search            "okd4.minhphupham.com", "minhphupham.com";
option ntp-servers              192.168.101.254;
 
subnet 192.168.101.0 netmask 255.255.255.0 {
  pool {
    range 192.168.101.30 192.168.101.50;
    deny unknown-clients;
  }
}
 
# Static reservation untuk OKD node
host okd-sno {
  hardware ethernet 52:54:00:cc:11:22;
  fixed-address 192.168.101.20;
  option host-name "sno.okd4.minhphupham.com";
}
EOF
 
systemctl restart dhcpd
systemctl status dhcpd

7. Setup DNS Server (BIND)

DNS setup yang proper sangat crucial buat OKD:

# Install BIND
dnf -y install bind bind-utils
systemctl enable named
mkdir -p /var/named/log/
 
# Main configuration
cat > /etc/named.conf << 'EOF'
options {
    listen-on port 53 { 127.0.0.1; 192.168.101.254; };
    listen-on-v6 port 53 { ::1; };
    directory       "/var/named";
    dump-file       "/var/named/data/cache_dump.db";
    statistics-file "/var/named/data/named_stats.txt";
    memstatistics-file "/var/named/data/named_mem_stats.txt";
 
    allow-query     { localhost; 192.168.101.0/24; };
    allow-recursion { localhost; 192.168.101.0/24; };
 
    recursion yes;
    dnssec-validation yes;
    forwarders { 8.8.8.8; 1.1.1.1; };
    forward only;
 
    managed-keys-directory "/var/named/dynamic";
    pid-file "/run/named/named.pid";
    session-keyfile "/run/named/session.key";
    include "/etc/crypto-policies/back-ends/bind.config";
};
 
logging {
    category notify { zone_transfer_log; };
    category xfer-in { zone_transfer_log; };
    category xfer-out { zone_transfer_log; };
 
    channel zone_transfer_log {
        file "/var/named/log/transfer.log" versions 10 size 50m;
        print-time yes;
        print-category yes;
        print-severity yes;
        severity info;
    };
 
    channel default_debug {
        file "/var/named/log/named.run";
        severity dynamic;
    };
};
 
zone "." IN {
    type hint;
    file "named.ca";
};
 
zone "okd4.minhphupham.com" IN {
    type master;
    file "zonefile.db";
    allow-query { localhost; 192.168.101.0/24; };
    allow-transfer { none; };
};
 
zone "101.168.192.in-addr.arpa" IN {
    type master;
    file "reverse.db";
    allow-query { localhost; 192.168.101.0/24; };
    allow-transfer { none; };
};
 
include "/etc/named.rfc1912.zones";
include "/etc/named.root.key";
EOF
 
# Forward zone file
cat > /var/named/zonefile.db << 'EOF'
$TTL 1W
@       IN      SOA     ns1.okd4.minhphupham.com.        root (
                        2025080602      ; serial
                        3H              ; refresh
                        30M             ; retry
                        2W              ; expiry
                        1W )            ; minimum
        IN      NS      ns1.okd4.minhphupham.com.
;
; Infrastructure services (Bastion)
bastion IN      A       192.168.101.254
ns1     IN      A       192.168.101.254
;
; OKD Single Node - All services point to SNO
sno     IN      A       192.168.101.20
api     IN      A       192.168.101.20
api-int IN      A       192.168.101.20
;
; Wildcard untuk applications
*.apps  IN      A       192.168.101.20
;
; SRV records untuk etcd
_etcd-server-ssl._tcp.okd4.minhphupham.com. 86400 IN SRV 0 10 2380 sno.okd4.minhphupham.com.
;EOF
EOF
 
# Reverse zone file  
cat > /var/named/reverse.db << 'EOF'
$TTL 1W
@       IN      SOA     ns1.okd4.minhphupham.com.        root (
                        2025080602      ; serial
                        3H              ; refresh
                        30M             ; retry
                        2W              ; expiry
                        1W )            ; minimum
        IN      NS      ns1.okd4.minhphupham.com.
;
254     IN      PTR     bastion.okd4.minhphupham.com.
254     IN      PTR     ns1.okd4.minhphupham.com.
20      IN      PTR     sno.okd4.minhphupham.com.
20      IN      PTR     api.okd4.minhphupham.com.
20      IN      PTR     api-int.okd4.minhphupham.com.
;EOF
EOF
 
# Start DNS service
systemctl start named
systemctl status named
 
# Update bastion to use local DNS
nmcli connection modify enp1s0 ipv4.dns "192.168.101.254"
nmcli connection reload

8. Test DNS Resolution

# Test forward lookup
dig +short api.okd4.minhphupham.com
nslookup api.okd4.minhphupham.com
host sno.okd4.minhphupham.com
 
# Test reverse lookup
dig +short -x 192.168.101.20
[root@bastion ~]# dig +short api.okd4.minhphupham.com
192.168.101.20
 
[root@bastion ~]# nslookup api.okd4.minhphupham.com
Server:         192.168.101.254
Address:        192.168.101.254#53
 
Name:   api.okd4.minhphupham.com
Address: 192.168.101.20
 
[root@bastion ~]# host sno.okd4.minhphupham.com
sno.okd4.minhphupham.com has address 192.168.101.20

9. Configure Firewall

firewall-cmd --permanent \
  --add-port=6443/tcp \
  --add-port=22623/tcp \
  --add-port=53/udp \
  --add-port=53/tcp \
  --add-port=67/udp \
  --add-port=68/udp \
  --add-port=80/tcp \
  --add-port=443/tcp \
  --add-service=dhcpv6-client \
  --add-service=dns \
  --add-service=mdns \
  --add-service=http \
  --add-service=https \
  --add-service=ntp
 
firewall-cmd --reload
firewall-cmd --list-all

Install OKD

10. Prepare OKD Installation Files

mkdir -p /root/okd-sno
cd /root/okd-sno
 
# Generate SSH key jika belum ada
ssh-keygen -t rsa -b 4096 -N "" -f ~/.ssh/id_rsa
 
# Create install-config.yaml
cat > install-config.yaml << 'EOF'
apiVersion: v1
baseDomain: minhphupham.com
metadata:
  name: okd4
 
compute:
- name: worker
  replicas: 0
 
controlPlane:
  name: master
  replicas: 1
  hyperthreading: Enabled
 
networking:
  networkType: OVNKubernetes
  clusterNetwork:
  - cidr: 10.128.0.0/14
    hostPrefix: 23
  serviceNetwork:
  - 172.30.0.0/16
  machineNetwork:
  - cidr: 192.168.101.0/24
 
platform:
  none: {}
 
bootstrapInPlace:
  installationDisk: /dev/disk/by-id/virtio-sno-disk
 
fips: false
pullSecret: '{"auths":{"fake":{"auth":"aWQ6cGFzcwo="}}}'
sshKey: |
  ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDbG8L93xi7AoUQ+n5JN347IzLP7xPVwDAg28rcjf2/7oX2zAQWON4zRLqi67lwdNlnWvd0B/h6jRLW3Z8Z//GZfeLsy0dI32sOtB/C0Zy2aycC032yF4FLkWiG0sKymyrJBKs1lO1sxS2DTcucHUALRwHm8qIIdAsT8fGc30dZJIDXsy1SNjbQGuOPdp+0B5lTvQ2lWs1YJ5spr1G52w5XzHiEwlTO8pACwoV413asjkzyWidb6aMahLQdjS+5WL92Ut8KzsPRV9PcUDcJJ26IHuxMM+ESZ3rWUBkgbOL+UgtaHEHirt23188YVhXZYWB7x7wEFH77J4vOQgx+OORnf851DFRJWSnlBCtKY+/o/BAFLgxpns552sfou883znP1HW0wHROEQtQEw3IQ+ZF1hjklGy3wPKIUDbQbUYIYLFA3tbO/WDOT5QmOSuQYfEi5+RHsbGuShBvR0hamOsnPlWsxNarWd1VdsJIA4PZmKOaEyU1S61OGhWtHSr+7wuk= root@bastion
EOF
 
 
 
# Generate single-node ignition config
openshift-install create single-node-ignition-config

11. Create Custom CoreOS ISO

# Install coreos-installer
dnf install -y coreos-installer
 
# Download base CoreOS ISO
ISO_URL=$(openshift-install coreos print-stream-json | grep location | grep x86_64 | grep iso | cut -d\" -f4)
curl -L $ISO_URL -o scos-live.iso
 
# Embed ignition config ke ISO
coreos-installer iso ignition embed -fi bootstrap-in-place-for-live-iso.ign scos-live.iso
 
# Add serial console support untuk troubleshooting
coreos-installer iso kargs modify \
  -a 'console=tty0' \
  -a 'console=ttyS0,115200n8' \
  scos-live.iso
 
# Verify ignition embedded
coreos-installer iso ignition show scos-live.iso | jq

Eksek kembali di host KVM (WSL2 Ubuntu)

12. Deploy OKD Single Node

Kembali ke WSL2 host dan deploy VM:

# Copy ISO dari bastion
scp root@192.168.101.254:/root/okd-sno/scos-live.iso .
 
# Deploy single node VM
sudo virt-install \
  --name sno.okd4.minhphupham.com \
  --description "OKD 4.19 Single Node" \
  --memory 32768 \
  --vcpus 8 \
  --cpu host-passthrough \
  --machine q35 \
  --os-variant fedora-coreos-stable \
  --disk pool=default,bus=virtio,size=150,format=qcow2,serial=sno-disk \
  --rng /dev/urandom \
  --graphics vnc,listen=0.0.0.0 \
  --serial pty \
  --console pty,target_type=serial \
  --cdrom scos-live.iso \
  --noreboot \
  --network bridge=vbr-okd,mac=52:54:00:cc:11:22
 
# Set autostart
virsh autostart sno.okd4.minhphupham.com
 
# Start installation
virsh start sno.okd4.minhphupham.com

Installation Process Flow

okd-febryan-web-flow-proses-instalasi

13. Monitor Installation Progress

Installation bakal makan waktu sekitar 30-45 menit. Temen-temen bisa monitor progress dengan beberapa cara:

# Via virt-manager
# Eksek di host KVM
virt-manager
 
# Via VNC (lebih user-friendly)
# Connect ke VNC port yang di-assign sama libvirt
 
# Monitor dari bastion server
tail -f /var/named/log/named.run
journalctl -f -u dhcpd
 
# Dari dalam node OKD
journalctl -b -f -u release-image.service -u bootkube.service
 
# Monitor di bastion server openshift wait-for
openshift-install wait-for install-complete --dir=/root/okd-sno --log-level=debug # (debug atau info)
 

okd-febryan-web-bootstrap-complete okd-febryan-web-bootstraping-process-1

14. Post-Installation Access

Setelah installation selesai, temen-temen bisa access cluster:

# Eksek di bastion servre
# Copy kubeconfig dari node (via bastion)
scp core@192.168.101.20:/opt/openshift/auth/kubeconfig ~/.kube/config
scp core@192.168.101.20:/opt/openshift/auth/kubeadmin-password ./
 
# Atau
# Copy dari folder install-config
cp /root/okd-sno/auth/kubeconfig ~/.kube/config
 
# Test cluster access
oc get nodes
oc get clusteroperators
 
# Access web console
https://console-openshift-console.apps.okd4.minhphupham.com

okd-febryan-web-testing-oc-cli okd-febryan-web-oc-get-co okd-febryan-web-login-dashboard okd-febryan-web-okd-4-19

Troubleshooting Common Issues

1. DHCP Issues

Kalau VM ga dapet IP, sementara coba manual assign via libvirt:

virsh net-update okd4 add ip-dhcp-host \
  '<host mac="52:54:00:cc:11:22" ip="192.168.101.20"/>' \
  --live --config

2. DNS Resolution Issues

# Test dari bastion
dig @127.0.0.1 api.okd4.minhphupham.com
dig @127.0.0.1 *.apps.okd4.minhphupham.com
 
# Check named config
named-checkconf
named-checkzone okd4.minhphupham.com /var/named/zonefile.db

3. Port 6443 Not Responding

OKD cluster might still be starting up. Check cluster operators:

oc get co
# Tunggu sampai semua operators status AVAILABLE=True

Final Cluster Overview

Setelah berhasil install, temen-temen akan punya:

Cluster Information

  • Platform: OKD 4.19.0-okd-scos.11
  • Architecture: Single Node OpenShift (SNO)
  • Network Plugin: OVN-Kubernetes
  • Container Runtime: CRI-O

Access Points

Default Credentials

  • Username: kubeadmin
  • Password: (check kubeadmin-password file)

okd-febryan-web-dashboard-overview okd-febryan-web-overview-cluster

Next Steps & Learning Path

Setelah cluster running, temen-temen bisa explore:

  1. Deploy sample applications
  2. Setup CI/CD pipelines dengan OpenShift Pipelines (Tekton)
  3. Explore OpenShift GitOps (ArgoCD)
  4. Setup monitoring dengan Prometheus/Grafana
  5. Configure storage dengan Local Storage Operator
  6. Setup multi-node High Availability (HA) mode untuk production environment

Kesimpulan

OKD Single Node OpenShift adalah cara excellent buat belajar enterprise Kubernetes features tanpa butuh resource cluster penuh. Setup ini perfect buat development, testing, atau sebagai learning environment.

Resource usage yang lumayan besar memang trade-off yang harus diterima, tapi fitur-fitur enterprise yang didapat totally worth it. Plus, temen-temen bisa scale up ke multi-node cluster nanti kalau butuh.

Happy clustering! 🚀


References

Advanced Resources

Written by Minh Phu Pham

Published on August 15, 2025

Share this article:

© 2025 | Minh Phu Pham. All rights reserved.