Configurar o Elastic Stack no GKE


Neste tutorial, mostramos como executar o Elastic Stack no GKE usando o operador do Elastic Cloud no Kubernetes (ECK, na sigla em inglês).

O Elastic Stack é uma solução de código aberto conhecida usada para gerar registros, monitorar e analisar dados em tempo real. Ao usar o Elastic Stack no GKE, você aproveita a escalonabilidade e a confiabilidade fornecidas pelo GKE Autopilot e os recursos avançados do Elastic Stack.

Este tutorial é destinado a administradores do Kubernetes ou engenheiros de confiabilidade do site.

Objetivos

  • Criar um cluster do GKE.
  • Implantar o operador de ECK.
  • Configurar clusters do Elasticsearch e Kibana usando o operador ECK
  • Implantar um Elastic Stack completo usando o operador de ECK.
  • Escalonamento automático de clusters do Elasticsearch e upgrade da implantação do Elastic Stack.
  • Usar o Elastic Stack para monitorar ambientes do Kubernetes.

Custos

Neste documento, você vai usar os seguintes componentes faturáveis do Google Cloud:

Para gerar uma estimativa de custo baseada na projeção de uso deste tutorial, use a calculadora de preços.

Novos usuários do Google Cloud podem estar qualificados para uma avaliação gratuita.

Ao concluir as tarefas descritas neste documento, é possível evitar o faturamento contínuo excluindo os recursos criados. Saiba mais em Limpeza.

