×

您可以配置一个LokiStack CR 来存储应用程序、审计和基础设施相关的日志。

Loki 是一个水平可扩展、高可用、多租户日志聚合系统,作为 Red Hat OpenShift 的 GA 日志存储提供,可以使用 OpenShift 可观测性 UI 进行可视化。OpenShift Logging 提供的 Loki 配置是一个短期日志存储,旨在使用户能够使用收集的日志进行快速故障排除。为此,Red Hat OpenShift 的 Loki 配置具有短期存储,并针对最新的查询进行了优化。

对于长期存储或长时间段的查询,用户应查看集群外部的日志存储。Loki 规模仅针对短期存储进行了测试和支持,最长为 30 天。

Loki 部署规模

Loki 的规模采用1x.<size>的格式,其中值1x是实例数,<size>指定性能能力。

1x.pico 配置定义了一个具有最小资源和限制要求的单一 Loki 部署,为所有 Loki 组件提供高可用性 (HA) 支持。此配置适用于不需要单个复制因子或自动压缩的部署。

不同规模配置的磁盘请求相似,允许客户测试不同的规模以确定最适合其部署需求的规模。

无法更改部署规模的数字1x

表 1. Loki 规模
1x.demo 1x.pico [仅限 6.1+] 1x.extra-small 1x.small 1x.medium

数据传输

仅限演示使用

50GB/天

100GB/天

500GB/天

2TB/天

每秒查询数 (QPS)

仅限演示使用

1-25 QPS,200ms

1-25 QPS,200ms

25-50 QPS,200ms

25-75 QPS,200ms

复制因子

2

2

2

2

总 CPU 请求

7 个 vCPU

14 个 vCPU

34 个 vCPU

54 个 vCPU

如果使用 ruler,则总 CPU 请求

8 个 vCPU

16 个 vCPU

42 个 vCPU

70 个 vCPU

总内存请求

17Gi

31Gi

67Gi

139Gi

如果使用 ruler,则总内存请求

18Gi

35Gi

83Gi

171Gi

总磁盘请求

40Gi

590Gi

430Gi

430Gi

590Gi

如果使用 ruler,则总磁盘请求

80Gi

910Gi

750Gi

750Gi

910Gi

先决条件

  • 您已使用 CLI 或 Web 控制台安装了 Loki Operator。

  • 您在创建ClusterLogForwarder的同一命名空间中拥有一个serviceAccount

  • serviceAccount被分配了collect-audit-logscollect-application-logscollect-infrastructure-logs集群角色。

核心设置和配置

基于角色的访问控制、基本监控和 Pod 部署位置以部署 Loki。

授权 LokiStack 规则 RBAC 权限

管理员可以通过将集群角色绑定到用户名来允许用户创建和管理他们自己的告警和记录规则。集群角色定义为包含用户所需基于角色的访问控制 (RBAC) 权限的ClusterRole对象。

以下集群角色可用于 LokiStack 的告警规则和记录规则

规则名称 描述

alertingrules.loki.grafana.com-v1-admin

拥有此角色的用户具有管理级别的访问权限来管理告警规则。此集群角色授予权限来创建、读取、更新、删除、列出和监视loki.grafana.com/v1 API 组内的AlertingRule资源。

alertingrules.loki.grafana.com-v1-crdview

拥有此角色的用户可以查看与loki.grafana.com/v1 API 组内的AlertingRule资源相关的自定义资源定义 (CRD) 的定义,但没有修改或管理这些资源的权限。

alertingrules.loki.grafana.com-v1-edit

拥有此角色的用户有权创建、更新和删除AlertingRule资源。

alertingrules.loki.grafana.com-v1-view

拥有此角色的用户可以读取loki.grafana.com/v1 API 组内的AlertingRule资源。他们可以检查现有告警规则的配置、标签和注释,但不能对其进行任何修改。

recordingrules.loki.grafana.com-v1-admin

