Volúmenes en Docker

Docker Volume

Antes de entrar en materia, debo comentar que este post se inicio por un problema que tuve alguna vez para montar un volumen NFS en un contenedor docker directamente, específicamente un volumen EFS (Elastic File System) de AWS. Debo reconocer que en un principio fue por desconocimiento, pero mas adelante me encontré con una serie de problemas por lo que opté finalmente por montar el volumen en la máquina host y luego montar el volumen en el contenedor.

Bueno, finalmente encontré una buena manera de solucionar este problema a través de los volúmenes de Docker.

Binding y Volúmenes

Debemos recordar que un contenedor es inmutable y efímero en si. Con esto quiero decir que un contenedor en si mismo no puede cambiar la imagen sobre la cual se esta ejecutando.  El contenedor mientras corre puede generar información modificar su filesystem cambiar todo lo que quiera mientras este en ejecución, pero una vez que este se termina y se remueve, toda la información escrita por el contenedor se pierde. Una vez que se inicia un nuevo contenedor con la misma imagen, nada de las modificaciones o de los datos generados se guardarán y por ende se perderán.

Binding

Para poder persistir los datos, se pueden montar directorios o archivos del filesystem de la máquina host, dentro del contenedor. Esto se llama binding. Al realizar un binding cualquier cambio que se haga dentro del contenedor, también podría verse reflejado por el archivo origen (host). Ejm.


docker run -d -v /opt/config/nginx.conf:/etc/nginx/conf.d/site.conf -p 80:80 nginx
#/opt/config/nginx.conf
# Archivo de configuración del SO host
#/etc/nginx/conf.d/site.conf
# Es el archivo que hace referencia a la máquina host, pero será usado en el container.
# En este caso será la configuración en Nginx.

Este mismo método se puede utilizar para montar directorios dentro del contenedor, de modo que los objetos o archivos generados por el contenedor puedan persistir en la máquina host y puedan ser usados en otro contenedor.

Un buen ejemplo de esto son las bases de datos. En general uno querría que los datos generados por el contenedor que la usa puedan ser persistidos y que no se pierdan en caso de tener que volver a crear el contenedor. Otra forma de persistir los datos son los volúmenes de docker

Volúmenes

Los volúmenes de docker son una forma especial de crear espacios para persistencia de archivos y la principal diferencia es que estos volúmenes pueden usar una serie de  drivers que permiten la integración de un volumen con algún tipo especifico de filesystem como por ejemplo Azure Filesystem, S3 de AWS, IPFS entre algunos. El driver por defecto es el local, que permite el uso del propio filesystem (ninguna novedad) como volumen.

Cada volumen es identificado con una etiqueta y no es necesario especificar un path en el SO host, ya que este volumen tiene una zona donde se crean todos los volúmenes dentro del filesystem del host. Una vez creado un volumen, puede ser montado dentro de un contenedor asociándolo a un directorio dentro del contenedor. Ejm.


docker run -d -v data:/var/lib/mysql -p 3306:3306 mysql

En el ejemplo anterior, se ha asociado un volumen llamado “data” en el path “/var/lib/mysql” dentro del contenedor. Esto quiere decir que todo los datos que se creen en ese path serán persistidos dentro de ese volumen.

¿ Pero, de dónde salió “data” ?

Bueno vamos a hacer un flashback al momento en que hemos definido tal volumen. Primero, debemos mencionar que utilizaremos el comando “volume” de docker para crear este volumen.

docker volume create data
data
docker volume ls
VOLUME NAME
local data

Con el comando anterior, hemos creado un volumen y el cual se llama “data”.  Con el comando “volume ls” podemos ver que se creo un volumen con el driver “local” que es el que viene por defecto.

Anteriormente hemos mencionado que el volumen se almacena localmente dentro del host en un repositorio local dentro del filesystem. La ruta en la que se guardan todos los volúmenes es “/var/lib/docker/volumes”. Para saber en que lugar exacto se ha creado el volumen se puede usar el comando “docker volume inspect {nombre_volumen}” el cual retornará un Json con la información.


