Skip to main content

One post tagged with "observability"

View All Tags

· One min read
liutao

Apache Skywalking 专门为微服务架构和云原生架构系统而设计并且支持分布式链路追踪的APM系统。Apache Skywalking 通过加载探针的方式收集应用调用链路信息,并对采集的调用链路信息进行分析,生成应用间关系和服务间关系以及服务指标。Apache Skywalking 目前支持多种语言,其中包括 Java.Net CoreNode.jsGo 语言。本文将从以 KubeGems 应用商店出发,来快速搭建一套Skywalking,希望能够帮助到大家。

安装SkyWalking OAP

KubeGems应用商店(HelmChart)是一个描述Kubernetes相关资源的文件集合,单个应用可以用来部署某些复杂的HTTP服务器以及Web全栈应用、数据库、缓存等

  1. Elasticsearch安装

在KubeGems应用商店中找到Elasticsearch

选择部署7.13.2版本,填写必要的【项目】、【环境】等信息

img

为方便演示,Master、ES副本数都配置为1,可根据实际需要配置参数,还可以修改 Values 中的配置

SkyWalking 初始化 ElasticSearch index 的是默认规则是 1 副本 1 分片,实际在使用中ElasticSearch 的实例数最好大于 2 个

img

点击部署,ES服务搭建完成。

img

  1. SkyWalking安装

同样在应用商店找到skywalking应用,填写基本信息,进入详细配置页,将数据设置为ES应用名称与端口

img

点击部署,可以看到skywalking-oap、skywalking-ui服务已经部署完成

img

在KubeGems控制台,找到容器服务-->运行时-->路由,创建路由,将skywalking-ui服务地址进行域名映射。我这里直接采用随机域名,用户可以根据自己公司内的域名手动配置。

img

在浏览器中打开路由访问地址,已经能正常看skywalking-ui的页面了

img

img

skywalking服务搭建完成啦,是不是非常的快速方便,哈哈哈哈哈😄

SkyWalking Agent

所谓Agent是指SkyWalking从各个平台(Java Python等)收集监控数据的代理,此处我们以为Java应用为例,收集Java应用产生的各种监控数据

SkyWalking的数据采集主要是通过业务探针(Agent)来实现的,针对不同的编程语言SkyWalking提供了对应的Agent实现。Java微服务接入SkyWalking可以使用“SkyWalking Java Agent”来上报监控数据。

这就需要Java微服务在部署启动的过程中需要获取 SkyWalking Java Agent 探针包,并在启动参数中通过--javaagent:xxx进行参数指定。而具体的集成方式大致有以下四种:

  • 使用官方提供的基础镜像;

  • 将agent包构建到已存在的基础镜像中;

  • 将agent包放到共享volume中;

  • 通过sidecar 模式挂载agent;

其中前两种方式主要是通过在构建Docker镜像的过程中将Agent依赖打包集成到Java服务的Docker镜像中,而sidecar模式则是利用k8s的相关特性来实现在容器启动时挂载Agent相关依赖。

为什么选择sidecar

Sidecard主要原理是通过Kubernetes的初始化容器initContainers来实现的,initContainers是一种专用容器,它应用容器启动之前运行,可以用于完成应用启动前的必要初始化工作。如果微服务是直接部署在 Kubernetes 集群,那么采用 sidecar 模式来使用 SkyWalking Agent会更加方便,因为这种方式不需要修改原来的基础镜像,也不需要重新构建新的服务镜像,而是会以sidecar模式,通过共享的volume将agent所需的相关文件直接挂载到已经存在的服务镜像中。

初始化容器InitContainers

InitContainers 就是用来做初始化工作的容器,可以是一个或者多个,如果有多个的话,这些容器会按定义的顺序依次执行,只有所有的initContainers执行完后,主容器才会被启动。我们知道一个Pod里面的所有容器是共享数据卷和网络命名空间的,所以initContainers里面产生的数据可以被主容器使用到的

自定义SkyWalking Agent镜像

  • 下载SkyWalking官方发行包,并解压到指定目录
#下载skywalking-8.6.0 for es7版本的发布包,与部署的skywalking后端版本一致
$ wget https://archive.apache.org/dist/skywalking/8.6.0/apache-skywalking-apm-8.6.0.tar.gz

