Configurare Elastic Stack su GKE


Questo tutorial mostra come eseguire Elastic Stack su GKE utilizzando l'operatore Elastic Cloud on Kubernetes (ECK).

Elastic Stack è una soluzione open source molto diffusa utilizzata per il logging, il monitoraggio e l'analisi dei dati in tempo reale. Utilizzando Elastic Stack su GKE, puoi usufruire della scalabilità e dell'affidabilità fornite da GKE Autopilot e delle potenti funzionalità di Elastic Stack.

Questo tutorial è rivolto agli amministratori di Kubernetes o ai site reliability engineer.

Obiettivi

  • Creare un cluster GKE.
  • Esegui il deployment dell'operatore ECK.
  • Configura i cluster Elasticsearch e Kibana utilizzando l'operatore ECK.
  • Esegui il deployment di uno stack Elastic completo utilizzando l'operatore ECK.
  • Scalare automaticamente i cluster Elasticsearch ed eseguire l'upgrade del deployment di Elastic Stack.
  • Utilizza Elastic Stack per monitorare gli ambienti Kubernetes.

Costi

In questo documento vengono utilizzati i seguenti componenti fatturabili di Google Cloud:

Per generare una stima dei costi in base all'utilizzo previsto, utilizza il calcolatore prezzi.

I nuovi utenti di Google Cloud potrebbero avere diritto a una prova senza costi.

Al termine delle attività descritte in questo documento, puoi evitare l'addebito di ulteriori costi eliminando le risorse che hai creato. Per ulteriori informazioni, vedi Pulizia.

