10.4. 配置 Elasticsearch 日志存储
您可以使用 Elasticsearch 6 来存储和组织日志数据。
您可以修改日志存储,包括:
- Elasticsearch 集群的存储
- 在集群中的数据节点之间复制分片,从完整复制到不复制
- 外部访问 Elasticsearch 数据
10.4.1. 配置日志存储
您可以通过修改 ClusterLogging
自定义资源(CR)来配置日志使用的日志存储类型。
先决条件
- 有管理员权限。
-
已安装 OpenShift CLI(
oc
)。 - 已安装 Red Hat OpenShift Logging Operator 和一个内部日志存储,它是 LokiStack 或 Elasticsearch。
-
您已创建了
ClusterLogging
CR。
Logging 5.9 发行版本不包含 OpenShift Elasticsearch Operator 的更新版本。如果您目前使用随 Logging 5.8 发布的 OpenShift Elasticsearch Operator,它将继续使用 Logging,直到 Logging 5.8 的 EOL 为止。您可以使用 Loki Operator 作为 OpenShift Elasticsearch Operator 的替代方案来管理默认日志存储。如需有关日志记录生命周期日期的更多信息,请参阅平台 Agnostic Operator。
步骤
修改
ClusterLogging
CRlogStore
规格:ClusterLogging
CR 示例apiVersion: logging.openshift.io/v1 kind: ClusterLogging metadata: # ... spec: # ... logStore: type: <log_store_type> 1 elasticsearch: 2 nodeCount: <integer> resources: {} storage: {} redundancyPolicy: <redundancy_type> 3 lokistack: 4 name: {} # ...
将 LokiStack 指定为日志存储的
ClusterLogging
CR 示例apiVersion: logging.openshift.io/v1 kind: ClusterLogging metadata: name: instance namespace: openshift-logging spec: managementState: Managed logStore: type: lokistack lokistack: name: logging-loki # ...
运行以下命令来应用
ClusterLogging
CR:$ oc apply -f <filename>.yaml
10.4.2. 将审计日志转发到日志存储
在日志记录部署中,容器和基础架构日志默认转发到 ClusterLogging
自定义资源(CR)中定义的内部日志存储。
默认情况下,审计日志不会转发到内部日志存储,因为这不提供安全存储。您需要自己确保转发审计日志的系统符合您所在机构及政府的相关要求,并具有适当的安全性。
如果此默认配置满足您的需要,则不需要配置一个 ClusterLogForwarder
CR。如果存在 ClusterLogForwarder
CR,日志不会转发到内部日志存储,除非定义了包含 default
输出的管道。
步骤
使用 Log Forward API 将审计日志转发到内部 Elasticsearch 实例:
创建或编辑定义
ClusterLogForwarder
CR 对象的 YAML 文件:创建 CR 以将所有日志类型发送到内部 Elasticsearch 实例。您可以在不进行任何更改的情况下使用以下示例:
apiVersion: logging.openshift.io/v1 kind: ClusterLogForwarder metadata: name: instance namespace: openshift-logging spec: pipelines: 1 - name: all-to-default inputRefs: - infrastructure - application - audit outputRefs: - default
- 1
- 管道(pipeline)定义使用指定输出转发的日志类型。默认输出将日志转发到内部 Elasticsearch 实例。
注意您必须在管道中指定所有三种类型的日志:应用程序、基础架构和审核。如果没有指定日志类型,这些日志将不会被存储并丢失。
如果您有一个现有的
ClusterLogForwarder
CR,请将管道添加到审计日志的默认输出中。您不需要定义默认输出。例如:apiVersion: "logging.openshift.io/v1" kind: ClusterLogForwarder metadata: name: instance namespace: openshift-logging spec: outputs: - name: elasticsearch-insecure type: "elasticsearch" url: http://elasticsearch-insecure.messaging.svc.cluster.local insecure: true - name: elasticsearch-secure type: "elasticsearch" url: https://elasticsearch-secure.messaging.svc.cluster.local secret: name: es-audit - name: secureforward-offcluster type: "fluentdForward" url: https://secureforward.offcluster.com:24224 secret: name: secureforward pipelines: - name: container-logs inputRefs: - application outputRefs: - secureforward-offcluster - name: infra-logs inputRefs: - infrastructure outputRefs: - elasticsearch-insecure - name: audit-logs inputRefs: - audit outputRefs: - elasticsearch-secure - default 1
- 1
- 此管道除外部实例外,还会将审计日志发送到内部 Elasticsearch 实例。
其他资源
10.4.3. 配置日志保留时间
您可以配置保留策略,指定默认 Elasticsearch 日志存储保留三个日志源的索引的时长:基础架构日志、应用程序日志和审计日志。
要配置保留策略,您需要为 ClusterLogging
自定义资源 (CR) 中的每个日志源设置 maxAge
参数。CR 将这些值应用到 Elasticsearch 滚动调度,它决定 Elasticsearch 何时删除滚动索引。
如果索引与以下条件之一匹配,Elasticsearch 会滚动索引,移动当前的索引并创建新索引:
-
索引早于
Elasticsearch
CR 中的rollover.maxAge
值。 - 索引大小超过主分片数乘以 40GB 的值。
- 索引的 doc 数大于主分片数乘以 40960 KB 的值。
Elasticsearch 会根据您配置的保留策略删除滚动索引。如果您没有为任何日志源创建保留策略,则默认在 7 天后删除日志。
先决条件
- 必须安装 Red Hat OpenShift Logging Operator 和 OpenShift Elasticsearch Operator。
步骤
配置日志保留时间:
编辑
ClusterLogging
CR,以添加或修改reservedPolicy
参数:apiVersion: "logging.openshift.io/v1" kind: "ClusterLogging" ... spec: managementState: "Managed" logStore: type: "elasticsearch" retentionPolicy: 1 application: maxAge: 1d infra: maxAge: 7d audit: maxAge: 7d elasticsearch: nodeCount: 3 ...
- 1
- 指定 Elasticsearch 应该保留每个日志源的时间。输入一个整数和时间单位: 周(w)、小时(h/H)、分钟(m)和秒。例如,
1d
代表一天。时间超过maxAge
的旧日志会被删除。默认情况下,日志会保留 7 天。
您可以验证
Elasticsearch
自定义资源(CR)中的设置。例如,Red Hat OpenShift Logging Operator 更新了以下
Elasticsearch
CR 以配置保留策略,包括设置以每八小时滚动基础架构日志的活跃索引,并在滚动后 7 天删除滚动的索引。OpenShift Container Platform 每 15 分钟检查一次,以确定是否需要滚动索引。apiVersion: "logging.openshift.io/v1" kind: "Elasticsearch" metadata: name: "elasticsearch" spec: ... indexManagement: policies: 1 - name: infra-policy phases: delete: minAge: 7d 2 hot: actions: rollover: maxAge: 8h 3 pollInterval: 15m 4 ...
注意不支持修改
Elasticsearch
CR。对保留策略的所有更改都必须在ClusterLogging
CR 中进行。OpenShift Elasticsearch Operator 部署 cron job,以使用定义的策略为每个映射滚动索引,并使用
pollInterval
调度。$ oc get cronjob
输出示例
NAME SCHEDULE SUSPEND ACTIVE LAST SCHEDULE AGE elasticsearch-im-app */15 * * * * False 0 <none> 4s elasticsearch-im-audit */15 * * * * False 0 <none> 4s elasticsearch-im-infra */15 * * * * False 0 <none> 4s
10.4.4. 为日志存储配置 CPU 和内存请求
每个组件规格都允许调整 CPU 和内存请求。您不应该手动调整这些值,因为 OpenShift Elasticsearch Operator 会设置适当的值以满足环境的要求。
在大型集群中,Elasticsearch 代理容器的默认内存限值可能不足,从而导致代理容器被 OOMKilled。如果您遇到这个问题,请提高 Elasticsearch 代理的内存请求和限值。
每个 Elasticsearch 节点都可以在较低的内存设置下运行,但在生产部署中不建议这样做。对于生产环境,为每个 pod 应该分配的数量应不少于默认的 16Gi。最好为每个 pod 分配不超过 64Gi 的尽量多的数量。
先决条件
- 必须安装 Red Hat OpenShift Logging 和 Elasticsearch Operator。
流程
编辑
openshift-logging
项目中的ClusterLogging
自定义资源(CR):$ oc edit ClusterLogging instance
apiVersion: "logging.openshift.io/v1" kind: "ClusterLogging" metadata: name: "instance" .... spec: logStore: type: "elasticsearch" elasticsearch:1 resources: limits: 2 memory: "32Gi" requests: 3 cpu: "1" memory: "16Gi" proxy: 4 resources: limits: memory: 100Mi requests: memory: 100Mi
在调整 Elasticsearch 内存量时,相同的值应该用于请求
和限值
。
例如:
resources: limits: 1 memory: "32Gi" requests: 2 cpu: "8" memory: "32Gi"
Kubernetes 一般遵循节点配置,不允许 Elasticsearch 使用指定的限值。为 请求(request)
和 限值(limit)
设置相同的值可确保 Elasticsearch 可以使用您想要的内存,假设节点具有可用内存。
10.4.5. 为日志存储配置复制策略
您可以定义如何在集群中的数据节点之间复制 Elasticsearch 分片:
先决条件
- 必须安装 Red Hat OpenShift Logging 和 Elasticsearch Operator。
流程
编辑
openshift-logging
项目中的ClusterLogging
自定义资源(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 数据节点的数目。
10.4.6. 缩减 Elasticsearch pod
减少集群中的 Elasticsearch pod 数量可能会导致数据丢失或 Elasticsearch 性能下降。
如果缩减,应该一次缩减一个 pod,并允许集群重新平衡分片和副本。Elasticsearch 健康状态返回绿色
后,您可以根据另一个 pod 进行缩减。
如果 Elasticsearch 集群设置为 ZeroRedundancy
,则不应缩减 Elasticsearch pod。
10.4.7. 为日志存储配置持久性存储
Elasticsearch 需要持久性存储。存储速度越快,Elasticsearch 性能越高。
在 Elasticsearch 存储中不支持将 NFS 存储用作卷或持久性卷(或者通过 NAS 比如 Gluster),因为 Lucene 依赖于 NFS 不提供的文件系统行为。数据崩溃和其他问题可能会发生。
先决条件
- 必须安装 Red Hat OpenShift Logging 和 Elasticsearch Operator。
流程
编辑
ClusterLogging
CR,将集群中的每个数据节点指定为绑定到持久性卷声明。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。
如果将本地卷用于持久性存储,请不要使用原始块卷,这在 LocalVolume
对象中的 volumeMode: block
描述。Elasticsearch 无法使用原始块卷。
10.4.8. 为 emptyDir 存储配置日志存储
您可以将 emptyDir 与 日志存储搭配使用来创建一个临时部署,临时部署一旦重启其中所有 Pod 的数据都会丢失。
使用 emptyDir 时,如果重启或重新部署日志存储,数据将会丢失。
先决条件
- 必须安装 Red Hat OpenShift Logging 和 Elasticsearch Operator。
流程
编辑
ClusterLogging
CR 以指定 emptyDir:spec: logStore: type: "elasticsearch" elasticsearch: nodeCount: 3 storage: {}
10.4.9. 执行 Elasticsearch 集群滚动重启
在更改 elasticsearch
配置映射或任何 elasticsearch-*
部署配置时,执行滚动重启。
此外,如果运行 Elasticsearch Pod 的节点需要重启,则建议滚动重启。
先决条件
- 必须安装 Red Hat OpenShift Logging 和 Elasticsearch Operator。
流程
执行集群滚动重启:
进入
openshift-logging
项目:$ oc project openshift-logging
获取 Elasticsearch Pod 的名称:
$ oc get pods -l component=elasticsearch
缩减收集器 Pod,以便它们停止向 Elasticsearch 发送新日志:
$ oc -n openshift-logging patch daemonset/collector -p '{"spec":{"template":{"spec":{"nodeSelector":{"logging-infra-collector": "false"}}}}}'
使用 OpenShift Container Platform es_util 工具执行分片同步刷新,确保在关机之前没有等待写入磁盘的待定操作:
$ oc exec <any_es_pod_in_the_cluster> -c elasticsearch -- es_util --query="_flush/synced" -XPOST
例如:
$ oc exec -c elasticsearch-cdm-5ceex6ts-1-dcd6c4c7c-jpw6 -c elasticsearch -- es_util --query="_flush/synced" -XPOST
输出示例
{"_shards":{"total":4,"successful":4,"failed":0},".security":{"total":2,"successful":2,"failed":0},".kibana_1":{"total":2,"successful":2,"failed":0}}
使用 OpenShift Container Platform es_util 工具防止在有意关闭节点时进行分片平衡:
$ oc exec <any_es_pod_in_the_cluster> -c elasticsearch -- es_util --query="_cluster/settings" -XPUT -d '{ "persistent": { "cluster.routing.allocation.enable" : "primaries" } }'
例如:
$ oc exec elasticsearch-cdm-5ceex6ts-1-dcd6c4c7c-jpw6 -c elasticsearch -- es_util --query="_cluster/settings" -XPUT -d '{ "persistent": { "cluster.routing.allocation.enable" : "primaries" } }'
输出示例
{"acknowledged":true,"persistent":{"cluster":{"routing":{"allocation":{"enable":"primaries"}}}},"transient":
完成后,会在每个部署中都有一个 ES 集群:
默认情况下,OpenShift Container Platform Elasticsearch 集群会阻止向其节点推出部署。使用以下命令来允许推出部署并允许 Pod 获取更改:
$ oc rollout resume deployment/<deployment-name>
例如:
$ oc rollout resume deployment/elasticsearch-cdm-0-1
输出示例
deployment.extensions/elasticsearch-cdm-0-1 resumed
部署了一个新 Pod。当 Pod 具有就绪的容器后,就能继续进行下一部署。
$ oc get pods -l component=elasticsearch-
输出示例
NAME READY STATUS RESTARTS AGE elasticsearch-cdm-5ceex6ts-1-dcd6c4c7c-jpw6k 2/2 Running 0 22h elasticsearch-cdm-5ceex6ts-2-f799564cb-l9mj7 2/2 Running 0 22h elasticsearch-cdm-5ceex6ts-3-585968dc68-k7kjr 2/2 Running 0 22h
部署完成后,重置 Pod 以禁止推出部署:
$ oc rollout pause deployment/<deployment-name>
例如:
$ oc rollout pause deployment/elasticsearch-cdm-0-1
输出示例
deployment.extensions/elasticsearch-cdm-0-1 paused
检查 Elasticsearch 集群是否处于
green
或yellow
状态:$ oc exec <any_es_pod_in_the_cluster> -c elasticsearch -- es_util --query=_cluster/health?pretty=true
注意如果您对先前命令中使用的 Elasticsearch Pod 执行了推出部署,该 Pod 将不再存在,并且此处需要使用新的 Pod 名称。
例如:
$ oc exec elasticsearch-cdm-5ceex6ts-1-dcd6c4c7c-jpw6 -c elasticsearch -- es_util --query=_cluster/health?pretty=true
{ "cluster_name" : "elasticsearch", "status" : "yellow", 1 "timed_out" : false, "number_of_nodes" : 3, "number_of_data_nodes" : 3, "active_primary_shards" : 8, "active_shards" : 16, "relocating_shards" : 0, "initializing_shards" : 0, "unassigned_shards" : 1, "delayed_unassigned_shards" : 0, "number_of_pending_tasks" : 0, "number_of_in_flight_fetch" : 0, "task_max_waiting_in_queue_millis" : 0, "active_shards_percent_as_number" : 100.0 }
- 1
- 在继续操作前,请确保此参数值为
green
或者yellow
。
- 如果更改了 Elasticsearch 配置映射,请对每个 Elasticsearch Pod 重复这些步骤。
推出集群的所有部署后,重新启用分片平衡:
$ oc exec <any_es_pod_in_the_cluster> -c elasticsearch -- es_util --query="_cluster/settings" -XPUT -d '{ "persistent": { "cluster.routing.allocation.enable" : "all" } }'
例如:
$ oc exec elasticsearch-cdm-5ceex6ts-1-dcd6c4c7c-jpw6 -c elasticsearch -- es_util --query="_cluster/settings" -XPUT -d '{ "persistent": { "cluster.routing.allocation.enable" : "all" } }'
输出示例
{ "acknowledged" : true, "persistent" : { }, "transient" : { "cluster" : { "routing" : { "allocation" : { "enable" : "all" } } } } }
扩展收集器 Pod,以便它们会将新日志发送到 Elasticsearch。
$ oc -n openshift-logging patch daemonset/collector -p '{"spec":{"template":{"spec":{"nodeSelector":{"logging-infra-collector": "true"}}}}}'
10.4.10. 将日志存储服务公开为路由
默认情况下,无法从日志记录集群外部访问部署了日志记录的日志存储。您可以启用一个 re-encryption termination 模式的路由,以实现外部对日志存储服务的访问来获取数据。
另外,还可以在外部创建一个重新加密路由,使用 OpenShift Container Platform 令牌和已安装的 Elasticsearch CA 证书以从外部访问日志存储。然后,使用包含以下内容的 cURL 请求访问托管日志存储服务的节点:
-
Authorization: Bearer ${token}
- Elasticsearch 重新加密路由和 Elasticsearch API 请求。
在内部,可以使用日志存储集群 IP 访问日志存储服务。您可以使用以下命令之一获取它:
$ oc get service elasticsearch -o jsonpath={.spec.clusterIP} -n openshift-logging
输出示例
172.30.183.229
$ oc get service elasticsearch -n openshift-logging
输出示例
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE elasticsearch ClusterIP 172.30.183.229 <none> 9200/TCP 22h
您可以使用类似如下的命令检查集群 IP 地址:
$ oc exec elasticsearch-cdm-oplnhinv-1-5746475887-fj2f8 -n openshift-logging -- 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
先决条件
- 必须安装 Red Hat OpenShift Logging 和 Elasticsearch Operator。
- 您必须具有项目的访问权限,以便能访问其日志。
流程
对外部公开日志存储:
进入
openshift-logging
项目:$ oc project openshift-logging
从日志存储提取 CA 证书并写入 admin-ca 文件:
$ oc extract secret/elasticsearch --to=. --keys=admin-ca
输出示例
admin-ca
以 YAML 文件形式创建日志存储服务的路由:
使用以下内容创建一个 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
- 添加日志存储 CA 证书或使用下一步中的命令。您不必设置一些重新加密路由所需的
spec.tls.key
、spec.tls.certificate
和spec.tls.caCertificate
参数。
运行以下命令,将日志存储 CA 证书添加到您在上一步中创建的路由 YAML 中:
$ cat ./admin-ca | sed -e "s/^/ /" >> <file-name>.yaml
创建路由:
$ oc create -f <file-name>.yaml
输出示例
route.route.openshift.io/elasticsearch created
检查是否公开了 Elasticsearch 服务:
获取此服务帐户的令牌,以便在请求中使用:
$ token=$(oc whoami -t)
将您创建的 Elasticsearch 路由设置为环境变量。
$ routeES=`oc get route elasticsearch -o jsonpath={.spec.host}`
要验证路由是否创建成功,请运行以下命令来通过公开的路由访问 Elasticsearch:
curl -tlsv1.2 --insecure -H "Authorization: Bearer ${token}" "https://${routeES}"
其响应类似于如下:
输出示例
{ "name" : "elasticsearch-cdm-i40ktba0-1", "cluster_name" : "elasticsearch", "cluster_uuid" : "0eY-tJzcR3KOdpgeMJo-MQ", "version" : { "number" : "6.8.1", "build_flavor" : "oss", "build_type" : "zip", "build_hash" : "Unknown", "build_date" : "Unknown", "build_snapshot" : true, "lucene_version" : "7.7.0", "minimum_wire_compatibility_version" : "5.6.0", "minimum_index_compatibility_version" : "5.0.0" }, "<tagline>" : "<for search>" }
10.4.11. 如果不使用默认的 Elasticsearch 日志存储,请删除未使用的组件
作为管理员,在非常罕见的情况下,当您将日志转发到第三方日志存储且不使用默认的 Elasticsearch 存储时,您可以从日志集群中移除几个未使用的组件。
换句话说,如果没有使用默认的 Elasticsearch 日志存储,您可以从 ClusterLogging
自定义资源 (CR) 中删除内部 Elasticsearch logStore
和 Kibana visualization
组件。删除这些组件是可选的,但会保存资源。
先决条件
验证您的日志转发程序没有将日志数据发送到默认的内部 Elasticsearch 集群。检查您用来配置日志转发的
ClusterLogForwarder
CR YAML 文件。验证它没有指定default
的outputRefs
元素。例如:outputRefs: - default
假定 ClusterLogForwarder
CR 将日志数据转发到内部 Elasticsearch 集群,并从 ClusterLogging
CR 中删除 logStore
组件。在这种情况下,内部 Elasticsearch 集群将不存在来存储日志数据。这会导致数据丢失。
流程
编辑
openshift-logging
项目中的ClusterLogging
自定义资源(CR):$ oc edit ClusterLogging instance
-
如果存在,请从
ClusterLogging
CR 中删除logStore
和visualization
小节。 保留
ClusterLogging
CR 的collection
小节。结果应类似以下示例:apiVersion: "logging.openshift.io/v1" kind: "ClusterLogging" metadata: name: "instance" namespace: "openshift-logging" spec: managementState: "Managed" collection: type: "fluentd" fluentd: {}
验证收集器 Pod 是否已重新部署:
$ oc get pods -l component=collector -n openshift-logging