8.4. 配置 Elasticsearch 以存储和整理日志数据

OpenShift Container Platform 使用 Elasticsearch (ES) 来存储和整理日志数据。

您可以对 Elasticsearch 部署进行的一些修改包括:

  • Elasticsearch 集群存储;
  • 如何在集群中的数据节点之间复制分片,包括从完整复制到不复制;
  • 允许外部对 Elasticsearch 数据进行访问。
注意

不支持缩减 Elasticsearch 节点。缩减规模时,Elasticsearch Pod 可能会被意外删除,这可能导致未分配分片,并且丢失副本分片。

Elasticsearch 是内存密集型应用程序。每个 Elasticsearch 节点需要 16G 内存来满足内存请求(requests)和限值(limits)的需要,除非集群日志记录自定义资源中另有指定。最初的 OpenShift Container Platform 节点组可能不足以支持 Elasticsearch 集群。您必须在 OpenShift Container Platform 集群中添加额外的节点,才能使用建议或更高的内存来运行。

每个 Elasticsearch 节点都可以在较低的内存设置下运行,但在生产部署中不建议这样做。

注意

如果将 Elasticsearch Operator (EO) 设置为非受管状态,并将 Cluster Logging Operator (CLO) 保留为受管状态,则 CLO 会还原您对 EO 进行的更改,因为 EO 由 CLO 进行管理。

8.4.1. 配置 Elasticsearch CPU 和内存限值

每个组件规格都允许调整 CPU 和内存限值。您应该无需手动调整这些值,因为 Elasticsearch Operator 会设置适当的值以满足环境的要求。

每个 Elasticsearch 节点都可以在较低的内存设置下运行,但在生产部署中不建议这样做。对于生产环境,为每个 Pod 应该分配的数量应不少于默认的 16Gi。最好为每个 Pod 分配不超过 64Gi 的尽量多的数量。

先决条件

  • 必须安装 Cluster Logging 和 Elasticsearch。

流程

  1. openshift-logging 项目中编辑集群日志记录自定义资源 (CR):

    $ oc edit ClusterLogging instance
    apiVersion: "logging.openshift.io/v1"
    kind: "ClusterLogging"
    metadata:
      name: "instance"
    ....
    spec:
        logStore:
          type: "elasticsearch"
          elasticsearch:
            resources: 1
              limits:
                memory: "16Gi"
              requests:
                cpu: "1"
                memory: "16Gi"
    1
    根据需要指定 CPU 和内存限值。如果这些值留白,则 Elasticsearch Operator 会设置默认值,它们应足以满足大多数部署的需要。

    如果调整了 Elasticsearch CPU 和内存的数量,您必须同时更改请求值和限制值。

    例如:

          resources:
            limits:
              cpu: "8"
              memory: "32Gi"
            requests:
              cpu: "8"
              memory: "32Gi"

    Kubernetes 一般遵循节点 CPU 配置,DOES 不允许 Elasticsearch 使用指定的限制。为 requestslimits 设置相同的值可以确保 Elasticseach 可以使用您需要它们使用的 CPU 和内存数量(假定节点有足够可用 CPU 和内存)。

8.4.2. 配置 Elasticsearch 复制策略

您可以定义如何在集群中的数据节点之间复制 Elasticsearch 分片:

先决条件

  • 必须安装 Cluster Logging 和 Elasticsearch。

流程

  1. openshift-logging 项目中编辑集群日志记录自定义资源 (CR):

    oc edit clusterlogging instance
    apiVersion: "logging.openshift.io/v1"
    kind: "ClusterLogging"
    metadata:
      name: "instance"
    
    ....
    
    spec:
      logStore:
        type: "elasticsearch"
        elasticsearch:
          redundancyPolicy: "SingleRedundancy" 1
    1
    为分片指定冗余策略。更改会在保存后应用。
    • FullRedundancy:Elasticsearch 将每个索引的主分片完整复制到每个数据节点。这可提供最高的安全性,但代价是需要最大数量的磁盘并且性能最差。
    • MultipleRedundancy:Elasticsearch 将每个索引的主分片完整复制到一半的数据节点。这可在安全性和性能之间提供很好的折衷。
    • SingleRedundancy:Elasticsearch 为每个索引的主分片制作一个副本。只要存在至少两个数据节点,日志就能始终可用且可恢复。使用 5 个或更多节点时,性能胜过 MultipleRedundancy。您不能将此策略应用于单个 Elasticsearch 节点的部署。
    • ZeroRedundancy:Elasticsearch 不制作主分片的副本。如果节点关闭或发生故障, 则可能无法获得日志数据。如果您更关注性能而非安全性,或者实施了自己的磁盘/PVC 备份/恢复策略,可以考虑使用此模式。
