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.

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!⎈

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.

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

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.

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