在 GKE 上設定 Elastic Stack

本教學課程說明如何使用 Elastic Cloud on Kubernetes (ECK) 運算子,在 GKE 上執行 Elastic Stack

Elastic Stack 是熱門的開放原始碼解決方案,可用於記錄、監控及分析即時資料。在 GKE 上使用 Elastic Stack,即可享有 GKE Autopilot 提供的擴充性和可靠性,以及強大的 Elastic Stack 功能。

本教學課程適用於 Kubernetes 管理員或網站可靠性工程師。

準備環境

在本教學課程中,您將使用 Cloud Shell 管理託管在 Google Cloud上的資源。Cloud Shell 已預先安裝本教學課程所需的軟體,包括 kubectlHelmgcloud CLI

如要使用 Cloud Shell 設定環境,請按照下列步驟操作:

  1. 在 Google Cloud 控制台中,按一下Cloud Shell 啟用圖示Google Cloud 控制台中的「啟用 Cloud Shell」,即可啟動 Cloud Shell 工作階段。系統會在 Google Cloud 控制台的底部窗格啟動工作階段。

  2. 新增並更新 Helm 資訊套件存放區:

    helm repo add elastic https://helm.elastic.co
    helm repo update
    
  3. 複製 GitHub 存放區:

    git clone https://github.com/GoogleCloudPlatform/kubernetes-engine-samples.git
    
  4. 變更為工作目錄:

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

建立 GKE 叢集

建立 GKE 叢集,並啟用控制層指標收集功能:

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

部署 ECK 運算子

Elastic Cloud on Kubernetes (ECK) 平台可讓您在 Kubernetes 叢集上部署及管理 Elastic Stack。

ECK 可自動部署及管理 Elastic Stack 叢集,簡化在 Kubernetes 上設定及維護 Elastic Stack 的程序。這項服務提供一組 Kubernetes 自訂資源,可用於在 Kubernetes 中建立及設定 Elasticsearch、Kibana、應用程式效能管理伺服器和其他 Elastic Stack 元件。開發人員和 DevOps 團隊可藉此大規模設定及管理 Elastic Stack 叢集。

ECK 支援多個 Elasticsearch 節點、自動應用程式容錯移轉、無縫升級和 SSL 加密。ECK 也提供監控及排解 Elasticsearch 效能問題的功能。

  1. 安裝 ECK Helm 資訊套件:

    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. 等待運算子準備就緒:

    watch kubectl get pods -n elastic-system
    

    輸出結果會與下列內容相似:

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

    如果運算子為 STATUS,請按 Ctrl+C 返回指令列。Running

使用 ECK 設定 Elastic Stack

使用 Elastic Stack (包括 Elasticsearch、Kibana 和以 Fleet 模式運作的 Elastic Agent),即可設定強大、可擴充且全代管的解決方案,透過 Kibana 管理及以視覺化方式呈現資料。

Kibana 是一項開放原始碼的資料分析和視覺化工具,可讓您在 Elasticsearch 中搜尋、分析及以視覺化方式呈現資料。

Elastic Agent 是一種輕量型資料傳送程式,可從記錄或指標等不同來源收集資料,並自動傳送至 Elasticsearch。

Elastic Fleet 是一種作業模式,Elastic 代理程式會向中央叢集伺服器回報,由該伺服器處理設定和管理作業。機群伺服器可簡化 Elastic 代理程式的部署、設定和資源調度作業,方便您管理大型複雜的部署作業。

Elasticsearch 自動調度資源是一項自我監控功能,可根據運算子定義的政策,在需要額外資源時回報。舉例來說,政策可能會指定某個層級應根據可用磁碟空間進行調整。Elasticsearch 可以監控磁碟空間,並在預測空間不足時建議擴充,但仍須由運算子新增必要資源。如要進一步瞭解 Elasticsearch 自動調度資源,請參閱 Elasticsearch 說明文件的「自動調度資源」一節。

設定 Elasticsearch 叢集

Elasticsearch 提供分散式 RESTful 搜尋和分析引擎,可快速有效率地儲存及搜尋大量資料。

在 Kubernetes 上部署 Elastic Stack 時,您應管理 VM 設定,特別是 Elasticsearch 要求的 vm.max_map_count settingvm.max_map_count 指定程序可分配給檔案的記憶體區域數量。Elasticsearch 必須將此值設為至少 262144,才能以最佳狀態執行。詳情請參閱 ECK 說明文件中的「虛擬記憶體」。

  1. 請查看下列資訊清單:

    # 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
    

    這個資訊清單說明 DaemonSet,可直接在主機上設定核心設定。DaemonSet 是 Kubernetes 控制器,可確保 Pod 副本在叢集中的每個節點上執行。

    上述資訊清單位於允許清單中,可在 Autopilot 上執行。請勿修改這份資訊清單,包括容器映像檔。

  2. 將這個資訊清單套用至叢集:

    kubectl apply -f max-map-count-setter-ds.yaml
    
  3. 請查看下列資訊清單:

    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

    這個資訊清單會定義 Elasticsearch 叢集,並包含下列欄位:

    • initContainers:等待虛擬記憶體主機的 Kernel 設定變更。
    • podDisruptionBudget:指定叢集不會在 Pod 重整程序期間遭到毀損。
    • config.node.roles:Elasticsearch 節點角色設定。如要進一步瞭解節點角色,請參閱 Elasticsearch 說明文件中的「節點」。
  4. 將這個資訊清單套用至叢集:

    kubectl apply -f elasticsearch.yaml
    
  5. 等待 Elasticsearch 叢集準備就緒:

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

    輸出結果會與下列內容相似:

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

    當 Elasticsearch 叢集 HEALTHgreenPHASEReady 時,請按下 Ctrl+C 返回指令列。

設定 Kibana

  1. 請查看下列資訊清單:

    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

    這個資訊清單說明 Kibana 自訂資源,可為 Fleet 伺服器和代理程式設定代理程式政策。

  2. 將這個資訊清單套用至叢集:

    kubectl apply -f kibana.yaml
    
  3. 等待 Pod 準備就緒:

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

    輸出結果會與下列內容相似:

    NAME     HEALTH   NODES   VERSION   AGE
    kibana   green    1       8.8.0     6m47s
    

    當 Pod HEALTHgreen 時,請按下 Ctrl+C 返回指令列。

設定負載平衡器以存取 Kibana

如要存取 Kibana,請建立 Kubernetes Ingress 物件、Google 管理的憑證、全域 IP 位址和 DNS 區域。

  1. 建立全域外部 IP 位址:

    gcloud compute addresses create "elastic-stack" --global
    
  2. 在 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. 建立含有名稱伺服器清單的 NS 記錄集,將 DNS 區域委派為基礎網域的子網域。您可以使用下列指令取得名稱伺服器清單:

    gcloud dns record-sets describe elk.BASE_DOMAIN \
        --type="NS" \
        --zone="elk" \
        --format="value(DATA)"
    
  4. 請查看下列資訊清單:

    # 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
    

    這個資訊清單說明 ManagedCertificate,該憑證會佈建 SSL 憑證來建立 TLS 連線。

  5. 將資訊清單套用至叢集:

    kubectl apply -f ingress.yaml
    

設定 Elastic Agent

  1. 請查看下列資訊清單:

    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

    這個資訊清單說明 Elastic Agent,可使用 ECK 設定 Fleet Server。

  2. 將這個資訊清單套用至叢集:

    kubectl apply -f fleet-server-and-agents.yaml
    
  3. 等待 Pod 準備就緒:

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

    輸出結果會與下列內容相似:

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

    當 Pod HEALTHgreen 時,請按下 Ctrl+C 返回指令列。

設定記錄和監控功能

Elastic Stack 可以使用 kube-state-metrics 匯出工具收集叢集層級指標。

  1. 安裝 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. 取得預設的 Kibana elastic 使用者憑證:

    kubectl get secret elasticsearch-es-elastic-user -o yaml -n elastic-system -o jsonpath='{.data.elastic}' | base64 -d
    
  3. 在瀏覽器中開啟 https://elk.BASE_DOMAIN,然後使用憑證登入 Kibana。

  4. 在選單中依序選取「數據分析」和「資訊主頁」

  5. 在搜尋文字欄位中輸入「Kubernetes 總覽」,然後選取「總覽資訊主頁」,即可查看基本指標。

    由於 GKE 限制存取 Kibana 用來取得叢集指標的部分控制層端點,因此部分資訊主頁面板可能不會顯示資料或錯誤訊息。