2020-11-04 22:43

Poniendose al Dia con PHP 8

Soy programador de PHP desde los infames tiempos (?) de PHP 5. Mucha agua corrió bajo el punte y así como PHP 7 supuso un gran avance en varios aspectos, estamos en la previa del lanzamiento de la nueva gran versión, que será PHP 8. Cuando escribo esto (noviembre de 2020), tenemos la RC3 salida hace un par de días.

Vengo siguiendo la evolución de esta versión de forma superficial pero continuada. Si bien la discusión detallada se puede seguir en el propio sitio a través de sus RFC, es cierto que eso a veces puede ser medio pesado por el nivel de detalles.

Por eso vengo siguiendo varios posts que les comparto, para ponerse al día medio rápido en lo que nos ofrece esta nueva versión.

  • El blog de Stitcher.io es uno de los mas activos en términos de estar al día con las novedades. En particular este post lista la mayoría de nuevas características (sobre todo en sintaxis).
  • Acá les dejo algunos post mas del mismo blog. [1] [2] [3]
  • Este otro post esta muy bueno, con 32 ejemplos para probarlos desde el mismo navegador.
  • Este ultimo me pareció piola de cara a los que laburamos hace tiempo con PHP, y es un conjunto de errores comunes que nos podemos encontrar ya si ejecutamos código actual con la nueva versión.

La idea era compartirles esta serie de links.

Hasta la próxima.

UPDATE: Voy a ir agregando acá nuevos posts que vaya encontrando:

2020-07-12 16:59

Screencasts en Gnome 3

Estoy preparando una charla que voy a dar en un par de semanas. Como material de la misma voy a integrar algunos videos de ejemplos, para no tener que ejecutarlos en vivo (porque a veces pueden fallar, roba tiempo de la charla, que la idea es que sea fluida, etc...)

Cuestión que, al no estar subido a la moda de ser Youtuber ni Streamer ni similar, no manejo el set de software estándar (Si, ya se, OBS + algún que otro editor onda Kdenlive). Esta bueno eso, pero a veces puede sonar a demasiado.

Soy usuario de Ubuntu + Gnome 3 desde hace años, y en algún momento me había cruzado con un atajo de teclado para activar una grabación del escritorio. Lo olvidé, pero en Reddit hoy me volvi a cruzar con eso, y recordé lo simple que era para evitar OBS (que de nuevo, esta muy bien, pero puede ser demasiado).

Lo estuve probando, y si bien no se si es lo que voy a usar definitivo, si esta bueno tener "a mano", saber que existe y como usarlo.

Screencast en Gnome 3

Antes yo lo conocía como Screencast, hoy son Vlogs o directamente un canal de Youtube. La idea es clips de videos que muestren como hacer algo "técnico", una solución a algo o documentar la forma de arreglar un problema.

Gnome 3 tiene la funcionalidad nativa de hacer Screencast casi desde que salió.

Para activarla, basta ejecutar Ctrl + Alt + Shift + R. Eso hace que en el panel de arriba a la derecha aparezca un icono "rojo".

TIL you can use Shift+Ctrl+Alt+R to record a video of the screen.

source: https://imgur.com/yf5BVor

Ellos dicen que lo integraron por propósitos de depuración. Con lo cual, las configuraciones por defecto son bastante pobres. Por ejemplo, el máximo de grabación por defecto son 30 segundos.

Como todo desde que encararon esa filosofía del nuevo escritorio, lo dejaron ahí, muy poco documentado, y se olvidaron. No se si se olvidaron, pero cuando un usuario les pide que le agreguen "opciones" la respuesta es "esta ahí, que alguien haga una extensión". Que se yo, cada uno maneja sus comunidades como quiere, y a Gnome la verdad que le va bastante bien. Pero es una respuesta medio chocante para mi.

EasyScreenCast

En fin, cuestión que alguien si le hizo caso al comentario y por eso existe la extensión EasyScreenCast. La use un rato, anda joya, y tiene muchas opciones para configurar.

En particular tuve unos problemas a la hora de grabar algo que no sea todo el escritorio (tengo dos monitores entonces es incomodo para usarlo). Pero rompía el escritorio (era necesario reiniciarlo) así que por el momento, no se si es lo que voy a usar. Capaz me pongo a hacer debug, pero por ahora es algo que tira para atrás el uso. Mi hipótesis es que al tener un Ubuntu viejo (18.04) la versión de Gnome con el plugin no están congeniando del todo bien.

