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).
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:
(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:
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:
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:
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:
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:
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:
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:
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:
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:
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.