Ahorre en costos de la nube de Kubernetes en AWS

La traducción del artículo se preparó la víspera del inicio del curso. "Plataforma de infraestructura basada en Kubernetes".

Ahorre en costos de la nube de Kubernetes en AWS

¿Cómo ahorrar en costos de la nube cuando se trabaja con Kubernetes? No existe una única solución adecuada, pero este artículo describe varias herramientas que pueden ayudarlo a administrar sus recursos de manera más efectiva y reducir sus costos de computación en la nube.

Escribí este artículo teniendo en mente Kubernetes para AWS, pero se aplicará (casi) exactamente de la misma manera a otros proveedores de nube. Supongo que sus clústeres ya tienen configurado el escalado automático (escalador automático de clúster). Eliminar recursos y reducir su implementación solo le permitirá ahorrar dinero si también reduce su flota de nodos trabajadores (instancias EC2).

Este artículo cubrirá:

Limpiar recursos no utilizados

Trabajar en un entorno de ritmo rápido es fantástico. Queremos organizaciones tecnológicas acelerado. Una entrega de software más rápida también significa más implementaciones de relaciones públicas, entornos de vista previa, prototipos y soluciones de análisis. Todo está implementado en Kubernetes. ¿Quién tiene tiempo para limpiar manualmente las implementaciones de prueba? Es fácil olvidarse de eliminar un experimento de una semana de antigüedad. La factura de la nube acabará subiendo por algo que olvidamos cerrar:

Ahorre en costos de la nube de Kubernetes en AWS

(Henning Jacobs:
Ziza:
(citas) Corey Quinn:
Mito: su cuenta de AWS depende de la cantidad de usuarios que tenga.
Hecho: Su puntuación de AWS es una función de la cantidad de ingenieros que tiene.

Ivan Kurnosov (en respuesta):
Hecho real: su puntuación de AWS es una función de la cantidad de cosas que olvidó deshabilitar/eliminar).

Conserje de Kubernetes (kube-janitor) ayuda a limpiar su clúster. La configuración del conserje es flexible para uso tanto global como local:

  • Las reglas de todo el clúster pueden definir el tiempo de vida máximo (TTL) para implementaciones de prueba/PR.
  • Los recursos individuales se pueden anotar con janitor/ttl, por ejemplo, para eliminar automáticamente el pico/prototipo después de 7 días.

Las reglas generales se definen en el archivo YAML. Su ruta se pasa a través del parámetro. --rules-file en kube-conserje. Aquí hay una regla de ejemplo para eliminar todos los espacios de nombres con -pr- en el nombre después de dos días:

- id: cleanup-resources-from-pull-requests
  resources:
    - namespaces
  jmespath: "contains(metadata.name, '-pr-')"
  ttl: 2d

El siguiente ejemplo regula el uso de la etiqueta de aplicación en los pods Deployment y StatefulSet para todos los nuevos Deployments/StatefulSets en 2020, pero al mismo tiempo permite la ejecución de pruebas sin esta etiqueta durante una semana:

- id: require-application-label
  # удалить deployments и statefulsets без метки "application"
  resources:
    - deployments
    - statefulsets
  # см. http://jmespath.org/specification.html
  jmespath: "!(spec.template.metadata.labels.application) && metadata.creationTimestamp > '2020-01-01'"
  ttl: 7d

Ejecute una demostración por tiempo limitado durante 30 minutos en un clúster que ejecuta kube-janitor:

kubectl run nginx-demo --image=nginx
kubectl annotate deploy nginx-demo janitor/ttl=30m

Otra fuente de aumento de costes son los volúmenes persistentes (AWS EBS). Eliminar un Kubernetes StatefulSet no elimina sus volúmenes persistentes (PVC - PersistentVolumeClaim). Los volúmenes de EBS no utilizados pueden generar fácilmente costos de cientos de dólares al mes. Kubernetes Janitor tiene una función para limpiar PVC no utilizados. Por ejemplo, esta regla eliminará todos los PVC que no estén montados por un módulo y a los que no haga referencia StatefulSet o CronJob:

