一条命令搞定容器日志收集,轻松解决运维烦恼

nginx 日志分析搭建案例 中大家已经明白如何通过 Pandora 快速搭建实时监控与报警平台的整个过程。除了 nginx 这类常见基础组件之外,您可能本身有一些自研的程序,也需要做相应的日志收集处理工作,那么操作方法与之类似,只是日志的解析方式不同而已。但是如果您的程序运行在容器云(如 Kubernetes)之上,那么该如何处理呢?

本文将以 Kubernetes 容器云平台运维 和 Kubernetes 容器云用户 两个视角,为您介绍如何使用 logkit 进行日志收集。

Kubernetes 容器云平台运维视角

作为 Kubernetes 容器云平台的运维,想要收集日志非常简单,因为 Kubernetes 已经将日志统一存放在 /var/log/containers/ 文件夹下,如下图所示:

此处输入图片的描述

对于每一个日志,都是一个软连接,连接到实际的日志文件。对于此类日志,使用 logkit 的文件读取模式 (tailx) 即可直接读取,接入方式如下。

数据接入

根据您机器的操作系统版本下载 logkit

https://github.com/qiniu/logkit/wiki/Download

解压后您可以看到

logkit
logkit.conf
public/
confs/

其中 logkit.conf 为主配置文件,用于配置 logkit 的 web 页面及端口配置,其中

  • bind_host 是设置绑定的端口,启动后可以根据这个页面配置 logkit。
  • static_root_path 是 logkit 页面的静态资源路径,就是填写 public 文件夹所在路径,强烈建议写成 绝对路径

运行 logkit

nohup ./logkit -f logkit.conf > logkit.log 2>&1

访问 logkit 配置页面

假设我们bind_host填写的页面内容为:"localhost:3000",那么我们可以在浏览器打开这个页面http://localhost:3000

点击【增加 Runner】,第一步 【配置数据源】

此处输入图片的描述

