云原生架构下的日志平台方案

简介: 在公司转型云原生架构的过程中,复杂的动态集群环境下,可观测性(Observability)对于快速定位和诊断问题,已上升到公司整体层面了。日志作为重要的三大(logs, metrics and traces)可监测要素之一尤为重要。同时日志系统提供的也不再局限于应用系统的诊断,还包括业务、运营、BI、审计、安全等领域,日志平台最终的目标是实现公司在云原生架构下各个方面的数字化、智能化。

云原生架构下的日志平台方案

作者简介

Ford, FDD架构师,十二年软件开发经验,主要负责云原生架构的设计,专注于基础架构,ServiceMesh拥护者,持续交付、敏捷实践者。

一、云原生架构下的日志系统特点

伴随公司近年来持续高速增长的业务发展,以及软件架构的微服务化,在水平和垂直双向扩展后线上运行的应用成倍增长。原本基于单体应用(Monolithic)场景下,使用tail、grep、awk的日志查询和日志分析方式已捉襟见肘、无法应对云原生架构下成倍增长的应用日志量和分布式项目的复杂运行环境挑战。

在公司转型云原生架构的过程中,复杂的动态集群环境下,可观测性(Observability)对于快速定位和诊断问题,已上升到公司整体层面了。日志作为重要的三大(logs, metrics and traces)可监测要素之一尤为重要。同时日志系统提供的也不再局限于应用系统的诊断,还包括业务、运营、BI、审计、安全等领域,日志平台最终的目标是实现公司在云原生架构下各个方面的数字化、智能化。

图:三大可监测要素:logs, metrics and traces

three-pillars-of-observability-.png

云原生架构下的日志方案比基于物理机、虚拟机场景的日志架构设计有较大的差异,比如:

1、动态的日志环境,在 kubernetes 集群环境下,应用的弹性伸缩、Pod的销毁和漂移、working节点的上线和下线都是常态,这种情况下日志的存在是瞬间的,伴随着Pod的销毁和漂移日志会被动销毁,因此日志数据需要被实时采集到集中式的存储设备中,同时对于日志采集器在此动态和复杂环境下的扩展性和适配性有新的要求。

2、资源消耗,在原有的传统ELK架构中,基于 JDK 的 Logstash 和 Filebeat 预期分别会消耗500M、12M左右的内存,在微服务、云原生的架构下,服务通常都会拆的很小,因此数据采集对于服务自身的资源消耗要尽可能的少。

3、日志平台的运维代价,运维一套动态环境下的日志采集和日志管理平台是复杂和繁琐的,日志平台应该SaaS话,作为底层基础设施,可一键部署和动态适配。

4、便捷的日志分析、日志系统最核心的功能是问题排查,问题排查的速度直接决定了事故响应速度、损失大小。一套可视化、高性能、智能分析的功能可以帮助用户快速定位问题。

二、云原生架构下的日志系统设计

2.1 方案选型

  • 云原生架构下的日志采集解决方案
编号 方案 优点 缺点
1 每个app的镜像中都集成日志收集组件,如logback-redis-appender 部署方便,kubernetes的yaml文件无须特别配置,可以灵活的为每个app自定义日志采集规则 强耦合,应用侵入式,不方便应用和日志收集组件升级和维护且会导致镜像过大
2 app的Pod内单独创建一个日志采集容器跟app的容器一起运行 低耦合,扩展性强,方便维护和升级 需要对 kubernetes 的yaml文件进行单独配置,略显繁琐
3 以 DaemonSet 方式在每个工作节点上启动一个日志采集的Pod, 将所有的Pod的日志都挂载到宿主机上 完全解耦,性能最高,管理起来最方便 需要统一日志收集规则,目录和输出方式

综合以上优缺点,我们选择使用方案三。

该方案在扩展性、资源消耗、部署和后期维护方面都能做到均衡,因此选择该方案。

以下整理各方案的架构图:

