aprendiendo ( Erlang ).

lunes, 13 de junio de 2011

Creación y conexión de nodos Erlang remotos.

| 7 comentarios |

Empecemos primero con los conceptos básicos para trabajar con nodos Erlang tanto en remoto como en local.

Nodo

Un nodo no es más que una ejecución del ERS (Erlang Runtime System) al que se le ha dado nombre. El nombre del nodo se establece al arrancar Erlang con los parámetros -name y -sname (nombre y nombre corto respectivamente).
Dicho de otra manera, un nodo es una unidad de trabajo que se identifica unívocamente por el átomo nombre@máquina (nombre largo) donde nombre es el nombre corto y máquina es la máquina donde se esta ejecutando el nodo.
Es importante, si queremos trabajar con máquinas remotas, que están se puedan ver entre sí. Parece una tontería pero yo conozco un primo que ... bueno ya sabéis.
Una máquina puede tener varios nodos y el mismo nombre corto puede estar utilizado en varias máquinas.
El parámetro -name se suele utilizar para nombrar nodos que se van a utilizar de forma remota. Mientras que -sname se suele utilizar para nombrar nodos locales.
Si arrancamos un nodo veremos la consola así:
$ erl -sname ping
Erlang R13B03 (erts-5.7.4) [source] [64-bit] [rq:1] [async-threads:0] [hipe] [kernel-poll:false]

Eshell V5.7.4  (abort with ^G)
(ping@máquina)1>
El prompt del Eshell cambia indicando el nodo actual.
Existe una función que nos permite saber el nodo actual node/0. Si no hemos creado el nodo la función nos devolverá el átomo nonode@nohost.

La cookie mágica

Lo normal en casi todas las redes es autenticarse para determinar si se puede o no establecer comunicación. En las redes de nodos Erlang es diferente. Cada nodo Erlang posee un átomo llamado cookie (o cookie mágica según los manuales de referencia). Esta cookie mágica, es en realidad una clave que compartirán todos los nodos de una red Erlang.
Cuando un nodo intenta conectarse a otro nodo las cookies mágicas de ambos son comparadas. Si son iguales se le da acceso y en caso contrario se le deniega el acceso.
Por lo dicho aquí, y por vuestra seguridad nunca, nunca pongas una clave o cookie como 1234, admin, etc, etc...
Para establecer la cookie, existen dos formas:
  1. Por parámetros: -setcookie clave.
  2. En consola: erlang:set_cookie(nodo@máquina, clave) para establecerla y para obtener la cookie erlang:get_cookie().
La cookie se guarda encriptada en el fichero .erlang.cookie del home.

Saber si tenemos conexión a otro nodo

Para saber si tenemos conexión con otro nodo remoto o no, tenemos la función ping/1 del módulo net_adm. A esta curiosa función, le pasamos el nombre del nodo (nombre@máquina) y nos responde ping si ha podido establecer conexión o pang en caso contrario.

Conectando dos nodos del mismo dominio

En una consola, voy a arrancar un nodo (nodo1) y en otra consola otro (nodo2).
$ erl -sname nodo1 -setcookie clave
Erlang R13B03 (erts-5.7.4) [source] [64-bit] [rq:1] [async-threads:0] [hipe] [kernel-poll:false]

Eshell V5.7.4  (abort with ^G)
(nodo1@maquina1)1>
Ahora el nodo2.
$ erl -sname nodo2 -setcookie clave
Erlang R13B03 (erts-5.7.4) [source] [64-bit] [rq:1] [async-threads:0] [hipe] [kernel-poll:false]

Eshell V5.7.4  (abort with ^G)
(nodo2@maquina2)1>
Verifiquemos que desde el nodo1 tenemos conexión al nodo2.
(nodo1@maquina1)1> net_adm:ping(nodo2@maquina2).
pong
(nodo1@maquina1)2> net_adm:ping(nodoDesconocido@máquina).
pang
(nodo1@maquina1)3> nodes().                              
[nodo2@maquina2]
Ahora vamos a conectarnos al nodo2 desde el nodo1. Para ello, haremos uso del modo JCL que ya explicamos en su momento.
(nodo1@maquina1)4> 
User switch command
 --> h
  c [nn]            - connect to job
  i [nn]            - interrupt job
  k [nn]            - kill job
  j                 - list all jobs
  s [shell]         - start local shell
  r [node [shell]]  - start remote shell
  q                 - quit erlang
  ? | h             - this message
 --> j
   1* {shell,start,[init]}
 --> r nodo2@maquina2
 --> j
   1  {shell,start,[init]}
   2* {nodo2@maquina2,shell,start,[]}
 --> c
