jueves, 17 de mayo de 2012

Solaris: Connecting to iSCSI targets



iSCSI es un protocolo que permite enviar comandos SCSI mediante tramas ethernet, el cual se utiliza en Storage Area Networks a fin de flexibilizar las soluciones de storage que existen hoy en día.

iSCSI, se compone básicamente de dos tipos de tecnologías, iniciadores (clientes), y targets, los cuales son aquellos equipos que están sirviendo unidades de disco (LUN's), para que los iniciadores las monten como si se trataran de discos físicamente conectados al equipo cliente.
iSCSI suele utilizarse por regla general en redes separadas a las de datos, por cuestiones de performance sobre todas las cosas, pero como bien sabemos, iSCSI hace uso del stack TCP/IP, y este tiene una limitación bastante común, el MTU que por default es 1500 bytes, a fin de sobrellevar este primer inconveniente, muchas redes iSCSI utilizan Jumbro frames, estos son paquetes especiales en los cuales el MTU a sido alterado, incrementando el tamaño de su payload, por ejemplo 9000 bytes, que es el tamaño más común para un Jumbo frame.
La utilización de Jumbo frames, requiere que las interfaces de red de ambos lados, tanto el iniciador, como el cliente, tengan con mismo valor de MTU configurados.

iSCSI naming iSCSI utiliza nombres únicos a fin de identificar cada dispositivo de manera única. Existen dos formas de realizar esta identificación, la primera de ellas es mediante EUI (Enterprise Unique Identifier), por último y más usado el IQN (iSCSI qualified names).
El primero de ellos consiste en el prefijo eui, seguido por un string hexadecimal de 16 caracteres. El segundo de ellos (IQN), esta formado por el prefijo iqn, seguido de la fecha, el dominio de autoridad para el equipo, y un string único que identifica a cada nodo. Un ejemplo de un IQN podría ser:
iqn.2012-05.com.foobar:01:0004ca100795.13557ab1f 
iSCSI Portals El iniciador y el target, contiene uno o más "portales". Cada portal, contiene una dirección IP y un número de puerto (por default TCP/3260), en el cual el iniciador y el target utilizan a fin de determinar que interfaz van a utilizar para inicializar la conexión. Cada conexión, se asocia a una sesión, debido a que iSCSI utiliza sesiones a fin de mantener un stack de comandos de manera ordenada entre el iniciador y el target.

Basta de teoría por el momento, vayamos a la práctica:

Algunos paquetes son necesarios a fin de soportar iSCSI en nuestro equipo corriendo Solaris 10, por lo cual debemos procurar tener instalados los siguientes paquetes:
SUNWiscsir    - Sun iSCSI Device Driver 
SUNWiscsiu    - Sun iSCSI Management Utilities
Una vez instalados estos, y presentadas las LUN a nuestro equipo, debemos iniciar mediante SMF, el servicio del iniciador iSCSI, para ello, utilizaremos svcadm:
# svcadm enable iscsi_initiator
Una vez inicializado, podemos obtener información sobre el estado del iniciador iSCSI, mediante iscsiadm, entre la información que nos muestra, econtraremos nuestro IQN, que nos será útil al momento de presentar una LUN al equipo:
# iscsiadm list initiator-node
Initiator node name: iqn.2012-05.com.foobar:01:0004ca100795.13557ab1f 
Initiator node alias: -
 Login Parameters (Default/Configured):
  Header Digest: NONE/- 
                Data Digest: NONE/-
 Authentication Type: NONE i 
        RADIUS Server: NONE 
        RADIUS access: unknown
 Configured Sessions: 1
Podemos ver, que nos muestra nuestro IQN, (iqn.1986-03.com.sun:01:0003ba0e0795.4455571f). Cada IQN, puede tener un alias, esto es una forma alternativa de llamar al mismo. Además, iSCSI soporta autenticación mediante usuario y contraseña utilizando CHAP, PAP o RADIUS.
Bien, ya teniendo toda esta información, podemos comenzar a trabajar. Seguiremos utilizando iscsiadm, para hacer el discovery de nuestro target y así establecer la sesión.
# iscsiadm add discovery-address 172.16.1.10:3260
# iscsiadm modify discovery --sendtargets enable
# devfsadm -i iscsi
Lo que hicimos en el paso anterior, fue mediante el método discovery, encontrar todas las LUN's que le son presentadas al equipo, luego mediante la opción modify discover --sendtargets establecemos la sesión con el target. Y por último creamos los links de los dispositivos de discos iSCSI en el directorio /dev (que son simplemente links simbólicos del directorio /devices).

Fantástico, ya tenemos accesibles nuestros discos (podemos comprobar esto mediante dmesg), ahora vamos a crear un slice en cada uno, para ello editaremos la VTOC (Virtual Table of Contents), utilizando format:
# format
Searching for disks...done

AVAILABLE DISK SELECTIONS:
       0. c0t0d0
          /pci@1f,0/ide@d/dad@0,0
       1. c0t2d0
          /pci@1f,0/ide@d/dad@2,0
       2. c1t0d0
          /iscsi/disk@iqn.2012-05.com.foobar:01:0004ca100795.13557ab1f,0
Specify disk (enter its number): 2
selecting c1t0d0
Disk not labeled.  Label it now? y
format, nos presenta los discos que tiene disponibles, podemos apreciar a simple vista, que el número 2, es nuestra LUN, por lo cual la seleccionamos y procedemos a escribir el label en el mismo para ello debemos editar la VTOC.
FORMAT MENU:
        disk       - select a disk
        type       - select (define) a disk type
        partition  - select (define) a partition table
        current    - describe the current disk
        format     - format and analyze the disk
        repair     - repair a defective sector
        label      - write label to the disk
        analyze    - surface analysis
        defect     - defect list management
        backup     - search for backup labels
        verify     - read and display labels
        save       - save new disk/partition definitions
        inquiry    - show vendor, product and revision
        volname    - set 8-character volume name
        !     - execute , then return
        quit

format> partition

PARTITION MENU:
        0      - change '0' partition
        1      - change '1' partition
        2      - change '2' partition
        3      - change '3' partition
        4      - change '4' partition
        5      - change '5' partition
        6      - change '6' partition
        7      - change '7' partition
        select - select a predefined table
        modify - modify a predefined partition table
        name   - name the current table
        print  - display the current table
        label  - write partition map and label to the disk
        ! - execute , then return
        Quit
Dentro del menu de format seleccionamos partition y vamos a definir un slide que ocupe todo el espacio de la LUN, en nuestro caso utilizaremos 0:
partition> print

Part      Tag    Flag     Cylinders        Size            Blocks
  0       root    wm       0               0         (0/0/0)           0
  1       swap    wu       0               0         (0/0/0)           0
  2     backup    wu       0 - 1959      15.01GB     (4606/0/0) 31471335
  3 unassigned    wm       0               0         (0/0/0)           0
  4 unassigned    wm       0               0         (0/0/0)           0
  5 unassigned    wm       0               0         (0/0/0)           0
  6        usr    wm       0               0         (0/0/0)           0
  7 unassigned    wm       0               0         (0/0/0)           0

partition> 0
Enter partition id tag[unassigned]: 
Enter partition permission flags[wm]:
Enter new starting cyl[2483]: 0
Enter partition size[31471335b, 1959c, 4441e, 15366.86mb, 15.01gb]: $

partition> label
Ready to label disk, continue? y
partition>quit
Lo que hicimos fue sencillo, seleccionamos la partición 0, no le asignamos ningún tag, luego le seteamos los permisos wm, esto significa que la partición es montable (no lo sería por ejemplo en el caso de la swap), y escribible, especificamos el primer cilindro de la misma, y le dijimos que la misma ocupará el total disponible por el disco, utilizando el comodín $. Por último escribimos el label a la VTOC.
Ahora bien, solo nos resta crear el filesystem. Aquí básicamente se pueden hacer dos cosas, la primera utilizar UFS, y la segunda de ellas ZFS.

Utilizando UFS:
# newfs /dev/rdsk/c1t0d0s0
newfs: construct a new file system /dev/rdsk/c1t0d0s0: (y/n)? y
Warning: 5208 sector(s) in last cylinder unallocated
/dev/rdsk/c1t0d0s0: 286471080 sectors in 46627 cylinders of 48 tracks, 128 sectors
139878.5MB in 2915 cyl groups (16 c/g, 48.00MB/g, 5824 i/g)
super-block backups (for fsck -F ufs -o b=#) at:
32, 98464, 196896, 295328, 393760, 492192, 590624, 689056, 787488, 885920,
Initializing cylinder groups:
..........................................................
super-block backups for last 10 cylinder groups at:
285576352, 285674784, 285773216, 285871648, 285970080, 286068512, 286166944,
286265376, 286363808, 286462240

# mount /dev/dsk/c1t0d0s0 /app
Utilizando ZFS:
En este ejemplo crearemos primero un zpool, y luego un filesystem con ZFS:
# zpool create rpool c1t0d0s0
# zpool status
  pool: foobar
 state: ONLINE
 scrub: none requested
config:
        NAME        STATE     READ WRITE CKSUM
        foobar      ONLINE       0     0     0
          c1t0d0s0  ONLINE       0     0     0

errors: No known data errors

# zfs create foobar/app
# zfs list
NAME                   USED  AVAIL  REFER  MOUNTPOINT
foobar                 92.0K  15.0G   9.5K  /foobar
foobar/app             24.0K  15.0G     8K  /foobar/app

No hay comentarios:

Publicar un comentario