kubernetes日志实现方案
Fluentd+Elastic-Search
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,而这一切不需要复杂的配置。
具体实现方案
td-agent.conf
是fluentd的一个样例配置文件。通过这个文件我们来了解具体fluentd怎么采集docker log的。kubelet在/var/log/containers/
下为每个container创建了一个日志文件的软链接。此目录下文件名记录的pod name
,namespace
, container name
,docker container id
。当然你必须得把/var/log/containers/
目录挂载进fluentd容器。
在fluentd中想要发送给es,需要安装fluent-plugin-elasticsearch
和fluent-plugin-kubernetes_metadata_filter plugins
插件。具体插件地址:https://github.com/uken/fluent-plugin-elasticsearch,https://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的机制启动。