<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Willian César</title>
    <description>The latest articles on Forem by Willian César (@willianccs).</description>
    <link>https://forem.com/willianccs</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F604517%2F346b342d-6ad7-4e4f-88e1-0479dc905292.jpeg</url>
      <title>Forem: Willian César</title>
      <link>https://forem.com/willianccs</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/willianccs"/>
    <language>en</language>
    <item>
      <title>Escalando aplicações automaticamente no Kubernetes usando KEDA</title>
      <dc:creator>Willian César</dc:creator>
      <pubDate>Wed, 23 Jun 2021 13:18:01 +0000</pubDate>
      <link>https://forem.com/willianccs/escalando-aplicacoes-automaticamente-no-kubernetes-usando-keda-c41</link>
      <guid>https://forem.com/willianccs/escalando-aplicacoes-automaticamente-no-kubernetes-usando-keda-c41</guid>
      <description>&lt;p&gt;Para quem ainda não conhece o &lt;a href="https://keda.sh/" rel="noopener noreferrer"&gt;KEDA (Kubernetes Event-Driven Autoscaling)&lt;/a&gt;, é:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Um componente leve e de finalidade única que pode ser adicionado a qualquer cluster do Kubernetes. Funciona junto com componentes Kubernetes padrão, como o Horizontal Pod Autoscaler (HPA) e pode estender a funcionalidade sem sobrescrever ou duplicação.&lt;br&gt;
Retirado da documentação oficial&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Foi lançado no fim de 2019 &lt;a href="https://cloudblogs.microsoft.com/opensource/2019/11/19/keda-1-0-release-kubernetes-based-event-driven-autoscaling/" rel="noopener noreferrer"&gt;(anúncio oficial)&lt;/a&gt; e é fruto de uma parceria entre Microsoft &amp;amp; Red Hat.&lt;/p&gt;

&lt;p&gt;E ele cumpre bem o lema, que é: &lt;strong&gt;“Application autoscaling made simple”&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Nativamente o Kubernetes só permite configurar &lt;a href="https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/" rel="noopener noreferrer"&gt;HPA&lt;/a&gt; com as métricas de CPU e memória.&lt;br&gt;
Se quiser escalar as aplicações utilizando outro tipo de métrica, por exemplo, lags de eventos ou filas, você precisa primeiro criar um adaptador de métricas (custom metrics) para extrair as métricas da fonte desejada. Entretanto se  precisar obter métricas de várias fontes usando vários adaptadores, você está sem sorte porque apenas um por vez é compatível (a menos que tenha mudado recentemente).&lt;/p&gt;

&lt;p&gt;Já o KEDA extrai de uma &lt;a href="https://keda.sh/docs/2.3/scalers/" rel="noopener noreferrer"&gt;variedade de fontes&lt;/a&gt; e dimensiona automaticamente suas implantações de &lt;code&gt;0&lt;/code&gt; a &lt;code&gt;N-instâncias&lt;/code&gt; com base em sua configuração no ScaledObject.&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsav8cxq4lajkb3tfo7bk.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsav8cxq4lajkb3tfo7bk.jpg" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Outro ponto interessante é que o KEDA não “reinventa a roda” e não construiu seu próprio mecanismo de escalonamento, se aproveitando de HPAs do Kubernetes e dos secrets (&lt;strong&gt;TriggerAuthentication&lt;/strong&gt;) já usados pelas aplicações.&lt;/p&gt;
&lt;h2&gt;
  
  
  INSTALANDO O KEDA
&lt;/h2&gt;

&lt;p&gt;As instruções para implantar o KEDA são muito simples e podem ser encontradas &lt;a href="https://keda.sh/docs/2.3/deploy/" rel="noopener noreferrer"&gt;aqui&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Existem três maneiras de implantar KEDA em seu cluster Kubernetes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Helm charts&lt;/li&gt;
&lt;li&gt;Operator Hub&lt;/li&gt;
&lt;li&gt;Implantar YAMLs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Vamos usar a primeira opção.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;helm repo add kedacore https://kedacore.github.io/charts
helm repo update

kubectl create ns keda
helm install keda kedacore/keda --namespace keda
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Após a instalação teremos 2 deployments (KEDA Operator e KEDA Metrics API) rodando no cluster…&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kubectl get deployment -n keda
NAME                              READY   UP-TO-DATE   AVAILABLE   AGE
keda-operator                     1/1     1            1           1h
keda-operator-metrics-apiserver   1/1     1            1           1h
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;e mais alguns CRDs disponíveis:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kubectl api-resources --api-group=keda.sh
NAME                     SHORTNAMES       APIGROUP   NAMESPACED   KIND
scaledjobs               sj               keda.sh    true         ScaledJob
scaledobjects            so               keda.sh    true         ScaledObject
triggerauthentications   ta,triggerauth   keda.sh    true         TriggerAuthentication
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;ScaledJobs*/ScaledObject&lt;/strong&gt;: Os ScaledJobs/ScaledObjects mapeiam uma fonte de evento para a jobs/deployments que você deseja dimensionar.&lt;br&gt;
&lt;strong&gt;TriggerAuthentication&lt;/strong&gt;: Se necessário, este recurso contém a configuração de autenticação necessária para monitorar a origem do evento.&lt;/p&gt;

&lt;p&gt;O "ScaledObject" também cria o HPA para você.&lt;/p&gt;

&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;O KEDA não apenas dimensiona deployments, mas também pode dimensionar seus jobs do Kubernetes. Em vez de ter muitos eventos processados ​​em sua implantação e aumentar ou diminuir com base no número de mensagens que precisam ser consumidas, o KEDA pode ativar um trabalho para cada mensagem na origem do evento.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;h2&gt;
  
  
  EXEMPLO COM KAFKA
