前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >云原生架构下的日志平台方案

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

原创
作者头像
云原生实验室
修改2020-12-08 18:12:53
2.5K0
修改2020-12-08 18:12:53
举报

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

作者简介

Ford, 云原生布道师,云原生实验室(CloudnativeLab.COM)创始人 专注于云计算领域数年,目前主要从事容器云平台的建设,推进各类基础设施服务的云原生化,乐于研发效能建设、产品驱动模式探索和敏捷高效的产品研发团队打造,ServiceMesh拥护者,持续交付、敏捷实践者。

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

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

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

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

three-pillars-of-observability-.png
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
_u65B9_u68481_uFF0C_u5E94_u7528.png

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

_u65B9_u68482_uFF0CPod_u4F34_u4.png
_u65B9_u68482_uFF0CPod_u4F34_u4.png

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

_u65B9_u68483_uFF0Cfluent-bit.png
_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-storagepath.png
node-container-log-storagepath02.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
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-and.png

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

kb-surunde.png
kb-surunde.png
2.4 集群审计日志采集

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

  • kubernetes-audit-policy.yamlapiVersion: audit.k8s.io/v1 # This is required. kind: PolicyDon'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: MetadataLong-running requests like watches that fall under this rule will notgenerate an audit event in RequestReceived.omitStages:
    • "RequestReceived"

图:kubernetes集群审计日志

k8s-audit-log.png
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

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 云原生架构下的日志平台方案
    • 一、云原生架构下的日志系统特点
      • 二、云原生架构下的日志系统设计
      • Don't log requests to a configmap called "controller-leader"
      • Don't log watch requests by the "system:kube-proxy" on endpoints or services
      • Don't log authenticated requests to certain non-resource URL paths.
      • Log the request body of configmap changes in kube-system.
      • Log configmap and secret changes in all other namespaces at the Metadata level.
      • Log all other resources in core and extensions at the Request level.
      • A catch-all rule to log all other requests at the Metadata level.
        • 三、总结
          • 四、参考文档
          相关产品与服务
          日志服务
          日志服务(Cloud Log Service,CLS)是腾讯云提供的一站式日志服务平台,提供了从日志采集、日志存储到日志检索,图表分析、监控告警、日志投递等多项服务,协助用户通过日志来解决业务运维、服务监控、日志审计等场景问题。
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档