注意

索引模板的主分片数量等于 Elasticsearch 数据节点的数目。

8.4.3. 配置 Elasticsearch 存储

Elasticsearch 需要持久性存储。存储速度越快,Elasticsearch 性能越高。

警告

在 Elasticsearch 存储中不支持将 NFS 存储用作卷或持久性卷(或者通过 NAS 比如 Gluster),因为 Lucene 依赖于 NFS 不提供的文件系统行为。数据崩溃和其他问题可能会发生。

先决条件

  • 必须安装 Cluster Logging 和 Elasticsearch。

流程

  1. 编辑集群日志记录 CR,将集群中的每个数据节点指定为绑定到 PVC。

    apiVersion: "logging.openshift.io/v1"
    kind: "ClusterLogging"
    metadata:
      name: "instance"
    
    ....
    
     spec:
        logStore:
          type: "elasticsearch"
          elasticsearch:
            nodeCount: 3
            storage:
              storageClassName: "gp2"
              size: "200G"

本例中指定,集群中的每个数据节点都绑定到请求“200G”的 AWS 通用 SSD (gp2) 存储的 PVC。

8.4.4. 为 Elasticsearch 配置 emptyDir 存储

您可以将 emptyDir 与 Elasticsearch 搭配使用来创建一个临时部署,临时部署一旦重启其中所有 Pod 的数据都会丢失。

注意

使用 emptyDir 时,如果重启或重新部署 Elasticsearch,数据将会丢失。

先决条件

  • 必须安装 Cluster Logging 和 Elasticsearch。

流程

  1. 编辑集群日志记录 CR 以指定 emptyDir:

     spec:
        logStore:
          type: "elasticsearch"
          elasticsearch:
            nodeCount: 3
            storage: {}

8.4.5. 将 Elasticsearch 公开为路由

默认情况下,无法从日志记录集群外部访问部署了集群日志记录的 Elasticsearch。您可以启用一个 re-encryption termination 模式的路由,以实现外部对 Elasticsearch 的访问来获取数据。

另外,还可以在外部创建一个重新加密路由,使用 OpenShift Container Platform 令牌和已安装的 Elasticsearch CA 证书以从外部访问 Elasticsearch。然后,使用包含以下信息的 cURL 请求来访问 Elasticsearch 节点:

在内部,您可以使用 Elasticsearch 集群 IP 访问 Elastiscearch:

您可以使用以下命令之一获取 Elasticsearch 集群 IP:

$ oc get service elasticsearch -o jsonpath={.spec.clusterIP} -n openshift-logging

172.30.183.229
oc get service elasticsearch

NAME            TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)    AGE
elasticsearch   ClusterIP   172.30.183.229   <none>        9200/TCP   22h

$ oc exec elasticsearch-cdm-oplnhinv-1-5746475887-fj2f8 -- curl -tlsv1.2 --insecure -H "Authorization: Bearer ${token}" "https://172.30.183.229:9200/_cat/health"

  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100    29  100    29    0     0    108      0 --:--:-- --:--:-- --:--:--   108

先决条件

  • 必须安装 Cluster Logging 和 Elasticsearch。
  • 您必须具有项目的访问权限,以便能访问其日志。

流程

