跳到主要内容

arct

k8s日志收集架构

https://kubernetes.io/docs/concepts/cluster-administration/logging/

容器日志的存储
  • Docker容器的日志

    容器日志驱动:

    https://docs.docker.com/config/containers/logging/configure/

    查看当前的docker主机的驱动:

    $ docker info --format '{{.LoggingDriver}}'

    json-file格式,docker会默认将标准和错误输出保存为宿主机的文件,路径为:

    /var/lib/docker/containers/<container-id>/<container-id>-json.log

    并且可以设置日志轮转:

    {
    "log-driver": "json-file",
    "log-opts": {
    "max-size": "10m",
    "max-file": "3",
    "labels": "production_status",
    "env": "os,customer"
    }
    }
  • k8s Pod的日志存储

    $ ll /var/log/pods/

总体分为三种方式:

  • 使用在每个节点上运行的节点级日志记录代理。
  • 在应用程序的 pod 中,包含专门记录日志的 sidecar 容器。
  • 将日志直接从应用程序中推送到日志记录后端。
使用节点级日志代理

优势:

  • 部署方便,使用DaemonSet类型控制器来部署agent即可
  • 对业务应用的影响最小,没有侵入性

劣势:

  • 只能收集标准和错误输出,对于容器内的文件日志,暂时收集不到
使用 sidecar 容器和日志代理
  • 方式一:sidecar 容器将应用程序日志传送到自己的标准输出。

    思路:在pod中启动一个sidecar容器,把容器内的日志文件吐到标准输出,由宿主机中的日志收集agent进行采集。

    $ cat count-pod.yaml
    apiVersion: v1
    kind: Pod
    metadata:
    name: counter
    spec:
    containers:
    - name: count
    image: busybox
    args:
    - /bin/sh
    - -c
    - \>
    i=0;
    while true;
    do
    echo "$i: $(date)" \>\> /var/log/1.log;
    echo "$(date) INFO $i" \>\> /var/log/2.log;
    i=$((i+1));
    sleep 1;
    done
    volumeMounts:
    - name: varlog
    mountPath: /var/log
    - name: count-log-1
    image: busybox
    args: [/bin/sh, -c, 'tail -n+1 -f /var/log/1.log']
    volumeMounts:
    - name: varlog
    mountPath: /var/log
    - name: count-log-2
    image: busybox
    args: [/bin/sh, -c, 'tail -n+1 -f /var/log/2.log']
    volumeMounts:
    - name: varlog
    mountPath: /var/log
    volumes:
    - name: varlog
    emptyDir: {}

    $ kubectl apply -f counter-pod.yaml
    $ kubectl logs -f counter -c count-log-1

    优势:

    • 可以实现容器内部日志收集
    • 对业务应用的侵入性不大

    劣势:

    • 每个业务pod都需要做一次改造
    • 增加了一次日志的写入,对磁盘使用率有一定影响
  • 方式二:sidecar 容器运行一个日志代理,配置该日志代理以便从应用容器收集日志。

    思路:直接在业务Pod中使用sidecar的方式启动一个日志收集的组件(比如fluentd),这样日志收集可以将容器内的日志当成本地文件来进行收取。

    优势:不用往宿主机存储日志,本地日志完全可以收集

    劣势:每个业务应用额外启动一个日志agent,带来额外的资源损耗

从应用中直接暴露日志目录

企业日志方案选型

目前来讲,最建议的是采用节点级的日志代理。

方案一:自研方案,实现一个自研的日志收集agent,大致思路:

  • 针对容器的标准输出及错误输出,使用常规的方式,监听宿主机中的容器输出路径即可
  • 针对容器内部的日志文件
    • 在容器内配置统一的环境变量,比如LOG_COLLECT_FILES,指定好容器内待收集的日志目录及文件
    • agent启动的时候挂载docker.sock文件及磁盘的根路径
    • 监听docker的容器新建、删除事件,通过docker的api,查出容器的存储、环境变量、k8s属性等信息
    • 配置了LOG_COLLECT_FILES环境变量的容器,根据env中的日志路径找到主机中对应的文件路径,然后生成收集的配置文件
    • agent与开源日志收集工具(Fluentd或者filebeat等)配合,agent负责下发配置到收集工具中并对进程做reload

> fluentd-pilot

方案二:日志使用开源的Agent进行收集(EFK方案),适用范围广,可以满足绝大多数日志收集、展示的需求。