En caso de encontrarle la vuelta, actualizo el post.

2020-07-03 18:45

Borrando Cosas Inutiles de Ubuntu (Versión 2020)

Introducción

Nunca esta demás saber que cosas borrar para mantener el disco raíz lo mas libre posible. Hoy me encontré con el Disco raíz con un 86% de ocupación y me dispuse a buscar cosas para borrar.

$ df -h 
Filesystem      Size  Used Avail Use% Mounted on
...
/dev/sda1        38G   31G  5,0G  86% /
...

Herramienta de diagnostico

Ok, que hacer? En primer lugar, un diagnostico. La primer mano nos la puede dar la aplicación baobab, que si mal no recuerdo siempre esta instalada (si tenes el escritorio por defecto de Ubuntu).

Se busca desde el launcher con ese nombre o "Analizador de Uso de Disco". Muestra las diferentes particiones y gráficos de forma cómoda directorios y sub-directorios:

Baobab Screenshoot

Replicas de paquetes de Snap

Ya usando baobab investigo y encuentro que uno de los directorios que mas archivo tiene es /var/lib/snapd/snaps. Ahi me encuentro con lo siguiente:

$ ls -la /var/lib/snapd/snaps
total 6180056
drwxr-xr-x  3 root root      4096 jul  3 18:40 .
drwxr-xr-x 21 root root      4096 jul  3 18:55 ..
-rw-------  2 root root  57266176 jun 13 12:12 bitwarden_25.snap
-rw-------  1 root root  57257984 jun 29 21:35 bitwarden_26.snap
-rw-------  1 root root  57614336 mar 25 22:43 core18_1705.snap
-rw-------  1 root root  57618432 abr 30 14:28 core18_1754.snap
-rw-------  2 root root  63942656 jun 19 11:05 core20_634.snap
-rw-------  1 root root 101724160 jun  2 16:18 core_9289.snap
-rw-------  1 root root 101191680 jun 24 16:07 core_9436.snap
-rw-------  2 root root  61710336 feb 27 02:55 discord_108.snap
-rw-------  1 root root  60096512 mar 18 11:54 discord_109.snap
-rw-------  1 root root  93212672 jun 23 16:27 drawio_37.snap
-rw-------  1 root root  93224960 jun 28 21:35 drawio_38.snap
-rw-------  2 root root 193806336 may 14  2019 eclipse_40.snap
-rw-------  1 root root 220319744 mar 25 07:39 eclipse_48.snap
-rw-------  1 root root 208605184 mar 11 20:01 gitkraken_153.snap
-rw-------  1 root root 208609280 abr 22 20:45 gitkraken_154.snap
-rw-------  1 root root 147488768 may 30 12:22 gnome-3-26-1604_100.snap
-rw-------  1 root root 147501056 nov 17  2019 gnome-3-26-1604_98.snap

Las apps están descargadas y "backupeadas" por las dudas.

Snap es una manera de instalar apps en Linux, fuertemente impulsada por Canonical. A veces es cómoda para instalar apps que no están en los repos clásicos o están en una versión desactualizada (via Apt).

Buscando un poco, se llega al siguiente comando:

$ snap list --all
Name                     Version                     Rev   Tracking          Publisher         Notes                                                           
bitwarden                1.18.0                      25    latest/stable     bitwarden✓        disabled                                                        
bitwarden                1.19.0                      26    latest/stable     bitwarden✓        -                                                               
core                     16-2.45.1                   9436  latest/stable     canonical✓        core                                                            
core                     16-2.45                     9289  latest/stable     canonical✓        core,disabled                                                   
core18                   20200311                    1705  latest/stable     canonical✓        base,disabled                                                   
core18                   20200427                    1754  latest/stable     canonical✓        base                                                            
core20                   20                          634   latest/stable     canonical✓        base                                                            
discord                  0.0.10                      108   latest/stable     snapcrafters      disabled                                                        
discord                  0.0.10                      109   latest/stable     snapcrafters      -                                                               
drawio                   13.3.1                      37    latest/stable     jgraph✓           disabled                                                        
drawio                   13.3.5                      38    latest/stable     jgraph✓           -                                                               
eclipse                  2019-03                     40    latest/stable     snapcrafters      disabled,classic
eclipse                  2019-12                     48    latest/stable     snapcrafters      classic
gitkraken                6.6.0                       154   latest/stable     gitkraken✓        -
gitkraken                6.5.4                       153   latest/stable     gitkraken✓        disabled

