iSCSI Target med Ubuntu Linux

Introduktion till iSCSI och IET

iSCSI är en standard för nätverksbaserad lagring som ofta används i olika SAN och NAS-lösningar. De två delarna som används för detta är iSCSI Target (den som agerar server) och iSCSI Initiator (den som agerar klient). För att få Linux att agera target så används IET (iSCSI Enterprise Target). IET erbjuder möjligheten att dela ut en mängd olika typer av enheter. Allt från vanliga hårddiskar eller partitioner, LVM volymer, RAID-enheter eller helt vanliga filer (som emulerade diskar) fungerar utmärkt. Du kan självklart också dela ut ett USB-minne eller en CD/DVD-enhet (som readonly) även om prestandan kanske inte är den bästa.

Vilka operativsystem stödjer iSCSI?

iSCSI stöds av de flesta operativsystem, Linux, FreeBSD, NetBSD, Mac OS X, Solaris och Windows.

Logical Unit Number (LUN)

När man i storage-världen talar om LUN menar man de logiska enheterna som är utdelade via ett SAN. LUN härstammar från SCSI, där man anger ett nummer för varje logisk enhet som skapats på en fysisk SCSI enhet. Med iSCSI representerar ett LUN alltså en utdelad volym. En iSCSI Initiator hanterar därför ett LUN som en fysisk SCSI eller IDE/SATA-enhet och kan alltså partioneras och användas på precis samma sätt. (se nedan)

Block-sharing vs File-sharing

iSCSI är ett “block sharing“-protokoll medan protokoll som Samba, FTP eller NFS är olika typer “file sharing“-protokoll. Fördelen med detta är att du kan partionera den utdelade volymen samt även välja vilket filsystem du vill ha på den utdelade disken. Nackdelen däremot är att endast en användare i taget kan ha åtkomst till ett LUN.

iSCSI Qualified Name (IQN)

För att adressera en iSCSI Target eller iSCSI Initiator så används ett IQN. Dessa gör att det i större miljöer blir lättare att hålla redan på vilken volym och på vilken fysisk maskin ett LUN finns. Följande format används:

iqn.<yyyy>-<mm>.<hostnamnet baklänges>:<namn på volymen>

Så, om storage.ifconfig.se delar ut en volym från den tredje disken, då kan det se ut på följande sätt:

iqn.2010-01.se.ifconfig.storage:disk3.lun0

Installera och Konfigurera IET

Börja med att installera paketet iscsitarget som installerar IET och behövande kernel moduler:

sudo apt-get update
sudo apt-get install iscsitarget

Därefter aktiverar du tjänsten genom att editera /etc/default/iscsitarget och ändra:

ISCSITARGET_ENABLE=false

till:

ISCSITARGET_ENABLE=true

Som standard lyssnar ietd på alla interface och om maskinen är ansluten mot Internet kan vem som helst kommat den. För att ietd enbart ska lyssna på 192.168.1.10 så måste du editera /etc/init.d/iscsitarget. Öppna filen med valfri editor och gå till rad 80, ändra:

start-stop-daemon --start --exec $DAEMON --quiet --oknodo

till:

start-stop-daemon --start --exec $DAEMON --quiet --oknodo -- -a 192.168.1.10

Du kan även ändra standard porten (3260) genom att lägga till -p följt av vilken port du vill använda. För mer information, kolla man-sidan för ietd. Därefter startar vi tjänsten med:

sudo /etc/init.d/iscsitarget start

Att använda en logisk volym eller partition som LUN

I filen /etc/ietd.conf så anger du vad och hur något ska delas ut. Du kan även ange de användare och lösenord (se nedan) som krävs för att kunna nå de utdelade volymerna.

Om du vill dela ut en logisk volym från LVM så använder du:

# LVM volym LogVol0 från volymgruppen VolGrupp0:
Target iqn.2010-01.storage.example.com:lun0
        Lun 0 Path=/dev/VolGrupp0/LogVol0,Type=blockio

Där Path måste peka på den logiska volymen. Du kan även ange att Path pekar på en vanlig partition istället och därmed dela ut den:

