kubernetes日志方案

kubernetes日志实现方案

基本翻译了 https://github.com/kubernetes/kubernetes/blob/master/cluster/addons/fluentd-elasticsearch/fluentd-es-image/td-agent.conf

  fluentd和es的日志方案是kubernetes官方推荐的方案。首先docker和fluentd集成的话就很容易,docker的log driver默认类型json,就是你从docker logs看到的日志,docker支持把日志输出到fluentd,因此在启动docker容器时你可以把日志重定向到一个fluentd address。或者是让fluentd采集一个不断输出的docker log文件。

  es这个工具更加强大,本身就可以做非关系型数据存储,然后底层基于Lucence,可以进行对全文索引和搜索。而且最重要的是fluentd有很多丰富的plugin,其中就有es plugin,当fluentd将日志采集以后可以直接发送给es,而这一切不需要复杂的配置。

具体实现方案

https://github.com/kubernetes/kubernetes/blob/master/cluster/addons/fluentd-elasticsearch/fluentd-es-image/td-agent.conf

  td-agent.conf是fluentd的一个样例配置文件。通过这个文件我们来了解具体fluentd怎么采集docker log的。kubelet在/var/log/containers/下为每个container创建了一个日志文件的软链接。此目录下文件名记录的pod namenamespacecontainer namedocker container id。当然你必须得把/var/log/containers/目录挂载进fluentd容器。

  在fluentd中想要发送给es,需要安装fluent-plugin-elasticsearchfluent-plugin-kubernetes_metadata_filter plugins插件。具体插件地址:https://github.com/uken/fluent-plugin-elasticsearchhttps://github.com/fabric8io/fluent-plugin-kubernetes_metadata_filter

  下面举个例子,默认docker的log是这样的:

{
"log":"2014/09/25 21:15:03 Got request with path wombat\n",
 "stream":"stderr",
 "time":"2014-09-25T21:15:03.499185026Z"
}

  当发送给es时,查询出来这样的

{
      "_index" : "logstash-2014.09.25",
      "_type" : "fluentd",
      "_id" : "VBrbor2QTuGpsQyTCdfzqA",
      "_score" : 1.0,
      "_source":{"log":"2014/09/25 22:45:50 Got request with path wombat\n",
                 "stream":"stderr","tag":"docker.container.all",
                 "@timestamp":"2014-09-25T22:45:50+00:00"}
}

   Kubernetes fluentd plugin插件用来在日志记录中写入一些kuberenetes的元数据,并在日志记录中增加一些label,这会使用户很容易根据这些字段过滤搜索日志。

   默认docker log的路径像这样:

/var/lib/docker/containers/997599971ee6366d4a5920d25b79286ad45ff37a74494f262e3bc98d909d0a7b

   对应的k8s建立的软链接文件:

/var/lib/docker/containers/997599971ee6366d4a5920d25b79286ad45ff37a74494f262e3bc98d909d0a7b/997599971ee6366d4a5920d25b79286ad45ff37a74494f262e3bc98d909d0a7b-json.log

   这个软链接的真实文件是synthetic-logger-0.25lps-pod_default_synth-lgr-997599971ee6366d4a5920d25b79286ad45ff37a74494f262e3bc98d909d0a7b.log这里边9975999…..是docker container id,fluentd容器中收集的文件是/var/log/containers/synthetic-logger-0.25lps-pod_default_synth-lgr-997599971ee6366d4a5920d25b79286ad45ff37a74494f262e3bc98d909d0a7b.log,产生的tag是var.log.containers.synthetic-logger-0.25lps-pod_default_synth-lgr-997599971ee6366d4a5920d25b79286ad45ff37a74494f262e3bc98d909d0a7b.log.Kubernetes fluentd plugin可以用来解析namespace,pod name,container name这些都会被加入到日志,最终的tag是:

kubernetes.var.log.containers.synthetic-logger-0.25lps-pod_default_synth-lgr-997599971ee6366d4a5920d25b79286ad45ff37a74494f262e3bc98d909d0a7b.log

   最终的日志记录是这样的:

# {
#   "log":"2014/09/25 21:15:03 Got request with path wombat\n",
#   "stream":"stderr",
#   "time":"2014-09-25T21:15:03.499185026Z",
#   "kubernetes": {
#     "namespace": "default",
#     "pod_name": "synthetic-logger-0.25lps-pod",
#     "container_name": "synth-lgr"
#   },
#   "docker": {
#     "container_id": "997599971ee6366d4a5920d25b79286ad45ff37a74494f262e3bc98d909d0a7b"
#   }
# }

   注意里边的kubernetes域和docker域。

   这样用户就可以用label,pod name,container name进行查询日志,这些仅仅需要对Kubernetes fluentd plugin进行简单的配置,但是在fluentd pod中需要secrets。

fluentd per node部署

   根据以上方案,fluentd需要在每个node上部署一个,fluentd肯定是要由kubelet创建管理的。如果通过官方的kube-up.sh脚本部署kubernetes,通过配置,fluentd和es可以随集群启动而自动创建。如果你发现你的k8s集群启动后,fluentd并没有启动,还可以在每个node上通过kubelet manifest的机制启动。