Si en la salida anterior se observa la ultima columna (Notes), se observa que hay muchas versiones en estado disabled. Así que en teoría se pueden borrar. El script que se encuentra aca a mi me funciono joya (ojo que avisan que según el idioma del sistema por ahí lo tienen que tocar).

Dejo una versión del script acá:

#!/bin/bash
# Removes old revisions of snaps
# CLOSE ALL SNAPS BEFORE RUNNING THIS
set -eu

LANG=C snap list --all | awk '/disabled/{print $1, $3}' |
    while read snapname revision; do
        sudo snap remove "$snapname" --revision="$revision"
    done

También es una buena idea revisar programas ahí instalados y que no estés usando, y eliminarlos, por ejemplo, en mi caso había un par que no estaba usando y los elimine:

sudo snap remove krita gitkraken eclipse drawio bitwarden youtube-dl

Para este punto, y solo preocupándome por Snap, la situación estaba así:

$ df -h 
Filesystem      Size  Used Avail Use% Mounted on
...
/dev/sda1        38G   27G  8,5G  77% /
...

Recupere alrededor de 3.5 Gb.

Logs is everywhere

El siguiente directorio que tenia bastante peso era el de logs. 4Gb de logs!!!!!

$ journalctl --disk-usage
Archived and active journals take up 3.7G in the file system.

El directorio principal de logs en un Ubuntu es /var/log, y dentro de dicho directorio, el journal (el log principal del sistema) era el que mas pesaba (casi el total). Ahí veo 2 problemas:

  • Mala política de borrado de logs
  • Porque se están llenando tanto?

Lo segundo es para pensarlo un poco e investigar, para el objetivo del post me voy a centrar en el primero punto.

Política de borrado

La rotación de logs es una tarea automática que hace el sistema. Básicamente va creando archivos nuevos para loguear los eventos mas actuales, y deja como históricos los viejos archivos. Para consultar estos registros, se puede usar el comando journalctl. No me voy a detener en este comando que daría para un post entero. Solo decir que una primer configuración a editar es el tamaño del log del sistema. Esto se hace desde /etc/systemd/journald.conf:

Como root, editar ese archivo, cambiando la linea:

#SystemMaxUse=

por

SystemMaxUse=100M

Donde el valor después del signo igual, debería ser el tamaño que queremos que ocupe. En este caso, 100 Megas me parece un valor mas que razonable.

Para terminar de aplicar el cambio, hay que reiniciar el servicio:

$ sudo systemctl restart systemd-journald.service
$ journalctl --disk-usage
Archived and active journals take up 104.0M in the file system.

Perfecto. Si volvemos a mirar el espacio en disco:

$ df -h 
Filesystem      Size  Used Avail Use% Mounted on
...
/dev/sda1        38G   24G   13G  66% /
...

Perfecto. ¿Con que seguir?

Cache de APT y Librerías sin uso

APT es la herramienta para gestión de paquetes de Ubuntu. Es típico que en el uso, genere una cache importante, y que en muchos casos queden librerías que ya no se utilizan y pueden borrarse. En mi caso no va a aportar demasiado porque estos comandos los suelo ejecutar con cierta regularidad, pero hay 3 parámetros que son muy útiles y es aconsejable ejecutarlos con cierta regularidad:

$ sudo apt clean
$ sudo apt autoclean
$ sudo apt autoremove

En el ultimo caso, puede querer eliminar paquetes y nos va a preguntar si estamos seguros. En general, no es problemático eliminarlos (aunque si no se esta seguro, ese ultimo comando podría no ejecutarse).

$ df -h 
Filesystem      Size  Used Avail Use% Mounted on
...
/dev/sda1        38G   23G   13G  65% /
...

En mi caso no ayudó mucho, pero puede ser útil este paso.

Directorio /usr

Si no esta pasando nada raro, y excluyendo el /home, el directorio /usr debería ser uno de los directorios con mas "peso" en el gráfico de Baobab. Es normal y esperable, ya que todas las aplicaciones y librerías del sistema se encuentra allí.

