GX博客

分享个人 Full-Stack JavaScript 项目开发经验

在集群中使用EFK接管Nginx日志

Nginx 默认的日志记录方式是将访问和错误日志按指定格式写入指定文件。access_log 指令甚至可以根据不同 server 和 location 将访问日志分别写入不同文件。最后还可以使用如 logrotate 这样的日志滚动程序对日志进行滚动和清理。

但是在分布式集群应用中,这些分散在不同主机上的滚动日志很难维护,亦难以搜索。Kubernetes 没有原生的集中式日志解决方案,EFK 是目前流行的解决方案之一。EFK,即 Elasticsearch、Fluentd 和 Kibana 组合的工具套件,用于集群集中式日志管理。

本文将会简单介绍 Kubernetes 集群中 EFK 的工作原理,以及如何令 EFK 接管 Nginx 的日志记录。


Docker 日志驱动程序

Kubernetes 本身没有日志机制,但是它默认使用的 Docker 容器引擎则有多种日志记录机制。Docker 守护程序会使用对应的日志驱动程序把容器标准输出流(stdout 和 stderr)的信息写入日志文件。

为了配合 EFK 默认的配置,我们可以使用 json-file 日志驱动程序。

查看 Docker 正在使用的日志驱动程序:

docker info

在 centos7 系统中,使用 yum 安装的 docker 会默认使用 journald 日志驱动程序。可以使用以下命令查看 docker 所有日志:

journalctl -u docker

要修改 docker 日志驱动程序,需要检查 /etc/sysconfig/docker 文件的启动参数,以及修改 /etc/docker/daemon.json 守护程序配置文件,例如配置为:

{
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "10m",
    "max-file": "3"
  }
}

修改配置后,还需要重启 docker:

systemctl restart docker
要查看更多关于 Docker 日志驱动程序的介绍,请点击这里

EFK 的工作过程

首先 Fluentd 会以 DaemonSet 的形式部署在集群各个节点上。它至少应挂载节点主机的 /var/lib/docker/containers 和 /var/log 目录,并且赋予获取和监听 pods 和 namespaces 的权限。Fluentd 的配置文件在 /fluentd/etc 目录下,其中包括默认的 kubernetes.conf 配置文件。

Fluentd 会以行作为记录单位,并且添加容器以及 pods 和 namespaces 等相关信息再发送给 Elasticsearch 集群服务。

Elasticsearch 集群服务一般以 StatefulSet 的方式部署,并挂载持久化存储卷,把 Fluentd 发送过来的信息作分布式存储和索引。

Kibana 为 Elasticsearch 数据提供可视化用户界面。它默认并没有身份验证机制,最简单的做法可以使其在 nginx 的 auth_basic 背后工作。


Nginx 的日志配置

Nginx 的 error_log 和 access_log 需要配置为记录到标准输出流中:

error_log  /dev/stderr warn;
access_log /dev/stdout main;

由于 Nginx 所有日志流量都会输出在一起,所以需要添加必要的信息以区分不同的日志流量,日志格式例子如下:

log_format  main  '$remote_addr - $remote_user [$time_local] "$host" "$request" '
                  '$status $body_bytes_sent "$http_referer" '
                  '"$http_user_agent" "$http_x_forwarded_for"';

与默认配置相比,上述配置添加了主机名称 "$host" 用于筛选。

当然,你也可以以 JSON 格式输出访问日志信息:

log_format main
          '{'
            '"time_local":"$time_local",'
            '"remote_addr":"$remote_addr",'
            '"remote_user":"$remote_user",'
            '"host":"host",'
            '"request":"$request",'
            '"status": "$status",'
            '"body_bytes_sent":"$body_bytes_sent",'
            '"request_time":"$request_time",'
            '"http_referrer":"$http_referer",'
            '"http_user_agent":"$http_user_agent",'
            '"http_x_forwarded_for":"$http_x_forwarded_for"'
          '}';

下图展示了 kubernetes.pod_name:"nginx-*" and "www.leeguangxing.cn" 的筛选结果:

efk

类似地,亦可以使用 kubernetes.pod_name:"nginx-*" and "[error]" 作为筛选 Nginx 错误日志。


上述就是 EFK 接管 Nginx 日志的所有介绍内容。

版权声明:

本文为博主原创文章,若需转载,须注明出处,添加原文链接。

https://leeguangxing.cn/blog_post_85.html