Primer contacto con Fn Project. Tratándolo de ejecutar sobre Windows 8.1

Este es el año en el que Oracle ha apostado, mas que nunca, por el open source y no solo eso, sino que su estrategia se enfoca totalmente al desarrollo moderno de aplicaciones y todo lo que tenga que ver con la infraestructura de dichas aplicaciones.




Una tendencia en la industria y algo que seguramente va a convertirse en una arquitectura a seguir es esto que se denomina como Serverless architecture. Esta arquitectura en donde nos centramos en la desarrollo de piezas de software, sin "preocuparnos" tanto por la infraestructura (lenguaje de programación, servidores, sistema operativo, etc) . Y como un elemento relacionado a este tipo de arquitecturas, podemos encontrar lo que se conoce como FaaS o Function as a Service, en donde lo que buscamos es crear funciones de propósito particular. Funciones que puedan estar desarrolladas / escritas con el lenguaje que mas te acomode y no solo eso, sino que estén bajo este concepto de Cloud Native, en donde no te importe en donde lo corras (plataforma Cloud) sino que tú estés enfocado en lo que realmente te interesa, que es el desarrollo del software.

Debo decir son términos que debemos estudiar, entender bien, aplicar bien y no solo llevarnos por la moda y las tendencias. Algunas características de este Function-as-a-service, son:

  1. Están escritas en Go, Java, Python, Node, etc. 
  2. Fácil de administrar para los operadores.Lo cual es un reto en todas estas iniciativas de microservicios y demás
  3. Relativamente fácil y al alcance de cualquier desarrollador
  4. Puede correrse en la nube o bien en el on premise:
  5. Arquitecturas híbridas
    • Arquitecturas híbridas
    • Importa tus funciones Lambda
Así como ya lo tradicional como: correr cualquier contenedor Docker como tu función y el hecho de que el propio proyecto sea mantenido por el Open Source.

Bien, toda esta información la puedes encontrar en el sitio del Projecto de Fn Project ubicado, en:
https://github.com/fnproject/fn

En donde podrás encontrar muchas cosas interesantes, entre ellas un pequeño tutorial que te guiará en como ambientar tu máquina  para que empieces a hacer ejemplos.

Es por eso que decidí escribir este post, pues no hay muchas publicaciones en español sobre este tema, y además hay algunas notas importantes que debes tomar en cuenta en caso estés usando una máquina Windows como la mía.

Lo primero que debemos de tomar en cuenta son los pre-requisitos:

1. Tener Docker instalado en tu máquina . De preferencia la versión 17.05 ó superior. En mi caso:

2. Create una cuenta en hub.docker.com

3. Ten instaladas las librerías de Fn. Esto lo puedes hacer descargándolo de aquí: https://github.com/fnproject/cli/releases . Descárgate el Fn.exe y ponlo en alguna carpeta . En mi caso lo puse aquí:


Seguramente te vas a preguntar: ¿Por qué en Windows? La verdad es que no hay otra respuesta sino: es la máquina que yo tengo. No voy a abrir una discusión sobre si Windows sirve o no, simplemente es lo que tengo y pues toca resolver los problemas que se pongan enfrente para echar a andar esto. Docker particularmente tiene sus detalles  y ahí es donde radica un poco la frustración de trabajar estas cosas en Windows. Sin embargo, para nuestra sorpresa, hay pocas consideraciones a tomar en cuenta y que haré mención en siguientes párrafos para que no batalles en ambientar tu PC.

Una vez que hayas cumplido los pre-requisitos, estás listo para escribir tu primer función, para ello sigue estos pasos sencillos:

Todo hazlo con el Docker Quickstart Terminal. Si no lo haces, vas a perder tiempo en tratar de que las cosas funcionen.
Así que búscalo en tu Windows y ejecútalo:


Esto te abrirá la línea de comando ya preparada para que Docker funcione.


Estando en esta línea de comando, ve a la ruta en la que descargaste el fn.exe y ejecutarás:

fn.exe start