En general no es aconsejable tocar ningún archivo de allí. En caso de tener alguna anomalía, es probable que pueda limpiarse eliminando el paquete o programa que la esta causando, pero no se aconseja eliminar archivos o sub directorios de forma directa en este caso.

BleachBit

Para terminar el post, es interesante mencionar esta GUI, llamada BleachBit, que es lo mas parecido a CCleaner que tenemos los usuarios de Linux.

Tiene una forma de eliminar cosas del sistema (usar con cuidado) pero al estar centrado en el usuario, nos haría ganar espacio en el /home. En caso de necesitarlo, es una buena opción.

Luego de borrar algunas cosas, la cantidad de disco ocupada finalmente fue la siguiente:

$ df -h 
Filesystem      Size  Used Avail Use% Mounted on
...
/dev/sda1        38G   23G   13G  64% /
...

Para mi suficiente, y no me llevo mucho tiempo. Espero que algo de esto les sirva.

2020-06-22 21:30

Volumenes de Docker y Discos USB Externos

Estoy levantando un media server en mi maquina, y aprovecho que hay mucho despliegue usando contenedores Docker.

El Problema

Como tengo todo mi contenido multimedia en un disco USB externo, aproveche y le vincule los volumenes al contenedor directamente a los paths del disco.

Entonces, los volumenes quedaban mas o menos como sigue. Uso la notación que pone Ubuntu al montar los discos externos:

/media/tomas/Elements/series:/series
/media/tomas/Elements/peliculas:/peliculas
....

De lado derecho es el path del directorio en el host. Del lado izquierdo es el directorio dentro del contenedor.

Como esto se hace en un equipo particular, eventualmente se reinicia (o se apaga y prende). Esto me genero 1 gran problema.

El servicio de Docker inicia durante el proceso de boot del equipo. Sin embargo, Ubuntu monta el disco al momento en el que el usuario inicia sesión.

Esto genera que Docker intente buscar los directorios de los volumenes en el Host, y al no encontrarlos, los crea. Este comportamiento se conoce como propagación y esta documentado1.

Sin embargo, sucedia que al iniciar sesión, Ubuntu intentaba montar en el directorio /media/tomas/Elements, pero debido a que este ya existia (dado que Docker lo creaba por el mecanismo de propagación), Ubuntu monta el disco en /media/tomas/Elements1.

El efecto de esto es que perdia acceso a los directorios dentro del contenedor.

La idea de solución

Buscando ayuda, lo que me sugieren y que es la solución es cambiar el orden del booteo, para que Docker inicie despues del proceso de mount. Esto no es tan facil como puede parecer. Requiere:

  • Buscar la unit del servicio de mount
  • Buscar la unit de systemd del servicio de Docker
  • Agregar el servicio de mount como dependencia de Docker
  • Hacer que el mount del disco se haga al inicio y no al iniciar sesion
  • Probarlo

A esa secuencia de pasos llegue luego de un poco de prueba y error.

A continuación documentaré los pasos que tuve que hacer

La solución

Aclaración del setup de mi equipo: Tengo una notebook corriendo Ubuntu 18.04, que ejecuta Systemd para gestionar el proceso de arranque del Sistema Operativo. Desconozco si en otras distros esto puede variar.

Nombre del servicio de mount en Systemd

Despues de buscar un rato, descubrí que el servicio que maneja el mount al inicio del sistema se llama udisks2.service. Una forma de ver los servicios en systemd es:

systemctl --type=service

Agregar dependencia de este servicio al inicio de Docker

En este paso, necesitamos que docker no arranque hasta que se termine el proceso udisks2.service.

En mi caso, la configuración de Systemd de Docker esta en /lib/systemd/system/docker.service (que tiene ademas un link simbolico en /etc/systemd/system/multi-user.target.wants/docker.service).

Alli dentro, busque la linea que contiene lo siguiente

After=network-online.target firewalld.service containerd.service

Y agregue al final de la misma (con separación de un espacio)

After=network-online.target firewalld.service containerd.service udisks2.service

Luego guarde y cerre el archivo.

Para que systemd tome este cambio, tuve que ejecutar:

sudo systemctl daemon-reload

Montar el disco al inicio del sistema y no de la sesión