Antes de começar

  1. Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
  2. Install the Google Cloud CLI.

  3. Se você estiver usando um provedor de identidade externo (IdP), primeiro faça login na CLI gcloud com sua identidade federada.

  4. Para inicializar a CLI gcloud, execute o seguinte comando:

    gcloud init
  5. Create or select a Google Cloud project.

    • Create a Google Cloud project:

      gcloud projects create PROJECT_ID

      Replace PROJECT_ID with a name for the Google Cloud project you are creating.

    • Select the Google Cloud project that you created:

      gcloud config set project PROJECT_ID

      Replace PROJECT_ID with your Google Cloud project name.

  6. Verify that billing is enabled for your Google Cloud project.

  7. Enable the GKE API:

    gcloud services enable container.googleapis.com
  8. Install the Google Cloud CLI.

  9. Se você estiver usando um provedor de identidade externo (IdP), primeiro faça login na CLI gcloud com sua identidade federada.

  10. Para inicializar a CLI gcloud, execute o seguinte comando:

    gcloud init
  11. Create or select a Google Cloud project.

    • Create a Google Cloud project:

      gcloud projects create PROJECT_ID

      Replace PROJECT_ID with a name for the Google Cloud project you are creating.

    • Select the Google Cloud project that you created:

      gcloud config set project PROJECT_ID

      Replace PROJECT_ID with your Google Cloud project name.

  12. Verify that billing is enabled for your Google Cloud project.

  13. Enable the GKE API:

    gcloud services enable container.googleapis.com
  14. Grant roles to your user account. Run the following command once for each of the following IAM roles: roles/container.clusterAdmin

    gcloud projects add-iam-policy-binding PROJECT_ID --member="user:USER_IDENTIFIER" --role=ROLE

    Replace the following:

    • PROJECT_ID: your project ID.
    • USER_IDENTIFIER: the identifier for your user account—for example, myemail@example.com.
    • ROLE: the IAM role that you grant to your user account.
    • Você precisa ser o proprietário de um nome de domínio. O nome do domínio não pode ter mais de 63 caracteres. É preciso usar o Cloud Domains ou outro registrador.

    Prepare o ambiente

    Neste tutorial, você vai usar o Cloud Shell para gerenciar recursos hospedados no Google Cloud. O Cloud Shell vem pré-instalado com o software necessário para este tutorial, incluindo o kubectl, o Helm e a gcloud CLI.

    Para configurar o ambiente com o Cloud Shell, siga estas etapas:

    1. Inicie uma sessão do Cloud Shell no console Google Cloud clicando em Ícone de ativação do Cloud Shell Ativar o Cloud Shell no consoleGoogle Cloud . Isso inicia uma sessão no painel inferior do console Google Cloud .

    2. Adicione e atualize um repositório de gráficos do Helm:

      helm repo add elastic https://helm.elastic.co
      helm repo update
      
    3. Clone o repositório do GitHub:

      git clone https://github.com/GoogleCloudPlatform/kubernetes-engine-samples.git
      
    4. Mude para o diretório de trabalho:

      cd kubernetes-engine-samples/observability/elastic-stack-tutorial
      

    Criar um cluster do GKE

    Crie um cluster do GKE com a coleta de métricas do plano de controle ativada:

    gcloud container clusters create-auto elk-stack \
        --location="us-central1" \
        --monitoring="SYSTEM,WORKLOAD,API_SERVER,SCHEDULER,CONTROLLER_MANAGER"
    

    Implantar o operador de ECK

    O Elastic Cloud on Kubernetes (ECK) é uma plataforma para implantar e gerenciar clusters do Elastic Stack em Kubernetes.

    O ECK automatiza a implantação e o gerenciamento de clusters do Elastic Stack, simplificando o processo de configuração e manutenção do Elastic Stack no Kubernetes. Ele fornece um conjunto de recursos personalizados do Kubernetes que pode ser usado para criar e configurar o Elasticsearch, o Kibana, o Servidor de Gerenciamento do desempenho de aplicativos e outros componentes do Elastic Stack no Kubernetes. Isso permite que desenvolvedores e equipes de DevOps configurem e gerenciem clusters do Elastic Stack em escala.

    O ECK oferece suporte a vários nós do Elasticsearch, failover automático de aplicativos, upgrades contínuos e criptografia SSL. O ECK também inclui recursos que permitem monitorar e solucionar problemas de desempenho do Elasticsearch.

    1. Instalar o gráfico do Helm do ECK:

      helm upgrade --install "elastic-operator" "elastic/eck-operator" \
          --version="2.8.0" \
          --create-namespace \
          --namespace="elastic-system" \
          --set="resources.limits.cpu=250m" \
          --set="resources.limits.memory=512Mi" \
          --set="resources.limits.ephemeral-storage=1Gi" \
          --set="resources.requests.cpu=250m" \
          --set="resources.requests.memory=512Mi" \
          --set="resources.requests.ephemeral-storage=1Gi"
      
    2. Aguarde o operador estar pronto:

      watch kubectl get pods -n elastic-system
      

      O resultado será assim:

      NAME                 READY   STATUS    RESTARTS   AGE
      elastic-operator-0   1/1     Running   0          31s    
      

      Quando o operador STATUS for Running, retorne à linha de comando pressionando Ctrl+C.

    Configurar o Elastic Stack com ECK

    Ao usar o Elastic Stack com Elasticsearch, Kibana e Elastic Agent trabalhando no modo Fleet, é possível configurar uma solução poderosa, escalonável e totalmente gerenciada para gerenciar e visualizar dados usando o Kibana.

    O Kibana é uma ferramenta de análise e visualização de dados de código aberto que permite pesquisar, analisar e visualizar dados no Elasticsearch.

    O Elastic Agent é um remetente de dados leve que coleta dados de diferentes fontes, como registros ou métricas, e os envia automaticamente para o Elasticsearch.

    Elastic Fleet é um modo de operação em que os agentes do Elastic se reportam a um servidor de frota central que cuida da configuração e do gerenciamento. O servidor da frota simplifica a implantação, a configuração e o escalonamento de agentes do Elastic, facilitando o gerenciamento de implantações grandes e complexas.

    O escalonamento automático do Elasticsearch é um recurso de automonitoramento que pode informar quando mais recursos são necessários com base em uma política definida pelo operador. Por exemplo, uma política pode especificar que um determinado nível precisa ser escalonado com base no espaço disponível em disco. O Elasticsearch pode monitorar o espaço em disco e sugerir escalonamento se prever uma escassez, embora ainda cabe ao operador adicionar os recursos necessários. Para mais informações sobre o escalonamento automático do Elasticsearch, consulte Escalonamento automático na documentação do Elasticsearch.

    Configurar um cluster do Elasticsearch

    O Elasticsearch fornece um mecanismo de pesquisa e análise RESTful distribuído e projetado para armazenar e pesquisar grandes volumes de dados de maneira rápida e eficiente.

    Ao implantar o Elastic Stack no Kubernetes, você precisa gerenciar as configurações de VM, especificamente o vm.max_map_count setting, que é exigido pelo Elasticsearch. vm.max_map_count especifica o número de áreas de memória que um processo pode alocar a um arquivo. O Elasticsearch precisa ter esse valor definido como pelo menos 262144 para ser executado de maneira ideal. Para mais informações, consulte Memória virtual na documentação do ECK.

    1. Analise o seguinte manifesto:

      apiVersion: scheduling.k8s.io/v1
      kind: PriorityClass
      metadata:
        name: user-daemonset-priority
      value: 999999999
      preemptionPolicy: PreemptLowerPriority
      globalDefault: false
      description: "User DaemonSet priority"

      Esse manifesto descreve um DaemonSet que define a configuração do kernel diretamente no host. Um DaemonSet é um controlador do Kubernetes que garante que uma cópia de um pod seja executada em cada nó de um cluster.

      O manifesto anterior está em uma lista de permissões para ser executado no Autopilot. Não modifique esse manifesto, incluindo as imagens do contêiner.

    2. Aplique este manifesto ao cluster:

      kubectl apply -f max-map-count-setter-ds.yaml
      
    3. Analise o seguinte manifesto:

      apiVersion: elasticsearch.k8s.elastic.co/v1
      kind: Elasticsearch
      metadata:
        name: elasticsearch
        namespace: elastic-system
      spec:
        version: "8.9.0"
        volumeClaimDeletePolicy: DeleteOnScaledownOnly
        podDisruptionBudget:
          spec:
            minAvailable: 2
            selector:
              matchLabels:
                elasticsearch.k8s.elastic.co/cluster-name: elasticsearch
        nodeSets:
          - name: default
            config:
              node.roles: ["master", "data", "ingest", "ml", "remote_cluster_client"]
            podTemplate:
              metadata:
                labels:
                  app.kubernetes.io/name: elasticsearch
                  app.kubernetes.io/version: "8.9.0"
                  app.kubernetes.io/component: "elasticsearch"
                  app.kubernetes.io/part-of: "elk"
              spec:
                nodeSelector:
                  cloud.google.com/compute-class: "Balanced"
                initContainers:
                  - name: max-map-count-check
                    command:
                      - sh
                      - -c
                      - while true; do mmc=$(cat /proc/sys/vm/max_map_count); if test ${mmc} -eq 262144; then exit 0; fi; sleep 1; done
                    resources:
                      requests:
                        cpu: 10m
                        memory: 16Mi
                        ephemeral-storage: 16Mi
                      limits:
                        cpu: 10m
                        memory: 16Mi
                        ephemeral-storage: 16Mi
                containers:
                  - name: elasticsearch
                    resources:
                      requests:
                        cpu: 990m
                        memory: 4080Mi
                        ephemeral-storage: 1008Mi
                      limits:
                        cpu: 1000m
                        memory: 4080Mi
                        ephemeral-storage: 1008Mi
                    env:
                      - name: ES_JAVA_OPTS
                        value: "-Xms2g -Xmx2g"
            count: 3
            volumeClaimTemplates:
              - metadata:
                  name: elasticsearch-data # Do not change this name unless you set up a volume mount for the data path.
                spec:
                  accessModes:
                    - ReadWriteOnce
                  resources:
                    requests:
                      storage: 2Gi
                  storageClassName: standard-rwo

      Esse manifesto define um cluster do Elasticsearch com os seguintes campos:

      • initContainers: aguarda a mudança das configurações do kernel do host de memória virtual.
      • podDisruptionBudget: especifica que o cluster não será destruído durante o processo de desfragmentação dos pods.
      • config.node.roles: configuração de papéis do nó do Elasticsearch. Para mais informações sobre papéis de nó, consulte na documentação do Elasticsearch.
    4. Aplique este manifesto ao cluster:

      kubectl apply -f elasticsearch.yaml
      
    5. Aguarde até que o cluster do Elasticsearch esteja pronto:

      watch kubectl --namespace elastic-system get elasticsearches.elasticsearch.k8s.elastic.co
      

      O resultado será assim:

      NAME            HEALTH   NODES   VERSION   PHASE   AGE
      elasticsearch   green    3       8.8.0     Ready   5m3s
      

      Quando o cluster do Elasticsearch HEALTH for green e PHASE for Ready, retorne à linha de comando pressionando Ctrl+C.

    Configurar o Kibana

    1. Analise o seguinte manifesto:

      apiVersion: kibana.k8s.elastic.co/v1
      kind: Kibana
      metadata:
        name: kibana
        namespace: elastic-system
      spec:
        version: "8.9.0"
        count: 1
        elasticsearchRef:
          name: elasticsearch
          namespace: elastic-system
        http:
          tls:
            selfSignedCertificate:
              disabled: true
        config:
          server.publicBaseUrl: https://elk.BASE_DOMAIN
          xpack.reporting.kibanaServer.port: 5601
          xpack.reporting.kibanaServer.protocol: http
          xpack.reporting.kibanaServer.hostname: kibana-kb-http.elastic-system.svc
          xpack.fleet.agents.elasticsearch.hosts: ["https://elasticsearch-es-http.elastic-system.svc:9200"]
          xpack.fleet.agents.fleet_server.hosts: ["https://fleet-server-agent-http.elastic-system.svc:8220"]
          xpack.fleet.packages:
          - name: system
            version: latest
          - name: elastic_agent
            version: latest
          - name: fleet_server
            version: latest
          - name: kubernetes
            version: latest
          xpack.fleet.agentPolicies:
          - name: Fleet Server on ECK policy
            id: eck-fleet-server
            namespace: default
            monitoring_enabled:
            - logs
            - metrics
            unenroll_timeout: 900
            package_policies:
            - name: fleet_server-1
              id: fleet_server-1
              package:
                name: fleet_server
          - name: Elastic Agent on ECK policy
            id: eck-agent
            namespace: default
            monitoring_enabled:
            - logs
            - metrics
            unenroll_timeout: 900
            package_policies:
            - package:
                name: system
              name: system-1
            - package:
                name: kubernetes
              name: kubernetes-1
        podTemplate:
          metadata:
            labels:
              app.kubernetes.io/name: kibana
              app.kubernetes.io/version: "8.9.0"
              app.kubernetes.io/component: "ui"
              app.kubernetes.io/part-of: "elk"
          spec:
            containers:
            - name: kibana
              resources:
                requests:
                  memory: 1Gi
                  cpu: 500m
                  ephemeral-storage: 1Gi
                limits:
                  memory: 1Gi
                  cpu: 500m
                  ephemeral-storage: 1Gi

      Neste manifesto, é descrito um recurso personalizado do Kibana que configura políticas de agente para o servidor da frota e os agentes.

    2. Aplique este manifesto ao cluster:

      kubectl apply -f kibana.yaml
      
    3. Aguarde até que os pods estejam prontos:

      watch kubectl --namespace elastic-system get kibanas.kibana.k8s.elastic.co
      

      O resultado será assim:

      NAME     HEALTH   NODES   VERSION   AGE
      kibana   green    1       8.8.0     6m47s
      

      Quando o HEALTH do pods for green, retorne à linha de comando pressionando Ctrl+C.

    Configurar um balanceador de carga para acessar o Kibana

    Para acessar o Kibana, crie um objeto Entrada do Kubernetes, um certificado gerenciado pelo Google, um endereço IP global e uma zona DNS.

    1. Crie um endereço IP externo global:

      gcloud compute addresses create "elastic-stack" --global
      
    2. Crie uma zona gerenciada e um conjunto de registros no Cloud DNS:

      gcloud dns managed-zones create "elk" \
          --description="DNS Zone for Airflow" \
          --dns-name="elk.BASE_DOMAIN" \
          --visibility="public"
      
      gcloud dns record-sets create "elk.BASE_DOMAIN" \
          --rrdatas="$(gcloud compute addresses describe "elastic-stack" --global --format="value(address)")" \
          --ttl="300" \
          --type="A" \
          --zone="elk"
      
    3. Delegar a zona de DNS como um subdomínio do domínio base criando um conjunto de registros NS com uma lista de servidores de nomes. Confira uma lista de servidores de nomes usando o seguinte comando:

      gcloud dns record-sets describe elk.BASE_DOMAIN \
          --type="NS" \
          --zone="elk" \
          --format="value(DATA)"
      
    4. Analise o seguinte manifesto:

      apiVersion: networking.gke.io/v1
      kind: ManagedCertificate
      metadata:
        name: elastic-stack
        namespace: elastic-system
      spec:
        domains:
          - elk.BASE_DOMAIN

      Nesse manifesto, é descrito um ManagedCertificate que provisiona um certificado SSL para estabelecer a conexão TLS.

    5. Aplique o manifesto ao cluster:

      kubectl apply -f ingress.yaml
      

    Configurar agentes Elastic

    1. Analise o seguinte manifesto:

      apiVersion: agent.k8s.elastic.co/v1alpha1
      kind: Agent
      metadata:
        name: fleet-server
        namespace: elastic-system
      spec:
        version: 8.9.0
        kibanaRef:
          name: kibana
          namespace: elastic-system
        elasticsearchRefs:
          - name: elasticsearch
            namespace: elastic-system
        mode: fleet
        fleetServerEnabled: true
        policyID: eck-fleet-server
        deployment:
          replicas: 1
          podTemplate:
            metadata:
              labels:
                app.kubernetes.io/name: fleet-server
                app.kubernetes.io/version: "8.9.0"
                app.kubernetes.io/component: "agent"
                app.kubernetes.io/part-of: "elk"
            spec:
              containers:
                - name: agent
                  resources:
                    requests:
                      memory: 512Mi
                      cpu: 250m
                      ephemeral-storage: 10Gi
                    limits:
                      memory: 512Mi
                      cpu: 250m
                      ephemeral-storage: 10Gi
              volumes:
                - name: "agent-data"
                  ephemeral:
                    volumeClaimTemplate:
                      spec:
                        accessModes: ["ReadWriteOnce"]
                        storageClassName: "standard-rwo"
                        resources:
                          requests:
                            storage: 10Gi
              serviceAccountName: fleet-server
              automountServiceAccountToken: true
              securityContext:
                runAsUser: 0

      Este manifesto descreve um agente Elastic que configura um servidor de frota com o ECK.

    2. Aplique este manifesto ao cluster:

      kubectl apply -f fleet-server-and-agents.yaml
      
    3. Aguarde até que os pods estejam prontos:

      watch kubectl --namespace elastic-system get agents.agent.k8s.elastic.co
      

      O resultado será assim:

      NAME            HEALTH   AVAILABLE   EXPECTED   VERSION   AGE
      elastic-agent   green    5           5          8.8.0     14m
      fleet-server    green    1           1          8.8.0     16m
      

      Quando o HEALTH do pods for green, retorne à linha de comando pressionando Ctrl+C.

    Configurar a geração de registros e o monitoramento

    O Elastic Stack pode usar o exportador kube-state-metrics para coletar métricas no nível do cluster.

    1. Instalar kube-state-metrics:

      helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
      helm repo update
      helm install kube-state-metrics prometheus-community/kube-state-metrics --namespace elastic-system
      
    2. Consiga as credenciais de usuário padrão do elastic do Kibana:

      kubectl get secret elasticsearch-es-elastic-user -o yaml -n elastic-system -o jsonpath='{.data.elastic}' | base64 -d
      
    3. Abra https://elk.BASE_DOMAIN no navegador e faça login no Kibana com as credenciais.

    4. No menu, selecione Analytics e, em seguida, Painéis.

    5. No campo de texto de pesquisa, digite Visão geral do Kubernetes e selecione Painel de visão geral para ver as métricas básicas.

      Alguns dos painéis podem não mostrar dados ou mensagens de erro porque o GKE limita o acesso a alguns dos endpoints do plano de controle que Kibana usa para conseguir métricas de cluster.

    Limpar

    Para evitar cobranças na sua conta do Google Cloud pelos recursos usados no tutorial, exclua o projeto que os contém ou mantenha o projeto e exclua os recursos individuais.

    Excluir o projeto

      Delete a Google Cloud project:

      gcloud projects delete PROJECT_ID

    Excluir recursos individuais

    Se você usou um projeto existente e não quer excluí-lo, exclua os recursos individuais.

    1. Exclua os componentes do Elastic Stack, o operador ECK e o kube-state-metrics:

      kubectl --namespace elastic-system delete ingresses.networking.k8s.io elastic-stack
      kubectl --namespace elastic-system delete managedcertificates.networking.gke.io elastic-stack
      kubectl --namespace elastic-system delete frontendconfigs.networking.gke.io elastic-stack
      kubectl --namespace elastic-system delete agents.agent.k8s.elastic.co elastic-agent
      kubectl --namespace elastic-system delete agents.agent.k8s.elastic.co fleet-server
      kubectl --namespace elastic-system delete kibanas.kibana.k8s.elastic.co kibana
      kubectl --namespace elastic-system delete elasticsearches.elasticsearch.k8s.elastic.co elasticsearch
      kubectl --namespace elastic-system delete daemonsets.apps max-map-count-setter
      kubectl --namespace elastic-system delete pvc --selector='elasticsearch.k8s.elastic.co/cluster-name=elasticsearch'
      helm --namespace elastic-system uninstall kube-state-metrics
      helm --namespace elastic-system uninstall elastic-operator
      
    2. Exclua o conjunto de registros DNS, o endereço IP, a zona gerenciada DNS e o cluster do GKE:

      gcloud dns record-sets delete "elk.BASE_DOMAIN" \
          --type="A" \
          --zone="elk" \
          --quiet
      
      gcloud compute addresses delete "elastic-stack" \
          --global \
          --quiet
      
      gcloud dns managed-zones delete "elk" --quiet
      
      gcloud container clusters delete "elk-stack" \
          --location="us-central1" \
          --quiet
      

    A seguir