Aforra nos custos da nube de Kubernetes en AWS

A tradución do artigo preparouse na véspera do comezo do curso "Plataforma de infraestrutura baseada en Kubernetes".

Aforra nos custos da nube de Kubernetes en AWS

Como aforrar custos na nube ao traballar con Kubernetes? Non hai unha única solución correcta, pero este artigo describe varias ferramentas que poden axudarche a xestionar os teus recursos de forma máis eficaz e reducir os custos de computación na nube.

Escribín este artigo pensando en Kubernetes para AWS, pero aplicarase (case) exactamente do mesmo xeito a outros provedores de nube. Supoño que os teus clústeres xa teñen configurado o escalado automático (cluster-autoscaler). Eliminar recursos e reducir a súa implantación só che aforrará diñeiro se tamén reduce a túa flota de nodos de traballo (instancias EC2).

Este artigo cubrirá:

  • limpar recursos non utilizados (kube-conserxe)
  • Reducir a escala durante as horas non laborables (Kube-downscaler)
  • usando autoescalado horizontal (HPA),
  • redución da reserva excesiva de recursos (informe-recurso-kube, VPA)
  • usando instancias Spot

Limpeza dos recursos non utilizados

Traballar nun ambiente de ritmo rápido é xenial. Queremos organizacións tecnolóxicas acelerado. A entrega de software máis rápida tamén supón máis implementacións de relacións públicas, contornas de vista previa, prototipos e solucións de análise. Todo está despregado en Kubernetes. Quen ten tempo para limpar manualmente as implementacións de proba? É fácil esquecerse de eliminar un experimento dunha semana. A factura da nube acabará aumentando debido a algo que esquecemos pechar:

Aforra nos custos da nube de Kubernetes en AWS

(Henning Jacobs:
Zhiza:
(citas) Corey Quinn:
Mito: a túa conta de AWS é unha función do número de usuarios que tes.
Feito: a túa puntuación de AWS é unha función do número de enxeñeiros que tes.

Ivan Kurnosov (en resposta):
Feito real: a súa puntuación de AWS é unha función do número de cousas que esqueceu desactivar/eliminar.)

Conserxeiro de Kubernetes (kube-janitor) axuda a limpar o seu clúster. A configuración do conserxe é flexible para uso global e local:

  • As regras de todo o clúster poden definir o tempo máximo de vida (TTL) para as implementacións de PR/proba.
  • Os recursos individuais pódense anotar con janitor/ttl, por exemplo, para eliminar automaticamente o pico/prototipo despois de 7 días.

As regras xerais defínense no ficheiro YAML. O seu camiño pasa polo parámetro --rules-file en kube-conserxe. Aquí tes un exemplo de regra para eliminar todos os espazos de nomes -pr- no nome despois de dous días:

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

O seguinte exemplo regula o uso da etiqueta da aplicación nos módulos Deployment e StatefulSet para todas as novas implementacións/StatefulSets en 2020, pero ao mesmo tempo permite a execución de probas sen esta etiqueta durante unha 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

Executa unha demostración por tempo limitado durante 30 minutos nun clúster que executa kube-janitor:

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

Outra fonte de aumento dos custos son os volumes persistentes (AWS EBS). A eliminación dun StatefulSet de Kubernetes non elimina os seus volumes persistentes (PVC - PersistentVolumeClaim). Os volumes de EBS non utilizados poden provocar facilmente custos de centos de dólares ao mes. Kubernetes Janitor ten unha función para limpar os PVC non utilizados. Por exemplo, esta regra eliminará todos os PVC que non estean montados por un módulo e que non sexan referenciados por StatefulSet ou CronJob:

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

Kubernetes Janitor pode axudarche a manter limpo o teu clúster e evitar que os custos de computación na nube se acumulen lentamente. Para obter instrucións de implantación e configuración, siga LERME kube-janitor.

Reducir a escala durante as horas non laborables

Normalmente, os sistemas de proba e probas son necesarios para funcionar só durante o horario laboral. Algunhas aplicacións de produción, como as ferramentas de administración/back office, tamén requiren unha dispoñibilidade limitada e poden desactivarse durante a noite.