Prima di iniziare

  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 utilizzi un provider di identità (IdP) esterno, devi prima accedere alla gcloud CLI con la tua identità federata.

  4. Per inizializzare gcloud CLI, esegui questo 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. Make sure 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 utilizzi un provider di identità (IdP) esterno, devi prima accedere alla gcloud CLI con la tua identità federata.

  10. Per inizializzare gcloud CLI, esegui questo 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. Make sure 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 PROJECT_ID with your project ID.
    • Replace USER_IDENTIFIER with the identifier for your user account. For example, user:myemail@example.com.

    • Replace ROLE with each individual role.
    • Devi essere proprietario di un nome di dominio. Il nome di dominio non deve contenere più di 63 caratteri. Puoi utilizzare Cloud Domains o un altro registrar.

    Prepara l'ambiente

    In questo tutorial utilizzerai Cloud Shell per gestire le risorse ospitate su Google Cloud. Cloud Shell è preinstallato con il software necessario per questo tutorial, tra cui kubectl, Helm e gcloud CLI.

    Per configurare l'ambiente con Cloud Shell:

    1. Avvia una sessione di Cloud Shell dalla console Google Cloud facendo clic su Icona di attivazione di Cloud Shell Attiva Cloud Shell nella consoleGoogle Cloud . Viene avviata una sessione nel riquadro inferiore della console Google Cloud .

    2. Aggiungi un repository di grafici Helm e aggiornalo:

      helm repo add elastic https://helm.elastic.co
      helm repo update
      
    3. Clona il repository GitHub:

      git clone https://github.com/GoogleCloudPlatform/kubernetes-engine-samples.git
      
    4. Passa alla directory di lavoro:

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

    Crea un cluster GKE

    Crea un cluster GKE con la raccolta delle metriche del control plane attivata:

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

    Esegui il deployment dell'operatore ECK

    Elastic Cloud on Kubernetes (ECK) è una piattaforma per il deployment e la gestione di Elastic Stack sui cluster Kubernetes.

    ECK automatizza il deployment e la gestione dei cluster Elastic Stack, semplificando la procedura di configurazione e manutenzione di Elastic Stack su Kubernetes. Fornisce un insieme di risorse personalizzate Kubernetes che puoi utilizzare per creare e configurare Elasticsearch, Kibana, Application Performance Management Server e altri componenti di Elastic Stack in Kubernetes. Ciò consente agli sviluppatori e ai team DevOps di configurare e gestire i cluster Elastic Stack su larga scala.

    ECK supporta più nodi Elasticsearch, il failover automatico delle applicazioni, gli upgrade senza interruzioni e la crittografia SSL. ECK include anche funzionalità che ti consentono di monitorare e risolvere i problemi relativi alle prestazioni di Elasticsearch.

    1. Installa il grafico Helm 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. Attendi che l'operatore sia pronto:

      watch kubectl get pods -n elastic-system
      

      L'output è simile al seguente:

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

      Quando l'operatore STATUS è Running, torna alla riga di comando premendo Ctrl+C.

    Configura Elastic Stack con ECK

    Utilizzando Elastic Stack con Elasticsearch, Kibana ed Elastic Agent in modalità Fleet, puoi configurare una soluzione potente, scalabile e completamente gestita per la gestione e la visualizzazione dei dati utilizzando Kibana.

    Kibana è uno strumento di analisi e visualizzazione dei dati open source che ti consente di cercare, analizzare e visualizzare i dati in Elasticsearch.

    Elastic Agent è un leggero shipper di dati che raccoglie dati da diverse origini, come log o metriche, e li invia automaticamente a Elasticsearch.

    Elastic Fleet è una modalità di funzionamento in cui gli agenti Elastic inviano report a un server di gestione centrale, che gestisce la loro configurazione. Il server fleet semplifica il deployment, la configurazione e lo scaling degli agenti Elastic, rendendo più semplice la gestione di deployment di grandi dimensioni e complessi.

    La scalabilità automatica di Elasticsearch è una funzionalità di automonitoraggio che può segnalare quando sono necessarie risorse aggiuntive in base a una policy definita dall'operatore. Ad esempio, un criterio potrebbe specificare che un determinato livello deve essere scalato in base allo spazio su disco disponibile. Elasticsearch può monitorare lo spazio su disco e suggerire lo scaling se prevede una carenza, anche se spetta comunque all'operatore aggiungere le risorse necessarie. Per ulteriori informazioni sulla scalabilità automatica di Elasticsearch, consulta Scalabilità automatica nella documentazione di Elasticsearch.

    Configura un cluster Elasticsearch

    Elasticsearch fornisce un motore di ricerca e analisi distribuito e RESTful progettato per archiviare e cercare grandi volumi di dati in modo rapido ed efficiente.

    Quando esegui il deployment di Elastic Stack su Kubernetes, devi gestire le impostazioni della VM, in particolare vm.max_map_count setting, che è richiesto da Elasticsearch. vm.max_map_count specifica il numero di aree di memoria che un processo può allocare a un file. Per un funzionamento ottimale, Elasticsearch deve avere questo valore impostato almeno su 262144. Per saperne di più, consulta la sezione Memoria virtuale nella documentazione di ECK.

    1. Esamina il seguente manifest:

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

      Questo manifest descrive un DaemonSet che configura l'impostazione del kernel direttamente sull'host. Un DaemonSet è un controller Kubernetes che garantisce che una copia di un pod venga eseguita su ogni nodo di un cluster.

      Il manifest precedente è presente in una lista consentita per l'esecuzione su Autopilot. Non modificare questo manifest, incluse le immagini del contenitore.

    2. Applica questo manifest al tuo cluster:

      kubectl apply -f max-map-count-setter-ds.yaml
      
    3. Esamina il seguente manifest:

      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

      Questo manifest definisce un cluster Elasticsearch con i seguenti campi:

      • initContainers: attende la modifica delle impostazioni del kernel dell'host di memoria virtuale.
      • podDisruptionBudget: specifica che il cluster non verrà eliminato durante il processo di deframmentazione dei pod.
      • config.node.roles: la configurazione dei ruoli dei nodi Elasticsearch. Per saperne di più sui ruoli dei nodi, consulta la sezione Nodo nella documentazione di Elasticsearch.
    4. Applica questo manifest al tuo cluster:

      kubectl apply -f elasticsearch.yaml
      
    5. Attendi che il cluster Elasticsearch sia pronto:

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

      L'output è simile al seguente:

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

      Quando il cluster Elasticsearch HEALTH è green e PHASE è Ready, torna alla riga di comando premendo Ctrl+C.

    Configura Kibana

    1. Esamina il seguente manifest:

      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

      Questo manifest descrive una risorsa personalizzata Kibana che configura i criteri dell'agente per il server fleet e gli agenti.

    2. Applica questo manifest al tuo cluster:

      kubectl apply -f kibana.yaml
      
    3. Attendi che i pod siano pronti:

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

      L'output è simile al seguente:

      NAME     HEALTH   NODES   VERSION   AGE
      kibana   green    1       8.8.0     6m47s
      

      Quando i pod HEALTH sono green, torna alla riga di comando premendo Ctrl+C.

    Configura un bilanciatore del carico per accedere a Kibana

    Per accedere a Kibana, crea un oggetto Ingress di Kubernetes, un certificato gestito da Google, un indirizzo IP globale e una zona DNS.

    1. Crea un indirizzo IP esterno globale:

      gcloud compute addresses create "elastic-stack" --global
      
    2. Crea una zona gestita e un insieme di record in 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. Delega la zona DNS come sottodominio del dominio di base creando un insieme di record NS con un elenco di server dei nomi. Puoi ottenere un elenco di server dei nomi utilizzando il seguente comando:

      gcloud dns record-sets describe elk.BASE_DOMAIN \
          --type="NS" \
          --zone="elk" \
          --format="value(DATA)"
      
    4. Esamina il seguente manifest:

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

      Questo manifest descrive un ManagedCertificate che esegue il provisioning di un certificato SSL per stabilire la connessione TLS.

    5. Applica il manifest al cluster:

      kubectl apply -f ingress.yaml
      

    Configura gli agenti elastici

    1. Esamina il seguente manifest:

      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

      Questo manifest descrive un Elastic Agent che configura un server fleet con ECK.

    2. Applica questo manifest al tuo cluster:

      kubectl apply -f fleet-server-and-agents.yaml
      
    3. Attendi che i pod siano pronti:

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

      L'output è simile al seguente:

      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 i pod HEALTH sono green, torna alla riga di comando premendo Ctrl+C.

    Configurazione di logging e monitoraggio

    Elastic Stack può utilizzare l'esportatore kube-state-metrics per raccogliere metriche a livello di cluster.

    1. Installa 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. Recupera le credenziali utente predefinite di Kibana elastic:

      kubectl get secret elasticsearch-es-elastic-user -o yaml -n elastic-system -o jsonpath='{.data.elastic}' | base64 -d
      
    3. Apri https://elk.BASE_DOMAIN nel browser e accedi a Kibana con le credenziali.

    4. Nel menu, seleziona Analytics, poi Dashboard.

    5. Nel campo di testo di ricerca, inserisci Panoramica di Kubernetes e seleziona Dashboard Panoramica per visualizzare le metriche di base.

      Alcuni pannelli della dashboard potrebbero non mostrare dati o messaggi di errore perché GKE limita l'accesso ad alcuni endpoint del control plane che Kibana utilizza per ottenere le metriche del cluster.

    Esegui la pulizia

    Per evitare che al tuo Account Google Cloud vengano addebitati costi relativi alle risorse utilizzate in questo tutorial, elimina il progetto che contiene le risorse oppure mantieni il progetto ed elimina le singole risorse.

    Elimina il progetto

      Delete a Google Cloud project:

      gcloud projects delete PROJECT_ID

    Elimina le singole risorse

    Se hai utilizzato un progetto esistente e non vuoi eliminarlo, elimina le singole risorse.

    1. Elimina i componenti di Elastic Stack, l'operatore ECK e 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. Elimina il set di record DNS, l'indirizzo IP, la zona gestita DNS e il cluster 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
      

    Passaggi successivi

    • Esplora architetture di riferimento, diagrammi e best practice su Google Cloud. Consulta il nostro Cloud Architecture Center.