7 日志记录

您可以使用 Oracle Cloud Infrastructure (OCI) 或外部工具为 Oracle Blockchain Platform Enterprise Edition 配置持久性日志记录。

概述

Oracle Blockchain Platform Enterprise Edition 基于 Kubernetes,在每个 pod 上本地存储日志。要防止在删除 pod 时删除日志,必须设置持久性日志记录,其中日志存储在中心位置。有两种方法可用于持久性日志记录。您可以使用外部日志记录工具,例如 Fluentd 和 Elastic Stack。或者,如果您使用 Oracle Kubernetes Engine 运行,则可以使用 Oracle Cloud Infrastructure (OCI) 支持的集中式日志记录解决方案。

使用 OCI 进行持久性记录

要使用 OCI 集中存储日志,请定义日志组并配置代理来对日志进行语法分析。日志存储在对象存储服务中。在使用 OCI 配置持久性日志记录之前,您的部署必须满足以下要求。
  • Kubernetes 区间中的动态组。要创建动态组,请单击导航菜单中的身份和安全。在身份下,单击,然后单击创建动态组。在匹配规则部分中将以下内容添加到动态组,以区间替换 Oracle Cloud ID。
    instance.compartment.id = '<compartment_ocid>'
    例如:
    instance.compartment.id = 'ocid1.compartment.oc1..aaaaaaaa4ws3242343243244nyb423432rwqsxigt2sia'
  • 允许动态组与日志记录服务交互的策略。要创建策略,请单击导航菜单中的身份和安全。在身份下,单击策略,然后单击创建策略
    Allow dynamic-group <my-group> to use log-content in compartment <target_compartment_name>
    例如:
    Allow dynamic-group okelogging to use log-content in compartment BlockchainTeam
在满足先决条件后,请完成以下步骤以使用 OCI 集中存储日志。
  1. 单击左上角的菜单图标,搜索 log ,然后选择 Logs
  2. 创建日志组。在日志记录下,选择日志组,然后单击创建日志组
  3. 创建定制日志。在日志记录下,选择日志,然后单击创建定制日志以打开创建定制日志向导。选择以前创建的日志组。
  4. 创建定制日志向导的第二页上,为定制日志创建代理配置,指定 Kubernetes 区间和动态组。
  5. 代理配置页的配置日志输入部分中,将代理的日志输入配置为使用以下文件路径,这是应用程序容器的默认路径。从输入类型列表中选择日志路径。为文件路径输入以下文件路径。此路径包括所有容器日志,包括系统和服务容器。
    /var/log/pods/*/*/*.log
  6. 等待,直到摄取日志。通常,日志在 3-5 分钟内摄取。
  7. 选择 Logs(日志),然后导航到定制日志并单击 Explore Log(浏览日志)。您可以分析、解析和筛选日志。
  8. 您还可以使用 OCI 将日志存储在对象存储服务中。
    1. 创建连接器。在日志记录下,选择连接器,然后单击创建连接器。选择日志记录作为,选择对象存储作为目标
    2. 根据需要配置源和目标。
    3. 启用日志部分下,为您创建的连接器将启用日志设置为已启用。此时将显示 Create Log 面板,其中包含日志保留时间的默认值。
    4. 等待,直到摄取日志。通常,日志在 3-5 分钟内摄取。然后,您可以在连接器日志中查看读写操作。日志现在正在写入对象存储服务。

有关详细信息,请参阅使用 OCI Logging Analytics 监视 Kubernetes 和 OKE 集群

使用外部工具进行持久性日志记录