Eshell V5.7.4  (abort with ^G)
(nodo2@maquina2)1> 
Lo primero es entrar en el modo de control de trabajos (JCL) pulsando Ctrl+g. He pulsado h para ver los comandos y j para saber los trabajos activos. El secreto esta en el comando r que nos permite crear un shell remoto, en nuestro caso a nodo2@maquina2. Comprobamos que tenemos el trabajo creado con j y como esta por defecto (por que tiene el asterisco) con c nos conectamos al trabajo activo.
Pues nada, ya estamos conectados al nodo2. No olvidemos que aunque trabajemos con el nodo2 y tengamos accesible las aplicaciones y módulos del nodo2 el trabajo pertenece al nodo1. Veamos los trabajos que tenemos en el nodo2:
(nodo2@maquina2)1> nodes().
[nodo1@maquina1]
(nodo2@maquina2)2> 
User switch command
 --> j
   1* {shell,start,[init]}
A continuación, voy a ir de un trabajo a otro y por último finalizaré el trabajo con el nodo2.
Eshell V5.7.4  (abort with ^G)
(nodo2@maquina2)1> nodes().
[nodo1@maquina1]
(nodo2@maquina2)2> 
User switch command
 --> j
   1  {shell,start,[init]}
   2* {nodo2@maquina2,shell,start,[]}
 --> c 1
(nodo1@maquina1)4>         
User switch command
 --> c 2
(nodo2@maquina2)2>         
User switch command
 --> k 2
 --> c
Unknown job
 --> j
   1  {shell,start,[init]}
 --> c 1
(nodo1@maquina1)4>  
Otra forma de conectar directamente es mediante la línea de comandos y el parámetro remote shell (remsh).
$erl -sname nodo1 -setcookie clave -remsh nodo2@maquina2
Erlang R13B03 (erts-5.7.4) [source] [64-bit] [rq:1] [async-threads:0] [hipe] [kernel-poll:false]

Eshell V5.7.4  (abort with ^G)
(nodo2@maquina2)1> 
User switch command
 --> j
   1* {nodo2@maquina2,shell,start,[]}

Conectando dos nodos remotos (dominios distintos)

El funcionamiento es el mismo pero tenemos que tener en cuenta lo siguiente:
  1. El demonio epmd (Erlang Port Mapper Daemon) es el encargado de mapear los puerto. Por defecto escucha en el puerto 4369. Se debe abrir el puerto para TCP y UDP.
  2. También se puede establecer otro rango de puertos mediante la línea de comandos -kernel inet_dist_listen_min 9000 inet_dist_listen_max 9005. Si te decantas por esta opción debes abrir el rango de puertos.
  3. Si se desea utilizar un shell seguro (ssh) utilizar -rsh ssh.
Pero lo principal es..., que ambas máquinas se vean.

Conclusión

Como hemos podido ver, teniendo claro algunos conceptos, resulta muy fácil crear nodos e interconectarlos, y abrir una consola de trabajo de forma remota.
En un futuro, estos conocimientos nos serán muy útiles para realizar la distribución de nuestra aplicaciones, crear servidores, monitores, supervisores, etc ...

Publicar un comentario en la entrada

7 comentarios:

  1. tachaaaan dijo...

    Oye muy bueno el artículo. Me ha resuelto algunas dudas que tenia

  2. Anónimo dijo...

    Soy nuevo en esto de Erlang y me ha parecido buenisimo el artículo.

  3. tachaaaan dijo...

    Te sugiero un enlace para la páginas de enlaces:

    El foro de Erlang-programing en google:
    https://groups.google.com/forum/#!forum/erlang-programming

  4. Verdi dijo...

    Gracias a ambos.

    Efectivamente me falta este enlace que incluiré en breve.

    Gracias

  5. George dijo...

    Excelente aporte, nos ayudo mucho con un trabajo de la u. adelante con mas posts!

  6. Verdi dijo...

    Me alegra que te sea útil. Ese es el sentido de blog.
    Seguiré trabajando por mejorar el blog y su contenido.

    Gracias.

  7. Anónimo dijo...

    Hay un pequeño fallo en la explicación del comando ping. Cuando funciona correctamente devuelve "pong":

    "A esta curiosa función, le pasamos el nombre del nodo (nombre@máquina) y nos responde ***ping*** si ha podido establecer conexión o pang en caso contrario."

    Muy buen artículo, me ha ayudado mucho.

 
Licencia Creative Commons
Aprendiendo Erlang por Verdi se encuentra bajo una Licencia Creative Commons Atribución-NoComercial-CompartirIgual 3.0 Unported.