RHCSA Lab Setup Guide

Complete lab setup using virsh/virt-install on your Arch workstation. No GUI required.


Prerequisites Check

# Verify virtualization support
lscpu | grep -i virtualization
# Should show: VT-x (Intel) or AMD-V (AMD)

# Check KVM modules loaded
lsmod | grep kvm
# Should show: kvm_intel or kvm_amd, plus kvm

# Verify libvirt installed and running
systemctl status libvirtd
virsh version

# Your user should be in libvirt group
groups | grep -E '(libvirt|kvm)'
# If not: sudo usermod -aG libvirt,kvm $USER && newgrp libvirt

Download Rocky Linux 9

Rocky Linux 9 is 100% binary-compatible with RHEL 9. Same commands, same packages, free.

# Create ISO directory
mkdir -p ~/isos

# Download Rocky 9 minimal (smaller, faster, CLI only)
curl -L -o ~/isos/Rocky-9-latest-x86_64-minimal.iso \
  https://download.rockylinux.org/pub/rocky/9/isos/x86_64/Rocky-9-latest-x86_64-minimal.iso

# Verify download (optional but recommended)
curl -L -o ~/isos/Rocky-9-latest-x86_64-minimal.iso.CHECKSUM \
  https://download.rockylinux.org/pub/rocky/9/isos/x86_64/CHECKSUM

cd ~/isos && sha256sum -c Rocky-9-latest-x86_64-minimal.iso.CHECKSUM --ignore-missing

Network Setup

# Check default network exists
virsh net-list --all

# If 'default' network not active:
virsh net-start default
virsh net-autostart default

# Verify network details
virsh net-info default
virsh net-dumpxml default | grep -E '(ip address|range)'

Fully automated, no interaction required. Best for spinning up/destroying VMs quickly.

Create Kickstart File

cat > /tmp/ks-server1.cfg << 'EOF'
# RHCSA Lab Server 1 - Kickstart
#version=RHEL9

# Language and keyboard
lang en_US.UTF-8
keyboard us

# Timezone (adjust to your location)
timezone America/Los_Angeles --utc

# Root password - CHANGE THIS or use: openssl passwd -6 'yourpassword'
rootpw --iscrypted $6$rounds=4096$randomsalt$hashedpasswordhere
# For lab use, plaintext is fine:
rootpw --plaintext changeme

# Create admin user with sudo
user --name=admin --groups=wheel --plaintext --password=changeme

# Network - DHCP with hostname
network --bootproto=dhcp --device=link --activate --hostname=server1.lab.local

# Partitioning - auto with LVM (exam uses LVM heavily)
clearpart --all --initlabel
autopart --type=lvm

# Installation source
cdrom

# Package selection - minimal + essentials
%packages
@^minimal-environment
vim-enhanced
bash-completion
tmux
tar
rsync
%end

# Post-install script
%post --log=/root/ks-post.log
# Enable cockpit for web management (optional)
systemctl enable cockpit.socket

# Allow wheel group sudo without password (lab convenience)
echo '%wheel ALL=(ALL) NOPASSWD: ALL' > /etc/sudoers.d/wheel-nopasswd

# Set up SSH for key auth later
mkdir -p /root/.ssh
chmod 700 /root/.ssh
%end

# Reboot after install
reboot
EOF

Create VM with Kickstart

# Create server1 - fully automated install
sudo virt-install \
  --name rhcsa-server1 \
  --ram 2048 \
  --vcpus 2 \
  --disk size=20,path=/var/lib/libvirt/images/rhcsa-server1.qcow2 \
  --os-variant rocky9 \
  --location ~/isos/Rocky-9-latest-x86_64-minimal.iso \
  --initrd-inject=/tmp/ks-server1.cfg \
  --extra-args="inst.ks=file:/ks-server1.cfg console=ttyS0" \
  --network network=default \
  --graphics none \
  --console pty,target_type=serial \
  --noautoconsole

# Watch the install (optional)
virsh console rhcsa-server1
# Ctrl+] to detach

Create Second Server (for clustering/NFS labs)

# Modify kickstart for server2
sed 's/server1/server2/g' /tmp/ks-server1.cfg > /tmp/ks-server2.cfg

# Create server2
sudo virt-install \
  --name rhcsa-server2 \
  --ram 2048 \
  --vcpus 2 \
  --disk size=20,path=/var/lib/libvirt/images/rhcsa-server2.qcow2 \
  --os-variant rocky9 \
  --location ~/isos/Rocky-9-latest-x86_64-minimal.iso \
  --initrd-inject=/tmp/ks-server2.cfg \
  --extra-args="inst.ks=file:/ks-server2.cfg console=ttyS0" \
  --network network=default \
  --graphics none \
  --console pty,target_type=serial \
  --noautoconsole

Option 2: VNC Install (Interactive GUI)

If you want to follow the book’s screenshots exactly for Chapter 1.