A continuación, tuve que configurar para que el disco se monte al inicio del sistema. Para ello, voy tomar el camino de hacerlo via interfaz gráfica y no por consola.

Para ello, usé una app que se busca en Gnome como Disks:

Disks Gnome App

Una vez allí, elegimos el disco en cuestion y entramos a sus "opciones de montaje":

Select Disk Mount Options

En esta nueva pantalla, se indicaron las siguientes cosas:

  1. Que no se use las configuraciones por defecto para la sesión
  2. Que se monte al arranque del sistema
  3. Que se identifique con el UUID (Esta ultima es optativa, pero era la que me pareció que dejaba el nombre mas apropiado al directorio donde se iba a montar)

Mount Options Window

Cambiar los paths en los volumenes

Una vez terminado esto, pude cambiar los paths de los volumenes del lado del host, dejandolos como sigue:

/mnt/9A567...0FD/series:/series
/mnt/9A567...0FD/peliculas:/peliculas
....

Probé reiniciar y todo funciono perfecto.

2018-09-08 15:15

Introducción a Spark

Apache Spark es un framework de procesamiento muy de moda en entornos de procesamiento para Big Data, IoT y Machine Learning.

Pipeline

El pipeline de trabajo en spark es conocido como DAG (Directed Acyclic Graph) y se basa en armar un grafo de trabajo donde las tareas se sucedan unas a otras segun se establezca.

Ademas, propone que muchas operaciones que en MapReduce involucran operaciones de entrada salida a disco, se hagan en memoria principal, lo que genera un rendimiento mayor comparado con su predecesor.

Lenguajes

Spark acepta Java, Scala, Python y R, aunque no todos estan soportados de la misma forma y de manera completa.

Otras herramientas

Spark ofrece ademas una consola interactiva para Scala, Python y R con capacidades REPL (Read, Evaluate, Print y Loop).

Ademas del core, Spark ofrece algunas librerias para tareas comunes en el ambito de big data: SparkSQL, Spark Streaming, Spark MLlib y Spark GraphX.

Es posible vincular Spark a una Notebook de Jupyter y trabajar desde la interfaz de esta herramienta para hacer pruebas. (TODO: Agregar link a la notebook).

Arquitectura

Una aplicación Spark consta de un master, que dependiendo de la plataforma puede ser Spark Master (standalone) Mesos Master (Apache Mesos) o ResourceManager (Apache Hadoop - YARN). Luego un proceso driver que se conoce como SparkContext y por ultimo de los workers.

2018-04-28 16:22

Automatizando deploy con Helm

Automatizando Deploy con Helm

  1. Tener un cluster kubernetes andando y corriendo (por ejemplo minikube)
$ minikube start
  1. Instalar Helm y Tiller

Tiller es un servidor in cluster de helm (Se instala en el cluster). Para mas detalle, ver la doc oficial.

$ helm init
Creating /home/tomas/.helm
Creating /home/tomas/.helm/repository
Creating /home/tomas/.helm/repository/cache
Creating /home/tomas/.helm/repository/local
Creating /home/tomas/.helm/plugins
Creating /home/tomas/.helm/starters
Creating /home/tomas/.helm/cache/archive
Creating /home/tomas/.helm/repository/repositories.yaml
Adding stable repo with URL: https://kubernetes-charts.storage.googleapis.com
Adding local repo with URL: http://127.0.0.1:8879/charts
$HELM_HOME has been configured at /home/tomas/.helm.

Tiller (the Helm server-side component) has been installed into your Kubernetes Cluster.

Please note: by default, Tiller is deployed with an insecure 'allow unauthenticated users' policy.
For more information on securing your installation see: https://docs.helm.sh/using_helm/#securing-your-helm-installation
Happy Helming!
  1. Actualizar Respositorio de Charts

Los programas que se instalan via Helm se llaman Charts. Antes de instalar un chart, se debe actualizar la lista de charts disponibles

helm repo update
Hang tight while we grab the latest from your chart repositories...
...Skip local chart repository
...Successfully got an update from the "stable" chart repository
Update Complete.  Happy Helming!⎈

2018-04-14 12:09

Curso de Git

El sabado 07 de Abril de 2018 estuvimos haciendo un taller de GIT en la UNLu.

Fue una experiencia muy interesante. Esperabamos muy poca gente y sin embargo el aula se lleno durante las 3 horas y media que duró el taller. Para algunos usar Git es algo tan omnipresente, que a veces cometemos el error de creer que es facil o que todos lo usan.

