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.
- 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.
- 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
- 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
- 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
- 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
- Una cuenta de AWS https://aws.amazon.com/free/
- Si estás usando Linux o Mac, puedes continuar al siguiente punto. Si estás usando Microsoft Windows, te sugiero que uses WSL2: https://docs.microsoft.com/en-us/windows/wsl/install
- Tener Git instalado https://github.com/git-guides/install-git
- Muy importante, instalar Kubectl https://docs.aws.amazon.com/eks/latest/userguide/install-kubectl.html
- Y finalmente, AWS CLI 2 https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html
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
- Te recomiendo que almacenes los logs de Kubernetes para observabilidad en Amazon CloudWatch, eso lo veremos en un siguiente episodio, sin embargo puedes encontrar más información en la documentación oficial: https://docs.aws.amazon.com/prescriptive-guidance/latest/implementing-logging-monitoring-cloudwatch/kubernetes-eks-logging.html
- Vamos a revisar el estado de los servicios y las direcciones para probar la aplicación. La columna EXTERNAL-IP es la que contiene la dirección Full Qualified Domain Name (FQDN) o CNAME que podemos usar para llamar al servicio.
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.