拥有此角色的用户具有管理级别的访问权限来管理记录规则。此集群角色授予权限来创建、读取、更新、删除、列出和监视loki.grafana.com/v1 API 组内的RecordingRule资源。

recordingrules.loki.grafana.com-v1-crdview

拥有此角色的用户可以查看与loki.grafana.com/v1 API 组内的RecordingRule资源相关的自定义资源定义 (CRD) 的定义,但没有修改或管理这些资源的权限。

recordingrules.loki.grafana.com-v1-edit

拥有此角色的用户有权创建、更新和删除RecordingRule资源。

recordingrules.loki.grafana.com-v1-view

拥有此角色的用户可以读取loki.grafana.com/v1 API 组内的RecordingRule资源。他们可以检查现有告警规则的配置、标签和注释,但不能对其进行任何修改。

示例

要为用户应用集群角色,必须将现有集群角色绑定到特定用户名。

集群角色可以是集群范围的或命名空间范围的,具体取决于您使用的角色绑定的类型。当使用RoleBinding对象时(例如使用oc adm policy add-role-to-user命令时),集群角色仅应用于指定的命名空间。当使用ClusterRoleBinding对象时(例如使用oc adm policy add-cluster-role-to-user命令时),集群角色应用于集群中的所有命名空间。

以下示例命令为指定用户授予在集群的特定命名空间中对告警规则进行创建、读取、更新和删除 (CRUD) 的权限

特定命名空间中告警规则 CRUD 权限的集群角色绑定示例命令
$ oc adm policy add-role-to-user alertingrules.loki.grafana.com-v1-admin -n <namespace> <username>

以下命令为指定用户授予对所有命名空间中告警规则的管理员权限

管理员权限的集群角色绑定示例命令
$ oc adm policy add-cluster-role-to-user alertingrules.loki.grafana.com-v1-admin <username>

使用 Loki 创建基于日志的告警规则

AlertingRule CR 包含一组规范和 Webhook 验证定义,用于声明单个LokiStack实例的告警规则组。此外,Webhook 验证定义提供对规则验证条件的支持。

  • 如果AlertingRule CR 包含无效的interval周期,则它是一个无效的告警规则。

  • 如果AlertingRule CR 包含无效的for周期,则它是一个无效的告警规则。

  • 如果AlertingRule CR 包含无效的 LogQL expr,则它是一个无效的告警规则。

  • 如果AlertingRule CR 包含两个名称相同的组,则它是一个无效的告警规则。

  • 如果以上情况均不适用,则告警规则被认为是有效的。

表 2. AlertingRule 定义
租户类型 AlertingRule CR 的有效命名空间

application

<your_application_namespace>

audit

openshift-logging

infrastructure