Durante mas de 3 horas, 38 personas con conocimientos muy diverso respecto a computación estuvieron aprendiendo como usar Git, surgieron dudas muy interesantes y creo que todos nos llevamos algo nuevo.

El material que se utilizó esta disponible aca.

2018-02-04 16:28

Kompose: Migrar tus archivos Docker Compose a Kubernetes

En un post anterior desplegamos un cluster de pruebas con contenedores usando Kubernetes y Minikube. Este esquema resulta util cuando lo que se quiere es desplegar y escalar un contenedor.

Sin embargo, muchas aplicaciones Docker comenzaron a orquestarse utilizando mas de un contenedor para hacer funcionar la misma. Por ejemplo, un contenedor con un web server, otro para la base de datos relacional, y un tercero para una base nosql.

Para este tipo de esquemas surgio docker-compose. Permitia de forma sencilla administrar la configuracion varios contenedores en simultaneo cuya imagen origen eran diferentes.

Para lograr un comportamiento similar con Kubernetes, existe la herramienta Kompose. Kompose nos permite tomar el contenido de un archivo docker-compose.yml y realizar las mismas acciones, pero utilizando Kubernetes.

Uso basico

Como siempre, nos salteamos la parte de instalacion dado que es sencilla y se encuentra documentada en la pagina oficial.

Kompose es muy sencilla de utilizar. Puede hacer 2 tareas principales:

  • Tomar un archivo docker-compose.yml y convertirlo a archivos de configuracion de Kubernetes.
  • Ejecutar el archivo docker-compose.yml directamente sin generar nuevos archivos.

La forma mas sencilla de utilizar es la segunda, dado que contamos con un proyecto con un archivo docker-compose.yml o en general conocemos ese formato bastante. Entonces se ejecuta

kompose up

y eso ya levanta con Kubernetes todos los contenedores indicados.

Troubleshooting

kompose up

WARN Unsupported root level volumes key - ignoring 
WARN Unsupported depends_on key - ignoring        
WARN Volume mount on the host "." isn't supported - ignoring path on the host

2018-02-03 12:15

Configuración para Sublime Text 3

Logo Sublime Text 3

Soy usuario activo de Sublime Text 3. Para proyectos pequeños o creacion de scripts, es el editor con el que me siento mas comodo trabajando.

La configuración default que tiene visual tiene algunos problemas. Lo primero que hago al instalar Sublime es editar un par de estas configuraciones, y dejo aca el archivo de configuración tal como lo tengo actualmente

{
    "bold_folder_labels": true,
    "caret_style": "phase",
    "draw_white_space": "all",
    "fade_fold_buttons": false,
    "font_face": "Inconsolata",
    "font_size": 12,
    "highlight_line": true,
    "highlight_modified_tabs": true,
    "ignored_packages":
    [
        "Vintage"
    ],
    "line_padding_bottom": 5.5,
    "line_padding_top": 5.5,
    "rulers":
    [
        80,
        120
    ],
    "tab_size": 4,
    "trim_trailing_white_space_on_save": true
}

Sobre las fuentes

La configuración font_face indica la fuente utilizada. Inconsolata no es una fuente que venga instalada por default. Para instalarla en Ubuntu, por ejemplo:

sudo apt install fonts-inconsolata

Plugines

Ademas de la configuración visual, Sublime tiene una amplia cantidad de plugins.

Aca va un listado de los que actualmente estoy utilizando:

  • All Autocomplete
  • BracketHighlighter
  • DocBlockr
  • GitGutter
  • Laravel Blade Highlighter
  • PHP Companion
  • SublimeCodeIntel
  • SublimeLinter-php

Temas

Existen muchisimos temas para Sublime. Puntualmente estoy en estos momentos utilizando Brogrammer.

2018-01-26 00:18

Algunas notas sobre Kubernetes

Logo Kubernetes

Sistema para orquestación de cluster. Esto no es un tutorial, son notas sueltas (personales) tomadas del tutorial oficial.

1. Crear un cluster

Kubernetes coordina un cluster para trabajar como una unica unidad. Para ello, las apps necesitan ser empaquetadas en forma de containers.

