How to Set Up iSCSI Storage on RHEL 7

iSCSI (Internet Small Computer System Interface) is a block-level network storage protocol that transports SCSI commands over TCP/IP networks. It is widely used in enterprise environments to provide shared block storage without the cost of dedicated Fibre Channel hardware. RHEL 7 ships with full iSCSI support via targetcli for building storage targets and iscsi-initiator-utils for connecting clients. This tutorial walks through configuring an iSCSI target server, connecting an initiator (client), and optionally enabling multipath and persistent mounts.

Prerequisites

  • Two RHEL 7 systems: one acting as the target (storage server) and one as the initiator (client)
  • Root or sudo access on both machines
  • A dedicated disk or file available on the target server for backing the iSCSI LUN
  • Both systems reachable over a shared network; firewall ports 3260/tcp open
  • SELinux awareness — labeling may be required for custom paths

Step 1: Install targetcli on the Target Server

targetcli is the management shell for the Linux kernel’s LIO (Linux I/O) target subsystem. Install it on the machine that will serve storage:

yum install -y targetcli
systemctl enable target
systemctl start target

Verify the service is active:

systemctl status target

Step 2: Create a Backstore

A backstore is the underlying storage object that backs an iSCSI LUN. LIO supports several backstore types. The two most common are fileio (a file on an existing filesystem) and block (a raw block device such as a disk or LVM volume).

Launch the targetcli interactive shell:

targetcli

Option A — fileio backstore (useful for testing):

/backstores/fileio create name=disk0 file_or_dev=/var/lib/iscsi_disks/disk0.img size=10G write_back=false

Create the directory first if needed:

mkdir -p /var/lib/iscsi_disks

Option B — block backstore (production with a raw device):

/backstores/block create name=disk0 dev=/dev/sdb

Step 3: Create an iSCSI Target IQN

An IQN (iSCSI Qualified Name) uniquely identifies the target. The format is iqn.YYYY-MM.reverse-domain:label.

/iscsi create iqn.2026-05.com.example:storage1

This creates the target node and a default portal listening on all interfaces at port 3260.

Step 4: Configure the Portal

By default a portal is created on 0.0.0.0:3260. To bind to a specific IP (recommended in multi-homed servers):

/iscsi/iqn.2026-05.com.example:storage1/tpg1/portals delete 0.0.0.0 3260
/iscsi/iqn.2026-05.com.example:storage1/tpg1/portals create 192.168.10.10 3260

Step 5: Create a LUN

Map the backstore to a LUN within the target’s TPG (Target Portal Group):

/iscsi/iqn.2026-05.com.example:storage1/tpg1/luns create /backstores/block/disk0

Step 6: Create an ACL for the Initiator

An ACL restricts which initiators can connect. You need the initiator’s IQN, found in /etc/iscsi/initiatorname.iscsi on the client machine.

# On the client, read the IQN:
cat /etc/iscsi/initiatorname.iscsi
# Example output: InitiatorName=iqn.1994-05.com.redhat:client1

Back on the target in targetcli:

/iscsi/iqn.2026-05.com.example:storage1/tpg1/acls create iqn.1994-05.com.redhat:client1

To add CHAP authentication to the ACL:

/iscsi/iqn.2026-05.com.example:storage1/tpg1/acls/iqn.1994-05.com.redhat:client1 set auth userid=iscsiuser password=SecurePass123

Step 7: Save the Configuration

saveconfig
exit

Open firewall port 3260 on the target:

firewall-cmd --permanent --add-port=3260/tcp
firewall-cmd --reload

Step 8: Install the iSCSI Initiator on the Client

yum install -y iscsi-initiator-utils
systemctl enable iscsid
systemctl start iscsid

Step 9: Discover and Log In to the Target

Use iscsiadm to discover targets advertised by the target server:

iscsiadm -m discovery -t sendtargets -p 192.168.10.10

Expected output:

192.168.10.10:3260,1 iqn.2026-05.com.example:storage1

Log in to the discovered target:

iscsiadm -m node -T iqn.2026-05.com.example:storage1 -p 192.168.10.10 --login

Verify the new block device appeared:

lsblk
dmesg | tail -20

To enable automatic login at boot:

iscsiadm -m node -T iqn.2026-05.com.example:storage1 -p 192.168.10.10 --op update -n node.startup -v automatic

Step 10: Optional — Multipath Setup

For redundant paths, install device-mapper-multipath and configure it:

yum install -y device-mapper-multipath
mpathconf --enable --with_multipathd y
systemctl enable multipathd
systemctl start multipathd
multipath -ll

Step 11: Partition, Format, and Mount the iSCSI Disk

Once the disk is visible (e.g., /dev/sdc or /dev/mapper/mpatha with multipath):

fdisk /dev/sdc
# Create a new partition: n, p, 1, defaults, w

mkfs.xfs /dev/sdc1
mkdir -p /mnt/iscsi_data

Add a persistent mount to /etc/fstab. The _netdev option is critical — it tells the system to wait for network availability before mounting:

/dev/sdc1  /mnt/iscsi_data  xfs  defaults,_netdev  0 0

Test the mount:

mount -a
df -h /mnt/iscsi_data

Conclusion

You have successfully configured an iSCSI storage target on RHEL 7 using targetcli, connected an initiator client with iscsiadm, and mounted the resulting block device with a network-aware _netdev fstab entry. This setup provides flexible, cost-effective shared block storage suitable for virtual machine images, database files, and clustered workloads. For production deployments consider enabling CHAP authentication on all ACLs, using dedicated storage NICs with jumbo frames, and layering device-mapper multipath across redundant paths for high availability.