1 of 72

Despliegue de aplicaciones en la nube

Cloud Computing

Máster en Tecnologías y Aplicaciones en Ingeniería Informática

2 of 72

1

Introducción

3 of 72

Kubernetes (K8s)

  • Plataforma de código abierto para orquestación de contenedores
  • Permite despliegue, escalado y gestión de aplicaciones contenedorizadas.
  • Permite el despliegue de aplicaciones en un cluster sin pensar en las máquinas que lo soportan​.
    • Máquinas físicas, máquinas virtuales, independencia del SO
  • Ofrece:​
    • Replicación​
    • (Auto)escalado​
    • Alta disponibilidad sin interrupciones
  • Proyecto Open Source 2014​ (Google)

4 of 72

Arquitectura de Kubernetes

  • Master:
    • Coordina actividades del cluster
      • Mantener estado
      • Escalado
      • Despliegue de actualizaciones
    • Recogida de datos de Workers y Pods
  • Nodos (Workers)
    • Ejecutan las aplicaciones
    • Agente Kubelet
      • Gestiona el nodo
      • Comunicación con Master

5 of 72

Funcionamiento de Kubernetes

  • Despliegue llega a Master
  • Master organiza los contenedores para que se ejecuten en Workers
  • Comunicación mediante API K8s
  • Es posible usar API K8s desde fuera

6 of 72

Componentes más importantes

7 of 72

Dónde usar Kubernetes

  • Local (desarrollo)​
    • Minikube, kind, k3s, Rancher, Activar Kubernertes en Docker Desktop, …
  • Cloud​
    • AKS (Azure Kubernetes Service)
    • GKE (Google Kubernetes Engine)
    • EKS (Amazon Elastic Kubernetes Service)
    • ...
  • On premise​
    • OpenStack (IaaS) + Rancher (Plataforma de administración de K8s)
    • kubeadm
    • ...

8 of 72

Herramientas interesantes

  • Octant
  • Lens

9 of 72

2

Instalación

10 of 72

Minikube

  • Implementación ligera de Kubernetes
    • La usaremos para pruebas y desarrollo
    • Despliega Kubernetes en un contenedor Docker
    • Despliega un cluster sencillo formado por un solo nodo
  • Instalación
  • Comandos básicos
    • Iniciar un cluster: minikube start
    • Acceso al Dashboard de Kubernetes: minikube dashboard
    • Detener el cluster local: minikube stop
    • Eliminar el cluster local: minikube delete
    • Iniciar un segundo cluster local: minikube start -p cluster2

11 of 72

Interacción con Kubernetes: kubectl (CLI de Kubernetes)

  • Instalación
  • Comandos de prueba
    • Versión: kubectl version
    • Información del cluster: kubectl cluster-info
    • Nodos que forman el cluster: kubectl get nodes
    • Lanzar despliegues
    • Crear servicios
    • ...
    • Agregar nodos

12 of 72

3

Objetos principales de Kubernetes

13 of 72

Objetos básicos

  • Pod
    • Contenedor (realmente un conjunto de contenedores) en ejecución
  • Service
    • Abstracción para exponer una aplicación
  • Volume
    • Almacenamiento para los contenedores
  • Namespace
    • Agrupan recursos y ofrecen abstracción de cluster virtual
  • ConfigMap
    • Para almacenar datos en forma de pares clave-valor
  • Secret
    • Para almacenar información sensible. Base-64 encoded

14 of 72

Objetos controladores

  • ReplicaSet
    • Asegura la ejecución del número de réplicas especificadas para un Pod
  • Deployment
    • Forma declarativa de definir los Pods y ReplicaSets
  • StatefulSet
    • Se usa para gestionar aplicaciones con estado.
  • DaemonSet
    • Cada nodo Kubernetes tiene una copia en ejecución de un Pod.
    • Util como daemon de almacenamiento, logs o monitorización.
  • Job
    • Crea uno o más pods y se asegura que finalizan correctamente.
    • Util para realizar cálculos y operaciones

15 of 72

Archivos de configuración YAML

  • Usaremos archivos YAML (manifiestos)
    • Desplegados con kubectl apply -f <filename>
    • Modificación del despliegue sobre el archivo y redespliegue con
      • kubectl apply -f <filename>
    • Eliminados con kubectl delete -f <filename>
  • Indentación estricta. Usar validadores (online o de consola)

16 of 72

Manifiestos YAML

  • Incluyen el estado que se quiere alcanzar (objetos a desplegar, réplicas, volúmenes, …)
  • Se despliegan con kubectl (CLI)
  • Ejemplo Nginx

17 of 72

Namespace

  • Organizan los despliegues realizados en un cluster
  • Recursos con nombre único a nivel de namespace
  • No se pueden anidar
  • Namespace de sistema: kube-system, kube-public, kube-node-lease
  • Namespace predeterminado: default
  • Usos
    • Organización
    • Evitar conflictos entre despliegues de equipos
    • Control de acceso y de recursos