docker volume inspect data
[ 
{ 
"CreatedAt": "2018-06-01T03:47:14Z",
 "Driver": "local",
 "Labels": {}, 
"Mountpoint": /var/lib/docker/volumes/data/_data", "Name": "data", 
"Options": {}, 
"Scope": "local"
 }

Dentro de la información de salida se puede notar la propiedad “Mountpoint” tiene la ruta donde localmente se guarda la información de ese volumen. Independiente del tipo de driver que se seleccione, siempre habrá una zona local donde se guardarán los datos dentro del filesystem local.

¿Qué pasa con el NFS?

Bueno, después de una gran explicación podrán entender como he llegado hasta el NFS… bueno, finalmente no hay un driver específico para NFS, pero descubrí que usando el driver local podemos montar un volumen NFS perfectamente, ya que este driver usa el sistema de archivos local como “mount” para trabajar con el sistema de archivos.

Precisamente uno de los parámetros que se necesita par montar un volumen a través del comando mount es “type”, el cual define que tipo de volumen queremos montar en nuestro SO. El driver local acepta varias opciones y entre ellas se encuentra el tipo de FS que se desea montar.  Para montar un volumen NFS debemos especificar el tipo y las opciones para montar. En nuestro caso, queremos montar un volumen de EFS de AWS, que no es mas que un volumen NFS con almacenamiento virtualmente infinito. Las opciones para montarlo son las mismas que un volumen NFS normal, mas algunas recomendaciones de AWS.

Las opciones para el driver local se deben pasar como un lista de tipo KEY=VALUE  o en una lista separadas por comas.

Nuestro caso sería:

tipo: NFS
Opciones:  rw,nfsvers=4.1,rsize=1048576,wsize=1048576,timeo=600
Host:  fs-9999999999.efs.us-east-2.amazonaws.com

las opciones del driver que usaremos son:

type: Tipo de FS
o:  Opciones para montar NFS
device: Path del volumen NFS

Finalmente el comando docker para crear un volumen NFS:

docker volume create --driver local \
--opt type=nfs \
--opt o=addr=fs-79854200.efs.us-east-2.amazonaws.com,rw,nfsvers=4.1,rsize=1048576,wsize=1048576,timeo=600 \
--opt device=:/ nfs

Con el comando anterior hemos creado un volumen de tipo NFS. En el momento de crearlo, este no monta el volumen, esto se hace efectivo cuando se ejecuta un contenedor. Una vez que se inicia con el comando run el contenedor realiza el mount del volumen NFS. Así:

docker run -d -v nfs:/mnt --name=nginx nginx

…Y Finalmente

Queda bastante claro que el manejo de volúmenes para persistencia de datos es algo que Docker ha abordado bastante bien. Sin embargo se debe dar una buena mirada en detalle en cada uno de estos drivers y así poder sacar provecho de estas funcionalidades, por que lo mas probable es que ya este resuelto.

En el caso particular que intentamos resolver en un principio los volúmenes se montaban sobre el host y luego se montaba como una carpeta (binding) el problema que derivaba de esto, es que si hay un cambio en el FS como or ejemplo el nombre de host, este se debía re configurar en la máquina host, lo que finalmente hacia mas complicado su automatización. Los contenedores no tienen por que saber cual finalmente el origen del FS y su configuración, esto se puede agregar directamente sobre los scripts que despliegan dejando el control de estas actividades a Docker.  En este caso usamos NFS por que AWS Elastic File System finalmente esta basado en el protocolo NFS Versión 4.

Finalmente lo mas recomendado en estos casos, es dejar que Docker se encargue de todas estas actividades ya que además todo esto facilita el trabajo de configuración y automatización al permitir el uso de scripts y archivos Dockerfile o Compose de manera transparente. Con esto se busca minimizar los puntos de fallas dejando que uno solo tenga el control, en este caso Docker.

 

#Agiles2017, un mes después…

Ya han pasado 4 semanas desde que asistí a #Agiles2017, 3 días de motivación, 3 días intenso, y 3 días para aprender.

Lo primero que hice fue hacer un “Estoy aquí” en Facebook, y a los minutos veo el mensaje de una gran amiga @msolisf – y dije listo, no estaré solo para conversar – por lo menos en el primer día (aun soy un poco tímido).

Busque mi credencial, mi polera y agua mineral que estaban regalando, y listo ya estábamos inmersos en el patio de la universidad Federico Santa Maria donde fue este magno evento.

Estábamos todos sentados esperando la bienvenida, y de repente veo que se está armando la pista de baile, sí, una pista de baile donde empezaron a tocar varios pies de cueca (nuestro hermoso baile nacional) fue el inicio donde fibras sensibles activaron el “pelometro”, vestidos de cueca china, porteña, y listo. Toco la oportunidad de salir a bailar y claro que lo hice.

Luego toco la bienvenida, explicar lo del openspace (para los que no conocíamos el formato) y el Marketplace donde muchas personas participaron para exponer los temas que dominaban, desde grandes gurus hasta los que se están iniciando en esto de querer ser rockstar. Se dio origen a #Agiles2017, donde más de 850 personas se reunirían, pertenecientes a 20 países y con más de 300 sesiones para nutrirse de conocimiento.

En la retina quedaron varios temas y grandes presentaciones de expositores, uno de ellos fue las 10 practicas no negociables del desarrollo ágil (con Veronica Rodriguez – Slin Castro) , dentro de este marco, se reforzaron varios temas de interés y que debemos estar constantemente recordando.

 

Con el pasar del tiempo toco el turno de ir donde una persona que conocí y que sin duda expone desde su experiencia y como lo lleva al día a día. Si es @jgarza una persona que a simple vista… es uno más, y que sin duda puedes verte reflejado por su trayectoria.

El tema que expuso @jgarzas te hace ver lo fácil que es caer en el lado oscuro de la agilidad, de recordarlo (por qué ya lo sabes) pero que se olvida fácil con el día a día en tu trabajo.

(@jgarzas quiso sacarse una foto con @tamoslistos) (aquí puedes ver su presentación aquí)

Otro tema que quedo en la retina fue la conversación de historias de usuario con @luchoSalazar en donde empezó con pequeño grupo de personas para luego termino con muchas personas alrededor, solo tenían 45 min por sesión, pero con Lucho teníamos para hablar todo el día con experiencias propias y de los integrantes que participaron.

Mi percepción del día 1 al día 3 es que este openspace fue mejorando cada día, consideraron mucho y se retroalimentaron de la opinión de todos.

Ya como termino del día 3, hicieron un carnaval, una batucada se presentó y para motivarse en la finalización una guerra épica de bombitas de agua en los jardines de la universidad.

#Agiles2017 ya termino, pero dejó una experiencia enriquecedora, donde sin duda aprendí, reforcé, y donde te deja con la sensación de… ¿porque no expuse un tema? Bueno el desafío ya está, y este 2018 es en Ciudad de México #Agilchingon #Agiles2018 y si se da la oportunidad de exponer, lo haré.

Agregando valor de Negocio – desde Trello hacia Domo

Desde hace ya bastante tiempo, y en nuestra estrategia de agilidad, hemos probado diferentes herramientas para mantener visibilidad de nuestro trabajo día a día. Sin hablar mucho de las otras herramientas, considero Trello nos ha traído grandes beneficios por su simpleza y facilidad de uso; no hay que explicar mucho a alguien que nunca lo ha visto o no tiene mucha experiencia, y eso, es más que valioso.

En mi perspectiva, si hay algo que no tienes en tu lista de pendientes, entonces no existe; y esto es lo que para mi gusto, Trello resuelve muy bien, todo lo que se te ocurra es muy sencillo de apilar… Ahora bien, si solo sumas a tu bandeja de entrada tareas y tareas que nunca se mueven, ese es otro problema; recuerden movimiento es muy diferente a progreso.

La manera versátil de organizar tareas en listas que propone trello hace mucho sentido en los tableros que queremos potenciar, tanto personales como grupales, pero en estos últimos es donde más encontramos valor, y los usamos para todo! … Aquí algunos ejemplos:

  • Metas semanales → Mensuales → Anuales. ¿Scrum de scrums? Esta es la fuente, también hay una pizarra física, pero cuando hay gente remota lo físico pierde valor.
  • Clientes (Mini-CRM). Cuántos clientes están activos? Cuántos han dejado de tener movimiento? Prospectos? Perdidos? Bueno, acá están todos…
  • Vacaciones:  Sí, hasta las peticiones de fechas se hacen por Trello! Chao correos o herramientas de RRHH que nadie entiende. Cuatro columnas son suficientes: Solicitadas, Aprobadas, Actuales y Tomadas. Además, se calculan automáticamente los días que te debe la compañía.
  • Colaboradores: Personas, Alianzas, Partners, Asociados y hasta la gente que se ha ido en un solo lugar… Algun teléfono? bueno ahi está su VCF, Foto, Ficha y hasta su foto por si no tenemos ni idea quién es.
  • Proyectos: actuales, exitosos, fracasos, servicios. Una cuenta total? Fácil, mediante la API de Trello. Fuente genial para estadísticas de compañía.
  • Asignaciones (staffing): Quién está en qué y con qué asignación. Muy útil, pero hay que actualizarla! OjO.
  • Ventas (Revenue)Tres columnas hacen magia: Facturas pendientes (proyección), emitidas y pagadas. Cada una con su monto, en un formato estándar. Tip, usar story points para el monto funciona perfecto.
  • Tareas Administrativas y Caja Chica. Bastante más claro que un excel en muchas oportunidades. Además, la secretaria siempre tendrá una visibilidad tremenda, lo que hace y deja de hacer.
  • Operaciones. Bueno, por último para algunos proyectos, donde la gestión es suficiente  con un simple Kanban… pero para proyectos que requieren muchas más métricas no es muy recomendable. Ejm, Tiempos consumidos (work-log).

Todo esto suena bien. Sin embargo, hizo falta algo, ¿cómo interpretar la gran cantidad de datos que se suben a los tableros día a día? Bueno para ello, primero hicimos varias cosas:

  1. Lo que está en la parte de más arriba es lo que tiene más prioridad.
  2. Las tareas deben tener etiquetas que permitan clasificar más adelante. Ojalá esta clasificación sea muy acotada, no vale la pena tener 100 etiquetas diferentes.
  3. Idealmente una persona por tarjeta. Responsabilidad compartida, no es de nadie.
  4. Agregar fechas de venciento es tan importante como agregar la tarea, da un marco de acción.
  5. Integrar Trello con alguna herramienta de chat, en nuestro caso Slack. La notificación del movimiento de una tarea es muy importante para la inercia de equipo. Muchos no lo perciben o le prestan atención, pero que haya uno entre diez, es suficiente.
  6. Finalizado (Done) es finalizado, no es casi finalizado, o falta poco, o de seguro mañana se cierra y me adelanto a cerrarlo. La definición de Finalizado, es una discusión muy importante, el consenso de equipo es lo que la hace poderoso.
  7. Limpiar los boards de manera recurrente, lo que está en Terminado pasa a ser archivado cada semana.
  8. Un reporte diario 8am (vía Mail), para empezar el día y ver donde estoy como deudor. Aquí es donde empieza a aparecer nuestra nueva herramienta.

Con todo esto, de nuevo parece que falta algo… la información es poco visible cuando el equipo crece y las tareas abundan; para esto, buscamos alguna herramienta que permita generar estadísticas y métricas de acuerdo a nuestros tableros, y … nuestra elección fue DOMO, una herramienta BI que permite interpretar datos de múltiples fuentes, procesarlos y desplegarlos en múltiples formatos, para ayudar a la toma de decisiones de negocio. Es bastante potente, se pueden combinar múltiples fuentes de datos, esta alojada en la nube y la modalidad gratis es suficiente para lo que buscamos.

Que hacemos con Domo entonces? Primero, conectamos Trello como fuente de datos, el permiso es por 30 días, así que cada mes toca renovar las credenciales para no perder acceso. El usuario que hace la integración, debe pertenecer a todos los tableros que se quieran leer, para ello usamos un usuario genérico para evitar depender de alguien en particular. Una vez con la integración lista, programamos una tarea en modalidad segundo plano todos los días a las 7am para traer lo último de las tarjetas y tenerlas como fuente de datos de Domo.

Una vez la data esta disponible, se crean páginas que agrupan tarjetas (no de trello), que corresponden básicamente a un gráfico o métrica. Aquí algunos ejemplos de lo que se puede lograr.

 

Esta es una muestra de lo que ha sido valioso para el equipo, algunas se han ofuscado por obvias razones; acá se muestran como modelo de inspiración o crítica, lo importante es que las métricas elegidas sean útiles a toda la organización.

Cada tarjeta tiene su detalle, por ejemplo, cuando se da click sobre una particular, se muestra el detalle asociado. Ejemplo, para clientes:

Bien, todos estas tarjetas (gráficos) se generan mediante una especie de tabla dinámica de excel, en un modo llamado “Analyzer”, donde se establecen las dimensiones de información y se puede jugar con datos calculados y formulas dinámicas (Beast mode) que la herramienta provee. Los tipos de gráfico disponibles son bastante completos y ricos visualmente, desde “funnel” de conversión, tablas,  “data science”, mapas y muchos más. Aún queda mucho por explorar, pero algo bien interesante es que las tarjetas ahora pueden ser embebidas dentro de contenido html en cualquier lugar o publicarse en redes sociales como Twitter, Facebook y LinkedIn.

¿Qué es lo más complicado? Bien, la exportación de Trello aún tiene muchos detalles por mejorar, y uno de las más complicadas es que las listas no son exportadas con el nombre, sino con el identificador único, por tanto, hay que hacer un mapeo/traducción para saber a que columna pertenece; lo bueno de esto, es que se hace una vez y de ahi se comparte a todas las tarjetas (como campo calculado). Un ejemplo de ello, es una función no tan limpia como:

CASE when `idList` = '58c36bb5f7781a57df6dba6c' then 'Inbox'
when `idList` = '56bf30f9e7857bb868a04b25' then 'Inbox'
when `idList` = '577d0f282076b7a67c595355' then 'Inbox'
when `idList` = '58c43cbc823286e6fa47d13e' then 'In Progress'
when `idList` = '5952afda7d036e870a9c33f8' then 'In Progress'
when `idList` = '596e4ef1ea1b31b1fbf6d1f7' then 'In Progress'
when `idList` = '58c43cbe3774edac9afe567a' then 'DONE'
when `idList` = '58e79a3918388b9ff9ef5516' then 'DONE'
else 'Other' End

Algo también que puede ser complicado, es que cuando una tarjeta en trello pertenece a dos personas, la exportación la toma como dos registros independientes y no un solo registro.

¿Qué queda faltando? Algo que se extraña de manera simple, es el poder comparar el día anterior con el actual, en ocasiones es útil poder determinar tendencias y contar con algo que permita validar si hubo un cambio o no con relación a la instancia inmediatamente anterior. De seguro se puede realizar, pero la implementación a primera vista no sería tan sencilla. En todo caso, Domo es una herramienta bastante versátil y va más allá del uso que le estamos dando acá.

Finalmente, siempre considerar que el valor más importante no está en las herramientas, sino en lo que podemos crear explorando y explotando las funcionalidades que nos brindan las elecciones tecnológicas que hacemos. Sin duda, tanto Trello como Domo, tienen muchos más usos de los acá planteados, pero la invitación es a probarlos, ajustarlos a las necesidades particulares y compartir los resultados.