您可以使用 Fluentd 和 Elastic Stack 集中存储日志。以下步骤已通过 Fluentd v1.16.2 和 Elasticsearch 7.9.1 进行测试。完成这些步骤时,请使用这些版本或更高版本。
  1. 创建名为 fluentd 的 Kubernetes 名称空间。
  2. 使用以下命令创建基于角色的访问控制资源。
    kubectl create -f fluentd-rbac.yaml -n fluentd
    将以下 fluentd-rbac.yaml 文件与命令一起使用。
    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: fluentd
      namespace: fluentd
    ---
    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRole
    metadata:
      name: fluentd
      namespace: fluentd
    rules:
    - apiGroups:
      - ""
      resources:
      - pods
      - namespaces
      verbs:
      - get
      - list
      - watch
    ---
    kind: ClusterRoleBinding
    apiVersion: rbac.authorization.k8s.io/v1
    metadata:
      name: fluentd
    roleRef:
      kind: ClusterRole
      name: fluentd
      apiGroup: rbac.authorization.k8s.io
    subjects:
    - kind: ServiceAccount
      name: fluentd
      namespace: fluentd
  3. 使用以下命令为 Fluentd 或 Elastic Stack 创建 ConfigMap 对象。
    kubectl create -f fluentd-configmap_removefilter_ascii.yaml -n fluentd
    将以下 fluentd-configmap_removefilter_ascii.yaml 文件与命令一起使用。
    在以下文件中,删除数字符号 (#) 以仅取消注释以下行之一。
    • 如果要写入 /tmp/obp.log 路径中的文件,请取消注释 @include file-fluent.conf
    • 如果您要写信给 Elasticsearch,请取消对 @include elastic-fluent.conf 的注释。
    以下文件显示写入 /tmp/obp.log 路径的示例。
    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: fluentd-config
      namespace: fluentd
    data:
      fluent.conf: |-
        ################################################################
        # This source gets all logs from local docker host
        #@include pods-kind-fluent.conf
        #@include pods-fluent.conf
        @include pods-nofilter.conf
        @include file-fluent.conf
        #@include elastic-fluent.conf
      pods-nofilter.conf: |-
        <source>
          @type tail
          path /var/log/containers/*.log
          format //^(?<time>.+) (?<stream>stdout|stderr) (?<logtag>.)? (?<log>.*)$/ /
          pos_file /var/log/fluentd-containers.log.pos
          tag kubernetes.*
          read_from_head true
        </source>
        <filter kubernetes.**>
         @type kubernetes_metadata
        </filter>
      file-fluent.conf: |-
         <match kubernetes.var.log.containers.**fluentd**.log>
          @type null
         </match>
         <match kubernetes.var.log.containers.**kube-system**.log>
           @type null
         </match>
         <match kubernetes.**>
           @type file
           path /tmp/obp.log
         </match>
      elastic-fluent.conf: |-
        <match kubernetes.var.log.containers.**fluentd**.log>
          @type null
        </match>
        <match kubernetes.var.log.containers.**kube-system**.log>
          @type null
        </match>
        <match kubernetes.**>
          @type elasticsearch
          host "#{ENV['FLUENT_ELASTICSEARCH_HOST'] || 'elasticsearch.elastic-kibana'}"
          port "#{ENV['FLUENT_ELASTICSEARCH_PORT'] || '9200'}"
          index_name fluentd-k8s-3
          type_name fluentd
          include_timestamp true
        </match>
  4. 使用以下命令为 Fluentd 创建 DaemonSet 对象。此命令在每个节点上创建一个 Fluentd pod。
    kubectl create -f fluentd.yaml -n fluentd
    将以下 fluentd.yaml 文件与命令一起使用。
    apiVersion: apps/v1
    kind: DaemonSet
    metadata:
      name: fluentd
      namespace: fluentd
      labels:
        k8s-app: fluentd-logging
        version: v1
    spec:
      selector:
        matchLabels:
          k8s-app: fluentd-logging
          version: v1
      template:
        metadata:
          labels:
            k8s-app: fluentd-logging
            version: v1
        spec:
          serviceAccount: fluentd
          serviceAccountName: fluentd
          tolerations:
          - key: node-role.kubernetes.io/master
            effect: NoSchedule
          - key: node-role.kubernetes.io/control-plane
            effect: NoSchedule 
          containers:
          - name: fluentd1
            imagePullPolicy: "Always"
            image: fluent/fluentd-kubernetes-daemonset:v1.16.2-debian-elasticsearch7-1.1
            env:
              - name:  FLUENT_ELASTICSEARCH_HOST
                value: "elasticsearch.elastic-kibana"
              - name:  FLUENT_ELASTICSEARCH_PORT
                value: "9200"
            resources:
              limits:
                memory: 200Mi
              requests:
                cpu: 100m
                memory: 200Mi
            volumeMounts:
            - name: fluentd-config
              mountPath: /fluentd/etc
            - name: logs
              mountPath: /tmp
            - name: varlog
              mountPath: /var/log
            - name: varlibdockercontainers
              mountPath: /var/lib/docker/containers
              readOnly: true
          terminationGracePeriodSeconds: 30
          volumes:
          - name: fluentd-config
            configMap:
              name: fluentd-config
          - name: varlog
            hostPath:
              path: /var/log
          - name: varlibdockercontainers
            hostPath:
              path: /var/lib/docker/containers
          - name: logs
            hostPath:
              path: /tmp
    Fluentd pod 或 Kubernetes 节点的 /tmp 目录中提供了 Oracle Blockchain Platform 日志。
  5. 要将日志发送到 Elastic Stack,请创建一个名为 elastic-kibana 的 Kubernetes 名称空间。
  6. 使用以下命令为弹性堆栈创建部署并将其作为服务公开。
    kubectl create -f elastic.yaml -n elastic-kibana
    将以下 elastic.yaml 文件与命令一起使用。
    apiVersion: v1
    kind: Namespace
    metadata:
      name: elastic-kibana
    
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: elasticsearch
      namespace: elastic-kibana
      labels:
        app: elasticsearch
    spec:
      selector:
        matchLabels:
          app: elasticsearch
      replicas: 1
      template:
        metadata:
          labels:
            app: elasticsearch
        spec:
          initContainers:
          - name: vm-max-fix
            image: busybox
            command: ["sysctl", "-w", "vm.max_map_count=262144"]
            securityContext:
              privileged: true
          containers:
          - name: elasticsearch
            image: elasticsearch:7.9.1
            imagePullPolicy: IfNotPresent
            ports:
            - containerPort: 9200
            env:
            - name: node.name
              value: "elasticsearch"
            - name: cluster.initial_master_nodes
              value: "elasticsearch"
            - name: bootstrap.memory_lock
              value: "false"
            - name: ES_JAVA_OPTS
              value: "-Xms512m -Xmx512m"
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: elasticsearch
      namespace: elastic-kibana
      labels:
        app: elasticsearch
    spec:
      type: ClusterIP
      selector:
        app: elasticsearch
      ports:
        - protocol: TCP
          name: http
          port: 9200
          targetPort: 9200
  7. 然后,可以使用以下命令检查 Elasticsearch 索引中的日志数据。
    curl -X GET "localhost:9200/_cat/indices/fluentd-k8s-*?v=true&s=index&pretty"
    curl -X GET "localhost:9200/fluentd-k8s-3/_search?pretty=true"
  8. 您还可以使用 Fluentd 将日志存储在每个节点上的本地块存储卷上。
    1. 为每个节点创建一个块存储卷,连接该卷并创建一个名为 /u01 的目录。
    2. 为 ext4 文件系统设置附加的块存储卷的格式。
    3. 在设备路径上挂载 /u01 目录。
    4. 更改 Fluentd 部署文件 (fluentd.yaml),使日志卷为 /u01,而不是 /tmp,如下面的代码片段所示。
      - name: logs
              hostPath:
                path: /u01
    5. 运行以下命令以应用 Fluentd 部署。
      kubectl apply -f fluentd.yaml -n fluentd
    6. 现在,日志在每个节点上的 /u01 目录中可见。

设置操作员云池的日志级别

可以设置 hlf-operatorobp-operator 云池的日志级别。设置日志级别的步骤因是否安装了 Oracle Blockchain Platform 而异。如果尚未安装 Oracle Blockchain Platform Enterprise Edition,请完成以下步骤。

  1. 打开相应的 deployment.yaml 文件进行编辑。hlf-operator pod 的文件位于以下位置:
    distribution_package_location/distribution-package/operators/helmcharts/hlf-operator/templates/deployment.yaml
    obp-operator pod 的文件位于以下位置:
    distribution_package_location/distribution-package/operators/helmcharts/obp-operator/templates/deployment.yaml
  2. 将以下行添加到此文件中。如注释中所示,您可以将日志级别设置为 debuginfoerror。在以下示例中,日志级别设置为 info
    --zap-log-level=info # debug, info, error
编辑文件后,文件的该部分可能与以下文本类似:
containers:
    - args:
    - --enable-leader-election
    - --zap-log-level=info # debug, info, error

如果已安装 Oracle Blockchain Platform ,请完成以下步骤。

  • 使用以下命令编辑 hlf-operatorobp-operator 云池的部署定义。添加或更新用于在 pod 模板规范下为 manager 容器配置日志级别的参数。
    kubectl edit deployment -n obp-cp obp-operator
    kubectl edit deployment -n obp-cp hlf-operator-controller-manager
更新容器参数后,部署定义可能与以下文本类似:
containers:
    - args:
    - --enable-leader-election
    - --zap-log-level=info # debug, info, error