管理服务器基础设施是一项复杂的任务。当一个集群行为异常时,登录到多台服务器,检查每个日志,并使用多个过滤器直到找到罪魁祸首,这不是资源的有效利用。
改进处理基础设施或应用程序方法的第一步是实施集中式日志记录系统。这将使您能够将来自任何应用程序或系统的日志收集到一个中心位置,并对其进行过滤、聚合、比较和分析。如果有服务器或应用程序,就应该有一个统一的日志记录层。
值得庆幸的是,我们有一个开源堆栈来简化这一过程。通过 Elasticsearch、Fluentd 和 Kibana (EFK) 的组合,我们可以创建一个强大的堆栈来收集、存储和可视化集中位置的数据。
让我们首先定义每个组件以了解全局。Elasticsearch 是一个开源的分布式 RESTful 搜索和分析引擎,或者简单来说是一个对象存储,所有日志都存储在其中。Fluentd 是一个开源数据收集器,可让您统一数据收集和使用,以便更好地使用和理解数据。最后,Kibana 是 Elasticsearch 的 Web UI。
一图胜千言

使用集中式 Fluentd 聚合器的 EFK 堆栈。
还有其他收集日志的方法,例如在每台主机中运行一个小型 Fluentd 转发器,但这超出了本文的范围。
要求
我们将在其自己的 Docker 容器中安装每个组件。借助 Docker,我们可以更快地部署每个组件,专注于 EFK 而不是特定于发行版的位,并且我们可以随时删除容器并重新开始。我们将使用官方的上游镜像。
要了解有关 Docker 的更多信息,请阅读 Vincent Batts 的优秀文章:Docker 初学者指南。
通过以 root 用户身份运行以下命令来增加 mmap 限制
$ sudo sysctl -w vm.max_map_count=262144
要永久设置此值,请更新 /etc/sysctl.conf
中的 vm.max_map_count
设置。
这是必需的;否则,Elasticsearch 可能会崩溃。
运行 Elasticsearch
为了允许容器彼此通信,请创建一个 Docker 网络
$ sudo docker network create efk
[...]
执行以下命令以在 Docker 中启动 Elasticsearch
$ sudo docker run --network=efk --name elasticsearch -d -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" -e "cluster.name=docker-cluster" -e "bootstrap.memory_lock=true" -e "ES_JAVA_OPTS=-Xms512m -Xmx512m" --ulimit memlock=-1:-1 -v elasticdata:/usr/share/elasticsearch/data docker.elastic.co/elasticsearch/elasticsearch-oss:6.2.2
验证容器是否正在运行
$ sudo docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
6e0db1486ee2 docker.elastic.co/elasticsearch/elasticsearch-oss:6.2.2 "/usr/local/bin/docke" About a minute ago Up About a minute 0.0.0.0:9200->9200/tcp, 0.0.0.0:9300->9300/tcp elasticsearch
让我们解耦命令以了解我们刚刚做了什么
- 我们使用
docker run
创建一个新容器。 - 我们使用
--network
将容器附加到该特定网络。 - 我们需要定义一个容器名称;它将用作主机名。
- 参数
-p
将我们的主机端口映射到容器端口。Elasticsearch 使用端口 9200 和 9300。 - 带有
-e
的多个参数是传递给容器以更改配置的环境变量。 - 我们定义了一个自定义
ulimit
以禁用交换以提高性能和节点稳定性。 - 容器在设计上是短暂的。这意味着它们不存储数据,因此为了保证数据和日志的安全,我们需要创建一个卷并将其挂载到容器内部。在我们的例子中,它被挂载到
/usr/share/elasticsearch/data
。这是 Elasticsearch 存储数据的路径。
验证卷是否已创建
$ sudo docker volume ls
[...]
local elasticdata
即使您删除容器,此卷也将存在。
太棒了!Elasticsearch 正在运行。让我们继续。
运行 Kibana
Kibana 是一个更简单的命令。执行以下命令来启动它
$ sudo docker run --network=efk --name kibana -d -p 5601:5601 docker.elastic.co/kibana/kibana-oss:6.2.2
默认情况下,Kibana 将尝试与名为 elasticsearch 的主机通信。
验证您是否可以在浏览器中通过此 URL 访问 Kibana:http://<docker host>:5601
此时,Elasticsearch 没有索引任何数据,因此您还无法执行太多操作。
让我们开始收集日志!
运行 Fluentd
以下步骤比较棘手,因为官方 Docker 镜像不包含 Elasticsearch 插件。我们将进行自定义。
创建一个名为 fluentd
的目录,其中包含一个名为 plugins
的子目录
$ mkdir -p fluentd/plugins
现在让我们创建 Fluentd 配置文件。在目录 fluentd
中,创建一个名为 fluent.conf
的文件,内容如下
$ cat fluentd/fluent.conf
<source>
type syslog
port 42185
tag rsyslog
</source>
<match rsyslog.**>
type copy
<store>
type elasticsearch
logstash_format true
host elasticsearch # Remember the name of the container
port 9200
</store>
</match>
<source>
块启用 syslog
插件,以及它将监听的端口和地址。<match rsyslog.**>
块将匹配来自 syslog
插件的所有日志,并将数据发送到 Elasticsearch。
现在在 Fluentd 文件夹中创建另一个名为 Dockerfile
的文件
$ cat fluentd/Dockerfile
FROM fluent/fluentd:v0.12-onbuild
RUN apk add --update --virtual .build-deps \
sudo build-base ruby-dev \
&& sudo gem install \
fluent-plugin-elasticsearch \
&& sudo gem sources --clear-all \
&& apk del .build-deps \
&& rm -rf /var/cache/apk/* \
/home/fluent/.gem/ruby/2.3.0/cache/*.gem
这将修改官方 Fluentd Docker 镜像并添加 Elasticsearch 支持。
Fluentd 目录应如下所示
$ ls fluentd/
Dockerfile fluent.conf plugins
现在我们可以构建容器了。在 Fluentd 目录中执行以下命令
$ sudo docker build fluentd/
[...]
Successfully built <Image ID>
现在我们准备好启动堆栈的最后一部分了。执行以下命令以启动容器
$ sudo docker run -d --network efk --name fluentd -p 42185:42185/udp <Image ID>
您的统一日志记录堆栈已部署。现在是时候配置您的主机的 rsyslog 以将数据发送到 Fluentd 了。
登录到您要从中收集日志的每个节点,并在 /etc/rsyslog.conf
的末尾添加以下行
*.* @<Docker Host>:42185
然后重启 rsyslog
服务
$ sudo systemctl restart rsyslog
不要忘记检查 Kibana——您的所有日志都将在那里。
使用 Docker Compose 总结一切
我们可以使用 Docker Compose 将我们之前执行的所有步骤组合成一个命令。Compose 是一个用于定义和运行多容器 Docker 应用程序的工具。使用 Compose,您可以使用 YAML 文件(称为 Compose 文件)来配置应用程序的服务;在我们的例子中是 EFK 服务。
要安装 Docker Compose,请执行以下命令
$ sudo curl -L https://github.com/docker/compose/releases/download/1.19.0/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
$ sudo chmod +x /usr/local/bin/docker-compose
验证它是否正常工作
$ docker-compose version
docker-compose version 1.19.0, build 9e633ef
太棒了!我们之前执行的所有步骤都可以用以下 docker-compose.yml
文件概括(我们仍然需要创建 Fluentd 文件夹和文件)
$ cat docker-compose.yml
version: '2.1'
services:
fluentd:
build: ./fluentd
links:
- "elasticsearch"
expose:
- 42185
ports:
- "42185:42185/udp"
logging:
driver: "json-file"
options:
max-size: 100m
max-file: "5"
elasticsearch:
image: docker.elastic.co/elasticsearch/elasticsearch-oss:6.2.2
container_name: elasticsearch
ports:
- "9200:9200"
environment:
- "discovery.type=single-node"
- "cluster.name=docker-cluster"
- "bootstrap.memory_lock=true"
- "ES_JAVA_OPTS=-Xms512m -Xmx512m"
ulimits:
memlock:
soft: -1
hard: -1
volumes:
- elasticdata:/usr/share/elasticsearch/data
kibana:
image: docker.elastic.co/kibana/kibana-oss:6.2.2
container_name: kibana
links:
- "elasticsearch"
ports:
- "5601:5601"
volumes:
elasticdata:
driver: local
然后您可以使用一个命令启动所有容器
$ sudo docker-compose up
如果您想删除所有容器(卷除外)
$ sudo docker-compose rm
借助一个简单的 YAML 文件,您的概念验证已准备好部署到任何地方,并获得一致的结果。当您彻底测试解决方案后,不要忘记阅读官方 Elasticsearch、Fluentd 和 Kibana 文档,使您的实施达到生产级别。
当您使用 EFK(和 Docker)时,您将认识到它是多么实用,并且您作为系统管理员的生活将永远不一样。
评论已关闭。