9.4. 配置日志转发

在日志记录部署中,容器和基础架构日志默认转发到 ClusterLogging 自定义资源(CR)中定义的内部日志存储。

默认情况下,审计日志不会转发到内部日志存储,因为这不提供安全存储。您需要自己确保转发审计日志的系统符合您所在机构及政府的相关要求,并具有适当的安全性。

如果此默认配置满足您的需要,则不需要配置一个 ClusterLogForwarder CR。如果存在 ClusterLogForwarder CR,日志不会转发到内部日志存储,除非定义了包含 default 输出的管道。

9.4.1. 关于将日志转发到第三方系统

要将日志发送到 OpenShift Container Platform 集群内部和外部的特定端点,您可以在 ClusterLogForwarder 自定义资源(CR)中指定输出管道的组合。您还可以使用 输入 将与特定项目关联的应用程序日志转发到端点。身份验证由 Kubernetes Secret 对象提供。

pipeline

定义从一个日志类型到一个或多个输出的简单路由,或定义您要发送的日志。日志类型是以下之一:

  • application.由集群中运行的用户应用程序生成的容器日志(基础架构容器应用程序除外)。
  • infrastructure.在 openshift*kube*default 项目中运行的容器日志,以及来源于节点文件系统的 journal 日志。
  • audit.由节点审计系统、auditd、Kubernetes API 服务器、OpenShift API 服务器和 OVN 网络生成的审计日志。

您可以使用管道中的 key:value 对为出站日志消息添加标签。例如,您可以在转发给其他数据中心的消息中添加一个标签,或者根据类型为日志添加标签。添加到对象的标签也会通过日志消息转发。

输入

将与特定项目关联的应用程序日志转发到管道。

在管道中,您要定义使用 inputRef 参数转发哪些日志类型,以及将日志转发到使用 outputRef 参数的位置。

Secret
包含机密数据的 key:value 映射,如用户凭据。

注意以下几点:

  • 如果您没有为日志类型定义管道,则将丢弃未定义类型的日志。例如,如果您为 applicationaudit 类型指定管道,但没有为 infrastructure 类型指定管道,则 infrastructure 日志会丢弃。
  • 您可以使用 ClusterLogForwarder 自定义资源(CR)中的多种输出类型将日志发送到支持不同协议的服务器。

以下示例将审计日志转发到安全的外部 Elasticsearch 实例,基础架构日志发送到不安全的外部 Elasticsearch 实例,应用程序日志发送到 Kafka 代理,以及 my-apps-logs 项目中的应用程序日志发送到内部 Elasticsearch 实例。

日志转发输出和管道示例

apiVersion: "logging.openshift.io/v1"
kind: ClusterLogForwarder
metadata:
  name: <log_forwarder_name> 1
  namespace: <log_forwarder_namespace> 2
spec:
  serviceAccountName: <service_account_name> 3
  outputs:
   - name: elasticsearch-secure 4
     type: "elasticsearch"
     url: https://elasticsearch.secure.com:9200
     secret:
        name: elasticsearch
   - name: elasticsearch-insecure 5
     type: "elasticsearch"
     url: http://elasticsearch.insecure.com:9200
   - name: kafka-app 6
     type: "kafka"
     url: tls://kafka.secure.com:9093/app-topic
  inputs: 7
   - name: my-app-logs
     application:
        namespaces:
        - my-project
  pipelines:
   - name: audit-logs 8
     inputRefs:
      - audit
     outputRefs:
      - elasticsearch-secure
      - default
     labels:
       secure: "true" 9
       datacenter: "east"
   - name: infrastructure-logs 10
     inputRefs:
      - infrastructure
     outputRefs:
      - elasticsearch-insecure
     labels:
       datacenter: "west"
   - name: my-app 11
     inputRefs:
      - my-app-logs
     outputRefs:
      - default
   - inputRefs: 12
      - application
     outputRefs:
      - kafka-app
     labels:
       datacenter: "south"

1
在传统的实现中,CR 名称必须是 instance。在多日志转发器实现中,您可以使用任何名称。
2
在旧的实现中,CR 命名空间必须是 openshift-logging。在多日志转发器实现中,您可以使用任何命名空间。
3
服务帐户的名称。如果没有在 openshift-logging 命名空间中部署日志转发器,则只有多日志转发器实现中才需要服务帐户。
4
使用带有安全 URL 的 secret 来配置安全 Elasticsearch 输出。
  • 描述输出的名称。
  • 输出类型: elasticsearch
  • Elasticsearch 实例的安全 URL 和端口作为有效的绝对 URL,包括前缀。
  • 用于 TLS 通信的端点所需的 secret。secret 必须存在于 openshift-logging 项目中。
5
配置不安全的 Elasticsearch 输出:
  • 描述输出的名称。
  • 输出类型: elasticsearch
  • Elasticsearch 实例的不安全 URL 和端口作为有效的绝对 URL,包括前缀。
6
使用客户端验证的 TLS 通信通过安全 URL 配置 Kafka 输出:
  • 描述输出的名称。
  • 输出的类型: kafka
  • 将 Kafka 代理的 URL 和端口指定为一个有效的绝对 URL,包括前缀。
7
用于过滤 my-project 命名空间中的应用程序日志的输入配置。
8
用于将审计日志发送到安全的外部 Elasticsearch 实例的管道配置:
  • 描述管道的名称。
  • inputRefs 是日志类型,在这个示例中是 audit
  • outputRefs 是输出使用的名称,在本例中,elasticsearch-secure 可以转发到安全的 Elasticsearch 实例,default 转发到内部 Elasticsearch 实例。
  • 可选:添加到日志的标签。
9
可选:字符串。要添加到日志中的一个或多个标签。对值加引号(如 "true"),以便它们被识别为字符串值,而不是作为布尔值。
10
管道配置,将基础架构日志发送到不安全的外部 Elasticsearch 实例。
11
管道配置,用于将日志从 my-project 项目发送到内部 Elasticsearch 实例。
  • 描述管道的名称。
  • inputRefs 是一个特定的输入: my-app-logs
  • outputRefsdefault
  • 可选:字符串。要添加到日志中的一个或多个标签。
12
将日志发送到 Kafka 代理的管道配置,不带有管道名称:
  • inputRefs 是日志类型,在这个示例中是 application
  • outputRefs 是要使用的输出名称。
  • 可选:字符串。要添加到日志中的一个或多个标签。
当外部日志聚合器不可用时,Fluentd 日志处理

如果外部日志记录聚合器不可用且无法接收日志,Fluentd 会继续收集日志并将其存储在缓冲中。当日志聚合器可用时,日志转发会恢复,包括缓冲的日志。如果缓冲区已满,Fluentd 会停止收集日志。OpenShift Container Platform 轮转日志并删除日志。您无法调整缓冲区大小,或者将持久性卷声明(PVC)添加到 Fluentd 守护进程集或 Pod 中。

支持的授权密钥

这里提供了常见的密钥类型。某些输出类型支持额外的专用密钥,记录在特定于输出的配置字段中。所有 secret 密钥都是可选的。通过设置相关密钥来启用您想要的安全功能。您需要创建并维护外部目的地可能需要的额外配置,如密钥和 secret 、服务帐户、端口打开或全局代理服务器配置。Open Shift Logging 不会尝试验证授权组合间的不匹配。

传输层安全性(TLS)