18 of 72

Creación de un namespace

19 of 72

Niveles de abstracción en Kubernetes

ReplicaSet

Deployment

Pod

Contenedor

gestiona un ...

gestiona un ...

es una abstracción de un ...

20 of 72

Pod

  • Unidad atómica en Kubernetes
  • Representa un grupo de uno o más contenedores
  • Los contenedores de un pod
    • Comparten una IP y un espacio de puertos
    • Siempre van juntos y se despliegan juntos en un nodo

21 of 72

Despliegue de pods

Con kubectl logs <pod> obtenemos los logs de un pod

22 of 72

Port forward a un pod

  • Ver en local lo que está sirviendo un pod
  • Establece un túnel SSH entre nuestro equipo y el pod con los puertos indicados
  • kubectl port-forward -n demo myweb 80:80

23 of 72

Nodos y pods

  • Normalmente virtuales
  • Gestionados por el Master
  • kubelet
    • Gestiona comunicación entre nodo y Master
    • Gestiona pods en ejecución del nodo
  • Docker
    • Descarga de imágenes
    • Registro de imágenes
    • Ejecución de contenedores

24 of 72

Deployment

  • Normalmente no desplegaremos Pods
  • Desplegaremos Deployments
  • Incluyen contenedores con imágenes diferentes que trabajarán de forma coordinada
  • Ejemplo: Backend junto a Frontend
  • Pueden incluir:
    • Número de réplicas
    • Recursos solicitados (p.e. RAM, porcentaje de CPU, …​)
  • Permiten el escalado independiente de sus pods
  • Monitorización por el Controlador de Deployment
    • Autocuración

25 of 72

Aplicación de ejemplo Tennis

  • API REST en PHP (Devuelve lista de países, jugadores, jugadores por país y detalles de jugador)
  • UI con lista de países como enlaces, jugadores de un país y detalles de un jugador
  • Repositorio de código

26 of 72

Tennis API

27 of 72

Deployment de Tennis API

Especificación del pod dentro de la especificación del deployment

Etiqueta a los pods para determinar a qué deployment pertenecen

28 of 72

Prueba de Tennis API

29 of 72

Deployment de la aplicación Tennis

30 of 72

Prueba de aplicación Tennis

  • La aplicación no recupera datos de API Tennis
    • Necesita la creación de un Service

31 of 72

Service

  • Abstracción que define
    • Una agrupación de Pods
    • Una política de acceso a ellos.
  • Selector: Determina el conjunto de Pods al que se dirige un Service

32 of 72

Label y Selector

  • Label: Búscame así
  • Selector: Busco esto

33 of 72

Emparejamiento Label y Selector en Tennis

34 of 72

Tipos de Service

  • En función del ámbito de la exposición del servicio:
    • ClusterIP: IP interna a nivel de cluster. Servicio accesible a nivel de cluster
    • NodePort: Servicio expuesto fuera del cluster concatenando la IP del nodo en el que está el pod y un número de puerto entre 30000 y 32767
    • LoadBalancer: Crea un balanceador externo con una IP externa asignada
    • ExternalName: Servicio expuesto usando un nombre

35 of 72

Service completo para Tennis

  • API ha de estar disponible como NodePort para la aplicación
  • Aplicación ha de estar disponible como LoadBalancer para usuarios
    • El proveedor cloud debe proporcionar el servicio LoadBalancer

kubectl apply -f https://gist.githubusercontent.com/ualmtorres/2a0a96749a8b0ced6b8fdd81a9258920/raw/23463255967a4156d1390befdd3bec872ae79bc0/tennis-service.yml

36 of 72

Limpieza del despliegue (servicios y deployments)

  • Eliminación de los servicios (Aplicación y API)
    • kubectl delete -f https://gist.githubusercontent.com/ualmtorres/2a0a96749a8b0ced6b8fdd81a9258920/raw/23463255967a4156d1390befdd3bec872ae79bc0/tennis-service.yml
  • Eliminación del despliegue de la aplicación
    • kubectl delete -f https://gist.githubusercontent.com/ualmtorres/3d4d28d2a245bbd348c300fa9594f133/raw/b3c799c50bb00c8536fd7c67523f9f0ed38eef0a/tennis-app-deployment.yml
  • Eliminación del despliegue de la API
    • kubectl delete -f https://gist.githubusercontent.com/ualmtorres/0729de5e0ff5b5fdd931abcc6aa2fc5a/raw/a5e992b4e240d011b01749ec16d01bdd3c0bf7b1/tennis-api-deployment.yml

37 of 72

ConfigMap

  • Almacenar datos no sensibles en forma de pares clave-valor
    • Uso en despliegues parametrizados
    • Los datos se guardan tal cual

