Blog de Amazon Web Services (AWS)

Picturesocial – Cómo desplegar una aplicación en Kubernetes

Por José Yapur, Senior Developer Advocate en AWS

Hasta el momento hemos aprendido sobre Containers, Kubernetes y Terraform. Ahora es tiempo de usar ese conocimiento para desplegar nuestro container en un clúster de Amazon Elastic Kubernetes Service. En este artículo aprenderemos, además, sobre la herramienta Kubectl y algunos comandos básicos de Kubernetes.

Para entender el flujo básico de un desarrollador con Kubernetes, tenemos que entender el flujo completo de desarrollo de una aplicación “contenerizada”, desde la perspectiva de despliegue. He diseñado este diagrama para ayudar a resumir el proceso.

Dividí el diagrama en 5 pasos para ayudar a aclarar las actividades que representan y el orden en el que suceden.

  1. Primero, tenemos que construir nuestra imagen de container, establecemos un nombre de imagen y una etiqueta. Una vez que la imagen fue creada podemos probar localmente que todo esté bien.
  2. Una vez que hemos probado el container, podemos hacer push de la imagen a un Container Registry, en este caso vamos a usar Amazon Elastic Container Registry. Todos los pasos necesarios para llegar hasta acá están en el primer episodio: https://go.aws/3OivK06
  3. Cuando la imagen de container está almacenada en el Container Registry tenemos que comenzar a trabajar en nuestro Manifest de Kubernetes, para eso es importante entender los conceptos básicos que nos permitan crear un pod, un replica set y un Service. Todo eso lo exploramos en el episodio 2: https://go.aws/3wucSns
  4. Ahora necesitamos crear nuestro clúster de Kubernetes y obtener las credenciales para ejecutar tareas por medio de Kubectl. En el tercer episodio aprendimos a crear un clúster de usando Terraform y a obtener las credenciales de conexión: https://go.aws/3GwBnEY
  5. Y por último, pero no menos importante, vamos a desplegar nuestra aplicación en Kubernetes usando el Manifest ¡Este último paso lo aprenderemos en este artículo!

Ahora que hemos recordado los episodios anteriores, despleguemos la aplicación. Estoy asumiendo que revisaste los episodios anteriores para continuar con este.

Pre-requisitos

O

  • Si esta es tu primera vez trabajando con AWS CLI o necesitas un refresh de como setear tus credenciales en el terminal te sugiero seguir este paso a paso: . Si no quieres instalar todo desde cero, en este mismo link podrás seguir los pasos para configurar Amazon Cloud9 que es un entorno de desarrollo virtual, que incluye casi todo el toolset que necesitas para este paso a paso.

Paso a Paso

  • Vamos a validar si tenemos Kubectl correctamente instalado, ejecutando:

kubectl version

  • Deberías obtener una versión mínima de Major:"1!, Minor:"22" para ejecutar este paso a paso. De lo contrario te sugiero revisar este link para aprender cómo actualizar: https://docs.aws.amazon.com/eks/latest/userguide/install-kubectl.html
  • Cuando creaste el clúster, también ejecutaste el comando para actualizar el Kubeconfig. No necesitas volverlo a ejecutar, pero recuerda que este paso es necesario :)

aws eks --region $(terraform output -raw region) update-kubeconfig --name $(terraform output -raw cluster_name)

  • Este paso descargó el archivo Kubeconfig con: a/ el nombre del clúster, b/ la url del api de Kubernetes, c/ la llave para conectarte. Ese archivo es guardado por defecto en /.kube/config. Puedes ver un ejemplo de la documentación oficial de Kubernetes a continuación
apiVersion: v1
clusters:
- cluster:
    certificate-authority: fake-ca-file
    server: https://1.2.3.4
  name: development
- cluster:
    insecure-skip-tls-verify: true
    server: https://5.6.7.8
  name: scratch
contexts:
- context:
    cluster: development
    namespace: frontend
    user: developer
  name: dev-frontend
- context:
    cluster: development
    namespace: storage
    user: developer
  name: dev-storage
- context:
    cluster: scratch
    namespace: default
    user: experimenter
  name: exp-scratch
current-context: ""
kind: Config
preferences: {}
users:
- name: developer
  user:
    client-certificate: fake-cert-file
    client-key: fake-key-file
- name: experimenter
  user:
    password: some-password
    username: exp
  • Ahora que nuestro Kubeconfig ha establecido una relación de confianza y nuestro terminal, vamos a aprender algunos comandos básicos de kubectl.
  • Primero, vamos a explorar cuántos workers están ejecutándose en este clúster. El siguiente comando retornará los 3 workers que creamos, la versión de Kubernetes y la edad de cada instancia de Amazon Elastic Compute Cloud desde la creación o actualización. Como puedes ver, cada worker está en una subnet diferente y en 3 zonas de disponibilidad separadas.

kubectl get nodes

  • Así como hicimos con los workers, podemos también ejecutar un comando similar para los pods. Ten en cuenta que aún no desplegamos nada, por lo que no deberíamos tener ningún pod. Adicionalmente si no especificamos un Namespace en el comando solo retorna información del amespace “default”.

kubectl get pods

  • Sin embargo, también podríamos ver los pods que se encuentran en todos los Namespaces, incluyendo los que son propios de Kubernetes, eso lo logramos añadiendo —all-namespacesa nuestros comandos.

kubectl get pods --all-namespaces

  • Lo mismo con Services, podemos revisar todos los servicios en el clúster. Como puedes ver, tienes el servicio default y el kube-system que se encarga de los DNS. Es importante que no editemos o eliminemos ninguno de esos Services o Pods ¡Créeme!