使用没有 secret 的 TLS URL (http://...ssl://...) 启用基本的 TLS 服务器端身份验证。可通过包含 Secret 并设置以下可选字段来启用额外的 TLS 功能:

  • 密码短语 :(字符串)对编码的 TLS 私钥进行解码。需要 tls.key
  • ca-bundle.crt: (字符串)用于服务器身份验证的客户 CA 的文件名。
用户名和密码
  • username :(字符串)身份验证用户名。需要 password
  • password :(字符串)身份验证密码。需要 username
简单身份验证安全层(SASL)
  • sasl.enable (布尔值)明确指定启用或禁用 SASL。如果缺失,则设置了任何其他 sasl. 密钥时自动启用 SASL。
  • sasl.mechanisms :(array)允许的 SASL 机制名称列表。如果缺少或为空,则使用系统默认值。
  • sasl.allow-insecure :(布尔值)允许发送明文密码的机制。默认为false。

9.4.1.1. 创建 Secret

您可以使用以下命令在包含您的证书和密钥文件的目录中创建 secret:

$ oc create secret generic -n <namespace> <secret_name> \
  --from-file=ca-bundle.crt=<your_bundle_file> \
  --from-literal=username=<your_username> \
  --from-literal=password=<your_password>
注意

建议使用通用或不透明 secret 来获得最佳结果。

9.4.2. 创建日志转发器

要创建日志转发器,您必须创建一个 ClusterLogForwarder CR,以指定服务帐户可以收集的日志输入类型。您还可以指定日志可以转发到的输出。如果使用多日志转发器功能,还必须在 ClusterLogForwarder CR 中引用服务帐户。

如果您在集群中使用多日志转发器功能,您可以使用任何名称在任意命名空间中创建 ClusterLogForwarder 自定义资源 (CR)。如果使用旧的实现,ClusterLogForwarder CR 必须命名为 instance,且必须在 openshift-logging 命名空间中创建。

重要

创建 ClusterLogForwarder CR 的命名空间需要管理员权限。

ClusterLogForwarder 资源示例

apiVersion: logging.openshift.io/v1
kind: ClusterLogForwarder
metadata:
  name: <log_forwarder_name> 1
  namespace: <log_forwarder_namespace> 2
spec:
  serviceAccountName: <service_account_name> 3
  pipelines:
   - inputRefs:
     - <log_type> 4
     outputRefs:
     - <output_name> 5
  outputs:
  - name: <output_name> 6
    type: <output_type> 7
    url: <log_output_url> 8
# ...

1
在传统的实现中,CR 名称必须是 instance。在多日志转发器实现中,您可以使用任何名称。
2
在旧的实现中,CR 命名空间必须是 openshift-logging。在多日志转发器实现中,您可以使用任何命名空间。
3
服务帐户的名称。如果没有在 openshift-logging 命名空间中部署日志转发器,则只有多日志转发器实现中才需要服务帐户。
4
收集的日志类型。此字段的值可以是 audit(用于审计日志)、application(用于应用程序日志)、infrastructure(用于基础架构日志),或输入为您的应用程序定义的名称。
5 7
要将日志转发到的输出类型。此字段的值可以是 default,loki,kafka,elasticsearch,fluentdForward,syslog, 或 cloudwatch
注意

多日志转发器实现不支持 default 输出类型。

6
要将日志转发到的输出的名称。
8
要将日志转发到的输出的 URL。

9.4.3. 启用多行异常检测

启用容器日志的多行错误检测。

警告

启用此功能可能会对性能有影响,可能需要额外的计算资源或备用日志记录解决方案。

日志解析器通常会错误地将同一个例外中的不同的行识别为不同的例外。这会导致额外的日志条目,以及要跟踪的信息的不完整或不正确。

java 异常示例

java.lang.NullPointerException: Cannot invoke "String.toString()" because "<param1>" is null
    at testjava.Main.handle(Main.java:47)
    at testjava.Main.printMe(Main.java:19)
    at testjava.Main.main(Main.java:10)

  • 要启用日志记录来检测多行异常,并将其重新编译到一个日志条目中,请确保 ClusterLogForwarder 自定义资源 (CR) 包含 detectMultilineErrors 字段,值为 true

ClusterLogForwarder CR 示例

apiVersion: logging.openshift.io/v1
kind: ClusterLogForwarder
metadata:
  name: instance
  namespace: openshift-logging
spec:
  pipelines:
    - name: my-app-logs
      inputRefs:
        - application
      outputRefs:
        - default
      detectMultilineErrors: true

9.4.3.1. 详情

当日志消息作为一系列针对一个例外的信息出现时,会将它们合并到一个统一的日志记录中。第一个日志消息的内容被替换为序列中所有消息字段的连接内容。

表 9.9. 每个收集器支持的语言:

语言FluentdVector

Java

JS

Ruby

Python

Golang

PHP

Dart

9.4.3.2. 故障排除

启用后,收集器配置将包括一个新的部分,类型是:detect_exceptions

vector 配置部分的示例

[transforms.detect_exceptions_app-logs]
 type = "detect_exceptions"
 inputs = ["application"]
 languages = ["All"]
 group_by = ["kubernetes.namespace_name","kubernetes.pod_name","kubernetes.container_name"]
 expire_after_ms = 2000
 multiline_flush_interval_ms = 1000

fluentd config 部分的示例

<label @MULTILINE_APP_LOGS>
  <match kubernetes.**>
    @type detect_exceptions
    remove_tag_prefix 'kubernetes'
    message message
    force_line_breaks true
    multiline_flush_interval .2
  </match>
</label>

9.4.4. 将日志转发到 Google Cloud Platform (GCP)

除了默认的 OpenShift Container Platform 日志存储外,您还可以将日志转发到 Google Cloud Logging

注意

不支持在 Fluentd 中使用此功能。

先决条件

  • Red Hat OpenShift Logging Operator 5.5.1 及更新的版本

步骤

  1. 使用 Google 服务帐户密钥创建 secret。

    $ oc -n openshift-logging create secret generic gcp-secret --from-file google-application-credentials.json=<your_service_account_key_file.json>
  2. 使用以下模板创建 ClusterLogForwarder 自定义资源 YAML:

    apiVersion: logging.openshift.io/v1
    kind: ClusterLogForwarder
    metadata:
      name: <log_forwarder_name> 1
      namespace: <log_forwarder_namespace> 2
    spec:
      serviceAccountName: <service_account_name> 3
      outputs:
        - name: gcp-1
          type: googleCloudLogging
          secret:
            name: gcp-secret
          googleCloudLogging:
            projectId : "openshift-gce-devel" 4
            logId : "app-gcp" 5
      pipelines:
        - name: test-app
          inputRefs: 6
            - application
          outputRefs:
            - gcp-1
    1
    在传统的实现中,CR 名称必须是 instance。在多日志转发器实现中,您可以使用任何名称。
    2
    在旧的实现中,CR 命名空间必须是 openshift-logging。在多日志转发器实现中,您可以使用任何命名空间。
    3
    服务帐户的名称。如果没有在 openshift-logging 命名空间中部署日志转发器,则只有多日志转发器实现中才需要服务帐户。
    4
    根据您要将日志存储在 GCP 资源层次结构中的位置,设置 projectId, folderId, organizationId, 或 billingAccountId 的项及其相应的值。
    5
    将值设为添加到 Log EntrylogName 字段的值。
    6
    使用管道指定要转发的日志类型:application, infrastructure, 或 audit

9.4.5. 将日志转发到 Splunk

除了内部的默认 OpenShift Container Platform 日志存储外,您还可以将日志转发到 Splunk HTTP 事件收集器 (HEC)

注意

不支持在 Fluentd 中使用此功能。

先决条件

  • Red Hat OpenShift Logging Operator 5.6 或更高版本
  • 带有指定了 vectorClusterLogging 实例作为收集器
  • Base64 编码的 Splunk HEC 令牌

流程

  1. 使用您的 Base64 编码的 Splunk HEC 令牌创建 secret。

    $ oc -n openshift-logging create secret generic vector-splunk-secret --from-literal hecToken=<HEC_Token>
  2. 使用以下模板创建或编辑 ClusterLogForwarder 自定义资源 (CR):

    apiVersion: logging.openshift.io/v1
    kind: ClusterLogForwarder
    metadata:
      name: <log_forwarder_name> 1
      namespace: <log_forwarder_namespace> 2
    spec:
      serviceAccountName: <service_account_name> 3
      outputs:
        - name: splunk-receiver 4
          secret:
            name: vector-splunk-secret 5
          type: splunk 6
          url: <http://your.splunk.hec.url:8088> 7
      pipelines: 8
        - inputRefs:
            - application
            - infrastructure
          name: 9
          outputRefs:
            - splunk-receiver 10
    1
    在传统的实现中,CR 名称必须是 instance。在多日志转发器实现中,您可以使用任何名称。
    2
    在旧的实现中,CR 命名空间必须是 openshift-logging。在多日志转发器实现中,您可以使用任何命名空间。
    3
    服务帐户的名称。如果没有在 openshift-logging 命名空间中部署日志转发器,则只有多日志转发器实现中才需要服务帐户。
    4
    指定输出的名称。
    5
    指定包含 HEC 令牌的 secret 名称。
    6
    将输出类型指定为 mvapich
    7
    指定 Splunk HEC 的 URL (包括端口)。
    8
    使用管道指定要转发的日志类型:application, infrastructure, 或 audit
    9
    可选:指定管道的名称。
    10
    指定使用此管道转发日志时使用的输出名称。

9.4.6. 通过 HTTP 转发日志

Fluentd 和 Vector 日志收集器都支持通过 HTTP 转发日志。要启用,在 ClusterLogForwarder 自定义资源 (CR) 中指定 http 作为输出类型。

步骤

  • 使用以下模板创建或编辑 ClusterLogForwarder CR:

    ClusterLogForwarder CR 示例

    apiVersion: logging.openshift.io/v1
    kind: ClusterLogForwarder
    metadata:
      name: <log_forwarder_name> 1
      namespace: <log_forwarder_namespace> 2
    spec:
      serviceAccountName: <service_account_name> 3
      outputs:
        - name: httpout-app
          type: http
          url: 4
          http:
            headers: 5
              h1: v1
              h2: v2
            method: POST
          secret:
            name: 6
          tls:
            insecureSkipVerify: 7
      pipelines:
        - name:
          inputRefs:
            - application
          outputRefs:
            - 8

    1
    在传统的实现中,CR 名称必须是 instance。在多日志转发器实现中,您可以使用任何名称。
    2
    在旧的实现中,CR 命名空间必须是 openshift-logging。在多日志转发器实现中,您可以使用任何命名空间。
    3
    服务帐户的名称。如果没有在 openshift-logging 命名空间中部署日志转发器,则只有多日志转发器实现中才需要服务帐户。
    4
    日志的目标地址。
    5
    使用日志记录发送的其他标头。
    6
    目标凭证的 secret 名称。
    7
    值可以是 truefalse
    8
    这个值应当与输出名称相同。

9.4.7. 从特定项目转发应用程序日志

除了内部日志存储外,您还可以将特定项目的应用程序日志副本转发到外部日志聚合器。您还必须配置外部日志聚合器,以接收来自 OpenShift Container Platform 的日志数据。

要从项目中配置转发应用程序日志,创建一个 ClusterLogForwarder 自定义资源(CR),其中至少从一个项目中输入,为其他日志聚合器提供可选输出,以及使用这些输入和输出的管道。

先决条件

  • 您必须有配置为使用指定协议或格式接收日志数据的日志服务器。

步骤

  1. 创建或编辑定义 ClusterLogForwarder CR 的 YAML 文件:

    ClusterLogForwarder CR 示例

    apiVersion: logging.openshift.io/v1
    kind: ClusterLogForwarder
    metadata:
      name: instance 1
      namespace: openshift-logging 2
    spec:
      outputs:
       - name: fluentd-server-secure 3
         type: fluentdForward 4
         url: 'tls://fluentdserver.security.example.com:24224' 5
         secret: 6
            name: fluentd-secret
       - name: fluentd-server-insecure
         type: fluentdForward
         url: 'tcp://fluentdserver.home.example.com:24224'
      inputs: 7
       - name: my-app-logs
         application:
            namespaces:
            - my-project 8
      pipelines:
       - name: forward-to-fluentd-insecure 9
         inputRefs: 10
         - my-app-logs
         outputRefs: 11
         - fluentd-server-insecure
         labels:
           project: "my-project" 12
       - name: forward-to-fluentd-secure 13
         inputRefs:
         - application 14
         - audit
         - infrastructure
         outputRefs:
         - fluentd-server-secure
         - default
         labels:
           clusterId: "C1234"

    1
    ClusterLogForwarder CR 的名称必须是 instance
    2
    ClusterLogForwarder CR 的命名空间必须是 openshift-logging
    3
    输出的名称。
    4
    输出类型:elasticsearch, fluentdForward, syslog, 或 kafka
    5
    外部日志聚合器的 URL 和端口作为有效的绝对 URL。如果启用了使用 CIDR 注解的集群范围代理,输出必须是服务器名称或 FQDN,而不是 IP 地址。
    6
    如果使用 tls 前缀,您必须为 TLS 通信指定端点所需的 secret 名称。secret 必须存在于 openshift-logging 项目中,并具有每个指向它们所代表证书的 tls.crttls.keyca-bundle.crt 密钥。
    7
    用于过滤指定项目的应用程序日志的输入配置。
    8
    如果没有指定命名空间,则会从所有命名空间收集日志。
    9
    管道配置将来自一个命名输入的日志定向到一个命名的输出。在本例中,名为 forward-to-fluentd-insecure 的管道将日志从一个名为 my-app-logs 的输入转发到名为 fluentd-server-insecure 的输出。
    10
    输入列表。
    11
    要使用的输出名称。
    12
    可选:字符串。要添加到日志中的一个或多个标签。
    13
    管道配置,将日志发送到其他日志聚合器。
    • 可选:指定管道的名称。
    • 使用管道指定要转发的日志类型:applicationinfrastructureaudit
    • 指定使用此管道转发日志时使用的输出名称。
    • 可选:指定将日志转发到默认日志存储的默认输出。
    • 可选:字符串。要添加到日志中的一个或多个标签。
    14
    请注意,使用此配置时,会从所有命名空间收集应用程序日志。
  2. 运行以下命令来应用 ClusterLogForwarder CR:

    $ oc apply -f <filename>.yaml

9.4.8. 从特定 pod 转发应用程序日志

作为集群管理员,您可以使用 Kubernetes pod 标签从特定 pod 收集日志数据并将其转发到日志收集器。

假设您的应用由容器集组成,并与不同命名空间中的其他容器集一起运行。如果这些 pod 具有标识应用程序标签,您可以收集和输出其日志数据到特定的日志收集器。

要指定 pod 标签,请使用一个或多个 matchLabels 键值对。如果指定了多个键值对,pod 必须与要选择的所有值匹配。

流程

  1. 创建或编辑定义 ClusterLogForwarder CR 对象的 YAML 文件。在文件中,使用 inputs[].name.application.selector.matchLabels 下的简单基于平等的选择器来指定 pod 标签,如下例所示。

    ClusterLogForwarder CR YAML 文件示例

    apiVersion: logging.openshift.io/v1
    kind: ClusterLogForwarder
    metadata:
      name: <log_forwarder_name> 1
      namespace: <log_forwarder_namespace> 2
    spec:
      pipelines:
        - inputRefs: [ myAppLogData ] 3
          outputRefs: [ default ] 4
      inputs: 5
        - name: myAppLogData
          application:
            selector:
              matchLabels: 6
                environment: production
                app: nginx
            namespaces: 7
            - app1
            - app2
      outputs: 8
        - <output_name>
        ...

    1
    在传统的实现中,CR 名称必须是 instance。在多日志转发器实现中,您可以使用任何名称。
    2
    在旧的实现中,CR 命名空间必须是 openshift-logging。在多日志转发器实现中,您可以使用任何命名空间。
    3
    指定来自 inputs[].name 的一个或多个以逗号分隔的值。
    4
    指定来自 outputs[] 的一个或多个以逗号分隔的值。
    5
    为具有一组唯一 pod 标签的每个应用程序定义唯一的 inputs[].name
    6
    指定您要收集的日志数据的 pod 标签的键值对。您必须指定一个键和值,而不仅仅是一个键。要被选择,pod 必须与所有键值对匹配。
    7
    可选:指定一个或多个命名空间。
    8
    指定要将日志数据转发到的一个或多个输出。
  2. 可选: 要将日志数据收集限制为特定的命名空间,请使用 inputs[].name.application.namespaces,如上例中所示。
  3. 可选: 您可以从具有不同 pod 标签的额外应用程序向同一管道发送日志数据。

    1. 对于 pod 标签的每个唯一组合,创建一个类似于显示的 inputs[].name 部分。
    2. 更新选择器(selectors)以匹配此应用的容器集标签。
    3. 将新的 inputs[].name 值添加到 inputRefs。例如:

      - inputRefs: [ myAppLogData, myOtherAppLogData ]
  4. 创建 CR 对象。

    $ oc create -f <file-name>.yaml

其他资源

9.4.9. API 审计过滤器概述

OpenShift API 服务器为每个 API 调用生成审计事件,详细说明请求者的请求、响应和请求者的身份,从而导致大量数据。API 审计过滤器使用规则启用非必要事件和事件大小减少,从而提高更易于管理的审计跟踪。按顺序检查规则,检查会在第一个匹配项时停止。事件中包含的数据量由 level 字段的值决定:

  • None: 事件被丢弃。
  • Metadata:只包含审计元数据,请求和响应正文会被删除。
  • Request:包含审计元数据和请求正文,响应正文会被删除。
  • RequestResponse:包含所有数据:元数据、请求正文和响应正文。响应正文可能非常大。例如,oc get pods -A 生成包含集群中每个 pod 的 YAML 描述的响应正文。

在日志记录 5.8 及更高版本中,ClusterLogForwarder 自定义资源 (CR) 使用与标准 Kubernetes Audit 策略相同的格式,同时提供以下附加功能:

通配符
用户、组、命名空间和资源的名称可以在前导或尾部带有 * 星号字符。例如,命名空间 openshift-\*openshift-apiserveropenshift-authentication 匹配。资源 \*/status 匹配 Pod/statusDeployment/status
默认规则

与策略中任何规则不匹配的事件将被过滤,如下所示:

  • 只读系统事件(如 getlistwatch)将被丢弃。
  • 服务帐户写入发生在与服务帐户相同的命名空间中的事件将被丢弃。
  • 所有其他事件都会被转发,受任何配置的速率限制。

要禁用这些默认值,请使用只有一个 level 字段的规则结束您的规则列表,或者添加一条空规则。

省略响应代码
要省略的整数状态代码列表。您可以使用 OmitResponseCodes 字段(没有创建事件)的 HTTP 状态代码列表根据响应中的 HTTP 状态代码丢弃事件。默认值为 [404, 409, 422, 429]。如果该值为空列表 [],则不会省略状态代码。

ClusterLogForwarder CR Audit 策作为 OpenShift Container Platform 审计策略外的补充起作用。ClusterLogForwarder CR 审计过滤器更改日志收集器转发的内容,并提供按操作动词、用户、组、命名空间或资源过滤的功能。您可以创建多个过滤器,将同一审计流的不同摘要发送到不同的位置。例如,您可以将详细的流发送到本地集群日志存储,并将不太详细的流发送到远程站点。

注意

提供的示例旨在说明审计策略中可能的规则范围,不是推荐的配置。

Audit 策略示例

apiVersion: logging.openshift.io/v1
kind: ClusterLogForwarder
metadata:
  name: instance
  namespace: openshift-logging
spec:
  pipelines:
    - name: my-pipeline
      inputRefs: audit 1
      filterRefs: my-policy 2
      outputRefs: default
  filters:
    - name: my-policy
      type: kubeAPIAudit
      kubeAPIAudit:
        # Don't generate audit events for all requests in RequestReceived stage.
        omitStages:
          - "RequestReceived"

        rules:
          # Log pod changes at RequestResponse level
          - level: RequestResponse
            resources:
            - group: ""
              resources: ["pods"]

          # Log "pods/log", "pods/status" at Metadata level
          - level: Metadata
            resources:
            - group: ""
              resources: ["pods/log", "pods/status"]

          # Don't log requests to a configmap called "controller-leader"
          - level: None
            resources:
            - group: ""
              resources: ["configmaps"]
              resourceNames: ["controller-leader"]

          # Don't log watch requests by the "system:kube-proxy" on endpoints or services
          - level: None
            users: ["system:kube-proxy"]
            verbs: ["watch"]
            resources:
            - group: "" # core API group
              resources: ["endpoints", "services"]

          # Don't log authenticated requests to certain non-resource URL paths.
          - level: None
            userGroups: ["system:authenticated"]
            nonResourceURLs:
            - "/api*" # Wildcard matching.
            - "/version"

          # Log the request body of configmap changes in kube-system.
          - level: Request
            resources:
            - group: "" # core API group
              resources: ["configmaps"]
            # This rule only applies to resources in the "kube-system" namespace.
            # The empty string "" can be used to select non-namespaced resources.
            namespaces: ["kube-system"]

          # Log configmap and secret changes in all other namespaces at the Metadata level.
          - level: Metadata
            resources:
            - group: "" # core API group
              resources: ["secrets", "configmaps"]

          # Log all other resources in core and extensions at the Request level.
          - level: Request
            resources:
            - group: "" # core API group
            - group: "extensions" # Version of group should NOT be included.

          # A catch-all rule to log all other requests at the Metadata level.
          - level: Metadata

1
收集的日志类型。此字段的值可以是 audit(用于审计日志)、application(用于应用程序日志)、infrastructure(用于基础架构日志),或输入为您的应用程序定义的名称。
2
审计策略的名称。

9.4.10. 将日志转发到外部 Loki 日志记录系统

除了默认的日志存储外,您还可以将日志转发到外部 Loki 日志记录系统。

要配置日志转发到 Loki,您必须创建一个 ClusterLogForwarder 自定义资源 (CR),并创建一个输出到 Loki 的 ClusterLogForwarder 自定义资源 (CR),以及使用输出的管道。到 Loki 的输出可以使用 HTTP(不安全)或 HTTPS(安全 HTTP)连接。

先决条件

  • 您必须有一个 Loki 日志记录系统在您通过 CR 中的 url 字段指定的 URL 中运行。

流程

  1. 创建或编辑定义 ClusterLogForwarder CR 对象的 YAML 文件:

    apiVersion: logging.openshift.io/v1
    kind: ClusterLogForwarder
    metadata:
      name: <log_forwarder_name> 1
      namespace: <log_forwarder_namespace> 2
    spec:
      serviceAccountName: <service_account_name> 3
      outputs:
      - name: loki-insecure 4
        type: "loki" 5
        url: http://loki.insecure.com:3100 6
        loki:
          tenantKey: kubernetes.namespace_name
          labelKeys:
          - kubernetes.labels.foo
      - name: loki-secure 7
        type: "loki"
        url: https://loki.secure.com:3100
        secret:
          name: loki-secret 8
        loki:
          tenantKey: kubernetes.namespace_name 9
          labelKeys:
          - kubernetes.labels.foo 10
      pipelines:
      - name: application-logs 11
        inputRefs:  12
        - application
        - audit
        outputRefs: 13
        - loki-secure
    1
    在传统的实现中,CR 名称必须是 instance。在多日志转发器实现中,您可以使用任何名称。
    2
    在旧的实现中,CR 命名空间必须是 openshift-logging。在多日志转发器实现中,您可以使用任何命名空间。
    3
    服务帐户的名称。如果没有在 openshift-logging 命名空间中部署日志转发器,则只有多日志转发器实现中才需要服务帐户。
    4
    指定输出的名称。
    5
    将类型指定为 "loki"
    6
    将 Loki 系统的 URL 和端口指定为有效的绝对 URL。您可以使用 http (不安全)或 https (安全 HTTP)协议。如果启用了使用 CIDR 注解的集群范围代理,输出必须是服务器名称或 FQDN,而不是 IP 地址。Loki 用于 HTTP(S) 通讯的默认端口为 3100。
    7
    对于安全连接,您可以通过指定 secret 来指定您进行身份验证的 httpshttp URL。
    8
    对于 https 前缀,请指定 TLS 通信端点所需的 secret 名称。secret 必须包含一个 ca-bundle.crt 键,它指向它所代表的证书。否则,对于 httphttps 前缀,您可以指定一个包含用户名和密码的 secret。在旧的实现中,secret 必须存在于 openshift-logging 项目中。如需更多信息,请参阅以下"示例:设置包含用户名和密码的 secret"。
    9
    可选:指定一个 metadata key 字段,为 Loki 中的 TenantID 字段生成值。例如,设置 tenantKey: kubernetes.namespace_name 使用 Kubernetes 命名空间的名称作为 Loki 中的租户 ID 的值。要查看您可以指定的其他日志记录字段,请查看以下"Additional resources"部分中的"Log Record Fields"链接。
    10
    可选:指定一个 metadata 字段键列表来替换默认的 Loki 标签。Loki 标签名称必须与正则表达式 [a-zA-Z_:][a-zA-Z0-9_:]* 匹配。元数据键中的非法字符被替换为 _,以组成标签名称。例如,kubernetes.labels.foo 元数据键变成 Loki 标签 kubernetes_labels_foo。如果没有设置 labelKeys,则默认值为:[log_type, kubernetes.namespace_name, kubernetes.pod_name, kubernetes_host]。尽量保持标签数量少,因为 Loki 会限制允许标签的大小和数量。请参阅配置 Loki、limit_config。您仍然可以使用查询过滤器基于任何日志记录字段进行查询。
    11
    可选:指定管道的名称。
    12
    使用管道指定要转发的日志类型:applicationinfrastructureaudit
    13
    指定使用此管道转发日志时使用的输出名称。
    注意

    由于 Loki 要求按时间戳正确排序日志流,labelKeys 始终包含 kubernetes_host 标签,即使您没有指定它。此包含确保每个流源自单一主机,这样可防止因为不同主机上的时钟差异而导致时间戳出现问题。

  2. 运行以下命令来应用 ClusterLogForwarder CR 对象:

    $ oc apply -f <filename>.yaml

其他资源

9.4.11. 将日志转发到外部 Elasticsearch 实例

除了内部日志存储外,您还可以将日志转发到外部 Elasticsearch 实例。您需要配置外部日志聚合器,以接收来自 OpenShift Container Platform 的日志数据。

要配置日志转发到外部 Elasticsearch 实例,请创建一个 ClusterLogForwarder 自定义资源(CR),其中包含输出到该实例的输出以及使用输出的管道。外部 Elasticsearch 输出可以使用 HTTP(不安全)或 HTTPS(安全 HTTP)连接。

要将日志转发到外部和内部 Elasticsearch 实例,请将输出和管道创建到外部实例,以及一个使用 default 输出将日志转发到内部实例的管道。

注意

如果您只想将日志转发到内部 Elasticsearch 实例,则不需要创建一个 ClusterLogForwarder CR。

先决条件

  • 您必须有配置为使用指定协议或格式接收日志数据的日志服务器。

步骤

  1. 创建或编辑定义 ClusterLogForwarder CR 的 YAML 文件:

    ClusterLogForwarder CR 示例

    apiVersion: logging.openshift.io/v1
    kind: ClusterLogForwarder
    metadata:
      name: <log_forwarder_name> 1
      namespace: <log_forwarder_namespace> 2
    spec:
      serviceAccountName: <service_account_name> 3
      outputs:
       - name: elasticsearch-example 4
         type: elasticsearch 5
         elasticsearch:
           version: 8 6
         url: http://elasticsearch.example.com:9200 7
         secret:
           name: es-secret 8
      pipelines:
       - name: application-logs 9
         inputRefs: 10
         - application
         - audit
         outputRefs:
         - elasticsearch-example 11
         - default 12
         labels:
           myLabel: "myValue" 13
    # ...

    1
    在传统的实现中,CR 名称必须是 instance。在多日志转发器实现中,您可以使用任何名称。
    2
    在旧的实现中,CR 命名空间必须是 openshift-logging。在多日志转发器实现中,您可以使用任何命名空间。
    3
    服务帐户的名称。如果没有在 openshift-logging 命名空间中部署日志转发器,则只有多日志转发器实现中才需要服务帐户。
    4
    指定输出的名称。
    5
    指定 elasticsearch 类型。
    6
    指定 Elasticsearch 版本。这可以是 678
    7
    指定外部 Elasticsearch 实例的 URL 和端口作为有效的绝对 URL。您可以使用 http (不安全)或 https (安全 HTTP)协议。如果启用了使用 CIDR 注解的集群范围代理,输出必须是服务器名称或 FQDN,而不是 IP 地址。
    8
    对于 https 前缀,请指定 TLS 通信端点所需的 secret 名称。secret 必须包含一个 ca-bundle.crt 键,它指向它所代表的证书。否则,对于 httphttps 前缀,您可以指定一个包含用户名和密码的 secret。在旧的实现中,secret 必须存在于 openshift-logging 项目中。如需更多信息,请参阅以下"示例:设置包含用户名和密码的 secret"。
    9
    可选:指定管道的名称。
    10
    使用管道指定要转发的日志类型:applicationinfrastructureaudit
    11
    指定使用此管道转发日志时使用的输出名称。
    12
    可选:指定将日志发送到内部 Elasticsearch 实例的 default 输出。
    13
    可选:字符串。要添加到日志中的一个或多个标签。
  2. 应用 ClusterLogForwarder CR:

    $ oc apply -f <filename>.yaml

示例:设置包含用户名和密码的 secret

您可以使用包含用户名和密码的 secret 来验证与外部 Elasticsearch 实例的安全连接。

例如,如果无法使用 mutual TLS (mTLS) 密钥,因为第三方运行 Elasticsearch 实例,您可以使用 HTTP 或 HTTPS 并设置包含用户名和密码的 secret。

  1. 创建类似于以下示例的 Secret YAML 文件。将 base64 编码的值用于 usernamepassword 字段。secret 类型默认为 opaque。

    apiVersion: v1
    kind: Secret
    metadata:
      name: openshift-test-secret
    data:
      username: <username>
      password: <password>
    # ...
  2. 创建 secret:

    $ oc create secret -n openshift-logging openshift-test-secret.yaml
  3. ClusterLogForwarder CR 中指定 secret 的名称:

    kind: ClusterLogForwarder
    metadata:
      name: instance
      namespace: openshift-logging
    spec:
      outputs:
       - name: elasticsearch
         type: "elasticsearch"
         url: https://elasticsearch.secure.com:9200
         secret:
            name: openshift-test-secret
    # ...
    注意

    url 字段中,前缀可以是 httphttps

  4. 应用 CR 对象:

    $ oc apply -f <filename>.yaml

9.4.12. 使用 Fluentd 转发协议转发日志

您可以使用 Fluentd forward 协议将日志副本发送到配置为接受协议的外部日志聚合器,而非默认的 Elasticsearch 日志存储。您需要配置外部日志聚合器以接收来自 OpenShift Container Platform 的日志。

要使用 forward 协议配置日志转发,请创建一个 ClusterLogForwarder 自定义资源(CR),并将一个或多个输出输出到使用这些输出的 Fluentd 服务器和管道。Fluentd 输出可以使用 TCP(不安全)或 TLS(安全 TCP)连接。

先决条件

  • 您必须有配置为使用指定协议或格式接收日志数据的日志服务器。

流程

  1. 创建或编辑定义 ClusterLogForwarder CR 对象的 YAML 文件:

    apiVersion: logging.openshift.io/v1
    kind: ClusterLogForwarder
    metadata:
      name: instance 1
      namespace: openshift-logging 2
    spec:
      outputs:
       - name: fluentd-server-secure 3
         type: fluentdForward 4
         url: 'tls://fluentdserver.security.example.com:24224' 5
         secret: 6
            name: fluentd-secret
       - name: fluentd-server-insecure
         type: fluentdForward
         url: 'tcp://fluentdserver.home.example.com:24224'
      pipelines:
       - name: forward-to-fluentd-secure 7
         inputRefs:  8
         - application
         - audit
         outputRefs:
         - fluentd-server-secure 9
         - default 10
         labels:
           clusterId: "C1234" 11
       - name: forward-to-fluentd-insecure 12
         inputRefs:
         - infrastructure
         outputRefs:
         - fluentd-server-insecure
         labels:
           clusterId: "C1234"
    1
    ClusterLogForwarder CR 的名称必须是 instance
    2
    ClusterLogForwarder CR 的命名空间必须是 openshift-logging
    3
    指定输出的名称。
    4
    指定 fluentdForward 类型。
    5
    指定外部 Fluentd 实例的 URL 和端口作为有效的绝对 URL。您可以使用 tcp (不安全)或者 tls (安全 TCP)协议。如果启用了使用 CIDR 注解的集群范围代理,输出必须是服务器名称或 FQDN,而不是 IP 地址。
    6
    如果使用 tls 前缀,您必须为 TLS 通信指定端点所需的 secret 名称。secret 必须存在于 openshift-logging 项目中,且必须包含指向它所代表证书的 ca-bundle.crt 键。
    7
    可选:指定管道的名称。
    8
    使用管道指定要转发的日志类型:applicationinfrastructureaudit
    9
    指定使用此管道转发日志时使用的输出名称。
    10
    可选:指定将日志转发到内部 Elasticsearch 实例的 default 输出。
    11
    可选:字符串。要添加到日志中的一个或多个标签。
    12
    可选:配置多个输出,将日志转发到任何受支持类型的其他外部日志聚合器:
    • 描述管道的名称。
    • inputRefs 是使用管道转发的日志类型:applicationinfrastructureaudit
    • outputRefs 是要使用的输出名称。
    • 可选:字符串。要添加到日志中的一个或多个标签。
  2. 创建 CR 对象:

    $ oc create -f <file-name>.yaml

9.4.12.1. 为 Logstash 启用 nanosecond 精度来从 fluentd 摄取数据

对于 Logstash 从 fluentd 摄取数据,您必须在 Logstash 配置文件中启用 nanosecond 精度。

流程

  • 在 Logstash 配置文件中,将 nanosecond_precision 设置为 true

Logstash 配置文件示例

input { tcp { codec => fluent { nanosecond_precision => true } port => 24114 } }
filter { }
output { stdout { codec => rubydebug } }

9.4.13. 使用 syslog 协议转发日志

您可以使用 syslog RFC3164RFC5424 协议将日志副本发送到配置为接受该协议的外部日志聚合器(替代默认的 Elasticsearch 日志存储或作为它的补充)。您需要配置外部日志聚合器(如 syslog 服务器)来接收来自 OpenShift Container Platform 的日志。

要使用 syslog 协议配置日志转,,请创建一个 ClusterLogForwarder 自定义资源(CR),并将一个或多个输出输出到使用这些输出的 syslog 服务器和管道。syslog 输出可以使用 UDP、TCP 或 TLS 连接。

先决条件

  • 您必须有配置为使用指定协议或格式接收日志数据的日志服务器。

流程

  1. 创建或编辑定义 ClusterLogForwarder CR 对象的 YAML 文件:

    apiVersion: logging.openshift.io/v1
    kind: ClusterLogForwarder
    metadata:
      name: <log_forwarder_name> 1
      namespace: <log_forwarder_namespace> 2
    spec:
      serviceAccountName: <service_account_name> 3
      outputs:
       - name: rsyslog-east 4
         type: syslog 5
         syslog: 6
           facility: local0
           rfc: RFC3164
           payloadKey: message
           severity: informational
         url: 'tls://rsyslogserver.east.example.com:514' 7
         secret: 8
            name: syslog-secret
       - name: rsyslog-west
         type: syslog
         syslog:
          appName: myapp
          facility: user
          msgID: mymsg
          procID: myproc
          rfc: RFC5424
          severity: debug
         url: 'tcp://rsyslogserver.west.example.com:514'
      pipelines:
       - name: syslog-east 9
         inputRefs: 10
         - audit
         - application
         outputRefs: 11
         - rsyslog-east
         - default 12
         labels:
           secure: "true" 13
           syslog: "east"
       - name: syslog-west 14
         inputRefs:
         - infrastructure
         outputRefs:
         - rsyslog-west
         - default
         labels:
           syslog: "west"
    1
    在传统的实现中,CR 名称必须是 instance。在多日志转发器实现中,您可以使用任何名称。
    2
    在旧的实现中,CR 命名空间必须是 openshift-logging。在多日志转发器实现中,您可以使用任何命名空间。
    3
    服务帐户的名称。如果没有在 openshift-logging 命名空间中部署日志转发器,则只有多日志转发器实现中才需要服务帐户。
    4
    指定输出的名称。
    5
    指定 syslog 类型。
    6
    可选:指定 syslog 参数,如下所列。
    7
    指定外部 syslog 实例的 URL 和端口。您可以使用 udp (不安全)、tcp (不安全)或者 tls (安全 TCP)协议。如果启用了使用 CIDR 注解的集群范围代理,输出必须是服务器名称或 FQDN,而不是 IP 地址。
    8
    如果使用 tls 前缀,您必须为 TLS 通信指定端点所需的 secret 名称。secret 必须包含一个 ca-bundle.crt 键,它指向它所代表的证书。在旧的实现中,secret 必须存在于 openshift-logging 项目中。
    9
    可选:指定管道的名称。
    10
    使用管道指定要转发的日志类型:applicationinfrastructureaudit
    11
    指定使用此管道转发日志时使用的输出名称。
    12
    可选:指定将日志转发到内部 Elasticsearch 实例的 default 输出。
    13
    可选:字符串。要添加到日志中的一个或多个标签。对值加引号(如 "true"),以便它们被识别为字符串值,而不是作为布尔值。
    14
    可选:配置多个输出,将日志转发到任何受支持类型的其他外部日志聚合器:
    • 描述管道的名称。
    • inputRefs 是使用管道转发的日志类型:applicationinfrastructureaudit
    • outputRefs 是要使用的输出名称。
    • 可选:字符串。要添加到日志中的一个或多个标签。
  2. 创建 CR 对象:

    $ oc create -f <filename>.yaml

9.4.13.1. 在消息输出中添加日志消息

您可以通过将 AddLogSource 字段添加到 ClusterLogForwarder 自定义资源(CR)将 namespace_namepod_namecontainer_name 元素添加到记录的 message 字段中。

  spec:
    outputs:
    - name: syslogout
      syslog:
        addLogSource: true
        facility: user
        payloadKey: message
        rfc: RFC3164
        severity: debug
        tag: mytag
      type: syslog
      url: tls://syslog-receiver.openshift-logging.svc:24224
    pipelines:
    - inputRefs:
      - application
      name: test-app
      outputRefs:
      - syslogout
注意

这个配置与 RFC3164 和 RFC5424 兼容。

没有 AddLogSource 的 syslog 消息输出示例

<15>1 2020-11-15T17:06:14+00:00 fluentd-9hkb4 mytag - - -  {"msgcontent"=>"Message Contents", "timestamp"=>"2020-11-15 17:06:09", "tag_key"=>"rec_tag", "index"=>56}

带有 AddLogSource 的 syslog 消息输出示例

<15>1 2020-11-16T10:49:37+00:00 crc-j55b9-master-0 mytag - - -  namespace_name=clo-test-6327,pod_name=log-generator-ff9746c49-qxm7l,container_name=log-generator,message={"msgcontent":"My life is my message", "timestamp":"2020-11-16 10:49:36", "tag_key":"rec_tag", "index":76}

9.4.13.2. syslog 参数

您可以为 syslog 输出配置以下内容。如需更多信息,请参阅 syslog RFC3164RFC5424 RFC。

  • facility: syslog facility.该值可以是十进制整数,也可以是区分大小写的关键字:

    • 0kern 用于内核信息
    • 1user 代表用户级信息(默认)。
    • 2mail 用于邮件系统。
    • 3daemon 用于系统守护进程
    • 4auth 用于安全/身份验证信息
    • 5syslog 用于 syslogd 内部生成的信息
    • 6lpr 用于行打印机子系统
    • 7news 用于网络新闻子系统
    • 8uucp 用于 UUCP 子系统
    • 9cron 用于 clock 守护进程
    • 10authpriv 用于安全身份验证信息
    • 11ftp 用于 FTP 守护进程
    • 12ntp 用于 NTP 子系统
    • 13security 用于 syslog audit 日志
    • 14console 用于 syslog alert 日志
    • 15solaris-cron 用于 scheduling 守护进程
    • 16-23local0 - local7 用于本地使用的工具
  • 可选: payloadKey :用作 syslog 消息有效负载的记录字段。

    注意

    配置 payloadKey 参数可防止将其他参数转发到 syslog。

  • RFC:用于使用 syslog 发送日志的 RFC。默认为 RFC5424。
  • severity:设置传出的 syslog 记录的syslog 的严重性。该值可以是十进制整数,也可以是区分大小写的关键字:

    • 0Emergency 用于代表系统不可用的信息
    • 1Alert 用于代表立即执行操作的信息
    • 2Critical 用于代表关键状况的信息
    • 3Error 用于代表错误状况的信息
    • 4Warning 用于代表警告条件的信息
    • 5Notice 用于代表正常但存在重要条件的信息
    • 6Informational 用于代表提示信息的信息
    • 7Debug 用于代表调试级别的信息(默认)
  • tag:Tag 指定记录字段,用作 syslog 消息上的标签。
  • trimPrefix:从标签中删除指定的前缀。

9.4.13.3. 其他 RFC5424 syslog 参数

以下参数适用于 RFC5424:

  • appName: APP-NAME 是一个自由文本字符串,用于标识发送日志的应用程序。必须为 RFC5424 指定。
  • msgID: MSGID 是一个用于标识消息类型的自由文本字符串。必须为 RFC5424 指定。
  • PROCID: PROCID 是一个自由文本字符串。该值的变化表示 syslog 报告不连续。必须为 RFC5424 指定。

9.4.14. 将日志转发到 Kafka 代理

除了默认的日志存储外,您还可以将日志转发到外部 Kafka 代理。

要配置日志转发到外部 Kafka 实例,请创建一个 ClusterLogForwarder 自定义资源(CR),包括输出到该实例的输出以及使用输出的管道。您可以在输出中包括特定的 Kafka 主题,也可以使用默认值。Kafka 输出可以使用 TCP(不安全)或者 TLS(安全 TCP)连接。

流程

  1. 创建或编辑定义 ClusterLogForwarder CR 对象的 YAML 文件:

    apiVersion: logging.openshift.io/v1
    kind: ClusterLogForwarder
    metadata:
      name: <log_forwarder_name> 1
      namespace: <log_forwarder_namespace> 2
    spec:
      serviceAccountName: <service_account_name> 3
      outputs:
       - name: app-logs 4
         type: kafka 5
         url: tls://kafka.example.devlab.com:9093/app-topic 6
         secret:
           name: kafka-secret 7
       - name: infra-logs
         type: kafka
         url: tcp://kafka.devlab2.example.com:9093/infra-topic 8
       - name: audit-logs
         type: kafka
         url: tls://kafka.qelab.example.com:9093/audit-topic
         secret:
            name: kafka-secret-qe
      pipelines:
       - name: app-topic 9
         inputRefs: 10
         - application
         outputRefs: 11
         - app-logs
         labels:
           logType: "application" 12
       - name: infra-topic 13
         inputRefs:
         - infrastructure
         outputRefs:
         - infra-logs
         labels:
           logType: "infra"
       - name: audit-topic
         inputRefs:
         - audit
         outputRefs:
         - audit-logs
         labels:
           logType: "audit"
    1
    在传统的实现中,CR 名称必须是 instance。在多日志转发器实现中,您可以使用任何名称。
    2
    在旧的实现中,CR 命名空间必须是 openshift-logging。在多日志转发器实现中,您可以使用任何命名空间。
    3
    服务帐户的名称。如果没有在 openshift-logging 命名空间中部署日志转发器,则只有多日志转发器实现中才需要服务帐户。
    4
    指定输出的名称。
    5
    指定 kafka 类型。
    6
    将 Kafka 代理的 URL 和端口指定为一个有效的绝对 URL,也可以同时指定特定标题。您可以使用 tcp (不安全)或者 tls (安全 TCP)协议。如果启用了使用 CIDR 注解的集群范围代理,输出必须是服务器名称或 FQDN,而不是 IP 地址。
    7
    如果使用 tls 前缀,您必须为 TLS 通信指定端点所需的 secret 名称。secret 必须包含一个 ca-bundle.crt 键,它指向它所代表的证书。在旧的实现中,secret 必须存在于 openshift-logging 项目中。
    8
    可选: 要发送不安全的输出,在 URL 前面使用 tcp 前缀。另外,省略此输出中的 secret 键及其 name
    9
    可选:指定管道的名称。
    10
    使用管道指定要转发的日志类型:applicationinfrastructureaudit
    11
    指定使用此管道转发日志时使用的输出名称。
    12
    可选:字符串。要添加到日志中的一个或多个标签。
    13
    可选:配置多个输出,将日志转发到任何受支持类型的其他外部日志聚合器:
    • 描述管道的名称。
    • inputRefs 是使用管道转发的日志类型:applicationinfrastructureaudit
    • outputRefs 是要使用的输出名称。
    • 可选:字符串。要添加到日志中的一个或多个标签。
  2. 可选: 要将单个输出转发到多个 Kafka 代理,请指定 Kafka 代理数组,如下例所示:

    # ...
    spec:
      outputs:
      - name: app-logs
        type: kafka
        secret:
          name: kafka-secret-dev
        kafka:  1
          brokers: 2
            - tls://kafka-broker1.example.com:9093/
            - tls://kafka-broker2.example.com:9093/
          topic: app-topic 3
    # ...
    1
    指定一个带有 brokerstopic 键的 kafka 键。
    2
    使用 brokers 键指定一个或多个代理的数组。
    3
    使用 topic 键指定要接收日志的目标主题。
  3. 运行以下命令来应用 ClusterLogForwarder CR:

    $ oc apply -f <filename>.yaml

9.4.15. 将日志转发到 Amazon CloudWatch

您可以将日志转发到 Amazon CloudWatch,这是由 Amazon Web Services (AWS) 托管的监控和日志存储服务。除了默认的日志存储外,您还可以将日志转发到 CloudWatch。

要配置日志转发到 CloudWatch,您必须创建一个 ClusterLogForwarder 自定义资源 (CR),其中包含 CloudWatch 的输出,以及使用输出的管道。

流程

  1. 创建一个 Secret YAML 文件,它使用 aws_access_key_idaws_secret_access_key 字段来指定您的 base64 编码的 AWS 凭证。例如:

    apiVersion: v1
    kind: Secret
    metadata:
      name: cw-secret
      namespace: openshift-logging
    data:
      aws_access_key_id: QUtJQUlPU0ZPRE5ON0VYQU1QTEUK
      aws_secret_access_key: d0phbHJYVXRuRkVNSS9LN01ERU5HL2JQeFJmaUNZRVhBTVBMRUtFWQo=
  2. 创建 secret.例如:

    $ oc apply -f cw-secret.yaml
  3. 创建或编辑定义 ClusterLogForwarder CR 对象的 YAML 文件。在文件中,指定 secret 的名称。例如:

    apiVersion: logging.openshift.io/v1
    kind: ClusterLogForwarder
    metadata:
      name: <log_forwarder_name> 1
      namespace: <log_forwarder_namespace> 2
    spec:
      serviceAccountName: <service_account_name> 3
      outputs:
       - name: cw 4
         type: cloudwatch 5
         cloudwatch:
           groupBy: logType 6
           groupPrefix: <group prefix> 7
           region: us-east-2 8
         secret:
            name: cw-secret 9
      pipelines:
        - name: infra-logs 10
          inputRefs: 11
            - infrastructure
            - audit
            - application
          outputRefs:
            - cw 12
    1
    在传统的实现中,CR 名称必须是 instance。在多日志转发器实现中,您可以使用任何名称。
    2
    在旧的实现中,CR 命名空间必须是 openshift-logging。在多日志转发器实现中,您可以使用任何命名空间。
    3
    服务帐户的名称。如果没有在 openshift-logging 命名空间中部署日志转发器,则只有多日志转发器实现中才需要服务帐户。
    4
    指定输出的名称。
    5
    指定 cloudwatch 类型。
    6
    可选:指定如何对日志进行分组:
    • logType 为每个日志类型创建日志组。
    • namespaceName 为每个应用程序命名空间创建一个日志组。它还会为基础架构和审计日志创建单独的日志组。
    • namespaceUUID 为每个应用命名空间 UUID 创建一个新的日志组。它还会为基础架构和审计日志创建单独的日志组。
    7
    可选:指定一个字符串来替换日志组名称中的默认 infrastructureName 前缀。
    8
    指定 AWS 区域。
    9
    指定包含 AWS 凭证的 secret 名称。
    10
    可选:指定管道的名称。
    11
    使用管道指定要转发的日志类型:applicationinfrastructureaudit
    12
    指定使用此管道转发日志时使用的输出名称。
  4. 创建 CR 对象。

    $ oc create -f <file-name>.yaml

示例:在 Amazon CloudWatch 中使用 ClusterLogForwarder

在这里,您会看到 ClusterLogForwarder 自定义资源 (CR) 示例及其输出到 Amazon CloudWatch 的日志数据。

假设您正在运行名为 mycluster 的 OpenShift Container Platform 集群。以下命令返回集群的 infrastructureName,稍后您将用它来编写 aws 命令:

$ oc get Infrastructure/cluster -ojson | jq .status.infrastructureName
"mycluster-7977k"

要为本例生成日志数据,您可以在名为 app 的命名空间中运行 busybox pod。busybox pod 每隔三秒钟将消息写入 stdout:

$ oc run busybox --image=busybox -- sh -c 'while true; do echo "My life is my message"; sleep 3; done'
$ oc logs -f busybox
My life is my message
My life is my message
My life is my message
...

您可以查找 busybox pod 运行的 app 命名空间的 UUID:

$ oc get ns/app -ojson | jq .metadata.uid
"794e1e1a-b9f5-4958-a190-e76a9b53d7bf"

ClusterLogForwarder 自定义资源 (CR) 中,您可以将 infrastructureauditapplication 日志类型配置为 all-logs 管道的输入。您还可以将此管道连接到 cw 输出,输出将日志转发到 us-east-2 区域的 CloudWatch 实例:

apiVersion: "logging.openshift.io/v1"
kind: ClusterLogForwarder
metadata:
  name: instance
  namespace: openshift-logging
spec:
  outputs:
   - name: cw
     type: cloudwatch
     cloudwatch:
       groupBy: logType
       region: us-east-2
     secret:
        name: cw-secret
  pipelines:
    - name: all-logs
      inputRefs:
        - infrastructure
        - audit
        - application
      outputRefs:
        - cw

CloudWatch 中的每个地区都包含三个级别的对象:

  • 日志组

    • 日志流

      • 日志事件

使用 ClusterLogForwarding CR 中的 groupBy: logTypeinputRefs 中的三种日志类型会在 Amazon Cloudwatch 中生成三个日志组:

$ aws --output json logs describe-log-groups | jq .logGroups[].logGroupName
"mycluster-7977k.application"
"mycluster-7977k.audit"
"mycluster-7977k.infrastructure"

每个日志组都包含日志流:

$ aws --output json logs describe-log-streams --log-group-name mycluster-7977k.application | jq .logStreams[].logStreamName
"kubernetes.var.log.containers.busybox_app_busybox-da085893053e20beddd6747acdbaf98e77c37718f85a7f6a4facf09ca195ad76.log"
$ aws --output json logs describe-log-streams --log-group-name mycluster-7977k.audit | jq .logStreams[].logStreamName
"ip-10-0-131-228.us-east-2.compute.internal.k8s-audit.log"
"ip-10-0-131-228.us-east-2.compute.internal.linux-audit.log"
"ip-10-0-131-228.us-east-2.compute.internal.openshift-audit.log"
...
$ aws --output json logs describe-log-streams --log-group-name mycluster-7977k.infrastructure | jq .logStreams[].logStreamName
"ip-10-0-131-228.us-east-2.compute.internal.kubernetes.var.log.containers.apiserver-69f9fd9b58-zqzw5_openshift-oauth-apiserver_oauth-apiserver-453c5c4ee026fe20a6139ba6b1cdd1bed25989c905bf5ac5ca211b7cbb5c3d7b.log"
"ip-10-0-131-228.us-east-2.compute.internal.kubernetes.var.log.containers.apiserver-797774f7c5-lftrx_openshift-apiserver_openshift-apiserver-ce51532df7d4e4d5f21c4f4be05f6575b93196336be0027067fd7d93d70f66a4.log"
"ip-10-0-131-228.us-east-2.compute.internal.kubernetes.var.log.containers.apiserver-797774f7c5-lftrx_openshift-apiserver_openshift-apiserver-check-endpoints-82a9096b5931b5c3b1d6dc4b66113252da4a6472c9fff48623baee761911a9ef.log"
...

每个日志流都包含日志事件。要查看 busybox Pod 的日志事件,您可以从 application 日志组中指定其日志流:

$ aws logs get-log-events --log-group-name mycluster-7977k.application --log-stream-name kubernetes.var.log.containers.busybox_app_busybox-da085893053e20beddd6747acdbaf98e77c37718f85a7f6a4facf09ca195ad76.log
{
    "events": [
        {
            "timestamp": 1629422704178,
            "message": "{\"docker\":{\"container_id\":\"da085893053e20beddd6747acdbaf98e77c37718f85a7f6a4facf09ca195ad76\"},\"kubernetes\":{\"container_name\":\"busybox\",\"namespace_name\":\"app\",\"pod_name\":\"busybox\",\"container_image\":\"docker.io/library/busybox:latest\",\"container_image_id\":\"docker.io/library/busybox@sha256:0f354ec1728d9ff32edcd7d1b8bbdfc798277ad36120dc3dc683be44524c8b60\",\"pod_id\":\"870be234-90a3-4258-b73f-4f4d6e2777c7\",\"host\":\"ip-10-0-216-3.us-east-2.compute.internal\",\"labels\":{\"run\":\"busybox\"},\"master_url\":\"https://kubernetes.default.svc\",\"namespace_id\":\"794e1e1a-b9f5-4958-a190-e76a9b53d7bf\",\"namespace_labels\":{\"kubernetes_io/metadata_name\":\"app\"}},\"message\":\"My life is my message\",\"level\":\"unknown\",\"hostname\":\"ip-10-0-216-3.us-east-2.compute.internal\",\"pipeline_metadata\":{\"collector\":{\"ipaddr4\":\"10.0.216.3\",\"inputname\":\"fluent-plugin-systemd\",\"name\":\"fluentd\",\"received_at\":\"2021-08-20T01:25:08.085760+00:00\",\"version\":\"1.7.4 1.6.0\"}},\"@timestamp\":\"2021-08-20T01:25:04.178986+00:00\",\"viaq_index_name\":\"app-write\",\"viaq_msg_id\":\"NWRjZmUyMWQtZjgzNC00MjI4LTk3MjMtNTk3NmY3ZjU4NDk1\",\"log_type\":\"application\",\"time\":\"2021-08-20T01:25:04+00:00\"}",
            "ingestionTime": 1629422744016
        },
...

示例:在日志组群名称中自定义前缀

在日志组名称中,您可以将默认的 infrastructureName 前缀 mycluster-7977k 替换为一个任意字符串,如 demo-group-prefix。要进行此更改,您需要更新 ClusterLogForwarding CR 中的 groupPrefix 字段:

cloudwatch:
    groupBy: logType
    groupPrefix: demo-group-prefix
    region: us-east-2

groupPrefix 的值替换默认的 infrastructureName 前缀:

$ aws --output json logs describe-log-groups | jq .logGroups[].logGroupName
"demo-group-prefix.application"
"demo-group-prefix.audit"
"demo-group-prefix.infrastructure"

示例:应用程序命名空间名称后命名日志组

对于集群中的每个应用程序命名空间,您可以在 CloudWatch 中创建日志组,其名称基于应用程序命名空间的名称。

如果您删除应用程序命名空间对象并创建名称相同的新对象,CloudWatch 会继续使用与以前相同的日志组。

如果您认为名称相同的连续应用程序命名空间对象相互等效,请使用本例中描述的方法。否则,如果您需要将生成的日志组相互区分,请参阅以下"为应用命名空间 UUID 注入日志组"部分。

要创建名称基于应用程序命名空间名称的应用程序日志组,您可以在 ClusterLogForwarder CR 中将 groupBy 字段的值设置为 namespaceName

cloudwatch:
    groupBy: namespaceName
    region: us-east-2

groupBy 设置为 namespaceName 只会影响应用程序日志组。它不会影响 auditinfrastructure 日志组。

在 Amazon Cloudwatch 中,命名空间名称显示在每个日志组名称的末尾。因为只有一个应用程序命名空间 "app",以下输出显示一个新的 mycluster-7977k.app 日志组,而不是 mycluster-7977k.application

$ aws --output json logs describe-log-groups | jq .logGroups[].logGroupName
"mycluster-7977k.app"
"mycluster-7977k.audit"
"mycluster-7977k.infrastructure"

如果本例中的集群包含多个应用命名空间,则输出中会显示多个日志组,每个命名空间对应一个日志组。

groupBy 字段仅影响应用日志组。它不会影响 auditinfrastructure 日志组。

示例:应用程序命名空间 UUID 后命名日志组

对于集群中的每个应用程序命名空间,您可以在 CloudWatch 中创建日志组,其名称是基于应用程序命名空间的 UUID。

如果您删除应用程序命名空间对象并创建新对象,CloudWatch 会创建一个新的日志组。

如果您考虑使用名称相同的连续应用程序命名空间对象,请使用本例中描述的方法。否则,请参阅前面的 "Example: Naming log groups for application namespace name" 部分。

要在应用程序命名空间 UUID 后命名日志组,您可以在 ClusterLogForwarder CR 中将 groupBy 字段的值设置为 namespaceUUID

cloudwatch:
    groupBy: namespaceUUID
    region: us-east-2

在 Amazon Cloudwatch 中,命名空间 UUID 出现在每个日志组名称的末尾。因为有一个应用程序命名空间 "app",以下输出显示一个新的 mycluster-7977k.794e1e1a-b9f5-4958-a190-e76a9b53d7bf 日志组,而不是 mycluster-7977k.application

$ aws --output json logs describe-log-groups | jq .logGroups[].logGroupName
"mycluster-7977k.794e1e1a-b9f5-4958-a190-e76a9b53d7bf" // uid of the "app" namespace
"mycluster-7977k.audit"
"mycluster-7977k.infrastructure"

groupBy 字段仅影响应用日志组。它不会影响 auditinfrastructure 日志组。

9.4.15.1. 使用现有 AWS 角色为 AWS CloudWatch 创建 secret

如果您有一个 AWS 的现有角色,您可以使用 oc create secret --from-literal 命令为 AWS 使用 STS 创建 secret。

流程

  • 在 CLI 中,输入以下内容来为 AWS 生成 secret:

    $ oc create secret generic cw-sts-secret -n openshift-logging --from-literal=role_arn=arn:aws:iam::123456789012:role/my-role_with-permissions

    Secret 示例

    apiVersion: v1
    kind: Secret
    metadata:
      namespace: openshift-logging
      name: my-secret-name
    stringData:
      role_arn: arn:aws:iam::123456789012:role/my-role_with-permissions

9.4.16. 从启用了 STS 的集群将日志转发到 Amazon CloudWatch

对于启用了 AWS Security Token Service (STS) 的集群,您可以手动创建 AWS 服务帐户,或使用 Cloud Credential Operator (CCO) 实用程序 ccoctl 创建凭证请求。

先决条件

  • Logging for Red Hat OpenShift: 5.5 及更新的版本

步骤

  1. 使用以下模板创建 CredentialsRequest 自定义资源 YAML:

    Cloudwatch 凭证请求模板

    apiVersion: cloudcredential.openshift.io/v1
    kind: CredentialsRequest
    metadata:
      name: <your_role_name>-credrequest
      namespace: openshift-cloud-credential-operator
    spec:
      providerSpec:
        apiVersion: cloudcredential.openshift.io/v1
        kind: AWSProviderSpec
        statementEntries:
          - action:
              - logs:PutLogEvents
              - logs:CreateLogGroup
              - logs:PutRetentionPolicy
              - logs:CreateLogStream
              - logs:DescribeLogGroups
              - logs:DescribeLogStreams
            effect: Allow
            resource: arn:aws:logs:*:*:*
      secretRef:
        name: <your_role_name>
        namespace: openshift-logging
      serviceAccountNames:
        - logcollector

  2. 使用 ccoctl 命令,使用 CredentialsRequest CR 为 AWS 创建角色。使用 CredentialsRequest 对象时,这个 ccoctl 命令会创建一个带有信任策略的 IAM 角色,该角色与指定的 OIDC 身份提供程序相关联,以及一个授予对 CloudWatch 资源执行操作的权限策略。此命令在 /<path_to_ccoctl_output_dir>/manifests/openshift-logging-<your_role_name>-credentials.yaml 中创建了一个 YAML 配置文件。此 secret 文件包含与 AWS IAM 身份提供程序进行身份验证时使用的 role_arn 键/值。

    $ ccoctl aws create-iam-roles \
    --name=<name> \
    --region=<aws_region> \
    --credentials-requests-dir=<path_to_directory_with_list_of_credentials_requests>/credrequests \
    --identity-provider-arn=arn:aws:iam::<aws_account_id>:oidc-provider/<name>-oidc.s3.<aws_region>.amazonaws.com 1
    1
    <name> 是用于标记云资源的名称,应该与 STS 集群安装过程中使用的名称匹配
  3. 应用创建的 secret:

    $ oc apply -f output/manifests/openshift-logging-<your_role_name>-credentials.yaml
  4. 创建或编辑 ClusterLogForwarder 自定义资源:

    apiVersion: logging.openshift.io/v1
    kind: ClusterLogForwarder
    metadata:
      name: <log_forwarder_name> 1
      namespace: <log_forwarder_namespace> 2
    spec:
      serviceAccountName: clf-collector 3
      outputs:
       - name: cw 4
         type: cloudwatch 5
         cloudwatch:
           groupBy: logType 6
           groupPrefix: <group prefix> 7
           region: us-east-2 8
         secret:
            name: <your_secret_name> 9
      pipelines:
        - name: to-cloudwatch 10
          inputRefs: 11
            - infrastructure
            - audit
            - application
          outputRefs:
            - cw 12
    1
    在传统的实现中,CR 名称必须是 instance。在多日志转发器实现中,您可以使用任何名称。
    2
    在旧的实现中,CR 命名空间必须是 openshift-logging。在多日志转发器实现中,您可以使用任何命名空间。
    3
    指定 clf-collector 服务帐户。如果没有在 openshift-logging 命名空间中部署日志转发器,则只有多日志转发器实现中才需要服务帐户。
    4
    指定输出的名称。
    5
    指定 cloudwatch 类型。
    6
    可选:指定如何对日志进行分组:
    • logType 为每个日志类型创建日志组。
    • namespaceName 为每个应用程序命名空间创建一个日志组。基础架构和审计日志不受影响,剩余的日志按照 logType 分组。
    • namespaceUUID 为每个应用命名空间 UUID 创建一个新的日志组。它还会为基础架构和审计日志创建单独的日志组。
    7
    可选:指定一个字符串来替换日志组名称中的默认 infrastructureName 前缀。
    8
    指定 AWS 区域。
    9
    指定包含 AWS 凭证的 secret 名称。
    10
    可选:指定管道的名称。
    11
    使用管道指定要转发的日志类型:applicationinfrastructureaudit
    12
    指定使用此管道转发日志时使用的输出名称。

其他资源