
ESCRITORES TECNOLOGICOS
Cómo Karpenter optimizó la gestión de nuestra infraestructura EKS en AWS
Las empresas enfrentan desafíos diarios en la gestión de la infraestructura de Kubernetes, especialmente para mantener la eficiencia y reducir costos. Aquí en SoftplanDescubrimos una solución que transforma la forma en que gestionamos nuestros clústeres EKS en AWS: Karpenter. Desafíos en la gestión de instancias Antes de hablar de Karpenter, es necesario dar unos pasos atrás y explicar un poco qué es el escalado automático de nodos. Supongamos que tenemos nuestro clúster con algunas máquinas (instancias) disponibles ejecutando nuestras cargas de trabajo. ¿Qué sucede si hay un pico en el uso de nuestras aplicaciones y necesitamos lanzar más instancias (réplicas) de nuestros pods? Sin escalamiento automático, necesitaríamos aprovisionar un nodo e indicarle que se una a nuestro clúster para que nuestros pods puedan iniciarse en esta nueva instancia. Recordando que el aprovisionamiento de una instancia no es instantáneo, hay un arranque completo de la máquina, configuraciones de red y muchas otras cosas antes de que esté completamente disponible. Bien, hablamos de usuarios pico en nuestras aplicaciones, pero ¿qué pasa cuando hay inactividad? ¿Realmente queremos dejar estos nodos en funcionamiento con un poder de cómputo subutilizado? Para resolver este y otros problemas entra en juego el concepto de escaladores automáticos. Escaladores automáticos Las implementaciones de escaladores automáticos son básicamente responsables del aprovisionamiento y la consolidación de nodos. Aquí estamos hablando de escalamiento horizontal, es decir, agregar más máquinas a nuestro clúster. Hay varias implementaciones de escalamiento automático de nodos, pero en este artículo nos centraremos en la implementación de AWS y por qué decidimos migrar a otra solución. A continuación, se muestra una figura que ejemplifica cómo funciona el escalamiento automático de nodos: Figura 01: Escalamiento automático de AWS - Grupos de escalamiento automático Al definir un grupo de escalamiento en AWS, necesitamos definir varias propiedades, como el número mínimo/máximo de instancias de nodo permitidas para este grupo, los recursos utilizados, el tipo de disco, las configuraciones de red (subredes, etc.) y muchos otros detalles. Por ejemplo, para un determinado tipo de aplicación que utiliza más CPU, configuraremos un grupo que contenga tipos de instancias con más CPU que memoria. Al final posiblemente tendremos algunos grupos distintos para ciertos tipos de aplicaciones. Uniendo las piezas: Cluster Auto Scaler Para que mi clúster pueda “hablar” con mi proveedor de nube (en este ejemplo, AWS), necesitamos un componente llamado Cluster Auto Scaler o CAS. Este componente fue creado por la comunidad que mantiene Kubernetes y está disponible aquí. A continuación, se puede ver una configuración CAS predeterminada, utilizando helm para la instalación: nameOverride: cluster-autoscaler awsRegion: us-east-1 autoDiscovery: clusterName: my-cluster image: repository: registry.k8s.io/autoscaling/cluster-autoscaler tag: v1.30.1 tolerations: - key: infra operator: Exists effect: NoSchedule nodeSelector: environment: "infra" rbac: create: true serviceAccount: name: cluster-autoscaler annotations: eks.amazonaws.com/role-arn: "role-aws" extraArgs: v: 1 stderrthreshold: info ¡Con esto configurado e instalado y nuestros grupos de escalamiento automático creados, acabamos de habilitar la administración automática de nuestros nodos! Por qué decidimos migrar a Karpenter Nuestro caso de uso aquí en Projuris es el siguiente: tenemos un clúster de desarrollo y un clúster de producción. Después de migrar a Gitlab SaaS, tuvimos el desafío de cómo aprovisionar ejecutores para ejecutar nuestras canalizaciones. Se decidió que utilizaríamos el clúster de desarrollo para aprovisionar estos ejecutores. En la “primera versión” elegimos el clúster de escalador automático porque era una configuración más simple y ya cumplía con nuestra configuración de producción. Pero luego empezamos a enfrentar algunos problemas con esta elección: Tiempo de aprovisionamiento: al iniciar un pipeline, el tiempo de aprovisionamiento de la máquina era un poco lento. El punto importante es que el clúster de escalador automático paga un “peaje” al proveedor de la nube por aprovisionar un nuevo nodo. Dificultad en la configuración de grupos: como tenemos algunos “perfiles” de pipeline, esta gestión se volvió un poco complicada, porque para cada nuevo perfil se debe crear un nuevo grupo de nodos. Costo: para mitigar el problema del inicio lento de un nuevo nodo, teníamos un perfil de máquina “en línea” que siempre estaba encendido, incluso sin ejecutar ningún pipeline. ¿Qué es Karpenter? Es una solución de cluster autoescalable creada por AWS, que promete el aprovisionamiento y consolidación de nodos siempre al menor coste posible. Es lo suficientemente inteligente como para saber que, por ejemplo, al comprar una máquina bajo demanda en AWS, dependiendo de la situación, es más rentable que si fuera una máquina spot. Y esa es sólo una de las características de esta herramienta. Karpenter también trabaja con la idea de “grupos” de máquinas (que en el mundo Karpenter llamamos NodePools), pero la diferencia es que esto lo hacemos a través de CRDs (custom resource translations) del propio Karpenter, es decir, tenemos manifiestos dentro de nuestro cluster con todas estas configuraciones, eliminando la necesidad de cualquier grupo de nodos creado en AWS. pool. ¿Cómo nos ayudó Karpenter a superar los desafíos presentados? Tiempo de aprovisionamiento: como Karpenter habla directamente con las API del proveedor de la nube, no es necesario pagar la tarifa del clúster del escalador automático. Tuvimos muchos problemas de tiempo de espera al aprovisionar nuevos nodos, después de cambiar a Karpenter este problema simplemente desapareció precisamente porque el aprovisionamiento es más eficiente. Dificultad para configurar grupos: con la solución NodePools y NodeClass de Karpenter esta configuración se volvió trivial y, lo más importante, versionada en nuestro control de versiones en Gitlab. En otras palabras, ¿necesita incluir un nuevo perfil de máquina en el NodePool? No hay problema, solo un envío y Karpenter lo considerará en las nuevas disposiciones. Costo: Pudimos utilizar máquinas, ya que los ejecutores con características similares ahora están asignados a nodos que soportan los requisitos de memoria y CPU requeridos. En otras palabras, en realidad estamos utilizando toda la potencia computacional que proporciona ese nodo. Esto también se aplica a la consolidación de nodos. Con el clúster de escalador automático había scripts complejos para drenar los nodos antes de la consolidación. Con Karpenter esto se configura en el NodePool de una manera muy simplificada. Un gran argumento para que la gerencia justifique invertir en este tipo de cambio es el costo. A continuación tenemos una comparación de costos usando Cluster AutoScaler y Karpenter en Enero/25, donde logramos un ahorro total de 16%: Figura 02: Periodo del 01/01 al 15/01 con ClusterAutoScaler Figura 03: Periodo del 16/01 al 31/01 con Karpenter Consideraciones finales La migración a Karpenter fue una decisión acertada. Hemos conseguido simplificar la gestión de nuestros nodos con diferentes perfiles de una forma muy simplificada. Todavía hay lugar para algunas mejoras, como usar un solo NodePool para simplificar las cosas aún más y permitir que los ejecutores configuren etiquetas específicas para el perfil de máquina que se debe aprovisionar para el ejecutor (más información en https://kubernetes.io/docs/reference/labels-annotations-taints/).