Configure o Elastic Stack no GKE

Este tutorial mostra como executar o Elastic Stack no GKE usando o operador Elastic Cloud on Kubernetes (ECK).

O Elastic Stack é uma solução de código aberto popular usada para registar, monitorizar e analisar dados em tempo real. Ao usar o Elastic Stack no GKE, pode beneficiar da escalabilidade e da fiabilidade fornecidas pelo GKE Autopilot e das poderosas funcionalidades do Elastic Stack.

Este tutorial destina-se a administradores do Kubernetes ou engenheiros de fiabilidade do site.

Prepare o ambiente

Neste tutorial, vai usar o Cloud Shell para gerir recursos alojados no Google Cloud. O Cloud Shell está pré-instalado com o software necessário para este tutorial, incluindo kubectl, Helm e a CLI gcloud.

Para configurar o seu ambiente com o Cloud Shell, siga estes passos:

  1. Inicie uma sessão do Cloud Shell a partir da Google Cloud consola, clicando em Ícone de ativação do Cloud Shell Ativar Cloud Shell na Google Cloud consola. Esta ação inicia uma sessão no painel inferior da Google Cloud consola.

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

    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
    

Crie um cluster do GKE

Crie um cluster do GKE com a recolha de métricas do plano de controlo ativada:

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

Implemente o operador ECK

O Elastic Cloud on Kubernetes (ECK) é uma plataforma para implementar e gerir o Elastic Stack em clusters do Kubernetes.

O ECK automatiza a implementação e a gestão de clusters do Elastic Stack, simplificando o processo de configuração e manutenção do Elastic Stack no Kubernetes. Fornece um conjunto de recursos personalizados do Kubernetes que pode usar para criar e configurar o Elasticsearch, o Kibana, o Application Performance Management Server e outros componentes do Elastic Stack no Kubernetes. Isto permite que os programadores e as equipas de DevOps configurem e façam a gestão de clusters do Elastic Stack em grande escala.

O ECK suporta vários nós do Elasticsearch, comutação por falha automática de aplicações, atualizações perfeitas e encriptação SSL. O ECK também inclui funcionalidades que lhe permitem monitorizar e resolver problemas de desempenho do Elasticsearch.

  1. Instale o gráfico 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 até que o operador esteja pronto:

    watch kubectl get pods -n elastic-system
    

    O resultado é semelhante ao seguinte:

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

    Quando o operador STATUS é Running, regresse à linha de comandos premindo Ctrl+C.

Configure o Elastic Stack com o ECK

Ao usar o Elastic Stack com o Elasticsearch, o Kibana e o Elastic Agent a funcionar no modo Fleet, pode configurar uma solução poderosa, escalável e totalmente gerida para gerir e visualizar dados através do Kibana.

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

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

A frota elástica é um modo de funcionamento em que os agentes elásticos comunicam com um servidor de frota central, que processa a respetiva configuração e gestão. O servidor de frota simplifica a implementação, a configuração e o dimensionamento de agentes elásticos, o que facilita a gestão de implementações grandes e complexas.

A escala automática do Elasticsearch é uma funcionalidade de monitorização automática que pode comunicar quando são necessários recursos adicionais com base numa política definida pelo operador. Por exemplo, uma política pode especificar que um determinado nível deve ser dimensionado com base no espaço em disco disponível. O Elasticsearch pode monitorizar o espaço em disco e sugerir o escalamento se prever uma escassez, embora seja ainda da responsabilidade do operador adicionar os recursos necessários. Para mais informações sobre o ajuste de escala automático do Elasticsearch, consulte o artigo Ajuste de escala automático na documentação do Elasticsearch.

Configure um cluster do Elasticsearch

O Elasticsearch oferece um motor de pesquisa e análise distribuído e RESTful concebido para armazenar e pesquisar grandes volumes de dados de forma rápida e eficiente.

Quando implementar o Elastic Stack no Kubernetes, deve gerir as definições de VM, especificamente o vm.max_map_count setting, que é necessário para o Elasticsearch. vm.max_map_count especifica o número de áreas de memória que um processo pode atribuir a um ficheiro. O Elasticsearch tem de ter este valor definido como, pelo menos, 262144 para ser executado de forma ideal. Para mais informações, consulte o artigo Memória virtual na documentação do ECK.

  1. Reveja o seguinte manifesto:

    # Copyright 2023 Google LLC
    #
    # Licensed under the Apache License, Version 2.0 (the "License");
    # you may not use this file except in compliance with the License.
    # You may obtain a copy of the License at
    #
    #      https://www.apache.org/licenses/LICENSE-2.0
    #
    # Unless required by applicable law or agreed to in writing, software
    # distributed under the License is distributed on an "AS IS" BASIS,
    # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    # See the License for the specific language governing permissions and
    # limitations under the License.
    
    apiVersion: scheduling.k8s.io/v1
    kind: PriorityClass
    metadata:
      name: user-daemonset-priority
    value: 999999999
    preemptionPolicy: PreemptLowerPriority
    globalDefault: false
    description: "User DaemonSet priority"
    ---
    apiVersion: apps/v1
    kind: DaemonSet
    metadata:
      name: max-map-count-setter
      namespace: elastic-system
      labels:
        k8s-app: max-map-count-setter
    spec:
      selector:
        matchLabels:
          name: max-map-count-setter
      template:
        metadata:
          labels:
            name: max-map-count-setter
        spec:
          priorityClassName: user-daemonset-priority
          nodeSelector:
            cloud.google.com/compute-class: "Balanced"
          initContainers:
            - name: max-map-count-setter
              image: docker.io/bash:5.2.15
              resources:
                requests:
                  cpu: 10m
                  memory: 10Mi
                  ephemeral-storage: 10Mi
                limits:
                  cpu: 50m
                  memory: 32Mi
                  ephemeral-storage: 10Mi
              securityContext:
                privileged: true
                runAsUser: 0
              command: ["/usr/local/bin/bash", "-e", "-c", "echo 262144 > /proc/sys/vm/max_map_count"]
          containers:
            - name: sleep
              image: docker.io/bash:5.2.15
              command: ["sleep", "infinity"]
              resources:
                requests:
                  cpu: 10m
                  memory: 10Mi
                  ephemeral-storage: 10Mi
                limits:
                  cpu: 10m
                  memory: 10Mi
                  ephemeral-storage: 10Mi
    

    Este manifesto descreve um DaemonSet que configura a definição do kernel diretamente no anfitrião. Um DaemonSet é um controlador do Kubernetes que garante que uma cópia de um Pod é executada em cada nó num cluster.

    O manifesto anterior está numa lista de autorizações para ser executado no Autopilot. Não modifique este manifesto, incluindo as imagens do contentor.

  2. Aplique este manifesto ao seu cluster:

    kubectl apply -f max-map-count-setter-ds.yaml
    
  3. Reveja 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

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

    • initContainers: aguarda que as definições do kernel do anfitrião de memória virtual mudem.
    • podDisruptionBudget: especifica que o cluster não vai ser destruído durante o processo de desfragmentação dos pods.
    • config.node.roles: configuração das funções dos nós do Elasticsearch. Para mais informações sobre as funções dos nós, consulte o artigo na documentação do Elasticsearch.
  4. Aplique este manifesto ao seu 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 é semelhante ao seguinte:

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

    Quando o cluster do Elasticsearch HEALTH estiver green e PHASE estiver Ready, regresse à linha de comandos premindo Ctrl+C.

Configure o Kibana

  1. Reveja 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

    Este manifesto descreve um recurso personalizado do Kibana que configura políticas de agentes para o servidor e os agentes da frota.

  2. Aplique este manifesto ao seu 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 é semelhante ao seguinte:

    NAME     HEALTH   NODES   VERSION   AGE
    kibana   green    1       8.8.0     6m47s
    

    Quando o Pods HEALTH estiver green, regresse à linha de comandos premindo Ctrl+C.

Configure um balanceador de carga para aceder ao Kibana

Para aceder ao Kibana, crie um objeto Kubernetes Ingress, um certificado gerido pela Google, um endereço IP global e uma zona DNS.

  1. Criar endereço IP externo global:

    gcloud compute addresses create "elastic-stack" --global
    
  2. Crie uma zona gerida e um conjunto de registos 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. Delegue a zona DNS como um subdomínio do domínio base criando um conjunto de registos NS com uma lista de servidores de nomes. Pode obter uma lista de servidores de nomes através do seguinte comando:

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

    # Copyright 2023 Google LLC
    #
    # Licensed under the Apache License, Version 2.0 (the "License");
    # you may not use this file except in compliance with the License.
    # You may obtain a copy of the License at
    #
    #      https://www.apache.org/licenses/LICENSE-2.0
    #
    # Unless required by applicable law or agreed to in writing, software
    # distributed under the License is distributed on an "AS IS" BASIS,
    # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    # See the License for the specific language governing permissions and
    # limitations under the License.
    
    apiVersion: networking.gke.io/v1beta1
    kind: FrontendConfig
    metadata:
      name: elastic-stack
      namespace: elastic-system
    spec:
      redirectToHttps:
        enabled: true
        responseCodeName: MOVED_PERMANENTLY_DEFAULT
    ---
    apiVersion: networking.gke.io/v1
    kind: ManagedCertificate
    metadata:
      name: elastic-stack
      namespace: elastic-system
    spec:
      domains:
        - elk.BASE_DOMAIN
    ---
    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: kibana
      namespace: elastic-system
      annotations:
        networking.gke.io/managed-certificates: elastic-stack
        networking.gke.io/v1beta1.FrontendConfig: elastic-stack
        kubernetes.io/ingress.global-static-ip-name: elastic-stack
        kubernetes.io/ingress.class: gce
    spec:
      defaultBackend:
        service:
          name: kibana-kb-http
          port:
            number: 5601
    

    Este manifesto descreve um ManagedCertificate que aprovisiona um certificado SSL para estabelecer a ligação TLS.

  5. Aplique o manifesto ao cluster:

    kubectl apply -f ingress.yaml
    

Configure agentes elásticos

  1. Reveja 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 elástico que configura um servidor de frota com o ECK.

  2. Aplique este manifesto ao seu 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 é semelhante ao seguinte:

    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 Pods HEALTH estiver green, regresse à linha de comandos premindo Ctrl+C.

Configure o registo e a monitorização

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

  1. Instale o 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. Obtenha as credenciais de utilizador predefinidas do Kibana elastic:

    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 inicie sessão no Kibana com as credenciais.

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

  5. No campo de texto de pesquisa, introduza Vista geral do Kubernetes e selecione Painel de controlo de vista geral para ver as métricas base.

    Alguns dos painéis do painel de controlo podem não apresentar dados ou apresentar mensagens de erro porque o GKE limita o acesso a alguns dos pontos finais do plano de controlo que o Kibana usa para obter métricas de clusters.