&lt;/h2&gt;

&lt;p&gt;Vamos dar uma olhada mais de perto no &lt;a href="https://keda.sh/docs/2.3/concepts/scaling-deployments/" rel="noopener noreferrer"&gt;ScaledObject&lt;/a&gt; e &lt;a href="https://keda.sh/docs/2.3/scalers/apache-kafka/" rel="noopener noreferrer"&gt;Kafka trigger&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
  name: kafka-consumer-scaler
  labels:
    deploymentName: my-kafka-consumer-service
  namespace: sample
spec:
  scaleTargetRef:
    deploymentName: my-kafka-consumer-service
  pollingInterval: 1        # Optional. Default: 30 seconds
  cooldownPeriod:  30       # Optional. Default: 300 seconds
  minReplicaCount: 0        # Optional. Default: 0
  maxReplicaCount: 10   # Optional. Default: 100
  triggers:
    - type: kafka
      metadata:
        topic: test-topic-1
        # brokerList: my-cluster-kafka-bootstrap.kafka:9092 - deprecated
        bootstrapServers: my-cluster-kafka-bootstrap.kafka:9092    
        consumerGroup: my-kafka-consumerGroup
        lagThreshold: '5'       # Default: 10
        offsetResetPolicy: latest
        allowIdleConsumers: false
      authenticationRef:
        name: keda-trigger-auth-kafka-credential
    ## Optional: list of topics to trigger
    #- type: kafka
    #   metadata:
    #     topic: test-topic-2
    #     bootstrapServers: my-cluster-kafka-bootstrap.kafka:9092    
    #     consumerGroup: my-kafka-consumerGroup
    #     lagThreshold: '5'     # Default: 10
    #     offsetResetPolicy: latest
    #     allowIdleConsumers: false
    #   authenticationRef:
    #     name: keda-trigger-auth-kafka-credential
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;O ScaledObject, TriggerAuthentication e a implantação referenciada em deploymentName precisam estar no mesmo namespace.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;Apesar de serem valores opcionais, é importante definir valores dentro dos padrões para seu negócio nos parâmetros &lt;code&gt;minReplicaCount&lt;/code&gt; e &lt;code&gt;maxReplicaCount&lt;/code&gt;. Para evitar rebalanceamento de partições no Kafka E/OU evitar que muitos pods sejam iniciados - consumindo todos os recursos do cluster 💥.&lt;/li&gt;
&lt;li&gt;O parâmetro &lt;code&gt;offsetResetPolicy&lt;/code&gt; pode ser earliest ou latest. Como o KEDA vai percorrer todos os tópicos, vale a pena entender como o código (negócio) se comporta com duplicidade de eventos. &lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Por padrão, o número de réplicas não excederá o número de partições em um tópico. Ou seja, se maxReplicaCount for definido mais do que o número de partições, o escalonador não vai atingir o valor definido. Caso queira mudar este comportamento, ajuste o parâmetro &lt;code&gt;allowIdleConsumers&lt;/code&gt; para &lt;code&gt;true&lt;/code&gt;. Porém, se houver mais número de consumidores do que número de partições em um tópico, o consumidor extra terá que ficar ocioso.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Para facilitar criamos um usuário no Kafka com permissão de somente leitura (&lt;code&gt;list&lt;/code&gt; e &lt;code&gt;describe&lt;/code&gt;) em todos os grupos e tópicos e referenciamos no TriggerAuthentication o &lt;strong&gt;secret&lt;/strong&gt; com este usuário:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;apiVersion: keda.sh/v1alpha1
kind: TriggerAuthentication
metadata:
  name: keda-trigger-auth-kafka-credential
  namespace: sample
spec:
  secretTargetRef:
  - key: sasl
    name: keda-credentials
    parameter: sasl
  - key: username
    name: keda-credentials
    parameter: username
  - key: password
    name: keda-credentials
    parameter: password
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  REFERÊNCIAS:
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://keda.sh/docs/2.3/" rel="noopener noreferrer"&gt;https://keda.sh/docs/2.3/&lt;/a&gt;&lt;br&gt;
&lt;a href="https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/" rel="noopener noreferrer"&gt;https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/&lt;/a&gt;&lt;br&gt;
&lt;a href="https://cloudblogs.microsoft.com/opensource/2020/04/06/kubernetes-event-driven-autoscaling-keda-cncf-sandbox-project/" rel="noopener noreferrer"&gt;https://cloudblogs.microsoft.com/opensource/2020/04/06/kubernetes-event-driven-autoscaling-keda-cncf-sandbox-project/&lt;/a&gt;&lt;br&gt;
&lt;a href="https://keda.sh/resources/" rel="noopener noreferrer"&gt;https://keda.sh/resources/&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  AGRADECIMENTOS
&lt;/h2&gt;

&lt;p&gt;Obrigado à &lt;a href="https://twitter.com/lipekis/status/1407064351010398208?s=20" rel="noopener noreferrer"&gt;todos os envolvidos&lt;/a&gt; que me incentivaram a escrever este artigo e revisaram o texto:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Felipe Lamarão Silva (@lipekis)&lt;/li&gt;
&lt;li&gt;Willian Itiho (@Willian_Itiho)&lt;/li&gt;
&lt;li&gt;Rafael Gomes (&lt;a class="mentioned-user" href="https://dev.to/gomex"&gt;@gomex&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>kubernetes</category>
      <category>keda</category>
    </item>
  </channel>
</rss>
