background

docker

docker的日志输出可以通过指定driver输出到不同的位置,常用的是journald和json-file。 使用journald日志输出可能受限于jourand的throttle作用, 因为journald是node agent, 负责该node上全部容器的日志收集, 当一个用户写入大量日志,就会进行rate limit, 这样导致其他用户也会丢失日志, 并且无法进行单个用户rate-limit 的设置; 而使用json-file log driver, docker是将log以json 格式保存到宿主机的目录之上, 默认是/var/lib/docker/containers/${docker-uid}, 可以通过log-opt参数配置log rotate文件大小和数量, 避免占用太多磁盘空间。 个人比较推荐使用json-file log driver, 不会丢日志, 耦合性较低,日志先格式化输出到磁盘上, 然后后面怎么处理都比较方便。 所有的log driver都需要经过docker daemon, 然后分发到不同的driver里, 这样就会有单点问题,分发和处理(序列化日志等)会有性能问题, 耗费机器资源, 严重情况下会导致整个docker daemon卡死。所以对于这种log较多的应用建议直接输出到文件中,而不是STDOUT, 避免影响docker daemon。

kubernetes

如果docker使用json-filelog driver, kubelet会为所有的容器日志创建一个软链接到/var/log/pods目录下, 包含各个pods所有的日志,文件名称由pod name, namespaces, container name, container Id等组成。kubernetes官方文档Logging Architecture介绍了三种日志收集方式, 并推荐使用daemonset部署log agent 方式收集, 这种方式部署简单, 节约资源, 但是灵活性不够, 无法针对每个pod做一些定制化的需求, 同时因为是一个node上的全局agent, 需要考虑所收集的多个pod的日志隔离, 避免相关影响。 在生产环境中, 我们可以统一由node agent来收集日志, 对于比较特殊的需求则使用sidecar的方式进行收集。

方案实现

日志收集的各种node agent的实现不尽相同, 有些agent是通过docker api获取容器日志的,例如开源的logspout,这种agent适用这种场景比较单一,如果我们还需要收集写到磁盘上的日志, logspout就无法胜任了。我们知道容器如果使用json-file这种log driver, 日志最终会保存在宿主机上的特定目录中的文件里, 所以我们可以归约以上所有的情况都为文件日志收集, 使用类似tail -f功能的程序来实现, 目前这样的开源工具很多, 例如fluentd, filebeat等, 除了基本的tailf功能外, log agent还需要考虑那些功能?

功能

  • label添加: 自动添加container name, containerID, node name的label,除了基本的contianer信息外,还应该支持用户自定义的label, 方便收集索引和数据处理。
  • 支持多种数据来源: 容器环境下的日志主要分为: 宿主机文件, 容器文件, 容器stdout,这些类型都可以归约为文件,因为容器的stdout也可以先落磁盘,然后由agent收集。
  • 自动发现容器创建、删除: 如果场景比较单一的话,比如只收集固定目录的文件,就可以统一使用文件tailf, 自动监视指定目录的变化即可。 如果需要一些高级的功能,例如目录多变,数据来源较多,就需要动态监听docker daemon事件, 并从container的label或者env中解析出动态传递的变量进行定制化。如果某些程序不支持监听docker daemon的事件的话,可以写一个对应的reloader,由reloader监听docker事件生成配置供agent使用。
  • 数据处理: 过滤,路由到不同的target,例如输出到kafaka, es等

上述功能对于不同的业务场景可能有不同的需求, 很多现在开源的工具都提供一种插件的方式来扩展功能,以fluend来说,提出Unified Logging Layer,通过各个插件进行日志路由和处理,目前基本插件都能找到开源的,可谓是一个日志收集生态。

性能

除了满足基本的功能之外, 就需要考虑性能问题了:

  • 多租户隔离: 容器环境下, 可能多个用户共享一台物理机, 如果一个容器写日志速率较快可能会影响其他用户正常操作, 因为一个node agent的收集速率总会有上限,并且在公有云环境下, 日志收集作为资源提供出去,是需要计费的, 此时就需要考虑限速, 容量调度, 优先级抢占等问题。该部分可以参见:Logtail技术分享(二) : 多租户隔离技术+双十一实战效果
  • 性能: 日志速率的速率越快, 单台node收集的日志越多, 可以满足更加丰富的业务场景。
  • 资源消耗: node agent往往是需要部署集群中所有的node上面, 所以影响面较广, 如果我们能显著降低资源消耗, 相当于省钱。
  • 稳定可靠: 自动降级,就算是异常情况, 程序Bug也不能影响用户, 此时就需要通过cgroup等技术进行容量的限制。 还有就是不能多收集日志或者丢失日志。

日志收集agent原理

这部分可以阅读下面链接的阿里云团队分享的文章, 这里highlight一下:

  1. 使用polling + inotify发现日志文件
  2. 使用dev+inode+signatrue标识一个文件
  3. 通过点位文件保证可靠性, 通过fsync+rename保证点位文件的可靠性
  4. 通过保持文件打开状态来保证文件采集完整