# удалить все PVC, которые не смонтированы и на которые не ссылаются StatefulSets
- id: remove-unused-pvcs
  resources:
  - persistentvolumeclaims
  jmespath: "_context.pvc_is_not_mounted && _context.pvc_is_not_referenced"
  ttl: 24h

Kubernetes Janitor puede ayudarle a mantener limpio su clúster y evitar que los costos de computación en la nube se acumulen lentamente. Para obtener instrucciones de implementación y configuración, siga README kube-conserje.

Reducir la escala durante las horas no laborales

Por lo general, los sistemas de prueba y preparación solo deben funcionar durante el horario comercial. Algunas aplicaciones de producción, como las herramientas de administración/back office, también requieren disponibilidad limitada y pueden desactivarse de la noche a la mañana.

Reducción de escala de Kubernetes (kube-downscaler) permite a los usuarios y operadores reducir el sistema durante las horas no laborables. Las implementaciones y StatefulSets pueden escalar a cero réplicas. Es posible que se suspendan CronJobs. Kubernetes Downscaler está configurado para un clúster completo, uno o más espacios de nombres o recursos individuales. Puede configurar "tiempo de inactividad" o, por el contrario, "tiempo de trabajo". Por ejemplo, para reducir el escalado tanto como sea posible durante las noches y los fines de semana:

image: hjacobs/kube-downscaler:20.4.3
args:
  - --interval=30
  # не отключать компоненты инфраструктуры
  - --exclude-namespaces=kube-system,infra
  # не отключать kube-downscaler, а также оставить Postgres Operator, чтобы исключенными БД можно было управлять
  - --exclude-deployments=kube-downscaler,postgres-operator
  - --default-uptime=Mon-Fri 08:00-20:00 Europe/Berlin
  - --include-resources=deployments,statefulsets,stacks,cronjobs
  - --deployment-time-annotation=deployment-time

Aquí hay un gráfico para escalar los nodos trabajadores del clúster los fines de semana:

Ahorre en costos de la nube de Kubernetes en AWS

Reducir la escala de ~13 a 4 nodos trabajadores ciertamente marca una diferencia notable en su factura de AWS.

Pero, ¿qué pasa si necesito trabajar durante el "tiempo de inactividad" del clúster? Ciertas implementaciones se pueden excluir permanentemente del escalamiento agregando la anotación downscaler/exclude: true. Las implementaciones se pueden excluir temporalmente mediante la anotación de reducción de escala/exclusión hasta con una marca de tiempo absoluta en el formato AAAA-MM-DD HH:MM (UTC). Si es necesario, todo el clúster se puede reducir implementando un pod con la anotación downscaler/force-uptime, por ejemplo, ejecutando nginx en blanco:

kubectl run scale-up --image=nginx
kubectl annotate deploy scale-up janitor/ttl=1h # удалить развертывание через час
kubectl annotate pod $(kubectl get pod -l run=scale-up -o jsonpath="{.items[0].metadata.name}") downscaler/force-uptime=true

ver LÉAME kube-downscaler, si está interesado en instrucciones de implementación y opciones adicionales.

Usar escalado automático horizontal

Muchas aplicaciones/servicios se enfrentan a un patrón de carga dinámico: a veces sus módulos están inactivos y otras veces funcionan a plena capacidad. Operar una flota permanente de cápsulas para hacer frente a la carga máxima máxima no es económico. Kubernetes admite el escalado automático horizontal en un recurso HorizontalPodAutoscaler (HPA). El uso de CPU suele ser un buen indicador de escalamiento:

apiVersion: autoscaling/v2beta2
kind: HorizontalPodAutoscaler
metadata:
  name: my-app
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: my-app
  minReplicas: 3
  maxReplicas: 10
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        averageUtilization: 100
        type: Utilization

Zalando ha creado un componente para conectar fácilmente métricas personalizadas para escalar: Adaptador de métricas de Kube (kube-metrics-adapter) es un adaptador de métricas genérico para Kubernetes que puede recopilar y ofrecer métricas personalizadas y externas para el escalado automático horizontal de pods. Admite el escalado basado en métricas de Prometheus, colas SQS y otras configuraciones. Por ejemplo, para escalar su implementación a una métrica personalizada representada por la aplicación misma como JSON en /metrics use:

apiVersion: autoscaling/v2beta2
kind: HorizontalPodAutoscaler
metadata:
  name: myapp-hpa
  annotations:
    # metric-config.<metricType>.<metricName>.<collectorName>/<configKey>
    metric-config.pods.requests-per-second.json-path/json-key: "$.http_server.rps"
    metric-config.pods.requests-per-second.json-path/path: /metrics
    metric-config.pods.requests-per-second.json-path/port: "9090"
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: myapp
  minReplicas: 1
  maxReplicas: 10
  metrics:
  - type: Pods
    pods:
      metric:
        name: requests-per-second
      target:
        averageValue: 1k
        type: AverageValue

Configurar el escalado automático horizontal con HPA debería ser una de las acciones predeterminadas para mejorar la eficiencia de los servicios sin estado. Spotify tiene una presentación con su experiencia y recomendaciones para HPA: escale sus implementaciones, no su billetera.

Reducir la sobreventa de recursos

Las cargas de trabajo de Kubernetes determinan sus necesidades de CPU/memoria a través de "solicitudes de recursos". Los recursos de CPU se miden en núcleos virtuales o, más comúnmente, en “millcores”, por ejemplo, 500 m implica 50 % de vCPU. Los recursos de memoria se miden en bytes y se pueden utilizar sufijos comunes, como 500Mi, que significa 500 megabytes. Las solicitudes de recursos "bloquean" la capacidad en los nodos trabajadores, lo que significa que un pod con una solicitud de CPU de 1000 m en un nodo con 4 vCPU dejará solo 3 vCPU disponibles para otros pods. [ 1 ]

Slack (exceso de reserva) es la diferencia entre los recursos solicitados y el uso real. Por ejemplo, un pod que solicita 2 GiB de memoria pero solo usa 200 MiB tiene ~1,8 GiB de memoria "excedente". El exceso cuesta dinero. Se puede estimar aproximadamente que 1 GiB de memoria redundante cuesta ~$10 por mes. [ 2 ]

Informe de recursos de Kubernetes (kube-resource-report) muestra el exceso de reservas y puede ayudarle a determinar el potencial de ahorro:

Ahorre en costos de la nube de Kubernetes en AWS

Informe de recursos de Kubernetes muestra el exceso agregado por aplicación y comando. Esto le permite encontrar lugares donde se pueden reducir las demandas de recursos. El informe HTML generado solo proporciona una instantánea del uso de recursos. Debe observar el uso de CPU/memoria a lo largo del tiempo para determinar las solicitudes de recursos adecuadas. A continuación se muestra un gráfico de Grafana para un servicio "típico" con uso intensivo de CPU: todos los pods utilizan significativamente menos de los 3 núcleos de CPU solicitados:

Ahorre en costos de la nube de Kubernetes en AWS

Reducir la solicitud de CPU de 3000 ma ~400 m libera recursos para otras cargas de trabajo y permite que el clúster sea más pequeño.

"El uso promedio de CPU de las instancias EC2 a menudo se sitúa en el rango porcentual de un solo dígito". escribe Corey Quinn. Mientras que para EC2 estimar el tamaño correcto puede ser una mala decisiónCambiar algunas consultas de recursos de Kubernetes en un archivo YAML es fácil y puede generar grandes ahorros.

Pero, ¿realmente queremos que la gente cambie los valores en los archivos YAML? No, ¡las máquinas pueden hacerlo mucho mejor! Kubernetes Escalador automático vertical de pod (VPA) hace precisamente eso: adapta las solicitudes de recursos y las limitaciones según la carga de trabajo. Aquí hay un gráfico de ejemplo de solicitudes de CPU de Prometheus (línea azul delgada) adaptadas por VPA a lo largo del tiempo:

Ahorre en costos de la nube de Kubernetes en AWS

Zalando utiliza VPA en todos sus clusters para componentes de infraestructura. Las aplicaciones no críticas también pueden utilizar VPA.

Encerrada dorada de Fairwind es una herramienta que crea un VPA para cada implementación en un espacio de nombres y luego muestra una recomendación de VPA en su panel. Puede ayudar a los desarrolladores a configurar las solicitudes de CPU/memoria correctas para sus aplicaciones:

Ahorre en costos de la nube de Kubernetes en AWS

escribí un pequeño entrada de blog sobre VPA en 2019, y recientemente en La comunidad de usuarios finales de CNCF discutió el tema del VPA.

Uso de instancias puntuales EC2

Por último, pero no menos importante, los costos de AWS EC2 se pueden reducir utilizando instancias Spot como nodos trabajadores de Kubernetes. [ 3 ]. Las instancias spot están disponibles con un descuento de hasta el 90 % en comparación con los precios On-Demand. Ejecutar Kubernetes en EC2 Spot es una buena combinación: debe especificar varios tipos de instancias diferentes para una mayor disponibilidad, lo que significa que puede obtener un nodo más grande por el mismo precio o por un precio menor, y la capacidad aumentada puede ser utilizada por cargas de trabajo de Kubernetes en contenedores.

¿Cómo ejecutar Kubernetes en EC2 Spot? Hay varias opciones: usar un servicio de terceros como SpotInst (ahora llamado "Spot", no me preguntes por qué), o simplemente agregar un Spot AutoScalingGroup (ASG) a tu clúster. Por ejemplo, aquí hay un fragmento de CloudFormation para un ASG puntual "con capacidad optimizada" con múltiples tipos de instancias:

MySpotAutoScalingGroup:
 Properties:
   HealthCheckGracePeriod: 300
   HealthCheckType: EC2
   MixedInstancesPolicy:
     InstancesDistribution:
       OnDemandPercentageAboveBaseCapacity: 0
       SpotAllocationStrategy: capacity-optimized
     LaunchTemplate:
       LaunchTemplateSpecification:
         LaunchTemplateId: !Ref LaunchTemplate
         Version: !GetAtt LaunchTemplate.LatestVersionNumber
       Overrides:
         - InstanceType: "m4.2xlarge"
         - InstanceType: "m4.4xlarge"
         - InstanceType: "m5.2xlarge"
         - InstanceType: "m5.4xlarge"
         - InstanceType: "r4.2xlarge"
         - InstanceType: "r4.4xlarge"
   LaunchTemplate:
     LaunchTemplateId: !Ref LaunchTemplate
     Version: !GetAtt LaunchTemplate.LatestVersionNumber
   MinSize: 0
   MaxSize: 100
   Tags:
   - Key: k8s.io/cluster-autoscaler/node-template/label/aws.amazon.com/spot
     PropagateAtLaunch: true
     Value: "true"

Algunas notas sobre el uso de Spot con Kubernetes:

  • Debe manejar las terminaciones puntuales, por ejemplo, fusionando el nodo cuando se detiene la instancia.
  • Zalando utiliza tenedor Autoescalamiento oficial del clúster con prioridades del grupo de nodos.
  • Nodos puntuales puede ser forzado aceptar “registros” de cargas de trabajo para ejecutar en Spot

Resumen

Espero que algunas de las herramientas presentadas le resulten útiles para reducir su factura de la nube. Puede encontrar la mayor parte del contenido del artículo también en mi charla en DevOps Gathering 2019 en YouTube y en diapositivas.

¿Cuáles son sus mejores prácticas para ahorrar costos en la nube en Kubernetes? Por favor házmelo saber en Gorjeo (@try_except_).

[ 1 ] De hecho, quedarán utilizables menos de 3 vCPU ya que los recursos reservados del sistema reducen el rendimiento del nodo. Kubernetes distingue entre capacidad de nodo físico y recursos "aprovisionados" (Nodo asignable).

[ 2 ] Ejemplo de cálculo: una instancia m5.large con 8 GiB de memoria cuesta ~$84 ​​​​por mes (eu-central-1, On-Demand), es decir bloquear 1/8 de nodo cuesta aproximadamente ~$10/mes.

[ 3 ] Hay muchas más formas de reducir su factura EC2, como Instancias reservadas, Plan de ahorro, etc. No cubriré esos temas aquí, ¡pero definitivamente debería investigarlos!

Obtenga más información sobre el curso.

Fuente: habr.com

Añadir un comentario