2 Recursos:

  • Master: Coordinación y gestión el cluster
  • Nodes: Son los workers del cluster (puede ser vm o nodo físico)

Cada nodo tiene un Kubelet, un agente que coordina el nodo y maneja la comunicación con el Master.

Cada nodo debe poder realizar operaciones de containers, usando Docker o rkt (Debe tenerlo instalado).

Para debug se recomienda utilizar Minikube. Instala un cluster y facilita la configuracion de kubernetes (Instalarlo a mano era complejo).

Tutorial interactivo

Testear la version de minikube

minikube version

Iniciar un cluster usando minikube

minikube start

Linea de comandos de Kubernetes: kubectl.

Version de kubectl (Para verificar que esta instalado):

kubectl version

Ver información de cluster

kubectl cluster-info

Ver nodos del cluster

kubectl get nodes

2. Crear deploys con kubectl

Una vez instalado Kubernetes, se deben crear aplicaciones en containers para ser ejecutadas sobre el cluster. Para esto se definen instruccion que el master ejecuta sobre los nodos.

Kubernetes Deployment Controller monitoriza las instancias y si se caen, las regenera nuevamente.

Tutorial interactivo

Correr un ejemplo

kubectl run kubernetes-bootcamp \
    --image=docker.io/jocatalin/kubernetes-bootcamp:v1 \
    --port=8080

Ver la app en ejecucion

kubectl get deployments

Generar un entrypoint al cluster (temporal para pruebas)

kubectl proxy

3. Explorar la App

Un Pod es un conjunto de containers que ejecutan aplicaciones y sus recursos asociados.

Los Pods son creados por Kubernetes al realizar el deploy de la app. Se crean siempre en un nodo.

Operaciones mas usadas de kubectl:

kubectl get
kubectl describe
kubectl logs
kubectl exec

Tutorial interactivo

Listar pods

kubectl get pods

Para obtener información detallada de los Pods

kubectl describe pods

Para acceder a los Pods, que funcionan en una red aislada y privada, se utiliza el proxy:

kubectl proxy

Dicho proxy expone temporalmente la red y permite la comunicación con el host. Esto se utiliza para acceder a la API de los Pods y realizar consultas de forma directa (Por ejemplo, usando el comando curl).

Para diversas operaciones con los pods, es necesario obtener el nombre que Kubernetes le asigno al mismo. Un comando para hacer esto es:

export POD_NAME=$(kubectl get pods -o go-template --template '{{range .items}}{{.metadata.name}}{{"\n"}}{{end}}')

Para ver los logs:

kubectl logs $POD_NAME

Todo lo que los proceso envien a stdout es expuesto como logs del pod.

Ejecutar comandos en un pod:

kubectl exec $POD_NAME env

Abrir una consola en un POD:

kubectl exec -ti $POD_NAME bash

4. Usar un servicio para exponer la App

Los Pods pueden ser reemplazados si es necesario. Desde que cada Pod tiene una IP unica, las aplicaciones no deberian conocer dichas IPs para poder conectarse a los Pods, porque estos puede "morir".

Los servicios en kubernetes proveen una abstraccion que permite establecer politicas de acceso sobre un conjunto lógico de Pods.

Los servicios permiten que a los pods se les adjunten labels, con diferentes objetivos (taggear versiones, separar versiones para test, debug y produccion).

Tutorial interactivo

Listar servicios expuestos:

kubectl get services

Exponer un servicio:

kubectl expose deployment/kubernetes-bootcamp --type="NodePort" --port 8080

Ver detalles de servicios:

kubectl describe services/kubernetes-bootcamp

Ver que puerto fue abierto externamente:

export NODE_PORT=$(kubectl get services/kubernetes-bootcamp -o go-template='{{(index .spec.ports 0).nodePort}}')
echo NODE_PORT=$NODE_PORT

Una vez expuesto, se puede consultar el servicio directamente con:

curl host01:$NODE_PORT

Consultar los pods que estan etiquetados con un label particular:

kubectl get pods -l run=kubernetes-bootcamp

El label en el caso anterior es run=kubernetes-bootcamp. Funciona identicamente para consultar servicios:

kubectl get services -l run=kubernetes-bootcamp

Obtener el nombre del POD

export POD_NAME=$(kubectl get pods -o go-template --template '{{range .items}}{{.metadata.name}}{{"\n"}}{{end}}')
echo Name of the Pod: $POD_NAME