# Första partitionen på /dev/sdb
Target iqn.2010-01.storage.example.com:lun0
        Lun 0 Path=/dev/sdb1,Type=blockio

För att ändringarna i /etc/ietd.conf ska gälla så måste du starta om tjänsten:

sudo /etc/init.d/iscsitarget restart

Att använda en vanlig fil som LUN

Om du vill dela ut en vanlig fil som virtuell disk så måste du först skapa filen. Volymen kommer ha samma storlek som filen, vilket innebär att det inte fungerar med en tom fil. Detta löser du enklast med dd:

dd if=/dev/zero of=/vart/filen/ligger/disk.raw bs=64k count=81920

Detta skapar en 5GB fil, därefter anger du bara följande i /etc/ietd.conf:

# En vanlig fil: /vart/filen/ligger/disk.raw
Target iqn.2010-01.storage.example.com:lun0
        Lun 0 Path=/vart/filen/ligger/disk.raw,Type=fileio

Autentisering

iSCSI stödjer autentisering via CHAP-protokollet. Ett protokoll som är relativt osäkert då det är sårbart mot både ordlistor, reflection och spoofing-attacker. IET har två typer av autentisering, den ena är för att kunna se och lista vilka LUN som finns tillgängliga, den andra är för att få åtkomst till ett specifikt LUN.

För att ange ett användarnamn och lösenord så använder du IncomingUser i /etc/ietd.conf:

# Autentisering
IncomingUser admin s3cr3ts3cr3t
 
# Första partitionen på /dev/sdb
Target iqn.2010-01.storage.example.com:lun0
        Lun 0 Path=/dev/sdb1,Type=blockio

Observera att lösenordet måste vara exakt 12 tecken långt pga CHAP. Du kan även ange flera användarnamn och lösenord genom att ange flera IncomingUser efter varandra.

För att kräva autentisering för att få åtkomst till ett specifikt LUN, använd IncomingUser under Target:

# Första partitionen på /dev/sdb
Target iqn.2010-01.storage.example.com:lun0
        IncomingUser admin thispassword
        Lun 0 Path=/dev/sdb1,Type=blockio

Detta innebär att du kan ha olika användarnamn och lösenord per-LUN och här kan du också ange flera IncomingUser för att ha flera “konton” på samma LUN. Notera dock att även om du använder autentisering, så är skickas all data i klartext, vilket innebär att vem som helst kan läsa trafiken om du använder iSCSI över Internet. Som med alla andra IP-baserade protokoll så kan du använda iSCSI över IPsec, men detta är inget jag använt personligen då jag enbart använder iSCSI lokalt.

Avslut

Syftet med denna guide är att ge läsaren en inblick i vad iSCSI är och vad det går att använda till. iSCSI innehåller en hel del andra områden, så som att ha flera anslutningar till samma LUN (för failover eller load-balancing), hårdvaru-baserade Initiators som HBA-kort (för att avlasta processorn), Internet Storage Name Service (iSNS), osv. För att inte tala om allt man kan optimera med TCP/IP via jumbo-paket, bufferstorlekar, window scaling, osv. Jag har heller inte nämnt hur man ansluter en Initiator till en Target, eftersom jag då skulle behöva förklara hur detta sker i flertalet operativsystem. Istället lämnar jag det osagt och spara det till en framtida artikel.

Angående prestanda och hastigheter så använder jag personligen ett “Intel PRO/1000 Gigabit”-kort i min server, en NetGear GS108 Switch och ett “Realtek RTL8168B/8111B Gigabit”-kort som är inbyggt i min arbetsdator. Jag har en överföringshastighet på ~55-60MB/s till min iSCSI volym vilket är ungefär vad min gamla IDE disk klarar av.

Jag har heller inte ändrat några inställningar för nätverket på varken server eller klient utan använder standardinställningarna i Ubuntu Server 9.10 respektive Windows 7 Ultimate. Om har jag missat något i artikeln eller är det något som inte riktigt stämmer, tveka inte att kommentera det, så åtgärdar jag det så snart det finns tid.