Automating iSCSI Multipathing with Ansible
Multipathing (MPIO - Multipath I/O) is essential for high availability and performance in iSCSI storage environments. It allows multiple network paths between an initiator (client) and a target (storage), ensuring failover and load balancing. In this guide, we will set up iSCSI multipathing on Linux using Ansible, automating installation, configuration, and monitoring.
1. Why Use Multipathing?
Multipathing provides:
- Redundancy - If one network path fails, another takes over
- Load Balancing - Distributes I/O across multiple paths
- Higher Bandwidth - Uses multiple network interfaces to increase throughput
- Failover Support - Automatically switches paths when a failure occurs
We will use Ansible to automate the deployment of iSCSI and multipath tools on multiple nodes.
2. Ansible Role: iscsi_multipath
We will create an Ansible role called iscsi_multipath that:
- Installs required packages
- Configures
iscsid.confandmultipath.conf - Discovers iSCSI targets
- Logs in to multiple iSCSI paths
- Ensures multipathing is enabled and running
2.1. Role Directory Structure
iscsi_multipath/
├── tasks/
│ ├── main.yml
├── templates/
│ ├── iscsid.conf.j2
│ ├── multipath.conf.j2
├── vars/
│ ├── main.yml
├── defaults/
│ ├── main.yml
├── meta/
│ ├── main.yml
├── README.md
3. Ansible Role Configuration
3.1. Define Variables
Create defaults/main.yml:
iscsi_target_ips:
- "192.168.2.253"
- "192.168.3.253"
iscsi_target_name: "iqn.2025-03.com.example:storage"
iscsi_chap_username: "your_username"
iscsi_chap_password: "your_secure_password"
3.2. Install Required Packages
Create tasks/main.yml:
---
- name: Install iSCSI and multipath packages
ansible.builtin.apt:
name:
- open-iscsi
- multipath-tools
state: present
update_cache: true
- name: Deploy iSCSI configuration
ansible.builtin.template:
src: iscsid.conf.j2
dest: /etc/iscsi/iscsid.conf
owner: root
group: root
mode: '0644'
- name: Deploy Multipath configuration
ansible.builtin.template:
src: multipath.conf.j2
dest: /etc/multipath.conf
owner: root
group: root
mode: '0644'
- name: Enable and start multipathd
ansible.builtin.systemd:
name: multipathd
state: started
enabled: true
- name: Discover iSCSI targets
ansible.builtin.shell: "iscsiadm -m discovery -t st -p {{ item }}"
loop: "{{ iscsi_target_ips }}"
register: iscsi_discovery
changed_when: false
- name: Log in to iSCSI targets
ansible.builtin.shell: "iscsiadm -m node -T {{ iscsi_target_name }} -p {{ item }} --login"
loop: "{{ iscsi_target_ips }}"
- name: Ensure iSCSI login persists across reboots
ansible.builtin.shell: "iscsiadm -m node -T {{ iscsi_target_name }} -p {{ item }} --op=update --name=node.startup --value=automatic"
loop: "{{ iscsi_target_ips }}"
3.3. Templates for Configuration Files
templates/iscsid.conf.j2
iscsid.startup = /bin/systemctl start iscsid.socket
node.startup = automatic
node.leading_login = No
node.session.auth.authmethod = CHAP
node.session.auth.username = {{ iscsi_chap_username }}
node.session.auth.password = {{ iscsi_chap_password }}
node.session.scan = auto
templates/multipath.conf.j2
defaults {
user_friendly_names yes
}
blacklist {
devnode "^sd[a-z]"
}
multipaths {
multipath {
wwid "{{ iscsi_wwid }}"
alias mpatha
path_grouping_policy "multibus"
path_selector "round-robin 0"
failback immediate
rr_weight priorities
no_path_retry 5
}
}
Note: The WWID (World Wide Identifier) should be retrieved manually using:
sudo multipath -ll
Then add it to vars/main.yml.
4. Running the Ansible Playbook
Create a playbook setup_iscsi_multipath.yml:
- name: Setup iSCSI Multipathing
hosts: all
become: true
roles:
- iscsi_multipath
Run the playbook:
ansible-playbook -i inventory setup_iscsi_multipath.yml
5. Verifying the Setup
Check Active iSCSI Sessions:
sudo iscsiadm -m session
Expected output:
tcp: [1] 192.168.2.253:3260,1 iqn.2025-03.com.example:storage
tcp: [2] 192.168.3.253:3260,1 iqn.2025-03.com.example:storage
Check Multipath Devices:
sudo multipath -ll
Expected output:
mpatha (3600140547f55689de4b49c098d9b1a3c) dm-0 LIO-ORG ,iscsi_target
size=20G features='0' hwhandler='0' wp=rw
|-+- policy='round-robin 0' prio=50 status=active
| - 2:0:0:0 sdb 8:16 active ready running
|-+- policy='round-robin 0' prio=50 status=enabled
| - 2:0:1:0 sdc 8:32 active ready running
6. Conclusion
With this Ansible role, we have successfully:
- Automated iSCSI multipathing setup
- Configured persistent iSCSI sessions
- Ensured failover and load balancing
- Simplified deployment across multiple nodes
This setup ensures high availability and performance while eliminating manual configuration errors.