13.3. 配置 LokiStack 日志存储
在日志记录文档中,LokiStack 指的是 Loki 和 Web 代理与 OpenShift Container Platform 身份验证集成的日志记录组合。LokiStack 的代理使用 OpenShift Container Platform 身份验证来强制实施多租户。Loki 将日志存储指代为单个组件或外部存储。
13.3.1. 为 cluster-admin 用户角色创建新组 复制链接链接已复制到粘贴板!
以 cluster-admin 用户身份查询多个命名空间的应用程序日志,其中集群中所有命名空间的字符总和大于 5120,会导致错误 Parse error: input size too long (XXXX > 5120)。为了更好地控制 LokiStack 中日志的访问,请使 cluster-admin 用户成为 cluster-admin 组的成员。如果 cluster-admin 组不存在,请创建它并将所需的用户添加到其中。
使用以下步骤为具有 cluster-admin 权限的用户创建新组。
流程
输入以下命令创建新组:
$ oc adm groups new cluster-admin输入以下命令将所需的用户添加到
cluster-admin组中:$ oc adm groups add-users cluster-admin <username>输入以下命令在组中添加
cluster-admin用户角色:$ oc adm policy add-cluster-role-to-group cluster-admin cluster-admin
13.3.2. 集群重启过程中的 LokiStack 行为 复制链接链接已复制到粘贴板!
在日志记录版本 5.8 及更新版本中,当 OpenShift Container Platform 集群重启时,Loki ingestion 和查询路径将继续在节点的可用 CPU 和内存资源中运行。这意味着 OpenShift Container Platform 集群更新过程中,LokiStack 没有停机。此行为通过使用 PodDisruptionBudget 资源来实现。Loki Operator 为 Loki 置备 PodDisruptionBudget 资源,它决定了每个组件必须可用的最少 pod 数量,以确保特定条件下正常操作。
13.3.3. 配置 Loki 以容忍节点故障 复制链接链接已复制到粘贴板!
在日志记录 5.8 及更新的版本中,Loki Operator 支持设置 pod 反关联性规则,以请求同一组件的 pod 调度到集群中的不同可用节点上。
关联性是 pod 的一个属性,用于控制它们希望调度到的节点。反关联性是 pod 的一个属性,用于阻止 pod 调度到某个节点上。
在 OpenShift Container Platform 中,可以借助 pod 关联性和 pod 反关联性来根据其他 pod 上的键/值标签限制 pod 有资格调度到哪些节点。
Operator 会为所有 Loki 组件设置默认、首选的 podAntiAffinity 规则,其中包括 compactor, distributor, gateway, indexGateway, ingester, querier, queryFrontend, 和 ruler 组件。
您可以通过在 requiredDuringSchedulingIgnoredDuringExecution 字段中配置所需的设置来覆盖 Loki 组件的首选 podAntiAffinity 设置:
ingester 组件的用户设置示例
apiVersion: loki.grafana.com/v1
kind: LokiStack
metadata:
name: logging-loki
namespace: openshift-logging
spec:
# ...
template:
ingester:
podAntiAffinity:
# ...
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchLabels:
app.kubernetes.io/component: ingester
topologyKey: kubernetes.io/hostname
# ...
13.3.4. 支持区域的数据复制 复制链接链接已复制到粘贴板!
在日志记录 5.8 及更新的版本中,Loki Operator 通过 pod 拓扑分布限制支持区感知数据复制。启用这个功能可提高可靠性,并防止出现单一区域故障的日志丢失。在将部署大小配置为 1x.extra-small, 1x.small, 或 1x.medium 时,replication.factor 字段会自动设置为 2。
为确保正确复制,您需要至少具有与复制因子指定的可用区数量。虽然可用区可能会比复制因素更多,但区域数量较少可能会导致写入失败。每个区域应托管相等的实例数量,以实现最佳操作。
启用区复制的 LokiStack CR 示例
apiVersion: loki.grafana.com/v1
kind: LokiStack
metadata:
name: logging-loki
namespace: openshift-logging
spec:
replicationFactor: 2
replication:
factor: 2
zones:
- maxSkew: 1
topologyKey: topology.kubernetes.io/zone
13.3.4.1. 从失败的区恢复 Loki pod 复制链接链接已复制到粘贴板!
在 OpenShift Container Platform 中,当特定可用区资源无法访问时,会发生区失败。可用性区域是云提供商数据中心内的隔离区域,旨在增强冗余和容错能力。如果您的 OpenShift Container Platform 集群没有配置为处理此操作,则区失败可能会导致服务或数据丢失。
Loki pod 是 StatefulSet 的一部分,它们附带 StorageClass 对象置备的 PVC。每个 Loki pod 及其 PVC 驻留在同一区域中。当在集群中发生区故障时,StatefulSet 控制器会自动尝试恢复失败的区中受影响的 pod。
以下流程将删除失败的区中的 PVC,以及其中包含的所有数据。为了避免完成数据丢失的 LokiStack CR 的 replication factor 字段,应该始终设置为大于 1 的值,以确保 Loki 复制。
先决条件
- 日志记录版本 5.8 或更高版本。
-
验证
LokiStackCR 是否具有大于 1 的复制因素。 - control plane 检测到区失败,故障区中的节点由云供应商集成标记。
StatefulSet 控制器会自动尝试重新调度失败的区中的 pod。因为关联的 PVC 也位于失败的区中,所以自动重新调度到不同的区无法正常工作。您必须手动删除失败的区中 PVC,以便在新区中成功重新创建有状态 Loki Pod 及其置备的 PVC。
流程
运行以下命令,列出处于
Pending状态的 pod:$ oc get pods --field-selector status.phase==Pending -n openshift-loggingoc get pods输出示例NAME READY STATUS RESTARTS AGE1 logging-loki-index-gateway-1 0/1 Pending 0 17m logging-loki-ingester-1 0/1 Pending 0 16m logging-loki-ruler-1 0/1 Pending 0 16m- 1
- 这些 pod 处于
Pending状态,因为它们对应的 PVC 位于失败的区中。
运行以下命令,列出处于
Pending状态的 PVC:$ oc get pvc -o=json -n openshift-logging | jq '.items[] | select(.status.phase == "Pending") | .metadata.name' -roc get pvc输出示例storage-logging-loki-index-gateway-1 storage-logging-loki-ingester-1 wal-logging-loki-ingester-1 storage-logging-loki-ruler-1 wal-logging-loki-ruler-1运行以下命令,删除 pod 的 PVC:
$ oc delete pvc __<pvc_name>__ -n openshift-logging然后,运行以下命令来删除 pod:
$ oc delete pod __<pod_name>__ -n openshift-logging
成功删除这些对象后,应在可用区域中自动重新调度它们。
13.3.4.1.1. 对处于终止状态的 PVC 进行故障排除 复制链接链接已复制到粘贴板!
如果 PVC 元数据终结器被设置为 kubernetes.io/pv-protection,PVC 可能会处于 terminating 状态。删除终结器应该允许 PVC 成功删除。
运行以下命令删除每个 PVC 的终结器,然后重试删除。
$ oc patch pvc __<pvc_name>__ -p '{"metadata":{"finalizers":null}}' -n openshift-logging
13.3.5. 对 Loki 日志的精细访问 复制链接链接已复制到粘贴板!
在日志记录 5.8 及更高版本中,Red Hat OpenShift Logging Operator 默认不授予所有用户对日志的访问权限。作为管理员,您需要配置用户访问权限,除非 Operator 已升级并且以前的配置已就位。根据您的配置和需要,您可以使用以下内容配置对日志的精细访问:
- 集群范围内的策略
- 命名空间范围策略
- 创建自定义 admin 组
作为管理员,您需要创建适合部署的角色绑定和集群角色绑定。Red Hat OpenShift Logging Operator 提供以下集群角色:
-
cluster-logging-application-view授予读取应用程序日志的权限。 -
cluster-logging-infrastructure-view授予读取基础架构日志的权限。 -
cluster-logging-audit-view授予读取审计日志的权限。
如果您从以前的版本升级,则额外的集群角色 logging-application-logs-reader 和关联的集群角色绑定 logging-all-authenticated-application-logs-reader 提供向后兼容性,允许任何经过身份验证的用户在命名空间中读取访问权限。
在查询应用程序日志时,具有命名空间权限的用户必须提供命名空间。
13.3.5.1. 集群范围内的访问 复制链接链接已复制到粘贴板!
集群角色绑定资源引用集群角色,以及设置集群范围的权限。
ClusterRoleBinding 示例
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: logging-all-application-logs-reader
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-logging-application-view
subjects:
- kind: Group
name: system:authenticated
apiGroup: rbac.authorization.k8s.io
13.3.5.2. 命名空间访问 复制链接链接已复制到粘贴板!
RoleBinding 资源可用于 ClusterRole 对象来定义用户或组可以访问日志的命名空间。
RoleBinding 示例
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: allow-read-logs
namespace: log-test-0
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-logging-application-view
subjects:
- kind: User
apiGroup: rbac.authorization.k8s.io
name: testuser-0
- 1
- 指定此
RoleBinding应用到的命名空间。
13.3.5.3. 自定义 admin 组访问 复制链接链接已复制到粘贴板!
如果您的大型部署具有多个需要更广泛的权限的用户,您可以使用 adminGroup 字段创建一个自定义组。属于 LokiStack CR 的 adminGroups 字段中指定的任何组的成员的用户被视为管理员。
如果管理员还分配了 cluster-logging-application-view 角色,则管理员用户可以访问所有命名空间中的所有应用程序日志。
LokiStack CR 示例
apiVersion: loki.grafana.com/v1
kind: LokiStack
metadata:
name: logging-loki
namespace: openshift-logging
spec:
tenants:
mode: openshift-logging
openshift:
adminGroups:
- cluster-admin
- custom-admin-group
13.3.6. 使用 Loki 启用基于流的保留 复制链接链接已复制到粘贴板!
使用日志记录版本 5.6 及更高版本,您可以根据日志流配置保留策略。这些规则可全局设置,每个租户或两个都设置。如果同时配置这两个,则租户规则会在全局规则之前应用。
如果没有在 s3 存储桶或 LokiStack 自定义资源 (CR) 中定义保留周期,则不会修剪日志,它们会永久保留在 s3 存储桶中,这可能会填满 s3 存储。
虽然日志记录版本 5.9 和更高版本支持模式 v12,但建议使用 v13。
要启用基于流的保留,请创建一个
LokiStackCR:AWS 的基于流的全局保留示例
apiVersion: loki.grafana.com/v1 kind: LokiStack metadata: name: logging-loki namespace: openshift-logging spec: limits: global:1 retention:2 days: 20 streams: - days: 4 priority: 1 selector: '{kubernetes_namespace_name=~"test.+"}'3 - days: 1 priority: 1 selector: '{log_type="infrastructure"}' managementState: Managed replicationFactor: 1 size: 1x.small storage: schemas: - effectiveDate: "2020-10-11" version: v11 secret: name: logging-loki-s3 type: aws storageClassName: gp3-csi tenants: mode: openshift-logging
AWS 的基于流的基于流的保留示例
apiVersion: loki.grafana.com/v1
kind: LokiStack
metadata:
name: logging-loki
namespace: openshift-logging
spec:
limits:
global:
retention:
days: 20
tenants:
application:
retention:
days: 1
streams:
- days: 4
selector: '{kubernetes_namespace_name=~"test.+"}'
infrastructure:
retention:
days: 5
streams:
- days: 1
selector: '{kubernetes_namespace_name=~"openshift-cluster.+"}'
managementState: Managed
replicationFactor: 1
size: 1x.small
storage:
schemas:
- effectiveDate: "2020-10-11"
version: v11
secret:
name: logging-loki-s3
type: aws
storageClassName: gp3-csi
tenants:
mode: openshift-logging
2 应用 LokiStack CR:
$ oc apply -f <filename>.yaml
13.3.7. Loki 速率限制错误故障排除 复制链接链接已复制到粘贴板!
如果 Log Forwarder API 将超过速率限制的大量信息转发到 Loki,Loki 会生成速率限制(429)错误。
这些错误可能会在正常操作过程中发生。例如,当将 logging 添加到已具有某些日志的集群中时,logging 会尝试充分利用现有日志条目时可能会出现速率限制错误。在这种情况下,如果添加新日志的速度小于总速率限值,历史数据最终会被处理,并且不要求用户干预即可解决速率限制错误。
如果速率限制错误持续发生,您可以通过修改 LokiStack 自定义资源(CR)来解决此问题。
LokiStack CR 在 Grafana 托管的 Loki 上不可用。本主题不适用于 Grafana 托管的 Loki 服务器。
Conditions
- Log Forwarder API 配置为将日志转发到 Loki。
您的系统向 Loki 发送大于 2 MB 的消息块。例如:
"values":[["1630410392689800468","{\"kind\":\"Event\",\"apiVersion\":\ ....... ...... ...... ...... \"received_at\":\"2021-08-31T11:46:32.800278+00:00\",\"version\":\"1.7.4 1.6.0\"}},\"@timestamp\":\"2021-08-31T11:46:32.799692+00:00\",\"viaq_index_name\":\"audit-write\",\"viaq_msg_id\":\"MzFjYjJkZjItNjY0MC00YWU4LWIwMTEtNGNmM2E5ZmViMGU4\",\"log_type\":\"audit\"}"]]}]}输入
oc logs -n openshift-logging -l component=collector后,集群中的收集器日志会显示包含以下错误消息之一的行:429 Too Many Requests Ingestion rate limit exceededVector 错误消息示例
2023-08-25T16:08:49.301780Z WARN sink{component_kind="sink" component_id=default_loki_infra component_type=loki component_name=default_loki_infra}: vector::sinks::util::retries: Retrying after error. error=Server responded with an error: 429 Too Many Requests internal_log_rate_limit=trueFluentd 错误消息示例
2023-08-30 14:52:15 +0000 [warn]: [default_loki_infra] failed to flush the buffer. retry_times=2 next_retry_time=2023-08-30 14:52:19 +0000 chunk="604251225bf5378ed1567231a1c03b8b" error_class=Fluent::Plugin::LokiOutput::LogPostError error="429 Too Many Requests Ingestion rate limit exceeded for user infrastructure (limit: 4194304 bytes/sec) while attempting to ingest '4082' lines totaling '7820025' bytes, reduce log volume or contact your Loki administrator to see if the limit can be increased\n"在接收结束时也会看到这个错误。例如,在 LokiStack ingester pod 中:
Loki ingester 错误消息示例
level=warn ts=2023-08-30T14:57:34.155592243Z caller=grpc_logging.go:43 duration=1.434942ms method=/logproto.Pusher/Push err="rpc error: code = Code(429) desc = entry with timestamp 2023-08-30 14:57:32.012778399 +0000 UTC ignored, reason: 'Per stream rate limit exceeded (limit: 3MB/sec) while attempting to ingest for stream
流程
更新
LokiStackCR 中的ingestionBurstSize和ingestionRate字段:apiVersion: loki.grafana.com/v1 kind: LokiStack metadata: name: logging-loki namespace: openshift-logging spec: limits: global: ingestion: ingestionBurstSize: 161 ingestionRate: 82 # ...
13.3.8. 配置 Loki 以容许 memberlist 创建失败 复制链接链接已复制到粘贴板!
在 OpenShift 集群中,管理员通常使用非专用 IP 网络范围。因此,Loki memberlist 配置会失败,因为默认情况下,它只使用私有 IP 网络。
作为管理员,您可以为 memberlist 配置选择 pod 网络。您可以修改 LokiStack CR,以使用 hashRing spec 中的 podIP。要配置 LokiStack CR,请使用以下命令:
$ oc patch LokiStack logging-loki -n openshift-logging --type=merge -p '{"spec": {"hashRing":{"memberlist":{"instanceAddrType":"podIP","type": "memberlist"}}}}'
LokiStack 示例,使其包含 podIP
apiVersion: loki.grafana.com/v1
kind: LokiStack
metadata:
name: logging-loki
namespace: openshift-logging
spec:
# ...
hashRing:
type: memberlist
memberlist:
instanceAddrType: podIP
# ...