阿里云SLS 容器采集全面兼容Kubernetes

简介: iLogtail致力于打造覆盖Trace、Metrics 以及Logging 的可观测性的统一Agent,而对Kubernetes 语义的原生支持大大增强了Log在Kubernetes场景的采集体验。

1. 背景

阿里云SLS 2018年初发布容器化采集方案后,恰逢Kubernetes 赢得了容器编排大战的胜利,由Google Kubernetes指数可以看出,Kubernetes 的关注度上升度明显,且在中国地区关注度上升明显。而从外部报道也可以看出,越来越多的头部厂商或中小厂商开始拥抱以Kubernetes为基础的云原生环境,因此SLS 对容器化日志采集方案进行再一次升级, 全面支持Kubernetes 语义采集。

2. 新功能介绍

2.1 Kubernetes 原生采集识别

Logtail原生支持Kubernetes下namespace,pod,container 或 labels 多种方式资源定义,全面兼容Kubernetes语义。新增采集参数如下:

参数

描述

K8sNamespaceRegex

支持正则匹配Kubernetes 被采集容器Namespace

K8sPodRegex

支持正则匹配Kubernetes 被采集容器Pod名

K8sContainerRegex

支持正则匹配Kubernetes 被采集容器的名字

IncludeK8sLabel

支持正则匹配Kubernetes Label 进行被采集资源筛选

ExcludeK8sLabel

支持正则匹配Kubernetes Label 进行被采集资源排除

2.2 容器标签采集

Logtail 支持携带容器中的ENV 值 或 Kubernetes Labels 进行上传到日志,进行更自由维度数据分析。新增参数如下:

参数

描述

ExternalEnvTag

支持将容器ENV制定KEY携带采集

ExternalK8sLabelTag

支持将POD Labels指定KEY携带采集

2.3 使用案例

接入用户将不同部署分离到不同Logstore 存储, 并希望携带部署版本和服务名称到日志字段,进行二次分析。

测试服务

测试服务产生标准输出流日志, 并通过ENV 暴露环境版本信息。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-log-demo
  namespace: default
  labels:
    app: nginx
spec:
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      name: nginx-log-demo
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx-log-demo
        image: registry.cn-hangzhou.aliyuncs.com/log-service/docker-log-test:latest
        command: ["/bin/mock_log"]
        args:  ["--log-type=nginx", "--stdout=true", "--stderr=true", "--total-count=1000000000", "--log-file-size=1000000000", "--log-file-count=2", "--logs-per-sec=10"]
        env:
        - name: VERSION
          value: 0.0.1
        resources:
          limits:
            memory: 200Mi
          requests:
            cpu: 100m
            memory: 200Mi

历史接入

历史版本Labels 接入为针对容器内部Label,如Docker Label,所以历史版本针对以上需求时,只能采用ENV 模式接入,且暴露参数固定为aliyun_logs_{key}_tags,详细使用请参考: 链接。因此接入用户需要对部署进行少量修改,且仅支持单tag附带上传:

env:
  - name: VERSION
    value: 0.0.1
  - name: "aliyun_logs_nginx-demo"
    value: "stdout"
  - name: "aliyun_logs_nginx-demo_tags"
    value: app=nginx
{
    "inputs": [
        {
            "detail": {
                "IncludeEnv": {
                    "aliyun_logs_nginx-demo": "stdout"
                },
                "Stderr": true,
                "Stdout": true
            },
            "type": "service_docker_stdout"
        }
    ],
    "global": {
        "AlwaysOnline": true
    }
}

新版接入

新版接入下, 全面兼容Kubernetes 语义,用户无需修改部署文件,仅需要配置采集配置,就可以数据自动上传,且ENV与Label 多组上传功能也更好支持业务进行灵活的报表统计, 新版接入配置如下,仅需要声明Kubernetes Label与Namespace,自动选定资源上传,ExternalK8sLabelTag与ExternalEnvTag功能自动上传Kubernetes 元信息。

{
    "inputs":[
        {
            "detail":{
                "Stderr":true,
                "IncludeK8sLabel":{
                    "app":"nginx"
                },
                "K8sNamespaceRegex":"default",
                "ExternalEnvTag":{
                    "VERSION":"env_version"
                },
                "ExternalK8sLabelTag":{
                    "app":"label_app"
                },
                "Stdout":true
            },
            "type":"service_docker_stdout"
        }
    ],
    "global":{
        "AlwaysOnline":true
    }
}

在demo 配置中,定义 "VERSION":"env_version" 配置,含义为自动读取环境变量中的VERSION 值,并附加到env_version 字段进行上传,由于demo Deployment.yaml 预定义的VERSION字段,所以自动上传env_version:0.0.1 字段。

 "ExternalEnvTag":{"VERSION":"env_version"}