Lo malo de hacer eso es que no funciona:



 pues al estar en Windows vas a tener que ejecutar esto:

docker run --rm --name functions -it -v /var/run/docker.sock:/var/run/docker.sock -v ${pwd}/data:/app/data -p 8080:8080 fnproject/fnserver

El puerto puede variar. En donde dice -p 8080:8080 puedes elegir otro puerto. Por default es ese que aparece allí. Este comando sí funciona y esto te arrancará tu server de funciones.



Ya lo tienes ejecutando en el puerto 8080 sobre la IP en la cual Docker se está ejecutando. Este dato lo obtienes cuando ejecutaste el Quickstart Terminal (un par de pasos anteriores). Toma nota de la IP, mi caso es la siguiente:


Ahora vamos a escribir una primera función muy simple. Para ello, ve al directorio en donde corriste fn.exe y crea una carpeta que se llame ejemplo, y adentro de ella genera un archivo con el siguiente contenido:

package main

import (
  "fmt"
)

func main() {
  fmt.Println("¡Saludos desde Fn Project!")
}

Es decir, debes de tener algo similar a esto:

Lo único que hicimos fue crear la carpeta de nombre "ejemplo", y adentro de ella func.go con el pequeño código que pusimos en líneas pasadas.

Ahora ábrete otro quickstart terminal de docker, pero siempre que hagas esto hazlo diciéndole que lo quieres abrir en una ventana nueva:




Ya que tengas tu ventana nueva, ve a la carpeta en donde alojaste a tu func.go



Antes de otra cosa vamos a ambientarnos con una variable de nombre: FN_REGISTRY su valor será tu usuario que ya tenías o que creaste en pasos anteriores en  hub.docker.com:

export FN_REGISTRY=rcarrascosps

También es necesario ambientar a la siguiente variable: FN_API_URL de la siguiente manera:

export FN_API_URL=http://192.168.99.100:8080

La IP debe ser la interfaz en donde está ejecutándose Docker y el puerto, es justamente el que escogimos en pasos anteriores.

(Esta variable es muy importante, pues si no lo haces, al realizar el deploy, fn va tratar de desplegarlo a localhost:8080 y esto te dará varios dolores de cabeza, pues ahí no está escuchando el servidor de funciones. Si bien está en tu máquina, el bind lo hizo a la IP donde está docker, no a localhost. Es por eso que debes indicarle la URL a través de esa variable. Si no, el error que te va a salir, es este:

Updating route /hello using image rcarrascosps/hello:0.0.33...
ERROR: Put http://localhost:8080/v1/apps/myapp/routes/hello: dial tcp 127.0.0.1:
8080: connectex: No se puede establecer una conexión ya que el equipo de destino
 denegó expresamente dicha conexión.

Pues el deploy lo hace por default a localhost. Sin embargo, al ambientar la variable FN_API_URL ya puedes indicarle en donde está escuchando el Functions Server.)


Después de esto, ejecuta un:   docker login




Ya que te hayas autenticado en el Hub de Docker, ejecutarás los siguientes comandos:


Eso nos generó un archivo de nombre func.yaml con este contenido:

version: 0.0.1
runtime: go
entrypoint: ./func


Después ejecuta:



Con esto hemos ejecutado nuestra primera función. Ahí verás el mensaje que colocamos en nuestro código en pasos anteriores.

Pero nos falta algo, que es desplegarlo en nuestro server local de funciones que ya tenemos ejecutándose localmente. Para eso ejecutaremos:


Con esto ya tenemos a nuestra función ejecutándose en nuestro server,  simplemente abre un navegador y pega la siguiente URL:

http://localhost:8080/r/myapp/ejemplo

o bien

http://192.168.99.100:8080/r/myapp/ejemplo

Al hacer esto, te debe responder:


Esto es un ejemplo muy simple, pero esto nos abre un panorama para lo que podemos hacer con esta plataforma. 

En siguientes publicaciones haremos un ejercicio mezclando varios elementos entre ellos Funciones, Chatbots, y seguramente algo de Oracle Wercker.