kubectl get pods --all-namespaces

  • También podemos revisar los replica set, ejecutando:

kubectl get rs --all-namespaces

  • Como puedes ver, los comandos para ejecutar las tareas básicas son bastante sencillos y explícitos. Ahora desplegaremos el container que creamos en nuestro primer episodio.
  • He preparado una Branch con todo lo que necesitas. Vamos a clonarla primero y posicionarnos en el folder que usaremos picture-social-sample/HelloWorld

git clone https://github.com/aws-samples/picture-social-sample.git -b ep4
cd picture-social-sample/HelloWorld

  • Abrimos el archivo manifest.yml. Este archivo es el Manifest de Kubernetes. Como podemos ver, creará un deployment, con dos réplicas, llamado helloworld con un pod y un container almacenado en 111122223333.dkr.ecr.us-east-1.amazonaws.com/helloworld. El manifest también incluye un Service con un Load Balancer público que será expuesto en el puerto 80 e invocará internamente al puerto 5111 de los pods.
#########################
# Definicion de los POD
#########################
apiVersion: apps/v1
kind: Deployment
metadata:
  name: helloworld
  labels:
    app: helloworld
spec:
  replicas: 2
  selector:
    matchLabels:
      app: helloworld
  template:
    metadata:
      labels:
        app: helloworld
    spec:
      containers:
      - name: helloworld
        image: 111122223333.dkr.ecr.us-east-1.amazonaws.com/helloworld
        resources:
          requests:
            memory: "256Mi"
            cpu: "250m"
          limits:
            memory: "512Mi"
            cpu: "500m"
---
#########################
# Definicion del servicio
#########################
kind: Service
apiVersion: v1
metadata:
  name: helloworld-lb
spec:
  selector:
    app: helloworld
  ports:
  - port: 80
    targetPort: 5111
  type: LoadBalancer
  • Ahora estamos listos para desplegar la aplicación, solo asegúrate de cambiar el Account ID y verificar la región, en el manifest.yml antes de continuar.
  • Vamos a usar el Namespace para este episodio. Recuerda que los Namespaces nos ayudarán a manejar los pods con orden y agrupación basada en afinidad o dominio de negocio ¡Es momento de crear el N!

kubectl create namespace tests

  • Con el Namespace creado vamos a aplicar los cambios en Kubernetes usando la ruta del archivo manifest.yml y especificando el Namespace que acabamos de crear.

kubectl apply -f manifest.yml -n tests

  • Ahora vamos a revisar el deployment, los pods y el service. No olvides siempre pasar el parámetro namespace -n
  • Al ejecutar el comando, deberíamos tener 2 réplicas de la misma pod.

kubectl get pods -n tests

  • Si quieres ver detalles de un pod en específico, puedes ejecutar el siguiente comando, donde podName es el nombre del pod que quieres revisar. Además, incluye información del scheduling y eventos históricos.

kubectl describe pod podName -n tests

  • Además, puedes revisar los logs de un pod en específico en tiempo real si ejecutas el comando de logs con -f

kubectl logs podName -f -n tests

kubectl get services -n tests

  • Ahora puedes abrir el navegador y probar tu aplicación, solo asegúrate de usar http en vez de https para esta prueba en específico.

  • Te recomiendo que expongas Services sólo de forma local y no exponiéndolos a internet. Vamos a aprender cómo exponer un endpoint al mundo exterior usando otras capas de seguridad como API Gateway con TLS, VPC Link y WAF en un siguiente episodio.
  • Este simple “Hello Jose” de respuesta, es la llamada al LoadBalancer que elige uno de los 2 pods y envía el request para luego mostrarlo en tu navegador.
  • Ahora, probemos por qué Kubernetes es un orquestador de contenedores que se “auto cura”. Vamos a eliminar una de las 2 pods y ver qué es lo que sucede.

kubectl delete pod podName -n tests

  • Tan pronto como un pod es eliminado, Kubernetes aprovisionará otro clone, debido a que se debe respetar la cantidad de réplicas de mi replica set. Si quieres ver todos los cambios en stream, puedes agregar el parámetro -wal comando para ver los cambios en tiempo real.

kubectl get pods -w -n tests

  • Puedes establecer una regla de auto escala para tu deployment ejecutando el siguiente comando. Donde --max es el número máximo de réplicas con el que trabajará este HPA o Auto escalador Horizontal de Pods, --min es el número de réplicas mínimas que deben existir y --cpu-percent es el porcentaje de CPU necesario para que se active esta regla.

kubectl autoscale deployment helloworld --max 10 --min 2 --cpu-percent 70 -n tests

  • Puedes revisar el estado de tu HPA ejecutando el siguiente comando:

kubectl get hpa -n tests

¡Espero que hayas disfrutado este artículo tanto como yo disfruté escribiéndolo! Y espero que te haya ayudado a clarificar los episodios anteriores. Si todo salió bien en este paso a paso entonces aprendiste a desplegar una aplicación a Kubernetes, crear servicios, usar los comandos para crear namespaces y trabajar entre namespaces, ver la descripción de objetos, ver logs de la aplicación y escalar la aplicación en base a reglas. No te olvides de ver el video para tener más detalles.

¡En el siguiente episodio aprenderemos a desarrollar una de las partes más importantes de Picturesocial, el API para reconocimiento de imágenes y auto etiquetado usando Amazon Rekognition!


Sobre el autor

José Yapur es Senior Developer Advocate en AWS con experiencia en Arquitectura de Software y pasión por el desarrollo especialmente en .NET y PHP. Trabajó como Arquitecto de Soluciones por varios años, ayudando a empresas y personas en LATAM.