对外部公开 Elasticsearch:

  1. 进入 openshift-logging 项目:

    $ oc project openshift-logging
  2. 从 Elasticsearch 提取 CA 证书并写入 admin-ca 文件:

    $ oc extract secret/elasticsearch --to=. --keys=admin-ca
    
    admin-ca
  3. 以 YAML 文件形式创建 Elasticsearch 服务的路由:

    1. 使用以下内容创建一个 YAML文件:

      apiVersion: route.openshift.io/v1
      kind: Route
      metadata:
        name: elasticsearch
        namespace: openshift-logging
      spec:
        host:
        to:
          kind: Service
          name: elasticsearch
        tls:
          termination: reencrypt
          destinationCACertificate: | 1
      1
      添加 Elasticsearch CA 证书或使用下一步中的命令。您不必设置一些重新加密路由所需的 spec.tls.keyspec.tls.certificatespec.tls.caCertificate 参数。
    2. 运行以下命令将 Elasticsearch CA 证书添加到您创建的路由 YAML 中:

      cat ./admin-ca | sed -e "s/^/      /" >> <file-name>.yaml
    3. 创建路由:

      $ oc create -f <file-name>.yaml
      
      route.route.openshift.io/elasticsearch created
  4. 检查是否公开了 Elasticsearch 服务:

    1. 获取此 ServiceAccount 的令牌,以便在请求中使用:

      $ token=$(oc whoami -t)
    2. 将您创建的 Elasticsearch 路由设置为环境变量。

      $ routeES=`oc get route elasticsearch -o jsonpath={.spec.host}`
    3. 要验证路由是否创建成功,请运行以下命令来通过公开的路由访问 Elasticsearch:

      curl -tlsv1.2 --insecure -H "Authorization: Bearer ${token}" "https://${routeES}/.operations.*/_search?size=1" | jq

      其响应类似于如下:

        % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                       Dload  Upload   Total   Spent    Left  Speed
      100   944  100   944    0     0     62      0  0:00:15  0:00:15 --:--:--   204
      {
        "took": 441,
        "timed_out": false,
        "_shards": {
          "total": 3,
          "successful": 3,
          "skipped": 0,
          "failed": 0
        },
        "hits": {
          "total": 89157,
          "max_score": 1,
          "hits": [
            {
              "_index": ".operations.2019.03.15",
              "_type": "com.example.viaq.common",
              "_id": "ODdiNWIyYzAtMjg5Ni0TAtNWE3MDY1MjMzNTc3",
              "_score": 1,
              "_source": {
                "_SOURCE_MONOTONIC_TIMESTAMP": "673396",
                "systemd": {
                  "t": {
                    "BOOT_ID": "246c34ee9cdeecb41a608e94",
                    "MACHINE_ID": "e904a0bb5efd3e36badee0c",
                    "TRANSPORT": "kernel"
                  },
                  "u": {
                    "SYSLOG_FACILITY": "0",
                    "SYSLOG_IDENTIFIER": "kernel"
                  }
                },
                "level": "info",
                "message": "acpiphp: Slot [30] registered",
                "hostname": "localhost.localdomain",
                "pipeline_metadata": {
                  "collector": {
                    "ipaddr4": "10.128.2.12",
                    "ipaddr6": "fe80::xx:xxxx:fe4c:5b09",
                    "inputname": "fluent-plugin-systemd",
                    "name": "fluentd",
                    "received_at": "2019-03-15T20:25:06.273017+00:00",
                    "version": "1.3.2 1.6.0"
                  }
                },
                "@timestamp": "2019-03-15T20:00:13.808226+00:00",
                "viaq_msg_id": "ODdiNWIyYzAtMYTAtNWE3MDY1MjMzNTc3"
              }
            }
          ]
        }
      }

8.4.6. 关于 Elasticsearch 警报规则

您可以在 Prometheus 中查看这些警报规则。

警报描述重要性

ElasticsearchClusterNotHealthy

集群健康状态为 RED 至少有 2 分钟。集群不接受写操作,分片可能缺失或者 master 节点尚未选定。

critical

ElasticsearchClusterNotHealthy

集群健康状态为 YELLOW 至少有 20 分钟。某些分片副本尚未分配。

warning

ElasticsearchBulkRequestsRejectionJumps

集群中节点的批量拒绝率高。此节点可能无法跟上索引速度。

warning

ElasticsearchNodeDiskWatermarkReached

集群中节点已达到磁盘低水位线。分片无法再分配给此节点。应该考虑向节点添加更多磁盘空间。

alert

ElasticsearchNodeDiskWatermarkReached

集群中节点已达到磁盘高水位线。若有可能,某些分片将重新分配到其他节点。确保向节点添加更多磁盘空间,或者丢弃分配给此节点的旧索引。

high

ElasticsearchJVMHeapUseHigh

集群中节点上的 JVM 堆使用量为 <value>

alert

AggregatedLoggingSystemCPUHigh

集群中节点上的系统 CPU 使用率是 <value>

alert

ElasticsearchProcessCPUHigh

集群中节点上的 ES 进程 CPU 使用率是 <value>

alert