Habilitar CloudWatch en un clúster eks de AWS

0
2296

Índice de contenidos

Introducción

En este tutorial vamos a construir un clúster de Kubernetes con el objetivo de monitorizar y observar datos e información procesable de nuestra aplicación, utilizando los servicios de AWS (Amazon Web Services), en concreto Amazon CloudWatch, para así recopilar datos de monitorización y operaciones en formato de registros, métricas y eventos.

Por un lado, vamos a crear un clúster de Kubernetes mediante eksctl.

Por otro lado, vamos a implementar el servicio de CloudWatch Container Insights en dicho clúster para realizar tareas de monitorización, resolución de problemas y configuración de alarmas relacionadas con los microservicios y orquestadores. Además, Container Insights provee información de servicios de administración de contenedores, como Amazon ECS para Kubernetes (EKS), Amazon Elastic Container Service (ECS), AWS Fargate y Kubernetes (k8s).

Para el clúster de Amazon EKS, vamos a utilizar un agente FluentD preconfigurado para recopilar los registros de CloudWatch, los cuáles se pueden analizar en mayor profundidad con el lenguaje de consulta avanzado de CloudWatch Logs Insights.

También recordar que los servicios de AWS no son del todo gratuitos y que esta implementación puede generar costes adicionales. Influirá el tipo de instancia de Amazon EC2 y no salirse de los límites de la capa gratuita de Amazon CloudWatch.

Aún así, para evitar generar cargos inesperados, al finalizar eliminaremos las políticas asociadas de CloudWatch para forzar a que el sistema falle y, por último, eliminar el clúster.

Entorno

El tutorial está escrito usando el siguiente entorno:

  • Hardware: Portátil MacBook Pro 14 (2,2 GHz Intel Core i7, 16GB RAM).
  • AWS CLI.
  • eksctl.
  • Amazon EC2.
  • Amazon EKS.
  • CloudWatch de Amazon.
  • AWS Lambda.
  • AWS CloudTrail.

Instalar eksctl

Antes de nada debemos saber que tanto eksctl como el AWS CLI requieren que tenga las credenciales de AWS configuradas en su entorno. Los pasos para crear una cuenta así como otras especificaciones de seguridad se pueden encontrar en este tutorial. Luego, debemos generar las claves para configurar los servicios necesarios de AWS CLI, esto lo puedes encontrar en otro tutorial de este blog.

Una vez hayamos terminado de configurar AWS, pasamos a crear el clúster de Amazon EKS mediante eksctl.

A continuación debemos instalar eksctl, una herramienta que nos permite automatizar muchas tareas individuales con los clusters de EKS. Los pasos para la instalación se pueden encontrar en la guía oficial de AWS para diferentes sistemas operativos (). En este caso, para instalarlo en macOS, basta con hacerlo mediante Homebrew con los siguientes comandos:

brew tap weaveworks/tap

Una vez terminado de instalar Weaveworks, debemos instalar eksctl mediante el siguiente comando:

brew install weaveworks/tap/eksctl

Por último, comprobamos su correcto funcionamiento mediante:

eksctl version

Instalar kubectl

Debes saber que Kubernetes utiliza una utilidad llamada kubectl para trabajar con los clusters de Kubernetes. De nuevo, los pasos para la instalación en diferentes sistemas operativos los puedes encontrar en la guía oficial, para instalarlo en macOS con la versión Kubernetes 1.18 debemos ejecutar el siguiente comando:

curl -o kubectl https://amazon-eks.s3.us-west-2.amazonaws.com/1.18.9/2020-11-02/bin/darwin/amd64/kubectl

Le damos permisos al binario:

chmod +x ./kubectl

Copiamos el binario a una carpeta en nuestro PATH:

mkdir -p $HOME/bin && cp ./kubectl $HOME/bin/kubectl && export PATH=$PATH:$HOME/bin

Por último, tras instalar kubectl, comprobamos que todo ha salido según lo esperado:

kubectl version --short --client

Crear el clúster Amazon EKS

Es necesario tener una versión de eksctl 0.33.0 o superior. Podemos crear el clúster usando un fichero de configuración yaml, pero para simplificar el proceso se hace uso de eksctl. ¡Al lío!, debemos modificar los siguientes parámetros:

eksctl create cluster --name <my-cluster> --version 1.18 --region <my-region> --nodegroup-name standard-workers --node-type <node-type> --nodes 2 --nodes-min 1 --nodes-max 2