Kubernetes Downscaler (kube-downscaler) permite aos usuarios e operadores reducir o sistema durante as horas non laborables. As implementacións e os StatefulSets poden escalar a cero réplicas. CronJobs pode ser suspendido. Kubernetes Downscaler está configurado para un clúster completo, un ou máis espazos de nomes ou recursos individuais. Podes configurar o "tempo de inactividade" ou, pola contra, o "tempo de traballo". Por exemplo, para reducir a escala na medida do posible durante as noites e as fins 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í tes un gráfico para escalar os nodos de traballo do clúster os fins de semana:

Aforra nos custos da nube de Kubernetes en AWS

A redución de ~ 13 a 4 nodos de traballo certamente fai unha diferenza notable na súa factura de AWS.

Pero e se teño que traballar durante o "tempo de inactividade" do clúster? Algunhas implantacións poden excluírse permanentemente da escala engadindo a anotación reductora/excluír: verdadeira. Os despregamentos pódense excluír temporalmente mediante a anotación de redución/exclusión ata cunha marca de tempo absoluta no formato AAAA-MM-DD HH:MM (UTC). Se é necesario, pódese reducir a escala de todo o clúster despregando un pod coa anotación downscaler/force-uptime, por exemplo, iniciando nginx blank:

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 README kube-downscaler, se estás interesado en instrucións de implantación e opcións adicionais.

Use a escala automática horizontal

Moitas aplicacións/servizos tratan cun patrón de carga dinámico: ás veces os seus módulos están inactivos e ás veces funcionan a plena capacidade. Operar unha flota permanente de vainas para facer fronte á máxima carga non é económico. Kubernetes admite a escala automática horizontal nun recurso HorizontalPodAutoscaler (HPA). O uso da CPU adoita ser un bo indicador para escalar:

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 creou un compoñente para conectar facilmente métricas personalizadas para escalar: Adaptador de métricas de Kube (kube-metrics-adapter) é un adaptador de métricas xenéricas para Kubernetes que pode recoller e ofrecer métricas personalizadas e externas para a escala automática horizontal dos pods. Admite a escala baseada nas métricas de Prometheus, filas SQS e outras configuracións. Por exemplo, para escalar a súa implementación a unha métrica personalizada representada pola propia aplicación 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

A configuración da escala automática horizontal con HPA debería ser unha das accións predeterminadas para mellorar a eficiencia dos servizos sen estado. Spotify ten unha presentación coa súa experiencia e recomendacións para HPA: escala as túas implementacións, non a túa carteira.

Reducir o exceso de reserva de recursos

As cargas de traballo de Kubernetes determinan as súas necesidades de CPU/memoria a través de "solicitudes de recursos". Os recursos da CPU mídense en núcleos virtuais ou máis comúnmente en "millicores", por exemplo, 500m implica un 50% de vCPU. Os recursos de memoria mídense en bytes e pódense usar sufixos comúns, como 500Mi, que significa 500 megabytes. As solicitudes de recursos "bloquean" a capacidade dos nodos de traballo, o que significa que un pod cunha solicitude de CPU de 1000 m nun nodo con 4 vCPU deixará só 3 vCPU dispoñibles para outros pods. [1]

Slack (exceso de reserva) é a diferenza entre os recursos solicitados e o uso real. Por exemplo, un pod que solicita 2 GiB de memoria pero só usa 200 MiB ten ~1,8 GiB de "exceso" de memoria. O exceso custa diñeiro. Pódese estimar aproximadamente que 1 GiB de memoria redundante custa ~ $ 10 ao mes. [2]

Informe de recursos de Kubernetes (kube-resource-report) mostra o exceso de reservas e pode axudarche a determinar o potencial de aforro:

Aforra nos custos da nube de Kubernetes en AWS

Informe de recursos de Kubernetes mostra o exceso agregado por aplicación e comando. Isto permítelle atopar lugares onde se poidan reducir as demandas de recursos. O informe HTML xerado só ofrece unha instantánea do uso dos recursos. Debería ver o uso da CPU/memoria ao longo do tempo para determinar as solicitudes de recursos adecuadas. Aquí tes un gráfico de Grafana para un servizo "típico" de CPU pesada: todos os pods están a usar significativamente menos que os 3 núcleos de CPU solicitados:

Aforra nos custos da nube de Kubernetes en AWS

Reducir a solicitude da CPU de 3000m a ~400m libera recursos para outras cargas de traballo e permite que o clúster sexa máis pequeno.

"O uso medio da CPU das instancias EC2 adoita estar no intervalo porcentual dun só díxito", escribe Corey Quinn. Mentres que para EC2 estimar o tamaño correcto pode ser unha mala decisiónCambiar algunhas consultas de recursos de Kubernetes nun ficheiro YAML é sinxelo e pode supoñer un gran aforro.

Pero realmente queremos que a xente cambie os valores nos ficheiros YAML? Non, as máquinas poden facelo moito mellor! Kubernetes Escalador automático de pod vertical (VPA) fai precisamente iso: adapta as solicitudes de recursos e as restricións segundo a carga de traballo. Aquí tes un gráfico de exemplo de solicitudes de CPU Prometheus (liña azul fina) adaptadas polo VPA ao longo do tempo:

Aforra nos custos da nube de Kubernetes en AWS

Zalando usa VPA en todos os seus clusters para compoñentes de infraestrutura. As aplicacións non críticas tamén poden usar VPA.

Goldilocks de Fairwind é unha ferramenta que crea un VPA para cada implantación nun espazo de nomes e despois mostra unha recomendación de VPA no seu panel. Pode axudar aos desenvolvedores a configurar as solicitudes de CPU/memoria correctas para as súas aplicacións:

Aforra nos custos da nube de Kubernetes en AWS

Escribín un pequeno publicación de blog sobre VPA en 2019, e recentemente en A comunidade de usuarios finais de CNCF discutiu o problema do VPA.

Usando instancias EC2 Spot

Por último, pero non menos importante, os custos de AWS EC2 pódense reducir usando instancias Spot como nodos de traballo de Kubernetes [3]. As instancias puntuales están dispoñibles cun desconto de ata o 90 % en comparación cos prezos baixo demanda. Executar Kubernetes en EC2 Spot é unha boa combinación: cómpre especificar varios tipos de instancias diferentes para unha maior dispoñibilidade, o que significa que podes obter un nodo máis grande polo mesmo prezo ou por un prezo inferior, e a capacidade aumentada pode ser utilizada por cargas de traballo de Kubernetes en contedores.

Como executar Kubernetes en EC2 Spot? Hai varias opcións: usar un servizo de terceiros como SpotInst (agora chamado "Spot", non me preguntes por que) ou simplemente engadir un Spot AutoScalingGroup (ASG) ao teu clúster. Por exemplo, aquí tes un fragmento de CloudFormation para un Spot ASG "optimizado para a capacidade" con varios 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"

Algunhas notas sobre o uso de Spot con Kubernetes:

  • Debe xestionar as terminacións Spot, por exemplo, fusionando o nodo cando se detén a instancia
  • Zalando usa garfo escalado automático do clúster oficial con prioridades do grupo de nodos
  • Spot nodos pode ser forzado aceptar "rexistros" de cargas de traballo para executarse en Spot

Resumo

Espero que consideres útiles algunhas das ferramentas presentadas para reducir a túa factura na nube. Tamén podes atopar a maioría dos contidos do artigo en a miña charla en DevOps Gathering 2019 en YouTube e en diapositivas.

Cales son as túas mellores prácticas para aforrar custos na nube en Kubernetes? Por favor, avisame en Twitter (@try_except_).

[1] De feito, permanecerán utilizables menos de 3 vCPU xa que o rendemento do nodo se reduce polos recursos reservados do sistema. Kubernetes distingue entre a capacidade do nodo físico e os recursos "aprovisionados" (Nodo asignable).

[2] Exemplo de cálculo: unha instancia m5.grande con 8 GiB de memoria é de ~ $ 84 ao mes (eu-central-1, On-Demand), é dicir. bloquear o nodo 1/8 é de aproximadamente $10 ao mes.

[3] Hai moitas máis formas de reducir a túa factura EC2, como instancias reservadas, plan de aforro, etc. Non cubrirei eses temas aquí, pero definitivamente deberías analizalos.

Máis información sobre o curso.

Fonte: www.habr.com

Engadir un comentario