Aplicar un nuevo label a un Pod:

kubectl label pod $POD_NAME app=v1

Consultar el label recien aplicado:

kubectl describe pods $POD_NAME
kubectl get pods -l app=v1

Borrar un servicio:

kubectl delete service -l run=kubernetes-bootcamp

5. Multiples instancias de una App

Escalar es incrementar el numero de instancias o pods para poder manejar incrementos de trafico en la aplicación. Los services manejan el trafico hacia los pods mendiante un load-balancer.

Tutorial interactivo

Escalar (scale up) un deployment llamado kubernetes-bootcamp a 4 replicas:

kubectl scale deployments/kubernetes-bootcamp --replicas=4

Ver los deployments:

kubectl get deployments

Controlar los pods (Tiene que haber 4):

kubectl get pods -o wide

Ver el deployment de forma mas detallada:

kubectl describe deployments/kubernetes-bootcamp

Ver el servicio:

kubectl describe services/kubernetes-bootcamp

Recuperar el nodo:

export NODE_PORT=$(kubectl get services/kubernetes-bootcamp -o go-template='{{(index .spec.ports 0).nodePort}}')
echo NODE_PORT=$NODE_PORT

Ejecutar varias veces:

curl host01:$NODE_PORT

Deberian responder diferentes pods de la misma app.

Ejecutar ahora solo 2 replicas (Scale down):

kubectl scale deployments/kubernetes-bootcamp --replicas=2

Confirmar el cambio:

kubectl get deployments

6. Realizando actualizaciones progresivas

La idea es lograr actualizaciones sin que se experimente una caida del servicio, esto permite poder actualizar las aplicaciones de forma mas seguida.

Kubernetes permite esto mediante las Rolling Updates. Esto permite actualizar sin tener downtimes y ademas puede ser revertido en caso de problemas (rollbacks).

Tutorial interactivo

Ver imagen actual de los pods (Campo image):

kubectl describe pods

Actualizar la image:

kubectl set image deployments/kubernetes-bootcamp kubernetes-bootcamp=jocatalin/kubernetes-bootcamp:v2

Ver información de los Pods:

kubectl get pods

No actualiza los viejos pods, sino que termina los anteirores y crea pods nuevos.

Verificar que la app actualizo:

kubectl describe services/kubernetes-bootcamp
export NODE_PORT=$(kubectl get services/kubernetes-bootcamp -o go-template='{{(index .spec.ports 0).nodePort}}')
echo NODE_PORT=$NODE_PORT
curl host01:$NODE_PORT

Tambien puede verificarse el exito mediante:

kubectl rollout status deployments/kubernetes-bootcamp

Deployar una version "con errores":

kubectl set image deployments/kubernetes-bootcamp kubernetes-bootcamp=jocatalin/kubernetes-bootcamp:v10

Ver problemas:

kubectl get deployments
kubectl get pods
kubectl describe pods

Rollback:

kubectl rollout undo deployments/kubernetes-bootcamp
kubectl get pods
kubectl describe pods

Dudas

  • ¿Un cluster kubernetes sirve para deploy de una app unica o muchas apps pueden convivir en el?

Se pueden hacer deploys de varias apps y se iran acomodando en los recursos que el cluster tenga disponibles.

  • ¿Un Pod es equivalente a un container?

Un pod es un container de una aplicación en particular gestionado por kubernetes

Troubleshooting

  • Al querer ejecutar minikube start se obtiene el error "Error starting host: Error getting state for host: machine does not exist".

El error completo es:

$ minikube start
Starting local Kubernetes v1.9.0 cluster...
Starting VM...
E0428 17:06:43.557255   18070 start.go:159] Error starting host: Error getting state for host: machine does not exist.

 Retrying.
E0428 17:06:43.557517   18070 start.go:165] Error starting host:  Error getting state for host: machine does not exist
================================================================================
An error has occurred. Would you like to opt in to sending anonymized crash
information to minikube to help prevent future errors?
To opt out of these messages, run the command:
        minikube config set WantReportErrorPrompt false
================================================================================
Please enter your response [Y/n]: n

Esto me pasó a mi por borrar en algun momento la vm de Virtualbox que crea minikube. La forma mas facil de recuperarse de este error es:

$ minikube delete
$ minikube start