注意选择数据源类型为 "tailx" 模式,填写日志路径为 /var/log/containers/*.log

然后配置解析方式,选择 【raw】方式解析
此处输入图片的描述

然后依次点击,知道配置发送方式时填写您的七牛账户"ak","sk"。

此时 logkit 部分您就配置完毕了,下面让我们来看看,作为 Kubernetes 平台的用户,我们该如何使用 logkit 。

Kubernetes 容器云平台用户视角

当你作为 Kubernetes 用户时,你无法将 logkit 安装在服务器上收集日志,但是你可以利用 Kubernetes 的 Daemonset 功能, 将 logkit 以 daemonset 的形式运行在 Kubernetes 的每一个机器上,此时 logkit 容器与您的实际容器通过共享 volume 的方式收集日志数据。

Docker 的日志统一放置在宿主机的 /var/lib/docker/containers 目录上,作为 daemonset 的 logkit 会自动探测该目录中新生成的日志并将之收集。

下载配置文件

您可以通过如下命令获取部署到 Kubernetes 的配置文件。

curl -L -O https://raw.githubusercontent.com/qiniu/logkit/develop/deploy/logkit_on_k8s.yaml

执行后生成的配置文件为 logkit_on_k8s.yaml,具体的配置如下(可能随版本变动下载到的会有所不同):

---
apiVersion: v1
kind: ConfigMap
metadata:
  name: logkit-config
  namespace: kube-system
  labels:
    k8s-app: logkit
data:
  k8s.conf: |-
    {
      "name": "k8s_runner",
      "batch_interval": 60,
      "reader": {
        "mode": "tailx",
        "log_path": "/var/log/containers/*.log",
        "read_from": "oldest",
        "datasource_tag": "source_file",
        "expire": "240h",
        "stat_interval": "3m"
      },
      "parser": {
        "type": "raw",
        "timestamp": "true"
      },
      "senders": [
        {
          "sender_type": "pandora",
          "pandora_repo_name": "k8s_log",
          "pandora_ak": "${QINIU_ACCESS_KEY}",
          "pandora_sk": "${QINIU_SECRET_KEY}",
          "pandora_host": "https://pipeline.qiniu.com",
          "pandora_region": "nb",
          "pandora_schema_free": "true",
          "pandora_enable_logdb": "true",
          "pandora_logdb_host": "https://logdb.qiniu.com",
          "pandora_gzip": "true",
          "pandora_uuid": "false",
          "pandora_withip": "true",
          "ft_strategy": "backup_only",
          "ignore_invalid_field": "true",
          "pandora_auto_convert_date": "true"
        }
      ]
    }
---
apiVersion: extensions/v1beta1
kind: DaemonSet
metadata:
  name: logkit
  namespace: kube-system
  labels:
    k8s-app: logkit
spec:
  template:
    metadata:
      labels:
        k8s-app: logkit
    spec:
      terminationGracePeriodSeconds: 30
      containers:
      - name: logkit
        image: wonderflow/logkit:v1.3.6
        env:
        - name: QINIU_ACCESS_KEY
          value: change_me_to_your_qiniu_access_key
        - name: QINIU_SECRET_KEY
          value: change_me_to_your_qiniu_secret_key
        - name: POD_NAMESPACE
          valueFrom:
            fieldRef:
              fieldPath: metadata.namespace
        securityContext:
          runAsUser: 0
        resources:
          limits:
            memory: 200Mi
          requests:
            cpu: 100m
            memory: 100Mi
        volumeMounts:
        - name: config
          mountPath: /app/confs/k8s.conf
          readOnly: true
          subPath: k8s.conf
        - name: varlibdockercontainers
          mountPath: /var/lib/docker/containers
          readOnly: true
        - name: varlogcontainers
          mountPath: /var/log/containers
          readOnly: true
        - name: varlogpods
          mountPath: /var/log/pods
          readOnly: true
      volumes:
      - name: config
        configMap:
          defaultMode: 0600
          name: logkit-config
      - name: varlibdockercontainers
        hostPath:
          path: /var/lib/docker/containers
      - name: varlogcontainers
        hostPath:
          path: /var/log/containers
      - name: varlogpods
        hostPath:
          path: /var/log/pods
      - name: data
        emptyDir: {}

修改配置文件

默认情况下,我们的配置文件会使用 kube-system 这个 Kubernetes 的 namespace ,所有的部署仅针对该 namespace 生效。如果你想要使用别的 namespace ,只需要修改配置文件的 namespace 部分,将之改为你的 namespace 名称。

另外,这份默认的配置文件,你只需要修改2个基本参数,就可以运行。

 - name: QINIU_ACCESS_KEY
   value: change_me_to_your_qiniu_access_key
 - name: QINIU_SECRET_KEY
   value: change_me_to_your_qiniu_secret_key

change_me_to_your_qiniu_access_key 改为您七牛账号的 AK(access_key) ,将 change_me_to_your_qiniu_secret_key 改为您七牛账号的SK(secret_key)。

部署到Kubernetes

部署到 Kubernetes 非常简单,只需要运行一行命令即可。

kubectl create -f logkit_on_k8s.yaml

通过以下命令查看部署是否成功:

$ kubectl --namespace=kube-system get ds/logkit

此时日志就源源不断的流向您的数据源啦,可以登录七牛的 pandora 日志检索平台查看。

登录Pandora界面

运行后,在 https://portal.qiniu.com/logdb 上就已创建了日志仓库:k8s_log , 点击右边的设置修改按钮,可以设置仓库的保存时长( logkit 自动创建的仓库数据默认保存 30 天),以及设置不同类型的分词。

此处输入图片的描述

点击【修改图标】进入后可以看到如下图所示。

此处输入图片的描述

注意

  • 修改仓库数据保存期限修改后即时生效
  • 修改数据的分词,修改后配置在 T+1 时间后生效,对之前的数据不生效。
  • 纯英文的日志建议设置为标准分词,以便快速检索数据;带有中文的数据建议设置为中文分词;如果字段都是关键字,类似"INFO"、"ERROR",则建议设置为”不分词“。

检索日志

进入日志检索页面,除用户的原始日志以外,默认就能获得各类基础信息,包括机器的 hostname 信息,Kubernetes container 信息, Kubernetes 的 namespace 信息,Kubernetes 的 pod 信息,容器的 IP 地址,机器的操作系统。

此处输入图片的描述

当然,你也可以去掉额外的信息,完全只关注日志本身,如下图所示,我们以关键字 Stopping 为例,检索 raw 字段结果如下。 (此处"raw"字段的分词为”标准分词“)

此处输入图片的描述

grafana监控和告警

具体配置可参考 Pandora 文档站中的Grafana 简介 此处不再赘述,下面只给出示例配置。

创建 Grafana App,如图6所示

图6 Grafana APP 创建

配置 Grafana LogDB 数据源,如图7所示,点击 logdb 使用指南,可以按照使用指南的指导在 Grafana 配置数据源。

图7 Grafana 数据源配置

注意事项

  • Default Query Settings 中, Group by interval 填写时间 10s,注意单位为s,m等,不能漏掉,必须小写。
  • Time Field Name 处填写您的 logdb 时间字段, 填您 nginx 配置的命名,在上述的截图示例中,是 time_local , 没有默认的 $ 符号
  • Index name 中,模式固定为 Daily , 串固定为 [reponame-]YYYY.MM.DD , 将 reponame 字符串改为您的数据源名称即可。
  • Version 固定为 2.x

新建 Grafana 的 dashboard 并创建 graph

设置 metrics

此处输入图片的描述

设置 alert 告警

设置 condition,可以选择 sum(), count() 等,IS ABOUT 为设置的阈值

此处输入图片的描述

设置告警 email 通知

首先,设置邮件通知组

此处输入图片的描述

点击 sent test,测试是否可以收到邮件

此处输入图片的描述

设置告警通知

此处输入图片的描述

当超过设置的阈值后就出现告警,并发邮件,包含之前写好的 message,以及此刻 graph 截图。如下图所示:

此处输入图片的描述

以上就轻松完成利用 Pandora 日志分析平台,轻松收集容器云日志,完成运维查看、告警相关功能啦!