openshift-/*, kube-/\*, default

步骤
  1. 创建一个AlertingRule自定义资源 (CR)

    基础设施AlertingRule CR 示例
      apiVersion: loki.grafana.com/v1
      kind: AlertingRule
      metadata:
        name: loki-operator-alerts
        namespace: openshift-operators-redhat (1)
        labels: (2)
          openshift.io/<label_name>: "true"
      spec:
        tenantID: "infrastructure" (3)
        groups:
          - name: LokiOperatorHighReconciliationError
            rules:
              - alert: HighPercentageError
                expr: | (4)
                  sum(rate({kubernetes_namespace_name="openshift-operators-redhat", kubernetes_pod_name=~"loki-operator-controller-manager.*"} |= "error" [1m])) by (job)
                    /
                  sum(rate({kubernetes_namespace_name="openshift-operators-redhat", kubernetes_pod_name=~"loki-operator-controller-manager.*"}[1m])) by (job)
                    > 0.01
                for: 10s
                labels:
                  severity: critical (5)
                annotations:
                  summary: High Loki Operator Reconciliation Errors (6)
                  description: High Loki Operator Reconciliation Errors (7)
    1 创建此AlertingRule CR 的命名空间必须具有与 LokiStack spec.rules.namespaceSelector 定义匹配的标签。
    2 labels 块必须与 LokiStack spec.rules.selector 定义匹配。
    3 infrastructure 租户的AlertingRule CR 仅在openshift-*kube-\*default 命名空间中受支持。
    4 kubernetes_namespace_name: 的值必须与metadata.namespace的值匹配。
    5 此必填字段的值必须为criticalwarninginfo
    6 此字段是必填字段。
    7 此字段是必填字段。
    应用程序AlertingRule CR 示例
      apiVersion: loki.grafana.com/v1
      kind: AlertingRule
      metadata:
        name: app-user-workload
        namespace: app-ns (1)
        labels: (2)
          openshift.io/<label_name>: "true"
      spec:
        tenantID: "application"
        groups:
          - name: AppUserWorkloadHighError
            rules:
              - alert:
                expr: | (3)
                  sum(rate({kubernetes_namespace_name="app-ns", kubernetes_pod_name=~"podName.*"} |= "error" [1m])) by (job)
                for: 10s
                labels:
                  severity: critical (4)
                annotations:
                  summary:  (5)
                  description:  (6)
    1 创建此AlertingRule CR 的命名空间必须具有与 LokiStack spec.rules.namespaceSelector 定义匹配的标签。
    2 labels 块必须与 LokiStack spec.rules.selector 定义匹配。
    3 kubernetes_namespace_name: 的值必须与metadata.namespace的值匹配。
    4 此必填字段的值必须为criticalwarninginfo
    5 此必填字段的值是对规则的总结。
    6 此必填字段的值是对规则的详细描述。
  2. 应用AlertingRule CR

    $ oc apply -f <filename>.yaml

配置 Loki 以容忍 memberlist 创建失败

在 OpenShift Container Platform 集群中,管理员通常使用非私有 IP 网络范围。结果,LokiStack memberlist 配置失败,因为默认情况下它只使用私有 IP 网络。

作为管理员,您可以为 memberlist 配置选择 Pod 网络。您可以修改LokiStack自定义资源 (CR) 以在hashRing规范中使用podIP地址。要配置LokiStack CR,请使用以下命令

$ oc patch LokiStack logging-loki -n openshift-logging  --type=merge -p '{"spec": {"hashRing":{"memberlist":{"instanceAddrType":"podIP"},"type":"memberlist"}}}'
包含podIP的 LokiStack 示例
apiVersion: loki.grafana.com/v1
kind: LokiStack
metadata:
  name: logging-loki
  namespace: openshift-logging
spec:
# ...
  hashRing:
    type: memberlist
    memberlist:
      instanceAddrType: podIP
# ...

启用基于流的 Loki 保留策略

您可以根据日志流配置保留策略。这些规则可以在全局范围内、按租户或同时两者设置。如果同时配置两者,则租户规则优先于全局规则。

如果在 s3 存储桶或 LokiStack 自定义资源 (CR) 中未定义保留期限,则日志不会被修剪,它们会永远保留在 s3 存储桶中,这可能会填满 s3 存储空间。

建议使用 Schema v13。

步骤
  1. 创建一个LokiStack CR

    • 启用基于流的全局保留策略,如下例所示

      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: v13
          secret:
            name: logging-loki-s3
            type: aws
        storageClassName: gp3-csi
        tenants:
          mode: openshift-logging
      1 设置所有日志流的保留策略。**注意:此字段不影响对象存储中存储的日志的保留期限。**
      2 将此块添加到 CR 时,将在集群中启用保留策略。
      3 包含用于定义日志流的LogQL 查询。spec: limits
    • 启用基于流的按租户保留策略,如下例所示

      AWS 按租户基于流的保留策略示例
      apiVersion: loki.grafana.com/v1
      kind: LokiStack
      metadata:
        name: logging-loki
        namespace: openshift-logging
      spec:
        limits:
          global:
            retention:
              days: 20
          tenants: (1)
            application:
              retention:
                days: 1
                streams:
                  - days: 4
                    selector: '{kubernetes_namespace_name=~"test.+"}' (2)
            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: v13
          secret:
            name: logging-loki-s3
            type: aws
        storageClassName: gp3-csi
        tenants:
          mode: openshift-logging
      1 按租户设置保留策略。有效的租户类型为applicationauditinfrastructure
      2 包含用于定义日志流的LogQL 查询
  2. 应用LokiStack CR

    $ oc apply -f <filename>.yaml

Loki Pod 部署

您可以通过在 Pod 上使用容忍度或节点选择器来控制 Loki Pod 在哪些节点上运行,并防止其他工作负载使用这些节点。

您可以通过 LokiStack 自定义资源 (CR) 为日志存储 Pod 应用容忍度,并通过节点规范为节点应用污点。节点上的污点是一个key:value对,指示节点排斥所有不允许该污点的 Pod。使用其他 Pod 上不存在的特定key:value对可以确保只有日志存储 Pod 才能在该节点上运行。

包含节点选择器的 LokiStack 示例
apiVersion: loki.grafana.com/v1
kind: LokiStack
metadata:
  name: logging-loki
  namespace: openshift-logging
spec:
# ...
  template:
    compactor: (1)
      nodeSelector:
        node-role.kubernetes.io/infra: "" (2)
    distributor:
      nodeSelector:
        node-role.kubernetes.io/infra: ""
    gateway:
      nodeSelector:
        node-role.kubernetes.io/infra: ""
    indexGateway:
      nodeSelector:
        node-role.kubernetes.io/infra: ""
    ingester:
      nodeSelector:
        node-role.kubernetes.io/infra: ""
    querier:
      nodeSelector:
        node-role.kubernetes.io/infra: ""
    queryFrontend:
      nodeSelector:
        node-role.kubernetes.io/infra: ""
    ruler:
      nodeSelector:
        node-role.kubernetes.io/infra: ""
# ...
1 指定适用于节点选择器的组件 Pod 类型。
2 指定移动到包含已定义标签的节点的 Pod。
包含节点选择器和容忍度的 LokiStack CR 示例
apiVersion: loki.grafana.com/v1
kind: LokiStack
metadata:
  name: logging-loki
  namespace: openshift-logging
spec:
# ...
  template:
    compactor:
      nodeSelector:
        node-role.kubernetes.io/infra: ""
      tolerations:
      - effect: NoSchedule
        key: node-role.kubernetes.io/infra
        value: reserved
      - effect: NoExecute
        key: node-role.kubernetes.io/infra
        value: reserved
    distributor:
      nodeSelector:
        node-role.kubernetes.io/infra: ""
      tolerations:
      - effect: NoSchedule
        key: node-role.kubernetes.io/infra
        value: reserved
      - effect: NoExecute
        key: node-role.kubernetes.io/infra
        value: reserved
      nodeSelector:
        node-role.kubernetes.io/infra: ""
      tolerations:
      - effect: NoSchedule
        key: node-role.kubernetes.io/infra
        value: reserved
      - effect: NoExecute
        key: node-role.kubernetes.io/infra
        value: reserved
    indexGateway:
      nodeSelector:
        node-role.kubernetes.io/infra: ""
      tolerations:
      - effect: NoSchedule
        key: node-role.kubernetes.io/infra
        value: reserved
      - effect: NoExecute
        key: node-role.kubernetes.io/infra
        value: reserved
    ingester:
      nodeSelector:
        node-role.kubernetes.io/infra: ""
      tolerations:
      - effect: NoSchedule
        key: node-role.kubernetes.io/infra
        value: reserved
      - effect: NoExecute
        key: node-role.kubernetes.io/infra
        value: reserved
    querier:
      nodeSelector:
        node-role.kubernetes.io/infra: ""
      tolerations:
      - effect: NoSchedule
        key: node-role.kubernetes.io/infra
        value: reserved
      - effect: NoExecute
        key: node-role.kubernetes.io/infra
        value: reserved
    queryFrontend:
      nodeSelector:
        node-role.kubernetes.io/infra: ""
      tolerations:
      - effect: NoSchedule
        key: node-role.kubernetes.io/infra
        value: reserved
      - effect: NoExecute
        key: node-role.kubernetes.io/infra
        value: reserved
    ruler:
      nodeSelector:
        node-role.kubernetes.io/infra: ""
      tolerations:
      - effect: NoSchedule
        key: node-role.kubernetes.io/infra
        value: reserved
      - effect: NoExecute
        key: node-role.kubernetes.io/infra
        value: reserved
    gateway:
      nodeSelector:
        node-role.kubernetes.io/infra: ""
      tolerations:
      - effect: NoSchedule
        key: node-role.kubernetes.io/infra
        value: reserved
      - effect: NoExecute
        key: node-role.kubernetes.io/infra
        value: reserved
# ...

要配置 LokiStack (CR) 的nodeSelectortolerations字段,可以使用oc explain命令查看特定资源的描述和字段。

$ oc explain lokistack.spec.template
示例输出
KIND:     LokiStack
VERSION:  loki.grafana.com/v1

RESOURCE: template <Object>

DESCRIPTION:
     Template defines the resource/limits/tolerations/nodeselectors per
     component

FIELDS:
   compactor	<Object>
     Compactor defines the compaction component spec.

   distributor	<Object>
     Distributor defines the distributor component spec.
...

有关更详细的信息,您可以添加特定字段。

$ oc explain lokistack.spec.template.compactor
示例输出
KIND:     LokiStack
VERSION:  loki.grafana.com/v1

RESOURCE: compactor <Object>

DESCRIPTION:
     Compactor defines the compaction component spec.

FIELDS:
   nodeSelector	<map[string]string>
     NodeSelector defines the labels required by a node to schedule the
     component onto it.
...

增强的可靠性和性能

确保 Loki 在生产环境中可靠高效的配置。

使用短期令牌启用对基于云的日志存储的认证

工作负载身份联合允许使用短期令牌对基于云的日志存储进行身份验证。

步骤
  • 使用以下选项之一启用身份验证:

    • 如果您使用 OpenShift Container Platform Web 控制台安装 Loki Operator,则会自动检测使用短期令牌的集群。系统会提示您创建角色并提供 Loki Operator 创建CredentialsRequest对象所需的数据,该对象会填充一个密钥。

    • 如果您使用 OpenShift CLI (oc) 安装 Loki Operator,则必须使用适合您存储提供程序的模板手动创建一个Subscription对象,如下例所示。此身份验证策略仅支持指示的存储提供程序。

      Azure 示例订阅
      apiVersion: operators.coreos.com/v1alpha1
      kind: Subscription
      metadata:
        name: loki-operator
        namespace: openshift-operators-redhat
      spec:
        channel: "stable-6.0"
        installPlanApproval: Manual
        name: loki-operator
        source: redhat-operators
        sourceNamespace: openshift-marketplace
        config:
          env:
            - name: CLIENTID
              value: <your_client_id>
            - name: TENANTID
              value: <your_tenant_id>
            - name: SUBSCRIPTIONID
              value: <your_subscription_id>
            - name: REGION
              value: <your_region>
      AWS 示例订阅
      apiVersion: operators.coreos.com/v1alpha1
      kind: Subscription
      metadata:
        name: loki-operator
        namespace: openshift-operators-redhat
      spec:
        channel: "stable-6.0"
        installPlanApproval: Manual
        name: loki-operator
        source: redhat-operators
        sourceNamespace: openshift-marketplace
        config:
          env:
          - name: ROLEARN
            value: <role_ARN>

配置 Loki 以容忍节点故障

Loki Operator 支持设置 Pod 反亲和性规则,以请求将相同组件的 Pod 调度到集群中不同的可用节点上。

亲和性是 Pod 的一个属性,它控制 Pod 优先在其上调度的节点。反亲和性是 Pod 的一个属性,它阻止 Pod 在节点上调度。

在 OpenShift Container Platform 中,Pod 亲和性Pod 反亲和性允许您根据其他 Pod 上的键值标签来约束 Pod 可以调度到的节点。

Operator 为所有 Loki 组件设置默认的、首选的podAntiAffinity规则,其中包括compactordistributorgatewayindexGatewayingesterquerierqueryFrontendruler组件。

您可以通过在requiredDuringSchedulingIgnoredDuringExecution字段中配置必需的设置来覆盖 Loki 组件的首选podAntiAffinity设置。

ingester 组件的用户设置示例
apiVersion: loki.grafana.com/v1
kind: LokiStack
metadata:
  name: logging-loki
  namespace: openshift-logging
spec:
# ...
  template:
    ingester:
      podAntiAffinity:
      # ...
        requiredDuringSchedulingIgnoredDuringExecution: (1)
        - labelSelector:
            matchLabels: (2)
              app.kubernetes.io/component: ingester
          topologyKey: kubernetes.io/hostname
# ...
1 定义必需规则的节。
2 必须匹配以应用规则的键值对(标签)。

集群重启期间 LokiStack 的行为

当 OpenShift Container Platform 集群重启时,LokiStack 数据摄取和查询路径将继续在节点可用的 CPU 和内存资源内运行。这意味着在 OpenShift Container Platform 集群更新期间,LokiStack 不会出现停机时间。此行为是通过使用PodDisruptionBudget资源实现的。Loki Operator 为 Loki 提供PodDisruptionBudget资源,这些资源决定了在某些条件下必须为每个组件提供的 Pod 最小数量以确保正常运行。

高级部署和可扩展性

用于高可用性、可扩展性和错误处理的专用配置。

区域感知数据复制

Loki Operator 支持通过 Pod topology spread constraints 实现区域感知数据复制。启用此功能可以增强可靠性,并在单个区域发生故障时防止日志丢失。当将部署大小配置为1x.extra-small1x.small1x.medium时,replication.factor字段会自动设置为 2。

为了确保正确的复制,您至少需要与复制因子指定的可用区域数量一样多的可用区域。虽然可以拥有比复制因子更多的可用区域,但拥有较少的区域会导致写入失败。为了获得最佳操作,每个区域都应托管相同数量的实例。

启用了区域复制的 LokiStack CR 示例
apiVersion: loki.grafana.com/v1
kind: LokiStack
metadata:
 name: logging-loki
 namespace: openshift-logging
spec:
 replicationFactor: 2 (1)
 replication:
   factor: 2 (2)
   zones:
   -  maxSkew: 1 (3)
      topologyKey: topology.kubernetes.io/zone (4)
1 已弃用的字段,输入的值会被replication.factor覆盖。
2 在安装时选择部署大小后,会自动设置此值。
3 任何两个拓扑域之间 Pod 数量的最大差异。默认为 1,您不能指定值为 0。
4 以拓扑键的形式定义区域,该键对应于节点标签。

从故障区域恢复 Loki Pod

在 OpenShift Container Platform 中,区域故障发生在特定可用区域资源变得不可访问时。可用区域是云提供商数据中心内的隔离区域,旨在增强冗余性和容错能力。如果您的 OpenShift Container Platform 集群未配置为处理此问题,则区域故障可能导致服务或数据丢失。

Loki Pod 是StatefulSet的一部分,它们带有由StorageClass对象提供的持久卷声明 (PVC)。每个 Loki Pod 及其 PVC 都位于同一区域。当集群中发生区域故障时,StatefulSet 控制器会自动尝试恢复故障区域中受影响的 Pod。

以下过程将删除故障区域中的 PVC 及其中包含的所有数据。为了避免完全丢失数据,应始终将LokiStackCR 的复制因子字段设置为大于 1 的值,以确保 Loki 正在进行复制。

先决条件
  • 验证您的LokiStackCR 的复制因子是否大于 1。

  • 控制平面检测到区域故障,并且云提供商集成标记了故障区域中的节点。

StatefulSet 控制器会自动尝试重新调度失败区域中的 Pod。由于关联的 PVC 也在失败区域中,因此无法自动重新调度到其他区域。您必须手动删除失败区域中的 PVC,才能成功重新创建 stateful Loki Pod 及其在新区域中配置的 PVC。

步骤
  1. 运行以下命令列出状态为“Pending”的 Pod:

    $ oc get pods --field-selector status.phase==Pending -n openshift-logging
    示例 oc get pods 输出:
    NAME                           READY   STATUS    RESTARTS   AGE (1)
    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 位于失败区域。
  2. 运行以下命令列出状态为“Pending”的 PVC:

    $ oc get pvc -o=json -n openshift-logging | jq '.items[] | select(.status.phase == "Pending") | .metadata.name' -r
    示例 oc 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
  3. 运行以下命令删除 Pod 的 PVC:

    $ oc delete pvc <pvc_name>  -n openshift-logging
  4. 运行以下命令删除 Pod:

    $ oc delete pod <pod_name>  -n openshift-logging

    成功删除这些对象后,它们应该会自动在可用区域中重新调度。

排查终止状态下的 PVC

如果 PVC 元数据最终器设置为 kubernetes.io/pv-protection,则 PVC 可能会挂起在终止状态而不会被删除。删除最终器应该允许 PVC 成功删除。

  • 运行以下命令删除每个 PVC 的最终器,然后重试删除操作。

    $ oc patch pvc <pvc_name> -p '{"metadata":{"finalizers":null}}' -n openshift-logging

排查 Loki 速率限制错误

如果日志转发器 API 转发的大量消息块超过 Loki 的速率限制,Loki 将生成速率限制 (429) 错误。

这些错误可能在正常运行期间发生。例如,当向已包含某些日志的集群添加日志时,在日志尝试摄取所有现有日志条目期间可能会发生速率限制错误。在这种情况下,如果新日志添加的速率小于总速率限制,则最终会摄取历史数据,并且速率限制错误会在无需用户干预的情况下解决。

如果速率限制错误持续发生,可以通过修改 LokiStack 自定义资源 (CR) 来解决此问题。

Grafana 托管的 Loki 上不提供 LokiStack CR。本主题不适用于 Grafana 托管的 Loki 服务器。

条件
  • 日志转发器 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 exceeded
    示例 Vector 错误消息:
    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=true
    示例 Fluentd 错误消息:
    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 摄取器 Pod 中:

    示例 Loki 摄取器错误消息:
    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
步骤
  • 更新 LokiStack CR 中的 ingestionBurstSizeingestionRate 字段。

    apiVersion: loki.grafana.com/v1
    kind: LokiStack
    metadata:
      name: logging-loki
      namespace: openshift-logging
    spec:
      limits:
        global:
          ingestion:
            ingestionBurstSize: 16 (1)
            ingestionRate: 8 (2)
    # ...
    1 ingestionBurstSize 字段定义每个分发器副本的最大本地速率限制样本大小(以 MB 为单位)。此值是硬限制。将此值至少设置为单个推送请求中预期的最大日志大小。不允许大小大于 ingestionBurstSize 值的单个请求。
    2 ingestionRate 字段是对每秒摄取样本最大数量(以 MB 为单位)的软限制。如果日志速率超过限制,则会发生速率限制错误,但收集器会重试发送日志。只要总平均值低于限制,系统就会恢复,并且错误会在无需用户干预的情况下解决。