#将下载的发布包解压到当前目录
$ tar -zxvf apache-skywalking-apm-es7-8.6.0.tar.gz
  • 修改配置,编辑config/agent.config文件,以下只列出部分配置项
# The agent namespace
# agent.namespace=${SW_AGENT_NAMESPACE:default-namespace}
# 表示提供相同功能/逻辑的逻辑组的服务名称
agent.service_name=${SW_AGENT_NAME:Your_ApplicationName}

# OAP服务地址,修改默认地址为skywalking-oap服务名
collector.backend_service=${SW_AGENT_COLLECTOR_BACKEND_SERVICES:skywalking-oap:11800}
# 日志文件名
logging.file_name=${SW_LOGGING_FILE_NAME:skywalking-api.log}
# 日志级别:TRACE、DEBUG、INFO、WARN、ERROR、OFF。
logging.level=${SW_LOGGING_LEVEL:INFO}
# 最大历史日志文件。发生翻转时,如果日志文件超过此数量,则最旧的文件将被删除。默认情况下,负数或零表示关闭。
logging.max_history_files=${SW_LOGGING_MAX_HISTORY_FILES:10}
# 挂载插件的特定文件夹。安装文件夹中的插件可以工作。
plugin.mount=${SW_MOUNT_FOLDERS:plugins,activations,bootstrap-plugins}
# 排除插件目录中定义的一些插件
# plugin.exclude_plugins=${SW_EXCLUDE_PLUGINS:}
  • 构建skywalking-agent sidecar 镜像并push至hub私有镜像仓库

在前面步骤中解压的skywalking发行包,进入agent目录编写Dockerfile文件

FROM busybox:latest
RUN set -eux && mkdir -p /usr/skywalking/agent/
COPY . /usr/skywalking/agent/
WORKDIR /
  • 完成Docker文件编写后,执行镜像构建命令:
# 构建镜像,注意最后一个.
docker build -t <your-registry>/skywalking-agent-sidecar:8.6.0 .
# 镜像推送至私有Harbor仓库
docker push <your-registry>/skywalking-agent-sidecar:8.6.0

sidecar挂载

在KubeGems中找到 【工作负载】,编辑更新工作负载进入到容器镜像页面

设置SW环境变量,编辑工作容器

  • SW_AGENT_NAME=\<YourApplicationName>
  • JAVA_TOOL_OPTIONS=-javaagent:/usr/skywalking/agent/skywalking-agent.jar

添加容器镜像,选择初始化容器将skywalking-agent-sidecard镜像进行挂载,并添加启动命令