38 of 72

Secret

  • Almacenan información sensible (contraseñas, tokens, claves ssh, …)
  • Los objetos Secret no están cifrados.
  • Están codificados en base64 y pueden hacerse visibles fácilmente.
  • Crear secret
    • Obtener el valor en base64 (echo -n 'secret' | base64)
    • Crear el Secret

39 of 72

4

Almacenamiento básico en volúmenes

40 of 72

Volúmenes locales

  • El almacenamiento en contenedores es efímero.
  • Ante un fallo de contenedor, kubelet lo reiniciará con un estado limpio.
  • Gran variedad de tipos de volúmenes
    • Sistemas de almacenamiento (Ceph, GlusterFS, NFS, …)
    • Cloud (AWS, Azure, Google Cloud, OpenStack, …)
  • Básicos (que veremos aquí)
    • emptyDir
    • hostPath

41 of 72

Volumen emptyDir

  • Asociado a un pod en un nodo
  • Usan el medio de almacenamiento del nodo (HD, SSD, NAS, …)
  • También pueden ser de tipo Memory(Util para cachés)
  • Uso:
    • Compartir datos entre contenedores en un pod o archivos de inicialización

42 of 72

Ubicación de volúmenes emptyDir

  • Creado dentro del directorio del pod
  • Ruta
    • /var/lib/kubelet/pods/<pod-uid>/volumes/kubernetes.io~empty-dir/<volume-name>
  • uid de un pod
    • kubectl get pods -n demo redis -o yaml | grep uid

43 of 72

Volumen hostPath

  • Monta en el contenedor un archivo o un directorio del sistema de archivos del nodo en el que está ejecutándose el pod
  • Problemas con varios nodos
    • Hay que mantener la sincronización (rsync, Syncthing, …)

44 of 72

Riesgo de volúmenes hostPath

  • Operación arriesgada
    • Acceso e incluso escritura en sistema de archivos del nodo del pod
  • type: Directory
    • El volumen sólo se crea si el directorio está creado previamente

45 of 72

5

Init containers

46 of 72

Init Containers

  • Contenedores de un pod que se ejecutan antes que el resto de contenedores de aplicación del pod
  • Suelen hacer operaciones de inicialización que no están presentes en la imagen de los otros contenedores del pod
  • Caso práctico: Aplicación con API conectada a MySQL
    • URL con script de inicialización de una base de datos
    • ConfigMap que configura la URL del script
    • Secret que almacena la contraseña MySQL
    • Volumen emptyDir con el script para ser montado por el contenedor BD
    • Init Container con imagen busybox
      • Descarga script de URL y lo coloca en volumen

47 of 72

Manifiestos de aplicación con Init Containers

48 of 72

6

Google Kubernetes Engine

49 of 72

Google Kubernetes Engine

  • Servicio gestionado de Kubernetes ofrecido por Google.
  • Ofrece autoescalado horizontal y vertical de pods y nodos.
  • Cluster GKE
    • Modo Autopilot (Pago por pod)
      • Escalado y administración por cuenta de Google
    • Modo estándar (Pago por nodo worker)
      • Escalado y administración por cuenta nuestra
      • Clusters regionales (varias regiones) y zonales (nodos en una sola zona)
  • Opción estándar cluster-1
    • 3 nodos e2-medium (2 vCPU, 4 GB RAM, 10 GB HD, sin autoescalado) -> 150$/mes

50 of 72

Configuración kubectl contra GKE

  • Descarga SDK de Google Cloud (gcloud)
  • Conexión
    • gcloud auth login
  • Inicialización (la instalación ya lo incluye)
    • gcloud init (usuario + proyecto)
  • Obtener credenciales GKE
    • gcloud container clusters get-credentials <cluster-name> --zone=<compute-zone>
  • Ahora kubectl queda configurado contra GKE

51 of 72

Contextos

  • Cluster Kubernetes al que está conectado kubectl
  • Contextos disponibles en ~/.kube/kubeconfig
  • Obtener contextos
    • kubectl config get-contexts
  • Usar contexto
    • kubectl config use-context <contexto>

52 of 72

Operaciones de interés

  • Modificación del tamaño del cluster (0 desactiva el cluster)
  • Autoescalado
  • ConfigMaps y Secrets disponibles en el menú Configuración

53 of 72

7

Volúmenes NFS con Filestore

54 of 72

Filestore

  • Solución gestionada de Google Cloud para almacenamiento en red
  • Compatible con NFS
  • Usado en GCE y GKE
  • Volumen de 1 TB mínimo
  • Se crea:
    • Instancia Filestore
    • Share (directorio de almacenamiento)
  • Persistente más allá de la vida de los pods y de los clusters GKE

55 of 72

