做者 | 元乙 阿里云存储服务技术专家html
导读:上一篇文章主要介绍 Kubernetes 日志输出的一些注意事项,日志输出最终的目的仍是作统一的采集和分析。在 Kubernetes 中,日志采集和普通虚拟机的方式有很大不一样,相对实现难度和部署代价也略大,但若使用恰当则比传统方式自动化程度更高、运维代价更低。本文为日志系列文章的第 4 篇。node
第一篇:《6 个 K8s 日志系统建设中的典型问题,你遇到过几个?》web
第二篇:《一文看懂 K8s 日志系统设计和实践》docker
第三篇:《9 个技巧,解决 K8s 中的日志输出问题》缓存
在 Kubernetes 中,日志采集相比传统虚拟机、物理机方式要复杂不少,最根本的缘由是 Kubernetes 把底层异常屏蔽,提供更加细粒度的资源调度,向上提供稳定、动态的环境。所以日志采集面对的是更加丰富、动态的环境,须要考虑的点也更加的多。less
例如:运维
Kubernetes | 传统方式 | |
---|---|---|
日志种类 | 文件、stdout、宿主机文件、journal | 文件、journal |
日志源 | 业务容器、系统组件、宿主机 | 业务、宿主机 |
采集方式 | Agent(Sidecar、DaemonSet)、直写(DockerEngine、业务) | Agent、直写 |
单机应用数 | 10-100 | 1-10 |
应用动态性 | 高 | 低 |
节点动态性 | 高 | 低 |
采集部署方式 | 手动、Yaml | 手动、自定义 |
日志的采集方式分为被动采集和主动推送两种,在 K8s 中,被动采集通常分为 Sidecar 和 DaemonSet 两种方式,主动推送有 DockerEngine 推送和业务直写两种方式。异步
总结下来:分布式
详细的各类采集方式对好比下:ide
DockerEngine | 业务直写 | DaemonSet方式 | Sidecar方式 | |
---|---|---|---|---|
采集日志类型 | 标准输出 | 业务日志 | 标准输出+部分文件 | 文件 |
部署运维 | 低,原生支持 | 低,只需维护好配置文件便可 | 通常,需维护DaemonSet | 较高,每一个须要采集日志的POD都须要部署sidecar容器 |
日志分类存储 | 没法实现 | 业务独立配置 | 通常,可经过容器/路径等映射 | 每一个POD可单独配置,灵活性高 |
多租户隔离 | 弱 | 弱,日志直写会和业务逻辑竞争资源 | 通常,只能经过配置间隔离 | 强,经过容器进行隔离,可单独分配资源 |
支持集群规模 | 本地存储无限制,若使用syslog、fluentd会有单点限制 | 无限制 | 取决于配置数 | 无限制 |
资源占用 | 低,docker | |||
engine提供 | 总体最低,省去采集开销 | 较低,每一个节点运行一个容器 | 较高,每一个POD运行一个容器 | |
查询便捷性 | 低,只能grep原始日志 | 高,可根据业务特色进行定制 | 较高,可进行自定义的查询、统计 | 高,可根据业务特色进行定制 |
可定制性 | 低 | 高,可自由扩展 | 低 | 高,每一个POD单独配置 |
耦合度 | 高,与DockerEngine强绑定,修改须要重启DockerEngine | 高,采集模块修改/升级须要从新发布业务 | 低,Agent可独立升级 | 通常,默认采集Agent升级对应Sidecar业务也会重启(有一些扩展包能够支持Sidecar热升级) |
适用场景 | 测试、POC等非生产场景 | 对性能要求极高的场景 | 日志分类明确、功能较单一的集群 | 大型、混合型、PAAS型集群 |
和虚拟机/物理机不一样,K8s 的容器提供标准输出和文件两种方式。在容器中,标准输出将日志直接输出到 stdout 或 stderr,而 DockerEngine 接管 stdout 和 stderr 文件描述符,将日志接收后按照 DockerEngine 配置的 LogDriver 规则进行处理;日志打印到文件的方式和虚拟机/物理机基本相似,只是日志可使用不一样的存储方式,例如默认存储、EmptyDir、HostVolume、NFS 等。
虽然使用 Stdout 打印日志是 Docker 官方推荐的方式,但你们须要注意:这个推荐是基于容器只做为简单应用的场景,实际的业务场景中咱们仍是建议你们尽量使用文件的方式,主要的缘由有如下几点:
Stdout 性能问题,从应用输出 stdout 到服务端,中间会通过好几个流程(例如广泛使用的 JSON LogDriver):应用 stdout -> DockerEngine -> LogDriver -> 序列化成 JSON -> 保存到文件 -> Agent 采集文件 -> 解析 JSON -> 上传服务端。整个流程相比文件的额外开销要多不少,在压测时,每秒 10 万行日志输出就会额外占用 DockerEngine 1 个 CPU 核;
Stdout 不支持分类,即全部的输出都混在一个流中,没法像文件同样分类输出,一般一个应用中有 AccessLog、ErrorLog、InterfaceLog(调用外部接口的日志)、TraceLog 等,而这些日志的格式、用途不一,若是混在同一个流中将很难采集和分析;
Stdout 只支持容器的主程序输出,若是是 daemon/fork 方式运行的程序将没法使用 stdout;
文件的 Dump 方式支持各类策略,例如同步/异步写入、缓存大小、文件轮转策略、压缩策略、清除策略等,相对更加灵活。
所以咱们建议线上应用使用文件的方式输出日志,Stdout 只在功能单一的应用或一些 K8s 系统/运维组件中使用。
Kubernetes 提供了标准化的业务部署方式,能够经过 yaml(K8s API)来声明路由规则、暴露服务、挂载存储、运行业务、定义缩扩容规则等,因此 Kubernetes 很容易和 CICD 系统集成。而日志采集也是运维监控过程当中的重要部分,业务上线后的全部日志都要进行实时的收集。
原始的方式是在发布以后手动去部署日志采集的逻辑,这种方式须要手工干预,违背 CICD 自动化的宗旨;为了实现自动化,有人开始基于日志采集的 API/SDK 包装一个自动部署的服务,在发布后经过 CICD 的 webhook 触发调用,但这种方式的开发代价很高。
在 Kubernetes 中,日志最标准的集成方式是以一个新资源注册到 Kubernetes 系统中,以 Operator(CRD)的方式来进行管理和维护。在这种方式下,CICD 系统不须要额外的开发,只需在部署到 Kubernetes 系统时附加上日志相关的配置便可实现。
早在 Kubernetes 出现以前,咱们就开始为容器环境开发日志采集方案,随着 K8s 的逐渐稳定,咱们开始将不少业务迁移到 K8s 平台上,所以也基于以前的基础专门开发了一套 K8s 上的日志采集方案。主要具有的功能有:
目前这套采集方案已经对外开放,咱们提供了一个 Helm 安装包,其中包括 Logtail 的 DaemonSet、AliyunlogConfig 的 CRD 声明以及 CRD Controller,安装以后就能直接使用 DaemonSet 采集以及 CRD 配置了。安装方式以下:
安装好上述组件以后,Logtail 和对应的 Controller 就会运行在集群中,但默认这些组件并不会采集任何日志,须要配置日志采集规则来采集指定 Pod 的各种日志。
除了在日志服务控制台上手动配置以外,对于 Kubernetes 还额外支持两种配置方式:环境变量和 CRD。
这种方式部署简单,学习成本低,很容易上手;但可以支持的配置规则不多,不少高级配置(例如解析方式、过滤方式、黑白名单等)都不支持,并且这种声明的方式不支持修改/删除,每次修改其实都是建立 1 个新的采集配置,历史的采集配置须要手动清理,不然会形成资源浪费。
例以下面的示例就是部署一个容器标准输出的采集,其中定义须要 Stdout 和 Stderr 都采集,而且排除环境变量中包含 COLLEXT_STDOUT_FLAG:false 的容器。
基于 CRD 的配置方式以 Kubernetes 标准扩展资源的方式进行管理,支持配置的增删改查完整语义,并且支持各类高级配置,是咱们极其推荐的采集配置方式。
实际应用场景中,通常都是使用 DaemonSet 或 DaemonSet 与 Sidecar 混用方式,DaemonSet 的优点是资源利用率高,但有一个问题是 DaemonSet 的全部 Logtail 都共享全局配置,而单一的 Logtail 有配置支撑的上限,所以没法支撑应用数比较多的集群。
上述是咱们给出的推荐配置方式,核心的思想是:
绝大部分 Kubernetes 集群都属于中小型的,对于中小型没有明确的定义,通常应用数在 500 之内,节点规模 1000 之内,没有职能明确的 Kubernetes 平台运维。这种场景应用数不会特别多,DaemonSet 能够支撑全部的采集配置:
对于一些用做 PaaS 平台的大型/超大型集群,通常业务在 1000 以上,节点规模也在 1000 以上,有专门的 Kubernetes 平台运维人员。这种场景下应用数没有限制,DaemonSet 没法支持,所以必须使用 Sidecar 方式,总体规划以下:
云原生应用平台邀 Kubernetes/容器/ Serverless/应用交付技术领域专家(P7-P8)加盟。
技术要求:Go/Rust/Java/C++,Linux,分布式系统;
工做年限:P7 三年起,P8 五年起,具体看实际能力;
工做地点:国内(北京 / 杭州 / 深圳);海外(旧金山湾区 / 西雅图)。
简历投递:xining.zj AT alibaba-inc.com。
“阿里巴巴云原生关注微服务、Serverless、容器、Service Mesh 等技术领域、聚焦云原生流行技术趋势、云原生大规模的落地实践,作最懂云原生开发者的技术圈。”