diff --git "a/docs/source/pages/Kubernetes/Kubernetes - Otimiza\303\247\303\243o e Desempenho" "b/docs/source/pages/Kubernetes/Kubernetes - Otimiza\303\247\303\243o e Desempenho" new file mode 100644 index 0000000000000000000000000000000000000000..5a12c5889febc6b0e712802d0b04566d2afd9890 --- /dev/null +++ "b/docs/source/pages/Kubernetes/Kubernetes - Otimiza\303\247\303\243o e Desempenho" @@ -0,0 +1,401 @@ +# Otimização e Desempenho + +- [x] gerenciamento de memoria pra cada pod +- [ ] nao dar mt memoria pro superset pq so faz dashboard +- [ ] Mais memoria pro spark que vai processar dados +- [x] limitar memoria pros pods +- [ ] se o pod do spark comecar a consumir mais memoria e matar o processo do superset -> pq nao tem limite de memoria pro spark +- [ ] cpu -> + threads pra uns e menos pra outros + - [ ] ver se os valores default são suficientes + +--- + +- Competição por recursos entre pods pode causar instabilidade e baixo desempenho. +- **Solução:** Definir limites e solicitações para garantir uso eficiente e evitar contenção. +- Evita que pods não estejam desperdiçando recursos + +--- + +### **Problemas de Desempenho no Kubernetes** + +- **Alocação de Recursos:** Uma das principais causas de problemas de desempenho no Kubernetes. Se seus contêineres não tiverem CPU, memória ou outros recursos suficientes para executar suas tarefas, eles podem apresentar lentidão ou falhas. Da mesma forma, a superalocação de recursos pode levar ao desperdÃcio e à utilização ineficiente. O scheduler do Kubernetes gerencia seus recursos baseado nas requisições e limites que foram configurados. Se vc tem uma situação onde um dos seus nós está com poucos recursos e vc não configurou nenhuma requisição no container, o kubernetes vai procurar qual a quantidade de memoria por ex, que vc requisitou quanto vc esta usando e os containers e pods que tem o maior gap (diferença) entre o que vc requisitoiu e o que vc está usando, eles são os que tem a maior possibilidade de serem mortos para liberar capacidade em um nó, que está sem capacidade. Então em um ambiente “não saudável†em que vc nao seta requests e limits, então o kubernetes pode acabar matando conteiners importantes para liberar espaço para outros. +- **Agendamento de Pods:** O Kubernetes usa um scheduler para distribuir pods entre os nós. Em casos de alta carga no cluster ou falta de recursos suficientes, os pods podem não ser agendados, resultando em degradação de desempenho. Isso pode ocorrer se os nós estiverem operando em capacidade máxima ou se as regras de **afinidade** e **anti-afinidade** para posicionamento dos pods não forem configuradas corretamente. +- **Solicitações/Restrições de Recursos Excessivas:** Configurar incorretamente as solicitações e limites de recursos para os contêineres pode causar problemas. Configurar limites muito baixos pode gerar gargalos de desempenho, enquanto configurá-los muito altos pode causar contenção de recursos. +- **Configuração Incorreta do Autoscaler Horizontal de Pods (HPA):** Se o HPA não estiver configurado corretamente, ele pode não escalar o número de réplicas conforme necessário, resultando em problemas de desempenho durante picos de tráfego. + +### **Resolvendo Problemas de Desempenho no Kubernetes** + +- **Monitoramento:** Implemente monitoramento abrangente do cluster, pods, nós e aplicações para identificar gargalos de desempenho e anomalias. +- **Gerenciamento de Recursos:** Aloque recursos adequados (CPU, memória, etc.) para os pods com base em suas necessidades e considere o uso de ferramentas como o Horizontal Pod Autoscaler (HPA) para escalar automaticamente o número de réplicas conforme a demanda. +- **Imagens de Contêiner Eficientes:** Otimize as imagens de contêiner para reduzir seu tamanho e evite dependências desnecessárias. +- **Manutenção Regular:** Mantenha o cluster Kubernetes e seus componentes atualizados para aproveitar as melhorias e correções de bugs mais recentes. +- **Testes de Carga:** Realize testes de carga para validar o desempenho e a escalabilidade de suas aplicações em diferentes condições. + +## Estratégias para Otimizar Recursos no Kubernetes + +### CPU + +- **Defina limites e solicitações de recursos apropriados para seus pods**: Ao configurar limites e solicitações de recursos, você garante que seus pods usem apenas os recursos de CPU necessários, evitando contenção de recursos. +- **Use o escalonamento horizontal de pods (HPA)** para ajustar automaticamente o número de réplicas dos seus pods com base no uso da CPU. Isso ajuda a garantir que seus pods tenham os recursos necessários para atender à s demandas da carga de trabalho. +- **Priorize pods importantes com pod priority e preemption**: Isso assegura que os pods mais crÃticos tenham os recursos necessários para funcionar corretamente, mesmo que outros estejam consumindo muitos recursos. +- **Monitore o uso de CPU dos seus pods e nodes** para identificar possÃveis gargalos ou contenção de recursos. Ferramentas como o painel do Kubernetes e o comando `kubectl top` são úteis para monitorar o uso de recursos. +- **Utilize afinidade de nodes, taints e tolerations** para garantir que os pods sejam agendados em nodes com recursos de CPU suficientes. Isso ajuda a evitar contenção de recursos e garante que seus pods funcionem corretamente. + +### Memória + +- **Defina limites e solicitações de recursos apropriados para seus pods**: Isso garante que os pods usem apenas os recursos de memória necessários, evitando contenção de recursos. +- **Use o escalonamento horizontal de pods (HPA)** para ajustar automaticamente o número de réplicas dos seus pods com base no uso de memória. +- **Monitore o uso de memória dos seus pods** utilizando ferramentas como o painel do Kubernetes e o comando `kubectl top`, que são úteis para acompanhar o consumo de recursos. +- **Utilize afinidade de nodes, taints e tolerations** para garantir que os pods sejam agendados em nodes com recursos de memória suficientes. + +## Agendamento de Pods + +- O scheduler do Kubernetes ([kube-scheduler](https://kubernetes.io/docs/concepts/scheduling-eviction/scheduler-perf-tuning/)) seleciona um nó em um cluster para colocar o Pod +- Cada nó tem capacidade máxima de CPU e memória para Pods +- O scheduler garante que a soma das solicitações de recursos seja menor que a capacidade do nó +- Ele recusa colocar um Pod se a verificação de capacidade falhar + +## Técnicas Avançadas para Otimização de Recursos + +### Gerenciando Recursos do Kubernets ([1](https://granulate.io/blog/managing-kubernetes-resources-cpu-memory/), [2](https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/)) + +O campo **limits** no manifesto do pod define os recursos máximos que podem ser usados pelo contêiner + +O campo **requests** define os recursos mÃnimos garantidos que serão reservados para ele. + +```jsx +apiVersion: v1 +kind: Pod +metadata: + name: my-pod +spec: + containers: + name: my-container + image: my_image + resources: + limits: + cpu: "1" + memory: "500Mi" + requests: + cpu: "500m" + memory: "100Mi" +``` + +→ Os valores de CPU podem ser especificados em milicores ou frações de CPU (millicpu) + +→ Os valores de memória podem ser especificados em bytes (mebibytes / megabytes) + +### Use as Quotas de Recursos no NÃvel do Namespace: + +As Quotas de Recursos permitem gerenciar o consumo geral de recursos por namespace, garantindo que uma única equipe ou projeto não monopolize os recursos do cluster. + +```jsx +apiVersion: v1 +kind: ResourceQuota +metadata: + name: example-quota + namespace: example-namespace +spec: + hard: + requests.cpu: "1" + requests.memory: 1Gi + limits.cpu: "2" + limits.memory: 2Gi + pods: "10" +``` + +Esta **ResourceQuota** limita a quantidade total de memória e CPU que todos os pods podem solicitar e o máximo que podem consumir dentro do **example-namespace**. + +## Autoscalers + +Sabemos que os requests e limits são cruciais para melhorar a performance, mas como podemos saber os valores ótimos? Para isso usamos **HPA** e **VPA**. + + + + + +## Horizontal Pod Autoscaler (HPA) + +O HPA dimensiona automaticamente o número de réplicas de pods com base na utilização observada de CPU/memória ou métricas personalizadas, garantindo que a aplicação possa lidar com cargas variáveis. + +Adiciona pods ao ambiente, baseado na demanda, permite o paralelismo. + +```jsx +apiVersion: autoscaling/v2beta2 +kind: HorizontalPodAutoscaler +metadata: + name: myapp-hpa +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: myapp + minReplicas: 1 + maxReplicas: 10 + metrics: + - type: Resource + resource: + name: cpu + target: + type: Utilization + averageUtilization: 50 +``` + +## Vertical Pod Autoscaler (VPA) + +Ajusta automaticamente as solicitações e limites de recursos dos pods com base em seu uso. + +Escalar um pod individualmente. Adcionar mais CPU ou RAM para ele. + +### Aproveitar os Modos de Recomendação + +O que é: Os modos de recomendação do Vertical Pod Autoscaler (VPA) determinam como as recomendações do VPA para solicitações e limites de recursos dos pods são aplicadas. Os modos são `Off`, `Initial`, `Recreate` e `Auto`, oferecendo flexibilidade desde apenas sugerir mudanças até aplicá-las automaticamente e reiniciar pods conforme necessário. + +Como usar: Para ajustar dinamicamente os modos do VPA, você pode implementar um controlador ou script Kubernetes que monitora o desempenho da aplicação e ajusta o modo do VPA de acordo. Abaixo está um exemplo conceitual de como você pode ajustar os modos do VPA com base em métricas de desempenho da aplicação: + +```jsx +apiVersion: autoscaling.k8s.io/v1 +kind: VerticalPodAutoscaler +metadata: + name: my-app-vpa +spec: + targetRef: + apiVersion: "apps/v1" + kind: Deployment + name: my-app + updatePolicy: + updateMode: "Auto" +``` + +Quando usar: O ajuste dos modos VPA é particularmente útil durante diferentes estágios do ciclo de vida de uma aplicação. Por exemplo, use o modo `Initial` durante os estágios iniciais da implantação para uma abordagem conservadora, e mude para `Auto` em aplicações maduras onde há maior confiança nas recomendações do VPA. + +Melhores práticas: Comece com uma abordagem conservadora (`Off` ou `Initial`) e gradualmente mude para modos mais agressivos (`Recreate` ou `Auto`) conforme você ganha confiança nas recomendações do VPA. Monitore o desempenho da aplicação atentamente após cada mudança de modo. + +Armadilhas comuns: Mudar muito rapidamente para um modo agressivo como `Auto` pode levar a reinicializações frequentes de pods, afetando a estabilidade da aplicação. Garanta testes completos antes de alterar os modos em ambientes de produção. + +## Cluster Autoscaler + +Adicionar ou remover nós do cluster baseados na demanda. + +## Node e Pod Affinity/Anti-Affinity + +Controla o posicionamento dos pods nos nós para otimizar a utilização de recursos e o desempenho. + +Adapta a aplicação para aproveitar de forma eficiente os recursos de hardware necessários ao seu funcionamento. + +### **Node affinity** + +Node affinity is conceptually similar to `nodeSelector`, allowing you to constrain which nodes your Pod can be scheduled on based on node labels. There are two types of node affinity: + +- `requiredDuringSchedulingIgnoredDuringExecution`: The scheduler can't schedule the Pod unless the rule is met. This functions like `nodeSelector`, but with a more expressive syntax. +- `preferredDuringSchedulingIgnoredDuringExecution`: The scheduler tries to find a node that meets the rule. If a matching node is not available, the scheduler still schedules the Pod. + +### PodAffinity + +Pode ser usado para especificar que pods que se comunicam ou compartilham recursos rodem no mesmo nó. + +```jsx +apiVersion: v1 +kind: Pod +metadata: + name: myapp-pod +spec: + affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: processorType + operator: In + values: + - GPU + podAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: security + operator: In + values: + - S1 + topologyKey: topology.kubernetes.io/zone + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - weight: 100 + podAffinityTerm: + labelSelector: + matchExpressions: + - key: security + operator: In + values: + - S2 + topologyKey: topology.kubernetes.io/zone +``` + +The node affinity rule specifies that this particular pod will only run on nodes that have the GPU label. + +The pod affinity rule specifies that the scheduler is allowed to place the example Pod on a node only if that node belongs to a specific [zone](https://kubernetes.io/docs/concepts/scheduling-eviction/topology-spread-constraints/) where other Pods have been labeled with `security=S1`. + +The pod anti-affinity rule specifies that the scheduler should try to avoid scheduling the Pod on a node if that node belongs to a specific [zone](https://kubernetes.io/docs/concepts/scheduling-eviction/topology-spread-constraints/) where other Pods have been labeled with `security=S2`. + +## Otimização de Armazenamento + +Use soluções e configurações de armazenamento apropriadas para garantir alto desempenho para aplicações com estado. + +```jsx +apiVersion: storage.k8s.io/v1 +kind: StorageClass +metadata: + name: fast-storage +provisioner: kubernetes.io/aws-ebs +parameters: + type: io1 + iopsPerGB: "10" + fsType: ext4 +``` + +## Monitoramento e Análise de Desempenho + +Colete e analise métricas de desempenho para identificar gargalos e otimizar o desempenho. Ferramentas como Prometheus e Grafana são comumente utilizadas para monitorar clusters Kubernetes. + +```jsx +apiVersion: v1 +kind: ConfigMap +metadata: + name: prometheus-config + namespace: monitoring +data: + prometheus.yml: | + global: + scrape_interval: 15s + scrape_configs: + - job_name: 'kubernetes' + kubernetes_sd_configs: + - role: node + - job_name: 'kubernetes-pods' + kubernetes_sd_configs: + - role: pod +``` + +## Verificar & Inspecionar + +Utilize `kubectl get pods`, `kubectl describe pods` e ferramentas de monitoramento para verificar e inspecionar a configuração de ajuste e otimização de desempenho. + +## **BenefÃcios da Otimização em Kubernetes:** + +- **Uso Eficiente de Recursos:** Garante que os recursos sejam utilizados de forma eficiente, reduzindo custos e melhorando o desempenho. +- **Escalabilidade:** Ajusta automaticamente as aplicações para lidar com cargas variáveis. +- **Alto Desempenho:** Otimiza o desempenho das aplicações e do cluster Kubernetes. +- **Monitoramento Proativo:** Identifica e resolve problemas de desempenho antes que afetem os usuários. + +## Minio com storage dinâmico do Ceph + +**Dynamic provisioning** é um recurso do Kubernetes que permite que volumes de armazenamento sejam criados automaticamente sob demanda, em vez de serem predefinidos manualmente. + +O storage dinâmico é usado para integrar o Ceph como backend de armazenamento para MinIO em ambientes Kubernetes. + +### Como funciona: + +1. **Configuração do Ceph como StorageClass**: + - Um **StorageClass** é definido no Kubernetes para o Ceph, usando provisionadores como **RBD** (RADOS Block Device) ou **CephFS**. + - Ele especifica as propriedades do armazenamento, como replicação, tamanho do volume e tipo de acesso. +2. **Criação de PVCs (PersistentVolumeClaims)**: + - As aplicações, incluindo MinIO, solicitam armazenamento criando PVCs. + - O provisionador dinâmico do Ceph cria automaticamente PersistentVolumes (PVs) com base nesses PVCs. +3. **Uso em MinIO**: + - O MinIO é implantado como um serviço no Kubernetes, utilizando os volumes provisionados dinamicamente pelo Ceph para armazenar os dados de objetos. + +kubectl delete deployment utility-api + +## Apresentação + +Não dar mt memoria pro superset pq so faz dashboard + +Mais memoria pro spark que vai processar dados + +E se o pod do spark comecar a consumir mais memoria e matar o processo do superset + +Uma vez que nao tem limite de memoria pro spark + +### REQ + +- Mostra arquivo `resources-demo-pod.yaml` , o carregamento, primeiro requisição dps limite +- REQ: cpu=1 , mem=14Gi +- `kubectl get nodes` +- `kubectl describe node local-cluster` +- Allocatable = 12Gb e 8 CPU +- mas pedimos 14, não deveria ser alocado a nenhum nó, vamos tentar +- `kubectl apply -f resource-management/resources-demo-pod.yaml` +- `kubectl get pods` +- status pending +- troca pra 2Gi +- `kubectl delete -f resource-management/resources-demo-pod.yaml` +- `kubectl apply -f resource-management/resources-demo-pod.yaml` +- `kubectl get pods -o wide` +- `kubectl delete -f resource-management/resources-demo-pod.yaml` + +### LIMITS + +- Esse pod pode usar quanta memória ele quiser, mas se tiver outros pods rodando na CPU, eles serão impactados por esse uso ilimitado +- mostra que da pra configurar limite tb +- SÓ MOSTRA NAO FAZ NADA +- LIM: cpu=1 , mem=3Gi +- muda a carga pra 4Gi +- Out of Memory Killed +- se o pod usa mais que o limite, ele é reiniciado + +### RESOURCE QUOTA + +- mostra arquivo +- `kubectl apply -f resource-management/resource-quota-demo.yaml` +- funciona pro namespace q esse resource-quota sera criado + - o maximo q pode pedir é o limite do resourcequota +- `kubectl apply -f resource-management/resources-demo-pod.yaml` +- não deu pq pediu mais que o maximo +- `kubectl delete resourcequota resource-quota` +- `kubectl delete pod resources-demo` +- Dps coloca 100Mi no memoria do pod + +### HPA + +- api utility pra gerar carregamento na cpu +- deployment tem 2 replicas +- service acessa a api +- `hpa.yaml` tem min=1 e max=5 replicas +- significa que vai escalar para um max de 5 replicas quando o uso da CPU atingir 70% +- `cd autoscaling` +- `kubectl apply -f deployment.yaml` +- `kubectl apply -f service.yaml` +- `kubectl apply -f hpa.yaml` +- `kubectl get pods` +- tem 4 replicas, o uso está acima de 70% +- se tiver menos manda um `kubectl get hpa` +- `kubectl describe hpa` + +### VPA + +- `kubectl apply -f vpa.yaml` +- `kubectl get vpa utility-api` +- `kubectl describe vpa utility-api` +- lower = estimativa minima de recursos pro container +- upper = maximo +- == requests e limits +- essa é a recomendação + +### Cluster Autoscaler + +Não da pra mostrar no minikube + +### BenefÃcios + +- **Uso Eficiente de Recursos**, reduzindo custos e melhorando o desempenho +- **Escalabilidade**, para lidar com cargas variáveis +- **Alto** **Desempenho**, otimizando as aplicações e do cluster +- **Monitoramento Proativo**, resolve problemas antes de afetar a aplicação + +### Affinity + +**afinidade de nós**: em quais nós o Pod pode ser agendado com base em rótulos dos nós. + +**afinidade de pod**: especificar que pods que se comunicam ou compartilham recursos rodem no mesmo nó. Só em um nó que participa de uma zona onde os pods foram nomeados S1 + +Adapta a aplicação para aproveitar de forma eficiente os recursos de hardware necessários ao seu funcionamento. \ No newline at end of file