PersistentVolume

  • Abstracción para el espacio de almacenamiento (p.e. share)
  • En NFS contiene
    • Tamaño
    • Modo de acceso
    • Servidor NFS
    • Share

56 of 72

PersistentVolumeClaim

  • Solicitud de espacio dentro de un PersistentVolume

Share

57 of 72

Despliegue conectado al PersistentVolumeClaim

Share

58 of 72

8

Horizontal Pod Autoscaler (HPA)

59 of 72

Horizontal Pod Autoscaler (HPA)

  • Permite el escalado en función de métricas de pods (p.e. CPU, RAM)
  • Los Deployment deben incluir los recursos consumidos
  • Se fija mínimo y máximo de réplicas
  • HPA desescala tras 5 minutos sin stress

60 of 72

Ejemplo del tenis con HPA

61 of 72

Prueba de carga con Apache Benchmark

  • Instalación: sudo apt-get install apache2-utils
  • Test: 10.000 peticiones con 10 concurrentes
    • ab -n 10000 -c 10 http://<ip-aplicacion>/
  • Recomendación
    • No partir de un cluster “ridículo” con un 1 sólo nodo “diminuto”
  • Visualización del estado del objeto HPA
    • kubectl get horizontalpodautoscalers.autoscaling -n demo --watch

62 of 72

Limpieza del entorno

  • Eliminación del HPA
    • kubectl delete -f https://gist.githubusercontent.com/ualmtorres/ff53c0d1ff1c00487bf49f1fe78d835e/raw/f2321d2a17343841dac473a6889e6866c33bd60e/tennis-hpa.yml
  • Eliminación de los servicios
    • kubectl delete -f https://gist.githubusercontent.com/ualmtorres/2a0a96749a8b0ced6b8fdd81a9258920/raw/23463255967a4156d1390befdd3bec872ae79bc0/tennis-service.yml

63 of 72

Limpieza del entorno (2)

  • Eliminación del deployment de la aplicación
    • kubectl delete -f https://gist.githubusercontent.com/ualmtorres/3ee88d2ccb75121d61e1c70cfffcaccf/raw/d09e767f9d43c8e01a6a1268b92dc4c12dc7e348/tennis-app-hpa.yml
  • Eliminación del deployment de la API
    • kubectl delete -f https://gist.githubusercontent.com/ualmtorres/9060280266cbb6c829706aee77eec3f7/raw/e481fee7251a086e30cd3dc2af1c95182cba72bd/tennis-api-hpa.yml

64 of 72

9

Caso de uso. API de productos

65 of 72

Escenario de partida

  • API en Laravel para CRUD sobre productos
  • Almacenamiento en MySQL
  • Imagen Docker: ualmtorres/laravel-products-api:v0
    • Mac M1: docker build --platform linux/amd64 -t ualmtorres/laravel-products-api:v0 .
  • Datos de conexión como variables de entorno
    • ENV DB_HOST
    • ENV DB_PORT
    • ENV DB_USERNAME
    • ENV DB_PASSWORD
    • ENV DB_DATABASE

66 of 72

Descripción de la API

  • CRUD Productos
  • Rutas
    • GET api/product
    • GET api/product/{id}
    • POST api/product
    • PUT api/product/{id}
    • DELETE api/product/{id}
  • Modelo
    • id: integer (autoincrement)
    • barcode: string
    • product: string
    • description: string
    • stock: integer
    • price: float
    • timestamps

DTO

(CREATE PRODUCT>)

67 of 72

Recursos Kubernetes necesarios

  • Deployment para la API
    • 2 réplicas
    • Valores de conexión como variables de entorno
  • ConfigMap para valores no sensibles
    • DB_PORT
  • Secret para valores sensibles
    • DB_HOST
    • DB_USERNAME
    • DB_PASSWORD
    • DB_DATABASE
  • Servicio para poder exponer y acceder al Deployment

68 of 72

Creación del objeto ConfigMap

  • El ConfigMap tiene un nombre y una lista de pares clave-valor
  • Enlace

69 of 72

Creación del objeto Secret

  • Los valores de un Secret se pasan en base64
    • Ejemplo: echo -n ‘password’ | base64 -> cGFzc3dvcmQ=
  • Crear en base64 valores para
    • DB_HOST
    • DB_USERNAME
    • DB_PASSWORD
    • DB_DATABASE
  • Enlace

70 of 72

Creación del objeto Deployment

  • Imagen ualmtorres/laravel-products-api:v0
    • Ojo: Variables de entorno falsas
  • Etiquetarlo para el servicio
    • Ejemplo: selector.matchLabels: laravel-products-api
  • Replicas 2
  • Uso de configmaps y secrets para configurar variables de entorno
  • Enlace

71 of 72

Deployment en acción

72 of 72

Creación del objeto Service

  • Busca el Deployment con selector laravel-products-api
  • Tipo: LoadBalancer -> Genera IP
  • Enlace