sh -c /usr/skywalking/agent/* /skywalking/agent

img

挂载emptyDir卷

img

点击确定保存工作负载信息,自动重启后进入应用容器,可以看到agent目标已经加载到容器中了

root@pod-7bc77468ff-7b4xt:/# cd /usr/skywalking/agent/
root@pod-7bc77468ff-7b4xt:/usr/skywalking/agent# ll

total 17716
drwxrwxrwx 9 root root 194 May 19 08:14 ./
drwxr-xr-x 3 root root 27 May 19 08:14 ../
-rw-r--r-- 1 root root 114 May 19 08:14 Dockerfile
drwxr-xr-x 2 root root 4096 May 19 08:14 activations/
drwxr-xr-x 2 root root 85 May 19 08:14 bootstrap-plugins/
drwxr-xr-x 2 root root 64 May 19 08:14 config/
drwxr-xr-x 2 root root 32 May 19 08:14 logs/
drwxr-xr-x 2 root root 4096 May 19 08:14 optional-plugins/
drwxr-xr-x 2 root root 45 May 19 08:14 optional-reporter-plugins/
drwxr-xr-x 2 root root 4096 May 19 08:14 plugins/
-rw-r--r-- 1 root root 18121582 May 19 08:14 skywalking-agent.jar

此时打开skywalking-ui,已经可以看到监控数据了

img

SkyWalking动态配置

SkyWalking配置主要是通过application.yml操作系统环境变量设置的,其中一些还支持来自上游管理系统的动态设置。上游服务支持包括Zookeeper、Etcd、Consul、Apollo、Nacos、K8s-configmap等。

目前SkyWalking支持以下动态配置

配置说明
agent-analyzer.default.slowDBAccessThresholdreceiver-trace/default/slowDBAccessThreshold慢数据库语句的阈值,覆盖application.yml.
agent-analyzer.default.uninstrumentedGateways未检测的网关覆盖gateways.yml.
alarm.default.alarm-settings警报设置将覆盖alarm-settings.yml
core.default.apdexThresholdapdex 阈值设置,将覆盖service-apdex-threshold.yml.
core.default.endpoint-name-grouping端点名称分组设置,将覆盖endpoint-name-grouping.yml.
agent-analyzer.default.sampleRate跟踪采样,覆盖receiver-trace/default/sampleRate.application.yml
agent-analyzer.default.slowTraceSegmentThreshold设置这个关于延迟的阈值将使慢跟踪段在花费更多时间时被采样,即使采样机制被激活。默认值为-1,这意味着不会对慢速跟踪进行采样。单位,毫秒。的覆盖receiver-trace/default/slowTraceSegmentThresholdapplication.yml
configuration-discovery.default.agentConfigurationsConfigurationDiscovery 设置

k8s-configmap

很多应用在其初始化或运行期间要依赖一些配置信息。大多数时候, 存在要调整配置参数所设置的数值的需求。 ConfigMap 是 Kubernetes 用来向应用 Pod 中注入配置数据的方法。

本文介绍如何通过KubGems平台动态配置SkyWalking参数

  • KubGems工作台 --> 配置中心 --> 配置 --> 创建配置
  • 添加参数及告警规则配置

img

  • 编辑yaml,添加修改app、compoent标签值
kind: ConfigMap
apiVersion: v1
metadata:
name: skywalking-dynamic-config
namespace: default
creationTimestamp: '2022-05-16T11:14:23Z'
labels:
component: oap
data:
agent-analyzer.default.sampleRate: '7000'
agent-analyzer.default.slowDBAccessThreshold: default:250,mongodb:100
alarm.default.alarm-settings: >-
rules:
# Rule unique name, must be ended with `_rule`.
service_resp_time_rule:
metrics-name: service_resp_time
op: ">"
threshold: 2000
period: 10
count: 3
silence-period: 5
message: 最近3分钟内服务 {name} 的平均响应时间超过2秒
  • 修改skywalking-oap环境变量信息,使用k8s-configmap配置
apiVersion: apps/v1
kind: Deployment
metadata:
name: skywalking-oap
labels:
app: skywalking
app.kubernetes.io/instance: skywalking
.........

env:

.....

- name: SW_CLUSTER_K8S_LABEL

value: app=skywalking,component=oap

- name: SW_CONFIGURATION

value: k8s-configmap

SW_CONFIGURATION= k8s-configmap,动态配置采用k8s-configmap SW_CLUSTER_K8S_LABEL= app=collector,release=skywalking,根据这个值自动选择合适的configmap

  • 重启skywalking-oap,配置生效

SkyWalking配置优化

OAP优化

skywalking写入ES的操作是使用了ES的批量写入接口,我们要做的是调整相关参数尽量降低ES索引的写入频率。 参数调整主要是针对skywalking的配置文件`application.yml,相关参数如下:

storage:
elasticsearch:
bulkActions: ${SW_STORAGE_ES_BULK_ACTIONS:4000} # Execute the bulk every 2000 requests
bulkSize: ${SW_STORAGE_ES_BULK_SIZE:40} # flush the bulk every 20mb
flushInterval: ${SW_STORAGE_ES_FLUSH_INTERVAL:30} # flush the bulk every 10 seconds whatever the number of requests
concurrentRequests: ${SW_STORAGE_ES_CONCURRENT_REQUESTS:4} # the number of concurrent requests
metadataQueryMaxSize: ${SW_STORAGE_ES_QUERY_MAX_SIZE:8000}

调整 bulkActions 默认2000次请求批量写入一次改到4000次;

  • bulkSize批量刷新从20M一次到40M一次;

  • flushInterval每10秒刷新一次堆改为每30秒刷新;

  • concurrentRequests查询的最大数量由5000改为8000。

过滤不需要监控的接口

  • 制作agent镜像时,将apm-trace-ignore-plugin-8.6.0.jar复制到\plugins下面

  • config目录下新建一个配置文件 apm-trace-ignore-plugin.config,文件内容为:

trace.ignore_path=${SW_AGENT_TRACE_IGNORE_PATH:/actuator,/actuator/**,/admin/**,/nacos/**}

设置采样率

在默认情况下,SkyWalking会采集所有追踪的数据。但是如果系统比较复杂,采集的端点比较多的时候,可能存储压力比较大,这个时候我们可以修改配置,只存储部分的调用链路信息。比如:50%。 设置采样率的时候并不会影响相关指标的计算。包括服务,服务实例,端点,拓扑图等相关指标的计算还是使用完整的数据计算的。

在k8s-configmap中,添加配置项,设置采样率为70%:

agent-analyzer.default.sampleRate: '7000'

总结

本文用于指导用于在 KubeGems 中快速部署并运行 SkyWalking服务,用户可在研发环境中快速启用此功能来验证 APM 相关功能。更多关于KubeGems 与 SkyWalking 的配置优化,我们会持续更新,敬请关注。

· One min read
LinkMaq

KubeGems Logging 服务主要面向平台内部以及平台内租户提供日志采集、解析、传输和存储等相关的能力。依靠 Logging Operator 对日志的配置和路由管理,实现平台的终端用户可以对应用运行期间的日志进行实时查询和分析。KubeGems 日志持久化采用 Grafana Loki 实现。

核心需求

多租户

KubeGems 是一个多租户平台,基于此场景。平台内部对于租户应用产生的日志应该具备独立的解析配置以及路由规则

系统鲁棒性

  • 高性能

    • 日志采集和转发性能至少需处理 10K line/sec
    • 支持采取日志限流策略
    • 日志延迟不得低于 5min
  • 可扩展

    • 架构支持灵活的水平扩展以提升整体日志吞吐量
    • 组件因满足无状态属性

可运维性

  • 可配置

    • 日志规则和路由的配置应 CRD 化,由 Operator 统一管理,并尽量做到配置简化。
    • 需支持常见的 json 解析字段增删改 等插件配置。
    • 应用日志应满足发送多种常见的数据管道或收集系统,诸如 kafka、elasticSearch、MongoDB 等。
  • 可视化

    • 日志规则应在 UI 中由用户组合装配置日志的解析与输出规则。
  • 监控与告警

    • 日志采集的状态统计,包含组件运行状态以及日志采集统计。
    • 需支持用户根据自定义日志片段进行设置告警规则。

需求边界

  • 对于应用日志没有输出到控制台(stdout)的场景,暂不纳入采集需求

可采取其他方式重定向内部日志到控制台,诸如s6-log

日志设计

Logging Operator

Logging Operator 是 BanzaiCloud 下开源的一个云原生场景下的日志采集方案。它在 2020 年 3 月的时候经过重构后的 v3 版本,底层凭借高效的 fluentbit 和插件丰富的 flunetd,Logging Operator几乎已经完美的适配了 kubernetes 模式下的日志采集场景。

在 KubeGems 1.20 的版本中,我们选择采用 Logging Operator 作为内部日志流传的核心框架。其主要原因如下:

  • 原生 Flow 和 Output 类资源作用域为 kubernetes 命名空间,这与 KubeGems 租户环境的资源独立性相谋和

  • 采用高性能的 fluentbit 作为日志采集客户端,fluentd 为日志聚合端。flunetd 在 logging 中通过 replicas 控制副本数,可根据吞吐量水平扩容

  • flunetd 支持的插件较为丰富,满足当前基本需求

Logging Operator 不足:

  • 核心资源 Flow 和 Output 交于用户配置较为困难,需要 KubeGems 将资源封装(也许兼容源对象)
  • 可观测性功能较弱
  • 日志 Match 部分功能较弱,无法通过直接匹配 workload 进行关联

KubeGems 日志整体架构

由 Logging Operator 负责日志组件的运行管理和配置管理,租户侧资源以 CR 的方式在所属的环境空间中管理。Operator 将 CR 渲染为 Fluentd 的配置文件,用于处理日志的过滤和转发规则。可观测部分,由 KubeGems Plugins 服务初始化 ServiceMonitor,抓取组件运行期间的状态。

KubeGems Logging

KubeGems 对 Logging Operator 的封装仅满足简单的两种模式的场景:

  • 精简模式

    开箱即用的日志采集模式,对于用户环境空间内的所有容器开启采集,并输出到 KubeGems 平台内置的 Loki 组件用于日志分析和告警等场景

  • 局部自定义模式

    面向希望通过配置局部容器采集,并需要对接外部日志分析系统的场景。则采用此方式,不过此时

除此之外,对于希望能够完全掌握平台内的日志路由的高端用户,KubeGems 只需兼容对 Logging Operator 的原始 CR 资源即可。

精简模式

对于通用场景下的容器控制台日志采集,KubeGems 采用精简模式配置规则,仅需在用户界面中支持 一键配置开启日志采集 功能。一键启用功能的实现主要分为两部分。

  1. KubeGems Installer 服务在对 kubernetes 集群启用 logging 插件时,将对 logging operator 以及关联的 clusteroutputs/containers-console资源进行初始化。

    默认的clusteroutput 资源定义了容器日志的输出路径是 Loki

  2. 用户创建默认的容器采集规则时,LabelSelector 为空,即匹配当前命名空间下的所有 Pod。

  3. Flow 中只启用 Prometheus 插件用于统计采集状态。

  4. Flow 中关联系统默认的 clusteroutputs/containers-console

即在精简模式下,KubeGems 只在租户空间的接口中传入如下参数:

POST  observe/log/<tenant_name>/flowlite?enabled=true&namespace=tenant
参数释意requiredType
enabled启用环境空间的日志采集功能TrueBoolean
namespace采集日志的目标命名空间TrueString

KubeGems 将 Flows 渲染为如下内容:

apiVersion: logging.banzaicloud.io/v1beta1
kind: Flow
metadata:
name: default
namespace: tenant
spec:
match:
- select: {}
filters:
- prometheus:
labels:
container: $.kubernetes.container_name
namespace: $.kubernetes.namespace_name
node: $.kubernetes.host
pod: $.kubernetes.pod_name
metrics:
- desc: Total number of log entries generated by either application containers
or system components
name: logging_entry_count
type: counter
globalOutputRefs:
- containers-console

局部自定义模式

用户如果需要按照应用日志需求,局部对环境空内应用进行日志的规则和路由时,KubeGems 需要对 Logging Operator 的 CR 资源进行优化,以方面在用户界面中实现跟友好的交互。其中首先需要处理平台 应用元数据 相关的事务。默认情况下 Flow 的规则采用 labelSelector 对命名空间内资源做匹配,如下:

apiVersion: logging.banzaicloud.io/v1beta1
kind: Flow
metadata:
name: default
namespace: tenant
spec:
localOutputRefs:
- defalt
match:
- select:
labels:
app: nginx

虽然通过 labelSelector可以灵活控制日志采集规则,但经过实际验证,这个逻辑仍然存在 反直觉的场景,用户大多需要的是在 Selector 阶段与应用资源直接关联 ,当然我们不能直接把label 与 workload 做等同映射。我们需要通过外部方式来对 Label 做通用性匹配。

KubeGems CommonLabels

KubeGems 通用标签 是根据用户上层操作而对 Kubernetes Workload 做自动注入的一组元数据。它是一组常量,被定义到common.go当中。 当用户在 Kubernetes 中做资源对象的操作时,它会以 mutatingwebhook的方式自动注入的被管理的资源对象当中。

CommonLabel 中的 kubegems.io/applications 或者 Kubernetes 中的 app.kubernetes.io/nameapp共同声明了该应用的 workerload 标签。基于此,用户在创建日志规则是,可以通过 LabelSelector 定位到环境下的唯一资源。对于用户提交的 Flow ,同一种日志解析、路由规则类型的资源可以集中管理配置,如下:

apiVersion: logging.banzaicloud.io/v1beta1
kind: Flow
metadata:
name: default
namespace: tenant
spec:
localOutputRefs:
- default
match:
- select:
labels:
kubegems.io/applications: nginx
- select:
labels:
kubegems.io/applications: mysql
- select:
labels:
app.kubernetes.io/name: tomcat

局部模式下的用户流程

局部自定义模式下,开放普通用户配置有限功能的 Flow 以及 Outputs 资源。KubeGems 仍然需要对 CR 做简单接口封装。它的调用流程如下:

  1. 创建日志规则时,请求KubeGems listWorkload 返回当前环境空间下具备采集条件( CommonLabel)的资源列表,由用户在前端选择加入。
  2. 用户界面内提供插件列表,有用户自定义插件是否启用
  3. 通过请求 KubeGems listOutput 返回当前环境下可用的日志路由。普通用户同时也具备列出 ClusterOutput 资源(它由KubeGems 平台管理员创建)。
  4. 日志规则关联 localOutputRefs或者 globalOutputRefs后提交给 KubeGems 后台渲染 Flow 文件。
  5. Flow/Output 资源由 Logging Operator 处理,并返回资源validate结果和状态。

即在 局部自定义模式 下,KubeGems 在租户空间的接口中传入如下参数:

POST  observe/log/<tenant_name>/flow?name=tenant&namespace=tenant&monitor=true&throttle=4000&geoip_keys=remote_addr&outputs=my-elasticsearch,my-kafka&clusteroutputs=loki
参数释意requiredType
name日志采集规则名称TrueString
namespace采集日志的目标命名空间TrueString
monitor启用日志采集状态监控,default: trueFalseBoolean
throttle启用容器级日志条目限速,Lines / 10sFalseInt16
geoip_keys启用 GEO IPFalseString
outputs普通日志输出通道,多个通道用 ,逗号分割At laeast oneString
clusteroutputs日志输出通道,多个通道用 ,逗号分割At laeast oneString

outputs 和 clusteroutputs 参数至少满足一个

KubeGems 将 Flow 渲染如下:

apiVersion: logging.banzaicloud.io/v1beta1
kind: Flow
metadata:
name: tenant
namespace: tenant
spec:
filters:
- geoip:
geoip_lookup_keys: remote_addr
records:
- city: ${city.names.en["remote_addr"]}
location_array: '''[${location.longitude["remote"]},${location.latitude["remote"]}]'''
country: ${country.iso_code["remote_addr"]}
country_name: ${country.names.en["remote_addr"]}
postal_code: ${postal.code["remote_addr"]}
- record_modifier:
records:
- throttle_group_key: ${record['kubernetes']['namespace_name']+record['kubernetes']['pod_name']}
- prometheus:
labels:
container: $.kubernetes.container_name
namespace: $.kubernetes.namespace_name
node: $.kubernetes.host
pod: $.kubernetes.pod_name
metrics:
- desc: Total number of log entries generated by either application containers
or system components
name: logging_entry_count
type: counter
- throttle:
group_bucket_limit: 4000
group_bucket_period_s: 10
group_key: throttle_group_key
localOutputRefs:
- my-elasticsearch
- my-kafka
globalOutputRefs:
- loki

原始模式

对于租户需要使用 Logging Operator 完整特性来做自定义日志解析场景,KubeGems 只需在页面中满足对 Flow 原始格式 的校验和提交即可。

POST  observe/log/<tenant_name>/flow?raw=true

Body:

apiVersion: logging.banzaicloud.io/v1beta1
kind: Flow
metadata:
name: kafka
spec:
filters:
- tag_normaliser: {}
- parser:
remove_key_name_field: true
reserve_data: true
parse:
type: multi_format
patterns:
- format: nginx
- format: regexp
expression: /foo/
- format: none
match:
- select:
labels:
app.kubernetes.io/name: log-generator
localOutputRefs:
- kafka-output

KubeGems Log Observability

KubeGems 的日志可观测性主要满足以下几点需求

  • 用户环境空间内的日志采集速率分析
  • 用户环境空间内的错误日志统计
  • 用户自定义的日志告警规则

默认情况下 KubeGems Logging 插件集成了 Loki 实例用于持久化平台内容器日志。借有 Loki Ruler,可实现日志告警和错误日志分析相关功能。

日志可观测性流程

  1. KubeGems Installer 在 Kubernetes 集群初始化阶段负责将 Logging 插件下的 Loki 和 Recording Rules 配置。
  2. 普通用户在用户界面中创建日志告警规则,由 KubeGems 将告警规则以 Loki API 方式提交。
  3. 当产生Loki 产生日志告警时,经由 AlertManager 将告警事件推送给用户,并在 KubeGems Webhook 记录。

在上述流程中,KubeGems 日志告警中仅需提供 logrules 接口,用于管理用户告警内容。

Log Alerting Template

Loki 的 Rules 的语法规则和 Prometheus 一样,区别只在expr中体现。当前 KubeGems 中的 Metrics 告警采用的是预制模板 的方式,以支持用户更快的创建规则。在日志告警规则也可参考此方式,预制常见的 LogQL 模板。

普通模板

普通模板即用户只需要设置日志关键字符以管道的方式过滤字符。KubeGems 在后端组装语句 expr 并请求 Loki API 完成规则提交 。查询语句如下:

sum by (pod,namespace,application) (count_over_time({pod="<pod>",namespace="<namespace>",applications="<applications>"}  |~ `<your_log_string>`  |~ `<your_log_string>`[1m]))

格式化模板(json/logfmt)

采用 LogQL 的格式化解析器提取日志,通过查找 key-values 的方式过滤结果。

  • json 解释器
sum by  (pod,namespace,application) (count_over_time({pod="<pod>",namespace="<namespace>",applications="<applications>"}  | json |  <your_key>=<your_string>  |   __error__=""[1m]))
  • logfmt
 sum by  (pod,namespace,application) (count_over_time({pod="<pod>",namespace="<namespace>",applications="<applications>"}  | logfmt |  <your_key>=<your_string>  |   __error__=""[1m]))

高级模式

采用 LogQL 原生语句直接提交 Rules。

上述 3 种 LogQL 预制模板,最终提交的格式化 alertrules 结构如下:

  - name: should_fire
rules:
- alert: <your_log_string>-alert
expr: sum by (pod,namespace,application) (count_over_time({pod="<pod>",namespace="<namespace>",applications="<applications>"} |~ `<$your_log_string>` |~ `<$your_log_string>`[1m])) >= <$your_thresholds>
for: 1m
labels:
severity: <$your_severity>
pod: {{$labels.pod}}
namespace: {{$labels.namespace}}
application: {{labels.applicastions}}
annotations:
summary: message <your_log_string> alerting ,now has {{$labels.value}}.

Log Recording Rules

Recording Rules 允许用户预先将需要进行大量计算的表达式的结果转化保存为一组新的时间序列,并将其通过 remote_write的方式写入 Prometheus。在 KubeGems 中,平台将接入 Logging Observability 的应用预制了通用性的 Error Log Rules。

与 Alerting Rules 一样,Recoring Rules 如要 Loki Ruler 的支持,这部分将在 KubeGems Installer 初始化中部署到您的集群。

关于 Loki Ruler 对 RemoteWrite 的配置,可查考loki/remote-write

Log Metrics

Log Metrics 在 KubeGems 中,由用户提交的日志采集器中声明,这部分采用 fluent-plugin-prometheus,核心部分即为每个进入管道的日志流创建一个 计数器(Counter)并记录其条目和元数据。

  - prrometheus:
labels:
container: $.kubernetes.container_name
namespace: $.kubernetes.namespace_name
node: $.kubernetes.host
pod: $.kubernetes.pod_name
metrics:
- desc: Total number of log entries generated by either application containers
or system components
name: logging_entry_count
type: counter

最终由 Prometheus 将指标logging_entry_count持久化到本地。

总结

KubeGems 中基于租户的日志采集方案整体设计采用 Logging Operator + Loki 架构,用户可根据企业自身组织结构对其进行管理和适配。对于在 Kubernetes 集群中操作原生的 CRD 资源复杂的场景下,KubeGems 尽量让用户在接入日志采集、监控和告警的三个方面做到开箱即用的功能,极大简化系统管理者或研发人员的是学习和接入成本。