In this tutorial I will share the steps to create iSCSI target using Ubuntu 22.04 VM installed on Oracle VirtualBox.
The iSCSI (Internet Small Computer Systems Interface) protocol is a standard used for linking data storage facilities. It provides the capability to work over IP networks, enabling long-distance storage management and access. The key components in an iSCSI architecture are the iSCSI target and the iSCSI initiator:
⦿ iSCSI Target: The iSCSI target is the server component, which holds the storage devices that are made available over the network. These devices can be hard disk drives, tape drives, media changers, or other SCSI devices. In the context of a virtual environment, an iSCSI target often represents storage on a network server that is made accessible to multiple clients (initiators) over a standard IP network.
⦿ iSCSI Initiator: The iSCSI initiator acts as the client that connects to the iSCSI target to access the remote storage. It is typically implemented as software running on a host system, but can also be implemented in hardware. The initiator uses the IP network to send SCSI commands to the target, facilitating data storage and retrieval as if the storage were locally connected.
1. Create backing storage device
We will need a storage device which will act as backend storage for the iSCSI target. So I have added a new 2GB storage /dev/sdb
on my Ubuntu VM. This can be verified using lsblk
command
2. Install Required Packages
We would need to install tgt
package to setup iscsi target on Ubuntu. This command requires either root access or a normal user with sudo access. It is recommended to update your repository using sudo apt update
followed by sudo apt install tgt
command to install the tgt
package and all dependencies.
3. Create a new iSCSI Target
We will create a new iSCSI target iqn.2024-04.com.example:target1
on /dev/sdb
using command sudo tgtadm --lld iscsi --op new --mode target --tid 1 -T iqn.2024-04.com.example:target1
.
You can update the name as per your requirement.
Let us understand individual options:
--lld iscsi
: Specifies the low-level driver (LLD) type. Here, iscsi
indicates that the operation pertains to an iSCSI target.--op new
: Specifies the operation type. In this case, new
is used to create a new entity, which is a target.--mode target
: This option sets the mode of operation to target management.--tid 1
: Specifies the target ID. This is a numeric identifier for the target; it must be unique for each target on the server.-T iqn.2024-04.com.example:target1
: Sets the iSCSI Qualified Name (IQN) for the target. This is a globally unique identifier for the target in iSCSI environments.
4. Add Logical Unit to iSCSI Target
We need to add the logical unit to the target using sudo tgtadm --lld iscsi --op new --mode logicalunit --tid 1 --lun 1 -b /dev/sdb
Let's understand individual options:
--op new
: Again, specifies that a new configuration item is being created.--mode logicalunit
: Sets the operation mode to manage logical units. A logical unit represents a block storage device (like a disk or partition) accessible via the iSCSI target.--tid 1
: Indicates that the logical unit is being added to the target with target ID 1.--lun 1
: Specifies the Logical Unit Number. LUN is the identifier used on the SCSI bus to distinguish between devices (like different disks or partitions).-b /dev/sdb
: Binds the logical unit to a specific block device on the host system, /dev/sdb
in this case, which becomes accessible to iSCSI initiators (clients).
5. Bind iSCSI target to IP address
Now let's bind the iSCSI target to an IP address. In our case we will bind it to all available interfaces using sudo tgtadm --lld iscsi --op bind --mode target --tid 1 -I ALL
Let's understand individual option here:
--op bind
: Specifies the operation to bind the target to one or more network interfaces, making it accessible over the network.--mode target
: Continues to operate in target management mode.--tid 1
: Specifies the target ID, ensuring the operation applies to the correct iSCSI target.-I ALL
: Specifies the interfaces to bind to. Using ALL
means the target will be available on all network interfaces of the host machine, and thus accessible from any network that the host is connected to. Alternatively, you could specify a particular IP address to restrict access to a specific network interface.
6. Making iSCSI Target Configuration Persistent
The commands we used to setup iSCSI target are non-persistent i.e. it will not survive reboot. To make persistent changes we need to either create a new systemctl service unit file which takes care of executing the provided commands every time during startup or we create a new config file inside /etc/tgt/conf.d/
directory.
Create a configuration file in /etc/tgt/conf.d/
, for example, target1.conf
:echo " <target iqn.2024-04.com.example:target1>
backing-store /dev/sdb
initiator-address ALL
</target>" | sudo tee /etc/tgt/conf.d/target1.conf
After adding the configuration, restart the tgt
service to apply sudo systemctl restart tgt
and verify the service status using sudo systemctl status tgt
.
7. Verify iSCSI Targets
Verify if the iSCSI targets are created using sudo tgtadm --lld iscsi --op show --mode target
8. Enable tgt Service
We are done with setting iSCSI target, let's enable the tgt
service using sudo systemctl enable tgt
. This command will enable the service to automatically start post reboot of the node. Additionally we can also include --now
argument to also start the service. But since we had already started the service in earlier steps this becomes redundant.
You can read more about systemctl at 10+ commands to list all systemctl services with status
9. Allow access via UFW Firewall
On Ubuntu the default firewall is UFW (Uncomplicated Firewall) so we need to enable access to port 3260 which is the default port for iSCSI Target so that any initiator can initiate a connection towards the target. Execute sudo ufw allow 3260/tcp
command from the terminal.
10. Connect from iSCSI Initiator
On the client machine, you can now connect to the iSCSI target using the initiator using iscsiadm --mode discovery --type sendtargets --portal 10.10.1.21 --discover
. You would need the target IP and the IQN you configured. In my case I am using Rocky Linux 9 as client VM while the Ubuntu server address is 10.10.1.21
. You can use ip a
or ifconfig
command to get the IP Address of your server where you configured the iSCSI Target.
Let's understand the options:
--type sendtargets
: This tells the discovery mode how to find the iSCSI targets.--portal
: This argument tells the iscsiadm
command which IP address and port to address to perform the discovery. Here 10.10.1.21
is my server IP address where I just configured iSCSI target, and optionally, you can specify a port as well. If no port is specified, the default port 3260 is used.--discover
: This argument tells the iscsid
service to perform a discovery.
11. Verify iSCSI target on Client
After the discovery you can check /var/lib/iscsi/nodes
for newly added target. You can also check inside /var/lib/iscsi/send_targets/10.10.1.21,3260/
for the target details.
12. Login to iSCSI Target
Now, we have seen that we can connect to the iSCSI target and have it sent us the configured LUNS. We should now connect to this LUN using iscsiadm --mode node --targetname iqn.2024-04.com.example:target1 --login
In this command, a few options are used:
--mode node:
This specifies iscsiadm
to enter node
mode. This is the mode in which the actual connection with the target can be established.--targetname
: This specifies the name of the target as discovered when using the iSCSI discovery process.--portal
: This is the IP address and port on which the target is listening.--login
: This authenticates to the target and will store credentials as well to ensure that on reboot the connection can be reestablished again.
13. Perform Post Login Checks on Client
Both the session and the node connection can be monitored, using the -P
option i.e. iscsiadm --mode node -P 1
. You can also list the connected iscsi targets using lsscsi
command.
After logging in to an iSCSI target server, the connections are persistent automatically. That means that on reboot, the iscsid
and iscsi services are started on the iSCSI client, and these services will read the iSCSI configuration that is locally stored to automatically reconnect.
Therefore, there is no need to put anything in configuration files if you have successfully connected once to the iSCSI server.
14. Perform Post Login Checks on Server
Once a client is connected to the iSCSI Target you can get the list of connected clients on the server using sudo tgtadm --lld iscsi --op show --mode target
. As you can see in my case in the image, server.example.com
with an IP or 10.10.1.17
is connected to the target which is the hostname and IP of my client.
Removing the iSCSI connection
If you need an iSCSI connection not to be restored after reboot, you first have to log out to disconnect the actual session by using below command
iscsiadm --mode node --targetname iqn.2024-04.com.example:target1 --portal 10.10.1.21 -u
Sample Output:
Logging out of session [sid: 1, target: iqn.2024-04.com.example:target1, portal: 10.10.1.21,3260]
Logout of [sid: 1, target: iqn.2024-04.com.example:target1, portal: 10.10.1.21,3260] successful.
Next you need to delete the corresponding IQN sub directory and all of its contents. You can do this with the below command
iscsiadm --mode node --targetname iqn.2024-04.com.example:target1 --portal 10.10.1.21 -o delete