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,
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 定义的所有元信息,我们可以通过以下方式进行更深入了解。
启动测试一个pod, 这里我们的测试pod ID 为956f352df0669。
进入容器对应节点,我们分别执行以下指令进行观察。
sudo crictl pods|grep 956f352df0669 查看指定ID POD,这一步其实查看的是就是Sandbox Container。
sudo crictl ps|grep 956f352df0669 查看指定POD 下的容器,这一步查看的是cotainer runtime 启动的进行,对于docker 和docker ps 等价。
docker ps |grep coredn 使用Docker 原生命令查看coredns 对应的所有容器,可以看到底层实际运行了2个Container。
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。