Como vemos, establecemos el nombre del clúster (testeks) y en la región (eu-west-1), especificamos con nodegroup-name donde residen los pods. También indicamos el tipo de nodo t2.micro (este tipo de instancia no se recomienda en entornos productivos por su bajo rendimiento). Con nodes min y max se registran el número de nodos mínimo y máximo en caso de habilitar el autoescalado. Y en este ejemplo, no nos interesa configurar el ssh para el worker node.

Una vez modificado, ejecutamos el siguiente comando:

eksctl create cluster --name testeks --version 1.18 --region eu-west-1 --nodegroup-name standard-workers --node-type t2.micro --nodes 2 --nodes-min 1 --nodes-max 2

Comentar que tardará en torno a 15 minutos. Cuando el clúster esté listo, comprobaremos mediante kubectl si la configuración es correcta:

kubectl get svc

Si todo ha salido bien, veremos la siguiente salida:

NAME             TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
svc/kubernetes   ClusterIP   10.100.0.1   <none>        443/TCP   1m

Configurar clúster

Tenemos un rol de IAM que fue creado por el eksctl pero no tiene las políticas de CloudWatch, tenemos que asociar la política para que los nodos puedan empezar a enviar logs a CloudWatch. Nos dirigimos al panel de instancias EC2 y añadimos el permiso CloudWatchLogsFullAccess a eksctl-testeks-nodegroup-standard-*.

CloudWatchLogsFullAccess

Container Insights en Amazon EKS

Ya que está disponible para EKS, vamos a utilizar Container Insights para recopilar, resumir las métricas y registros de nuestra aplicación. También se puede establecer alarmas de CloudWatch en las métricas que recopila Container Insights.

Estos eventos de registro de rendimiento son entradas que utilizan un esquema JSON estructurado que permite incorporar y almacenar datos. A partir de estos datos, CloudWatch crea métricas agregadas a nivel de clúster, nodo, pod y servicio.

Debemos tener cuidado ya que las métricas recopiladas por Container Insights se cobran como métricas personalizadas. Para obtener más información acerca de los precios de CloudWatch puedes consultar aquí.

Para implementar Container Insights en Amazon EKS debemos ejecutar el siguiente comando:

curl https://raw.githubusercontent.com/aws-samples/amazon-cloudwatch-container-insights/latest/k8s-deployment-manifest-templates/deployment-mode/daemonset/container-insights-monitoring/quickstart/cwagent-fluentd-quickstart.yaml | sed "s/{{cluster_name}}/cluster-name/;s/{{region_name}}/cluster-region/" | kubectl apply -f -

En este comando, cluster-name es el nombre de nuestro clúster EKS y, cluster-region el nombre de la región donde los logs son publicados. Modificamos los parámetros quedando así:

curl https://raw.githubusercontent.com/aws-samples/amazon-cloudwatch-container-insights/latest/k8s-deployment-manifest-templates/deployment-mode/daemonset/container-insights-monitoring/quickstart/cwagent-fluentd-quickstart.yaml | sed "s/{{cluster_name}}/testeks/;s/{{region_name}}/eu-west-1/" | kubectl apply -f -

Si todo ha salido bien, se puede observar cómo se ha configurado el agente de Cloudwatch como un DaemonSet para enviar las métricas y, FluentD para enviar registros a CloudWatch Logs.

En este punto nos dirigimos al panel de navegación de Container Insights, elija Performance Monitoring. Podemos ver una serie de recursos específicos o seleccionar el tipo de recurso que deseas ver.

Monitoreo

Las métricas que CloudWatch establece en EKS con Container Insight se pueden consultar aquí.

También podemos consultar los logs enviados mediante FluentD. Para ello nos dirigimos a Registros → Grupo de registros y en este caso, seleccionamos:

/aws/containerinsights/testeks/performance

CloudWatchLogs

Además, CloudWatch no crea automáticamente todas las métricas posibles a partir de los datos de registro, podemos ver métricas adicionales y niveles adicionales de granularidad haciendo uso de CloudWatch Logs Insights para analizar los eventos de registro de rendimiento sin procesar.

Automatizando la retención del grupo de registros

Retención grupo de registros

Podemos observar que los registros de CloudWatch se clasifican como “hot storage”, esto viene a decir que son mucho más costosos que otras opciones de almacenamiento como el S3.

Así que para obtener el máximo rendimiento de los registros de CloudWatch a un bajo coste, lo ideal es mover los registros más antiguos a S3 para una retención a largo plazo.

CloudWatch organiza los registros en un grupo de registros y cuando un nuevo grupo de registros es creado, su período de retención se establece a Never expire (No vence nunca), lo que significa que los registros se almacenan de forma indefinida.

Esto resulta un poco tedioso ya que uno de los principales objetivos es ahorrar costes. Para ello, una de las posibles soluciones es automatizar el proceso de creación de la infraestructura mediante Terraform, otra alternativa es hacer uso de CloudTrail. Para este tutorial nos apoyaremos en esta última alternativa.