图:方案1,应用内置采集组件,异步采集

_u65B9_u68481_uFF0C_u5E94_u7528.png

图:方案2,Pod伴侣容器,Sidercar模式

_u65B9_u68482_uFF0CPod_u4F34_u4.png

图:方案3,宿主机统一采集方案

_u65B9_u68483_uFF0Cfluent-bit.png

2.2 方案实施及验证

2.2.1 方案说明

在集群启动时以 DaemonSet 方式在每个机器启动一个 Fluent-bit agent,收集日志然后发送给 Elasticsearch。实现方式是每个agent挂载目录 /var/log/containers/ 使用 Fluent-bit 的tail插件扫描每个容器日志文件,直接发送给 Elasticsearch。

而 /var/log/containers/ 的日志实际映射自 kubernetes 节点上的容器日志,如下图所示:

图:节点在/var/log/containers/目录下的文件链接路径

node-container-log-storagepath.png

node-container-log-storagepath02.png

fluent-bit 监听及Input配置

    @INCLUDE input-kubernetes.conf
    @INCLUDE filter-kubernetes.conf
    @INCLUDE output-elasticsearch.conf

  input-kubernetes.conf: |
    [INPUT]
        Name              tail
        Tag               kube.*
        Path              /var/log/containers/*.log
        Parser            docker
        DB                /var/log/flb_kube.db
        Mem_Buf_Limit     5MB
        Skip_Long_Lines   On
        Refresh_Interval  10

采集agent本身也是基于 kubernetes 集群部署的,当集群节点扩容时,由 kube-scheduler 执行新节点的 fluent-bit agent 的自动完成部署。

Elasticsearch 和 Kibana 目前使用的云供应商的服务,自带 X-pack 插件,支持商业版才有的权限管理功能。

2.2.2 实施

1、fluent-bit采集器配置(server, input, filters and output)

fluentd_u91C7_u96C6_u5668_u914D.png

2、fluent-bit在kubernetes集群中的RABC权限创建

  • fluent-bit-service-account.yaml

    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: fluent-bit
      namespace: logging
  • fluent-bit-role.yaml

    apiVersion: rbac.authorization.k8s.io/v1beta1
    kind: ClusterRole
    metadata:
      name: fluent-bit-read
    rules:
    - apiGroups: [""]
      resources:
      - namespaces
      - pods
      verbs: ["get", "list", "watch"]
  • fluent-bit-role-binding.yaml

    apiVersion: rbac.authorization.k8s.io/v1beta1
    kind: ClusterRoleBinding
    metadata:
      name: fluent-bit-read
    roleRef:
      apiGroup: rbac.authorization.k8s.io
      kind: ClusterRole
      name: fluent-bit-read
    subjects:
    - kind: ServiceAccount
      name: fluent-bit
      namespace: logging

3、Fluent-bit在kubernetes集群节点以Daemonset方式部署

  • fluent-bit-ds.yaml

    apiVersion: extensions/v1beta1
    kind: DaemonSet
    metadata:
      name: fluent-bit
      namespace: logging
      labels:
        k8s-app: fluent-bit-logging
        version: v1
        kubernetes.io/cluster-service: "true"
    spec:
      template:
        metadata:
    labels:
    k8s-app: fluent-bit-logging
    version: v1
    kubernetes.io/cluster-service: "true"
    annotations:
    prometheus.io/scrape: "true"
    prometheus.io/port: "2020"
    prometheus.io/path: /api/v1/metrics/prometheus
        spec:
    containers:
    - name: fluent-bit
    image: fluent/fluent-bit:1.2.1
    imagePullPolicy: Always
    ports:
      - containerPort: 2020
    env:
    - name: FLUENT_ELASTICSEARCH_HOST
      value: "elasticsearch"
    - name: FLUENT_ELASTICSEARCH_PORT
      value: "9200"
    volumeMounts:
    - name: varlog
      mountPath: /var/log
    - name: varlibdockercontainers
      mountPath: /var/lib/docker/containers
      readOnly: true
    - name: fluent-bit-config
      mountPath: /fluent-bit/etc/
    terminationGracePeriodSeconds: 10
    volumes:
    - name: varlog
    hostPath:
      path: /var/log
    - name: varlibdockercontainers
    hostPath:
      path: /var/lib/docker/containers
    - name: fluent-bit-config
    configMap:
      name: fluent-bit-config
    serviceAccountName: fluent-bit
    tolerations:
    - key: node-role.kubernetes.io/master
    operator: Exists
    effect: NoSchedule
    - operator: "Exists"
    effect: "NoExecute"
    - operator: "Exists"
    effect: "NoSchedule"

#### 2.3 验证日志平台

  • 简单查询
  • 分词查询
  • 精准查询
  • 复合查询 (AND OR)
  • 基于字段的查询
  • 项目过滤
  • 机器、节点过滤
  • 正则查询
  • 区间查询
  • 查询上下文
  • 日志列表显示定制
  • 时间选择

图:日志查询 - 复合查询 (AND OR)

kb-and.png

图:日志查询-查询上下文

kb-surunde.png

2.4 集群审计日志采集

方案中的,Fluent-bit支持采集kubernetes集群的事件审计日志,在kube-apiserver操作导致的状态变更的都会产生相应日志,如下 kubernetes-audit-policy.yaml 定义了收集那些审计日志,只需要在kube-api启动文件中引用此配置,通过使用 --audit-policy-file

  • kubernetes-audit-policy.yaml
apiVersion: audit.k8s.io/v1 # This is required.
kind: Policy
# Don't generate audit events for all requests in RequestReceived stage.
omitStages:
  - "RequestReceived"
rules:
  # Log pod changes at RequestResponse level
  - level: RequestResponse
    resources:
    - group: ""
      # Resource "pods" doesn't match requests to any subresource of pods,
      # which is consistent with the RBAC policy.
      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
    # Long-running requests like watches that fall under this rule will not
    # generate an audit event in RequestReceived.
    omitStages:
      - "RequestReceived"

图:kubernetes集群审计日志

k8s-audit-log.png

三、总结

随着云原生架构下日益复杂的分布式系统,日志比较分散,应用监控和排查问题都比较困难,同时效率还低下,本文中kubernetes集群下的集中式日志平台就是为了解决这个问题。将集群日志、应用日志,安全日志收集、检索、统计、分析以及对日志信息的 Web 管理等集中化管控,实现了快速问题排查、高效解决问题的重要的途径。

在生产部署时,可以根据业务系统容量来确定是否引入 Kafaka 队列,线下环境也可以不引入 Kafaka 队列,简单部署,后续需要扩展再接入 Kafaka 队列。

本文中Elasticsearch 和 Kibana 使用的云厂商的服务,线下开发环境,考虑成本节约的因素可以使用 helm 快速构建,参考如下:

  • 使用 helm 快速部署 Elasticsearch

    helm repo add incubator https://kubernetes-charts-incubator.storage.googleapis.com/
    helm install --name elasticsearch stable/elasticsearch \
        --set master.persistence.enabled=false \
        --set data.persistence.enabled=false \
        --namespace logging
  • 使用 helm 快速部署 Kibana

    helm install --name kibana stable/kibana \
        --set env.ELASTICSEARCH_URL=http://elasticsearch-client:9200 \
        --namespace logging

### 四、参考文档

https://github.com/fluent/fluentd

https://kubernetes.io/docs/tasks/debug-application-cluster/audit/

https://github.com/kubernetes/kubernetes/tree/master/cluster/addons/fluentd-elasticsearch

https://github.com/fluent/fluent-bit

https://github.com/anjia0532/gcr.io_mirror

相关实践学习
通过日志服务实现云资源OSS的安全审计
本实验介绍如何通过日志服务实现云资源OSS的安全审计。
目录
相关文章
|
3月前
|
存储 调度 C++
16 倍性能提升,成本降低 98%! 解读 SLS 向量索引架构升级改造
大规模数据如何进行语义检索? 当前 SLS 已经支持一站式的语义检索功能,能够用于 RAG、Memory、语义聚类、多模态数据等各种场景的应用。本文分享了 SLS 在语义检索功能上,对模型推理和部署、构建流水线等流程的优化,最终带给用户更高性能和更低成本的针对大规模数据的语义索引功能。
375 27
|
存储 Cloud Native 数据处理
从嵌入式状态管理到云原生架构:Apache Flink 的演进与下一代增量计算范式
本文整理自阿里云资深技术专家、Apache Flink PMC 成员梅源在 Flink Forward Asia 新加坡 2025上的分享,深入解析 Flink 状态管理系统的发展历程,从核心设计到 Flink 2.0 存算分离架构,并展望未来基于流批一体的通用增量计算方向。
380 0
从嵌入式状态管理到云原生架构:Apache Flink 的演进与下一代增量计算范式
|
5月前
|
运维 监控 Cloud Native
从本土到全球,云原生架构护航灵犀互娱游戏出海
本文内容整理自「 2025 中企出海大会·游戏与互娱出海分论坛」,灵犀互娱基础架构负责人朱晓靖的演讲内容,从技术层面分享云原生架构护航灵犀互娱游戏出海经验。
509 16
|
5月前
|
运维 监控 Cloud Native
从本土到全球,云原生架构护航灵犀互娱游戏出海
内容整理自「 2025 中企出海大会·游戏与互娱出海分论坛」,灵犀互娱基础架构负责人朱晓靖的演讲内容,从技术层面分享云原生架构护航灵犀互娱游戏出海经验。
|
3月前
|
Cloud Native Serverless API
微服务架构实战指南:从单体应用到云原生的蜕变之路
🌟蒋星熠Jaxonic,代码为舟的星际旅人。深耕微服务架构,擅以DDD拆分服务、构建高可用通信与治理体系。分享从单体到云原生的实战经验,探索技术演进的无限可能。
微服务架构实战指南:从单体应用到云原生的蜕变之路
|
3月前
|
Java Linux 虚拟化
【Docker】(1)Docker的概述与架构,手把手带你安装Docker,云原生路上不可缺少的一门技术!
1. Docker简介 1.1 Docker是什么 为什么docker会出现? 假定您在开发一款平台项目,您的开发环境具有特定的配置。其他开发人员身处的环境配置也各有不同。 您正在开发的应用依赖于您当前的配置且还要依赖于某些配置文件。 您的企业还拥有标准化的测试和生产环境,且具有自身的配置和一系列支持文件。 **要求:**希望尽可能多在本地模拟这些环境而不产生重新创建服务器环境的开销 问题: 要如何确保应用能够在这些环境中运行和通过质量检测? 在部署过程中不出现令人头疼的版本、配置问题 无需重新编写代码和进行故障修复
395 2
|
3月前
|
人工智能 Kubernetes Cloud Native
Higress(云原生AI网关) 架构学习指南
Higress 架构学习指南 🚀写在前面: 嘿,欢迎你来到 Higress 的学习之旅!
814 0
|
6月前
|
Ubuntu 编译器 C语言
在Ubuntu22.04平台上交叉编译针对Rv1126架构的GCC13.2.0编译器的步骤。
遵循上述步骤,您应该能够在Ubuntu 22.04平台上成功交叉编译适用于RISC-V架构RV1126的GCC 13.2.0编译器,允许您为目标硬件构建应用程序和操作系统组件。
347 10
|
6月前
|
运维 监控 Cloud Native
从“守机器”到“写策略”——云原生架构把运维逼成了架构师
从“守机器”到“写策略”——云原生架构把运维逼成了架构师
139 1