且上述配置中含有ExternalK8sLabelTag配置,含义为自动读取Pod Labels中的app值,并附加到label_app字段进行上传,由于demo Deployment.yaml 中预定义Deployment labels 为app:nginx,所以自动上传labela_app:nginx。

"ExternalK8sLabelTag":{"app":"label_app"}

2.4 版本要求

Logtail 全面兼容Kubernetes 采集语义的最低版本为:1.0.34,

  1. ACK 用户可以进行组件升级安装,操作步骤参考:链接

  2. 自建Kubernetes用户升级步骤请参考:链接

3. 实现原理

3.1 CRI 简介

和容器网络接口(CNI)和容器存储接口(CSI)一样,容器运行时接口(CRI)定义了容器和镜像的服务的接口规范,旨在解耦Kubelet 与Container Runtime, 使得Kubernetes 自由支持多种容器底层,目前已经支持Docker、Containerd、Cri-o、Rkt等多种Container Runtime。CRI 同时也提供工具去操作CRI API,名称crictl,感兴趣的同学可以参考以下链接学习使用方法: CRI-tools

3.2 Pod 与CRI 之间的关系

重所周知,Pod 是Kubernetes 调度的最小资源单位,而当我们深入Pod内部,看到的是其实是Namespace 隔离的一些进程组(针对Docker 或Containerd视角,以下介绍也基于此视角进行)。

当Pod 创建时,CRI优先创建一个Sandbox 的Container,Sandbox 创建了Linux Namespace空间,使得用户在外部视角看po像是一个独立节点单元。其次Sandbox会安装Pod 定义的容器镜像启动一系列进程,并且按照Pod 中定义的每个容器的消耗进行CGroup定义,进行运行时CPU,内存等资源的限制。

从以上描述可以看出CRI 创建的Sandbox 容器其实携带了Pod 定义的所有元信息,我们可以通过以下方式进行更深入了解。

  1. 启动测试一个pod, 这里我们的测试pod ID 为956f352df0669。

  2. 进入容器对应节点,我们分别执行以下指令进行观察。

    1. sudo crictl pods|grep 956f352df0669 查看指定ID POD,这一步其实查看的是就是Sandbox Container。

    2. sudo crictl ps|grep 956f352df0669 查看指定POD 下的容器,这一步查看的是cotainer runtime 启动的进行,对于docker 和docker ps 等价。

    3. docker ps |grep coredn 使用Docker 原生命令查看coredns 对应的所有容器,可以看到底层实际运行了2个Container。

    4. docker inspect 74f7b6f18ea4 使用Docker 原生命令查看Pause 信息, 可以看到外部Pod定义。

3.3 Logtail集成

正如上文简述,Kubernetes Pod 的元信息存在于CRI 定义下的Sandbox Container,因此Logtail 基于标准CRI API与Pod的底层定义进行交互,通过原生Kubernetes定义进行资源日志采集的筛选。

在Logtail 全面兼容Kubernetes语义采集后,我们可以看到Logtail 与其他采集方案相比有如下优势:

Logtail

Logstash

fluentd

filebeat

采集方式

宿主机文件

支持

支持

支持

支持

容器文件

支持自动发现,并全面兼容Kubernetes发现机制

静态采集

静态采集

静态采集

stdout

支持自动发现,并全面兼容Kubernetes发现机制

静态采集

静态采集

静态采集

数据处理

处理方式

正则,anchor,分隔符,json,自动支持Kubernetes 语义字段添加

插件扩展

插件扩展

插件扩展

过滤

正则

插件扩展

插件扩展

正则

路由

正则

插件扩展

插件扩展

不支持

配置

Kubernetes集成

支持Kubernetes CRD, 与应用一起自动化部署

自动更新

支持

支持

支持

支持

服务端配置

支持

支持简单功能

辅助管理软件扩展

不支持

性能

采集性能

极简单核120M/s、正则20M/s

单核2M/s 左右

单核3-5M/s左右

极简单核12M/s

资源消耗

平均CPU2%,内存40M

10倍以上性能消耗

10倍以上性能消耗

CPU10倍,内存持平

可靠性

数据保存

支持

插件支持

插件支持

支持

采集点保存

支持

支持

支持

支持

监控

本地监控

支持

支持

支持

支持

服务端监控

支持,监控数据详细且全开放

支持简单功能

需要集成Prometheus扩展

支持简单功能

4. 总结

iLogtail致力于打造覆盖Trace、Metrics 以及Logging 的可观测性的统一Agent,而对Kubernetes 语义的原生支持大大增强了Log在Kubernetes场景的采集体验, 欢迎大家参与iLogtail 社区,一起构建更好的可观测统一Agent。



相关文章或链接

  1. Google Kubernetes 指数

  2. Introducing Container Runtime Interface (CRI) in Kubernetes

  3. Container Runtimes Part 4: Kubernetes Container Runtimes & CRI

  4. The Almighty Pause Container

  5. CRI API阿里云SLS 容器采集全面兼容Kubernetes

作者介绍
目录