Lo que logramos con esta automatización es que cuando se crea un nuevo grupo de registros de CloudWatch, se establece por defecto un tiempo de retención deseable para dicho grupo de registro. Después de ese tiempo de retención, todos los datos del flujo de registro del grupo serán eliminados automáticamente.

Cuando se crea un nuevo grupo de registro de CloudWatch, una regla de eventos dispara una función Lambda. Entonces, esta función establece un tiempo de retención para el grupo de registro de CloudWatch.

Lo primero que necesitamos es crear un rol IAM, así la Lambda tendrá acceso a otros recursos de AWS. Crea un rol IAM y asociarle la política de un servicio.

Ahora, creamos una función AWS Lambda, en el runtime establecemos Node.js 12.x como el lenguaje que quiere utilizar esta función y, cambiamos el rol de ejecución al previamente creado. Llegados a este punto debemos reemplazar el código de la función por este:

const AWS = require('aws-sdk');
const cloudwatchLogs = new AWS.CloudWatchLogs();

function setRetentionOfCloudwatchLogGroup(logGroupName, duration) {
    let params = {
        logGroupName : logGroupName,
        retentionInDays: duration
    };
    return cloudwatchLogs.putRetentionPolicy(params).promise();
}

exports.handler = async (event) => {
    const logGroupName = event.logGroupName ? event.logGroupName : event.detail.requestParameters.logGroupName;
    try {
        await setRetentionOfCloudwatchLogGroup(logGroupName, 14);
        console.log('Retention has been set to ' + logGroupName + 'for 2 weeks');
        return;
    } catch(error) {
        console.error(error);
        throw error;
    }
};

El siguiente paso es crear una regla de eventos de CloudWatch.

  1. Servicios de AWS → CloudWatch → Reglas → Crear una regla.
  2. En Origen del evento, elegimos Patrón de eventos y en nombre del servicio seleccionamos CloudWatch Logs. Como tipo de evento establecemos AWS API Call via CloudTrail (en caso de no tener configurado CloudTrail, debemos hacerlo). https://eu-west-1.console.aws.amazon.com/cloudtrail/home?region=eu-west-1#/

Aquí voy a hacer un pequeño paréntesis ya que te estarás preguntando el por qué del uso de CloudTrail. Básicamente, necesitamos detectar cuándo se crea un nuevo servicio en el historial de los eventos de actividad de la cuenta de AWS para así poder lanzar la Lambda y que modifique el periodo de retención. Con Cloudtrail se puede registrar, monitorear de manera continua y retener la actividad de la cuenta relacionada con acciones en toda su infraestructura de AWS.

Trail create

  1. Una vez creado el trail, continuamos con la configuración. En operaciones específicas indicamos CreateLogGroup. En Destinos, seleccionamos Función Lambda y la función Lambda previamente creada.

Evento CloudWatch Logs

  1. Por último, damos un nombre, descripción (opcional) y estado (habilitado) y, le damos a crear regla.

Eliminación del clúster

Algunos de los servicios de AWS no son del todo gratuitos, recordar crear un presupuesto para la cuenta y activar una alerta para evitar que le cobren una cantidad de dinero no deseada.

Después, nos debemos dirigir a la consola del IAM y se deben eliminar las políticas de Cloudwatch asociadas para que el sistema falle.

Permisos CloudWatch

Por último, eliminamos el clúster.

eksctl delete cluster --name testeks

Conclusiones

Disponemos de un clúster de Kubernetes que está listo para algunos propósitos de prueba, investigación y aprendizaje. Hemos visto parte del ecosistema que envuelve a CloudWatch y cómo configurarlo, y cómo recopilar y resumir métricas mediante Container Insights.

Además, hemos visto la posibilidad de crear estructuras más complejas, por ejemplo, se hace uso de CloudTrail para monitorizar los eventos de la actividad de los usuarios y el uso de las API.

Por último, hemos automatizado la retención del grupo de registros de AWS CloudWatch para reducir sobrecostes. Ahora, lo ideal es mover los registros que se van a eliminar a S3 para una retención a largo plazo, pero eso es otra historia.

DEJA UNA RESPUESTA

Por favor ingrese su comentario!

He leído y acepto la política de privacidad

Por favor ingrese su nombre aquí

Información básica acerca de la protección de datos

  • Responsable:
  • Finalidad:
  • Legitimación:
  • Destinatarios:
  • Derechos:
  • Más información: Puedes ampliar información acerca de la protección de datos en el siguiente enlace:política de privacidad