Configuring iSCSI Initiator on CentOS Stream 9: Connecting SAN/NAS Storage for Enterprise Environments

CentOS tutorial - IT technology blog
CentOS tutorial - IT technology blog

iSCSI or Fibre Channel — Which One Is Right for Your Infrastructure?

I once worked at a company running a NetApp storage system, and the first question that always came up when connecting a Linux server to SAN was: iSCSI or Fibre Channel (FC)? It’s not a matter of “which one is better” — it’s “which one fits your existing infrastructure.”

FC latency can drop below 1ms with extremely stable throughput — but it requires dedicated HBA cards (~$300–500 each), dedicated FC switches, and upfront costs that can easily run into the tens of thousands of dollars. iSCSI runs over your existing Ethernet/IP network with no special hardware needed. With 10GbE, throughput is sufficient for most mid-sized enterprise workloads. For SMB environments or dev/test setups, the practical choice is fairly obvious.

iscsiadm vs Cockpit vs iSNS: What Should You Use?

On CentOS/RHEL, there are a few ways to manage the iSCSI initiator — I’ve tried all three, and here’s my honest take:

  • iscsiadm (CLI): The official tool, full-featured, and scriptable — this is what you want in production. The syntax is a bit verbose, but once you get used to it, it’s not a problem.
  • Cockpit + iSCSI module: A browser-based GUI, convenient for admins who aren’t comfortable with the CLI — but offers less control and is harder to debug when things go wrong.
  • iSNS (Internet Storage Name Service): Like DNS for iSCSI, automatically discovers targets in large storage environments — requires a dedicated iSNS server, which is overkill if you only have a few dozen LUNs.

sendtargets vs Static Node vs iSNS

This part rarely gets covered, but it’s important to understand when setting things up:

  • sendtargets: Queries the iSCSI portal directly and the server returns a list of available targets — simple and practical when you know the portal address. This is what I use 90% of the time.
  • Static node: Configures the target IQN directly without discovery — useful when you know the exact target and want tighter control.
  • iSNS: Auto-discovers targets in large enterprise environments — requires a dedicated iSNS server, suited for environments with hundreds of targets.

In practice, 90% of the time you only need sendtargets + iscsiadm — no dependency on auxiliary servers, easy to script, and much simpler to debug.

Hands-On Deployment: From Installation to Mounting

Step 1: Install the iSCSI Initiator

CentOS Stream 9 uses the iscsi-initiator-utils package:

sudo dnf install -y iscsi-initiator-utils
sudo systemctl enable --now iscsid

Check your initiator’s IQN (iSCSI Qualified Name) — this is your server’s unique identifier in the storage system:

cat /etc/iscsi/initiatorname.iscsi
# Output: InitiatorName=iqn.1994-05.com.redhat:xxxxxxxx

The IQN is unique per machine. If you clone a VM without changing the IQN, it will conflict with any active sessions — a mistake I ran into during a server migration.

Step 2: Configure CHAP Authentication

This step often gets skipped with the reasoning that “it’s an internal storage network, why bother with auth?” But iSCSI has no encryption by default — traffic flows in plaintext. CHAP at least provides authentication, so you’re not leaving the target open to your entire network segment:

sudo vi /etc/iscsi/iscsid.conf

Find and update the following lines:

# Enable CHAP
node.session.auth.authmethod = CHAP

# Authentication credentials (ask your storage admin)
node.session.auth.username = your_username
node.session.auth.password = your_password

# If mutual CHAP is needed (target authenticates back to initiator)
node.session.auth.username_in = target_username
node.session.auth.password_in = target_password

Step 3: Discovery — Finding iSCSI Targets

Use sendtargets to discover targets (replace 192.168.1.100 with your iSCSI portal IP):

sudo iscsiadm -m discovery -t sendtargets -p 192.168.1.100:3260

The output will list the available targets:

192.168.1.100:3260,1 iqn.2024-01.com.company:storage.lun01
192.168.1.100:3260,1 iqn.2024-01.com.company:storage.lun02

Step 4: Log In to the Target

Log in to all discovered targets:

sudo iscsiadm -m node --loginall=automatic

Or log in to a specific target:

sudo iscsiadm -m node \
  --targetname "iqn.2024-01.com.company:storage.lun01" \
  --portal "192.168.1.100:3260" \
  --login

Check active sessions:

sudo iscsiadm -m session -P 1

Step 5: Confirm the Disk Appears

After a successful login, the kernel recognizes the LUN as a regular SCSI device — no reboot required:

lsblk
# or
sudo fdisk -l | grep "Disk /dev/sd"

If you see additional /dev/sdb, /dev/sdc… entries appearing — those are your iSCSI LUNs.

Step 6: Format and Mount

# Format with XFS (recommended for storage workloads)
sudo mkfs.xfs /dev/sdb

# Create mount point
sudo mkdir -p /mnt/iscsi-data

# Test mount
sudo mount /dev/sdb /mnt/iscsi-data

# Verify
df -hT /mnt/iscsi-data

Step 7: Auto-Mount at Boot — Don’t Skip This Step

iSCSI mounts differ from local disks in one critical way: the network must be ready before mounting. Without the _netdev option in /etc/fstab, your server can get stuck at the boot screen waiting for a mount timeout — I’ve seen servers add 90 extra seconds to every boot just because of this oversight:

sudo blkid /dev/sdb  # Get UUID
sudo vi /etc/fstab
# Add this line (replace with actual UUID):
UUID=xxxx-xxxx-xxxx  /mnt/iscsi-data  xfs  defaults,_netdev,nofail  0 0

The nofail option prevents the server from getting stuck at boot if the storage target is unavailable. Enable the related services:

sudo systemctl enable iscsi iscsid
sudo systemctl enable remote-fs.target

Real-World Tips — Lessons from an Emergency Migration

When CentOS 8 reached EOL, I had to migrate 5 servers to Rocky Linux in one week — and iSCSI was the most stressful part because storage downtime directly impacted production databases. Here’s what I learned from that experience:

  • Document IQNs before migrating: The IQN on the old machine differs from the new one. If the storage admin has configured ACLs by IQN, you need to notify them to update — otherwise you can log in successfully but see no LUNs, and waste hours debugging.
  • Use multipath whenever possible: The device-mapper-multipath package allows multiple paths to the same LUN — with automatic failover if one network link goes down. For production databases, this is less of a “nice to have” and more of a necessity.
  • Verify MTU consistency: Jumbo Frames (MTU 9000) can significantly improve iSCSI throughput, but MTU must be consistent across the entire path from NIC → switch → storage array. An MTU mismatch causes packet fragmentation, reducing throughput by 30–40% with nothing unusual appearing in the logs — the kind of problem that can take hours to track down.
  • Dedicate a separate network for storage traffic: Don’t share a NIC with management traffic. At minimum, use a dedicated VLAN — to avoid situations where a backup job saturates the network and starves the database’s storage.

Troubleshooting Common Issues

Login Failed — Authentication Error

# Update CHAP settings directly on the node
sudo iscsiadm -m node \
  --targetname "iqn.2024-01.com.company:storage.lun01" \
  --portal "192.168.1.100:3260" \
  -o update \
  -n node.session.auth.authmethod -v CHAP

sudo iscsiadm -m node \
  --targetname "iqn.2024-01.com.company:storage.lun01" \
  --portal "192.168.1.100:3260" \
  -o update \
  -n node.session.auth.username -v your_user \
  -n node.session.auth.password -v your_pass

Target Doesn’t Reconnect After Reboot

# Set node startup mode to automatic
sudo iscsiadm -m node -o update -n node.startup -v automatic

# Verify services are running
sudo systemctl status iscsid iscsi

Safe Logout During Maintenance

# Unmount first — IMPORTANT, do not skip this step
sudo umount /mnt/iscsi-data
sudo sync

# Then logout
sudo iscsiadm -m node --logoutall=all

iSCSI on CentOS Stream 9 is production-ready and stable enough for database storage — I’m running it in a live environment with dozens of LUNs without any issues. Setups usually fail not because the tooling is complex, but because three things tend to get overlooked: CHAP authentication, multipath for high availability, and _netdev in fstab. Get those three right, and the rest goes fairly smoothly.

Share: