在 GKE 上设置 Elastic Stack


本教程介绍如何使用 Elastic Cloud on Kubernetes (ECK) 运算符在 GKE 上运行 Elastic Stack

Elastic Stack 是一种常用的开源解决方案,用于实时记录、监控和分析数据。使用 GKE 上的 Elastic Stack,您可以受益于 GKE Autopilot 提供的可伸缩性和可靠性,以及强大的 Elastic Stack 功能。

本教程面向 Kubernetes 管理员或站点可靠性工程师。

目标

  • 创建 GKE 集群。
  • 部署 ECK 运算符。
  • 使用 ECK 运算符配置 Elasticsearch 集群和 Kibana。
  • 使用 ECK 运算符部署完整的 Elastic Stack。
  • 自动扩缩 Elasticsearch 集群并升级 Elastic Stack 部署。
  • 使用 Elastic Stack 监控 Kubernetes 环境。

费用

在本文档中,您将使用 Google Cloud 的以下收费组件:

您可使用价格计算器根据您的预计使用情况来估算费用。 Google Cloud 新用户可能有资格申请免费试用

完成本文档中描述的任务后,您可以通过删除所创建的资源来避免继续计费。如需了解详情,请参阅清理

准备工作

  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. To initialize the gcloud CLI, run the following command:

    gcloud init
  4. 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.

  5. Make sure that billing is enabled for your Google Cloud project.

  6. Enable the GKE API:

    gcloud services enable container.googleapis.com
  7. Install the Google Cloud CLI.
  8. To initialize the gcloud CLI, run the following command:

    gcloud init
  9. 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.

  10. Make sure that billing is enabled for your Google Cloud project.

  11. Enable the GKE API:

    gcloud services enable container.googleapis.com
  12. 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_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.
  • 您必须拥有域名。域名长度不得超过 63 个字符。您可以使用 Cloud Domains 或其他注册商。

准备环境

在本教程中,您将使用 Cloud Shell 来管理 Google Cloud 上托管的资源。Cloud Shell 中预安装了本教程所需的软件,包括 kubectlHelmgcloud CLI

如需使用 Cloud Shell 设置您的环境,请按照以下步骤操作:

  1. 点击 Google Cloud 控制台中的 Cloud Shell 激活图标 激活 Cloud Shell,从 Google Cloud 控制台启动 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
    

    当运算符 STATUSRunning 时,按 Ctrl+C 返回到命令行。

使用 ECK 配置 Elastic Stack

通过将 Elastic Stack 与 Elasticsearch、Kibana 和 Elastic Agent 搭配使用并在设备群模式下工作,您可以设置强大、可伸缩的全托管式解决方案,以使用 Kibana 管理和可视化数据。

Kibana 是一种开源数据分析和可视化工具,让您可在 Elasticsearch 中搜索、分析和可视化数据。

Elastic Agent 是一个轻量级数据发送器,可从不同来源(例如日志或指标)收集数据,并将数据自动发送到 Elasticsearch。

Elastic Fleet 是一种操作模式,在此模式下,Elastic 代理会向中央设备群服务器报告,该服务器处理其配置和管理。设备群服务器简化了 Elastic 代理的部署、配置和扩缩,让您可更轻松地管理大型复杂部署。

Elasticsearch 自动扩缩是一项自我监控功能,可根据运算符定义的政策报告何时需要其他资源。例如,政策可能会指定特定层级应根据磁盘可用空间进行扩缩。Elasticsearch 可以监控磁盘可用空间,并在预测短缺时建议扩缩,但运算符仍负责添加必要的资源。如需详细了解 Elasticsearch 自动扩缩,请参阅 Elasticsearch 文档中的自动扩缩

配置 Elasticsearch 集群

Elasticsearch 提供分布式 RESTful 搜索和分析引擎,旨在快速高效地存储和搜索大量数据。

在 Kubernetes 上部署 Elastic Stack 时,您应管理虚拟机设置,具体而言,就是 Elasticsearch 所需的 vm.max_map_count settingvm.max_map_count 指定进程可以分配给一个文件的内存区域数量。Elasticsearch 必须将此值设置为至少 262144 才能以最佳方式运行。如需了解详情,请参阅 ECK 文档中的虚拟内存

  1. 请查看以下清单:

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

    此清单描述了一个直接在主机上配置内核设置的 DaemonSet。此清单已列入许可名单,可在 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:等待虚拟内存主机的内核设置发生更改。
    • 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 自定义资源,用于为设备群服务器和代理配置代理政策。

  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. 请查看以下清单:

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

    此清单描述了 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

    此清单描述使用 ECK 配置设备群服务器的 Elastic Agent。

  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 用于获取集群指标的某些控制平面端点进行访问。

清理

为避免因本教程中使用的资源导致您的 Google Cloud 账号产生费用,请删除包含这些资源的项目,或者保留项目但删除各个资源。

删除项目

    Delete a Google Cloud project:

    gcloud projects delete PROJECT_ID

逐个删除资源

如果您使用的是现有项目,并且不想将其删除,请逐个删除资源。

  1. 删除 Elastic Stack 组件、ECK 运算符和 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. 删除 DNS 记录集、IP 地址、DNS 托管区域和 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
    

后续步骤