# Create VM with VNC graphics
sudo virt-install \
  --name rhcsa-server1 \
  --ram 2048 \
  --vcpus 2 \
  --disk size=20,path=/var/lib/libvirt/images/rhcsa-server1.qcow2 \
  --os-variant rocky9 \
  --cdrom ~/isos/Rocky-9-latest-x86_64-minimal.iso \
  --network network=default \
  --graphics vnc,listen=127.0.0.1,port=5901 \
  --noautoconsole

# Connect with VNC viewer
vncviewer 127.0.0.1:5901
# Or: virt-viewer rhcsa-server1

VM Management Commands

Daily Operations

# List all VMs
virsh list --all

# Start VM
virsh start rhcsa-server1

# Graceful shutdown
virsh shutdown rhcsa-server1

# Force off (like pulling power)
virsh destroy rhcsa-server1

# Connect to console (Ctrl+] to escape)
virsh console rhcsa-server1

# Get IP address
virsh domifaddr rhcsa-server1

# SSH to VM (after getting IP)
ssh admin@$(virsh domifaddr rhcsa-server1 | awk '/ipv4/{print $4}' | cut -d/ -f1)

Snapshots (Save Your Progress!)

# Create snapshot before risky operations
virsh snapshot-create-as rhcsa-server1 --name "before-lvm-lab" --description "Clean state before LVM chapter"

# List snapshots
virsh snapshot-list rhcsa-server1

# Revert to snapshot (VM must be off)
virsh shutdown rhcsa-server1
virsh snapshot-revert rhcsa-server1 --snapshotname "before-lvm-lab"
virsh start rhcsa-server1

# Delete snapshot
virsh snapshot-delete rhcsa-server1 --snapshotname "before-lvm-lab"

Reset Lab (Start Fresh)

# Nuclear option - delete and recreate
virsh destroy rhcsa-server1 2>/dev/null
virsh undefine rhcsa-server1 --remove-all-storage

# Then re-run virt-install from above

Add Extra Disks (For Storage Labs)

Chapters 13-14 need extra disks for partitioning and LVM practice.

# Create 5GB disk images
sudo qemu-img create -f qcow2 /var/lib/libvirt/images/rhcsa-server1-disk2.qcow2 5G
sudo qemu-img create -f qcow2 /var/lib/libvirt/images/rhcsa-server1-disk3.qcow2 5G

# Attach to running VM (hot-add)
virsh attach-disk rhcsa-server1 /var/lib/libvirt/images/rhcsa-server1-disk2.qcow2 vdb --persistent
virsh attach-disk rhcsa-server1 /var/lib/libvirt/images/rhcsa-server1-disk3.qcow2 vdc --persistent

# Verify inside VM
ssh admin@server1 'lsblk'
# Should show vdb and vdc as 5G disks

SSH Key Setup (Convenience)

# Copy your SSH key to VMs
ssh-copy-id admin@$(virsh domifaddr rhcsa-server1 | awk '/ipv4/{print $4}' | cut -d/ -f1)

# Add to ~/.ssh/config for easy access
cat >> ~/.ssh/config << 'EOF'

# RHCSA Lab VMs
Host server1
    HostName 192.168.122.10
    User admin

Host server2
    HostName 192.168.122.20
    User admin
EOF

# Now just: ssh server1

DHCP IPs change. Set static for consistent access:

# On server1 (after SSH in)
sudo nmcli connection modify "Wired connection 1" \
  ipv4.addresses 192.168.122.10/24 \
  ipv4.gateway 192.168.122.1 \
  ipv4.dns 192.168.122.1 \
  ipv4.method manual

sudo nmcli connection up "Wired connection 1"

Quick Reference Card

Task Command

List VMs

virsh list --all

Start VM

virsh start <name>

Stop VM

virsh shutdown <name>

Force stop

virsh destroy <name>

Console access

virsh console <name> (Ctrl+] to exit)

Get IP

virsh domifaddr <name>

Create snapshot

virsh snapshot-create-as <name> --name "label"

Revert snapshot

virsh snapshot-revert <name> --snapshotname "label"

Delete VM

virsh undefine <name> --remove-all-storage

Add disk

virsh attach-disk <name> /path/to/disk.qcow2 vdX --persistent


Troubleshooting

"Cannot access storage" Error

# Check libvirt can access the path
sudo ls -la /var/lib/libvirt/images/

# Fix permissions
sudo chown -R libvirt-qemu:libvirt /var/lib/libvirt/images/

No IP Address

# VM might not have requested DHCP
virsh console rhcsa-server1
# Login, then:
nmcli connection up "Wired connection 1"

VNC Connection Refused

# Check VNC is listening
sudo ss -tlnp | grep 5901

# Try virt-viewer instead
virt-viewer rhcsa-server1

Next Steps

  1. [ ] Download Rocky 9 ISO

  2. [ ] Create kickstart file

  3. [ ] Spin up server1

  4. [ ] SSH in and verify

  5. [ ] Create snapshot "fresh-install"

  6. [ ] Begin Chapter 1 exercises