日志采集中的关键技术分析
Logtail技术分享(一) : Polling + Inotify 组合下的日志保序采集方案
Logtail技术分享(二) : 多租户隔离技术+双十一实战效果

More topic

Logging Architecture
Cluster-level Logging in Kubernetes with Fluentd
阿里PB级Kubernetes日志平台建设实践

logging in kubernetes的更多相关文章

  1. kubernetes实战(三):k8s v1.11.1 持久化EFK安装

    1.镜像下载 所有节点下载镜像 docker pull kibana: docker tag kibana: docker.elastic.co/kibana/kibana: docker pull ...

  2. Kubernetes 集群日志 和 EFK 架构日志方案

    目录 第一部分:Kubernetes 日志 Kubernetes Logging 是如何工作的 Kubernetes Pod 日志存储位置 Kubelet Logs Kubernetes 容器日志格式 ...

  3. Kubernetes集群初探

    上文我们在一台虚机上演示了Kubernetes基于redis和docker的guestbook留言簿案例,本文我们将通过配置Kubernetes集群的方式继续深入研究.集群组件安装如下配置. IP N ...

  4. kubernetes 1.3 的安装和集群环境部署

    简介: Docker:是一个开源的应用容器引擎,可以为应用创建一个轻量级的.可移植的.自给自足的容器. Kubernetes:由Google开源的Docker容器集群管理系统,为容器化的应用提供资源调 ...

  5. Docker实践(6)—CentOS7上部署Kubernetes

    Kubernetes架构 Kubernetes的整体架构如下: Master为主控节点,上面运行apiserver,scheduler,controller-manager等组件.Minion相当于工 ...

  6. kubernetes学习笔记

    docker实现了更便捷的单机容器虚拟化的管理, docker的位置处于操作系统层与应用层之间; 相对传统虚拟化(KVM,XEN): docker可以更加灵活的去实现一些应用层功能, 同时对资源的利用 ...

  7. 基于kubernetes构建Docker集群管理详解-转

    http://blog.liuts.com/post/247/ 一.前言        Kubernetes 是Google开源的容器集群管理系统,基于Docker构建一个容器的调度服务,提供资源调度 ...

  8. 无网络centos7中部署kubernetes

    本文提供的kubernetes1.1实际为kubernetes0.8,最新kubernetes部署方式见下一篇文章:centos下kubernetes+flannel部署. 一.部署环境信息: 1)m ...

  9. CentOS7 安装kubernetes

    2台机器,1台为Master,1台为Node 修改Host Master为dmaster,Node为dslave 安装K8s and Etcd 在Master机器上安装 yum install etc ...

随机推荐

  1. 使用runc直接运行容器

    组件containerd负责集群节点上容器的生命周期管理,并向上为docker daemon提供gRPC接口,containerd依靠runC去创建容器进程.而在容器启动之后,runC进程会退出. 可 ...

  2. Vue——watch监听对象,监听嵌套多次的对象属性

    首先是watch 然后是methods

  3. React组件略讲

    React是前端组件化开发的开山鼻祖,这种开发方式彻底解决了的前端组件复用的痛点.今天,就来研究一下React组件开发. 前端同学一般都会从Vue入门,因为Vue使用的<template> ...

  4. 请求库urllib和urllib3

    # coding=utf-8 # urllib """ 使用python的urllib库去模拟浏览器请求网页,常用内容如下: urllib.request 发送HTTP请 ...

  5. Java NIO 三大组件之 Buffer

    NIO大三组件 之Buffer 一.什么是Buffer Buffer是用于特定原始类型的数据的容器. 它的实质就是一组数组,用于存储不同类型的数据. 二.缓冲区的类型 缓冲区类型除了Boolean值类 ...

  6. Spring Boot和Feign中使用Java 8时间日期API(LocalDate等)的序列化问题【转】

    Spring Boot和Feign中使用Java 8时间日期API(LocalDate等)的序列化问题 http://blog.didispace.com/Spring-Boot-And-Feign- ...

  7. Netty学习——protoc的新手使用流程

    Netty学习——protoc的新手使用流程 关于学习的内容笔记,记下来的东西等于又过了一次脑子,记录的更深刻一些. 1. 使用IDEA创建.proto文件,软件会提示你安装相应的语法插件 安装成功之 ...

  8. 八分音符(频率)卷积算子 Octave Convolution

    为什么读此系列文章? 优化数学和计算理论帮助机器学习完成问题分类: 1)按照领域划分,比如计算机视觉,自然语言处理,统计分析预测形: 2)按照算法复杂划分,比如是否是NP-Hard问题,是否需要精确解 ...

  9. 搞清楚一道关于Integer的面试题

    请看题1: public class IntegerDemo { public static void main(String[] args) { Integer a = 888; Integer b ...

  10. SpringBoot使用注解(@value)读取properties(yml)文件中 配置信息

    为了简化读取properties文件中的配置值,spring支持@value注解的方式来获取,这种方式大大简化了项目配置,提高业务中的灵活性. 1. 两种使用方法1)@Value("#{co ...