在本教程中,我们将部署一个 metricbeat 来监控正在运行的容器的健康状况和系统指标。
为什么需要监控,为什么需要 Metricbeat?
一个常见的问题,但很少有人回答。 首先,无论我们部署的是 docker 容器还是老式的金属箱(即物理服务器),监控它们的健康状况至关重要。 最大的问题是,当我们在现场运行多台服务器时,识别哪台服务器出现问题的效率如何? 或者确定特定服务器何时崩溃有多容易? 答案可以在监控数据中找到(如果我们一开始就收集过)。
基于经验和团队文化,管理员通常编写自己的脚本或程序来收集服务器指标。 事实上,这是一种相当直接的方法,通常效果很好……直到部署了许多服务器实例。 脚本和程序是否可扩展以处理多服务器监控? 有多少定制以及监控不同系统(例如操作系统、数据库、应用程序服务器等)的难易程度。 如果以上问题的答案不是很确定,我们可能需要更好的解决方案。
来自 Elastic(该公司)的 Metricbeat 提供了一个单一的可执行文件,它有助于获取最常见的服务器/服务指标,包括主机(即操作系统级别)、数据库(mySQL、postgreSQL)、消息队列(kafka、rabbitMQ)等等。 与其它解决方案不同,Metricbeat 得到维护并积极开发以支持度量消费; 现在我们需要做的就是维护配置文件而不是我们脚本/程序中的逻辑。
使用 docker 创建 Elastic Stack
我们首先来仿照之前的文章 “Elasticsearch:如何在 Docker 上运行 Elasticsearch 8.x 进行本地开发” 来创建我们的 docker-compose.yml 文件:
docker-compose.yml
1. version: "3.9"
2. services:
3. elasticsearch:
4. image: elasticsearch:8.6.2
5. container_name: elasticsearch
6. environment:
7. - discovery.type=single-node
8. - ES_JAVA_OPTS=-Xms1g -Xmx1g
9. - xpack.security.enabled=false
10. volumes:
11. - type: volume
12. source: es_data
13. target: /usr/share/elasticsearch/data
14. ports:
15. - target: 9200
16. published: 9200
17. networks:
18. - elastic
20. kibana:
21. image: kibana:8.6.2
22. container_name: kibana
23. ports:
24. - target: 5601
25. published: 5601
26. depends_on:
27. - elasticsearch
28. networks:
29. - elastic
31. metricbeat:
32. image: docker.elastic.co/beats/metricbeat:8.6.2
33. container_name: metricbeat
34. environment:
35. ELASTICSEARCH_HOSTS: http://elasticsearch:9200
36. volumes:
37. - metricbeat-data01:/usr/share/metricbeat/data
38. networks:
39. - elastic
40. depends_on:
41. - elasticsearch
43. volumes:
44. es_data:
45. driver: local
46. metricbeat-data01:
47. driver: local
49. networks:
50. elastic:
51. name: elastic
52. driver: bridge
我们添加了一个名为 metricbeat 的服务,并通过环境变量 (ELASTICSEARCH_HOSTS) 声明了目标 elasticsearch 主机。 还为此服务 (metricbeat-data01) 添加了一个新卷(用于数据存储)。 该服务的网络应设置为 elastic,原因是该服务应与我们的目标 elasticsearch 主机/节点位于同一网络上。
让我们通过发出以下命令来启动服务:
docker-compose up
等所有的容器都启动后,我们可以使用如下的命令来进行查看:
docker ps
1. $ docker ps
2. CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3. 52072cc96dfc docker.elastic.co/beats/metricbeat:8.6.2 "/usr/bin/tini -- /u…" About a minute ago Up About a minute metricbeat
4. 2511ea046940 kibana:8.6.2 "/bin/tini -- /usr/l…" 2 minutes ago Up About a minute 0.0.0.0:5601->5601/tcp kibana
5. 4465801cb251 elasticsearch:8.6.2 "/bin/tini -- /usr/l…" 2 minutes ago Up About a minute 0.0.0.0:9200->9200/tcp, 9300/tcp elasticsearch
从上面,我们可以看出来正在运行的容器: elasticsearch,kibana 及 metricbeat。
我们可以到 Kibana 中进行查看:
从上面,我们可以看出来被收集进来的指标信息。
从上面显示的信息中,我们可以看出来它收集的正是运行 Metricbeat 容器的指标。在默认的情况下,system 模块是被启动的。它会自动帮我们收集系统指标。有关 Metricbeat 的使用请阅读之前的文章 “Beats:Beats 入门教程 (二)”。
恭喜我们已经成功地在我们的集群上添加了 metricbeat 监控! 收集的数据可以显示在反映操作系统/主机指标的指标应用程序上,包括 CPU、内存、负载、网络、进程等。
显示操作系统/主机指标非常有用,但有时我们可能也想知道服务器/服务的行为方式。 举个例子,我们可以监控我们的 elasticsearch 节点的健康状况吗? 如果您现在点击 “Stack Monitoring” 应用程序,将显示此页面:
简单的意思是……没有可用的 Elasticsearch 监控数据 :(
了解 metricbeat 模块
对于现代版本的弹性堆栈,弹性搜索节点的监控建议启用名为“elasticsearch-xpack”的 metricbeat 模块。 那么什么是 metricbeat 模块??? 一个简单的句子——模块包含与目标服务器/服务对话的逻辑,并维护一组用于收集的指标的逻辑分组; 因此它就像一个配置管理器。
模块在 yml 文件中声明并存储在 {metricbeat_root}/modules.d 文件夹下。 elasticsearch-xpack.yml 示例如下:
elasticsearch-xpack.yml
1. # Module: elasticsearch
2. # Docs: https://www.elastic.co/guide/en/beats/metricbeat/main/metricbeat-module-elasticsearch.html
4. - module: elasticsearch
5. xpack.enabled: true
6. period: 10s
7. hosts: ["http://localhost:9200"]
8. #username: "user"
9. #password: "secret"
对于大多数情况,我们会修改要收集的指标集(即指标集设置)、监控主机(例如 localhost:9200 或 node01:9200)并激活 xpack 监控功能(即 xpack.enabled)。
现在摆在我们面前的挑战是……如何更新 elasticsearch-xpack.yml 文件? 好吧……一种方法是我们启动服务,然后通过 telnet / ssh 进入 metricbeat 容器并更新配置文件。例如,我们可以这样来进入到容器中:
1. $ docker ps
2. CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3. 52072cc96dfc docker.elastic.co/beats/metricbeat:8.6.2 "/usr/bin/tini -- /u…" About an hour ago Up About an hour metricbeat
4. 2511ea046940 kibana:8.6.2 "/bin/tini -- /usr/l…" About an hour ago Up About an hour 0.0.0.0:5601->5601/tcp kibana
5. 4465801cb251 elasticsearch:8.6.2 "/bin/tini -- /usr/l…" About an hour ago Up About an hour 0.0.0.0:9200->9200/tcp, 9300/tcp elasticsearch
6. $ docker exec -it metricbeat /bin/bash
7. metricbeat@52072cc96dfc:~$
这种方式可能是最简单的,但它根本不可扩展,并且引入了最终难以维护的手动操作。 一个不太脏的解决方案肯定是值得的。
构建自定义的 metricbeat docker 镜像
就像我们之前讨论的那样,我们试图只维护配置文件而不是脚本/程序逻辑(也是手动操作)。 因此,针对上述挑战的更简洁的解决方案是使用更新的 metricbeat.yml 构建自定义 docker 镜像。
创建 metricbeat.yml 如下:
metricbeat.yml
1. metricbeat.config.modules:
2. path: ${path.config}/modules.d/*.yml
3. reload.enabled: false
5. processors:
6. - add_cloud_metadata: ~
7. - add_docker_metadata: ~
9. output.elasticsearch:
10. hosts: '${ELASTICSEARCH_HOSTS:elasticsearch:9200}'
11. username: '${ELASTICSEARCH_USERNAME:}'
12. password: '${ELASTICSEARCH_PASSWORD:}'
14. # enabled modules for monitoring (e.g. elasticsearch-xpack)
15. metricbeat.modules:
16. - module: elasticsearch
17. xpack.enabled: true
18. period: 10s
19. hosts: ["http://node01:9200"]
1. $ pwd
2. /Users/liuxg/data/metricbeat
3. $ ls
4. docker-compose.yml metricbeat.yml
我们声明要启用 elasticsearch 模块,目标主机是 elasticsearch:9200。 由于 hosts 配置是一个数组,因此可以仅设置 1 个 metricbeat 实例并使用多节点的指标。
接下来,让我们更新 docker-compose.yml 如下:
docker-compose.yml
1. version: "3.9"
2. services:
3. elasticsearch:
4. image: elasticsearch:8.6.2
5. container_name: elasticsearch
6. environment:
7. - discovery.type=single-node
8. - ES_JAVA_OPTS=-Xms1g -Xmx1g
9. - xpack.security.enabled=false
10. volumes:
11. - type: volume
12. source: es_data
13. target: /usr/share/elasticsearch/data
14. ports:
15. - target: 9200
16. published: 9200
17. networks:
18. - elastic
20. kibana:
21. image: kibana:8.6.2
22. container_name: kibana
23. ports:
24. - target: 5601
25. published: 5601
26. depends_on:
27. - elasticsearch
28. networks:
29. - elastic
31. metricbeat:
32. build: .
33. # image: docker.elastic.co/beats/metricbeat:8.6.2
34. container_name: metricbeat
35. environment:
36. ELASTICSEARCH_HOSTS: http://elasticsearch:9200
37. volumes:
38. - metricbeat-data01:/usr/share/metricbeat/data
39. networks:
40. - elastic
41. depends_on:
42. - elasticsearch
44. volumes:
45. es_data:
46. driver: local
47. metricbeat-data01:
48. driver: local
50. networks:
51. elastic:
52. name: elastic
53. driver: bridge
配置文件的唯一变化是用 build 配置替换 image 配置。 build 只是意味着我们正在从本地 Dockerfile 配置构建自定义镜像。 Dockerfile 包含构建自定义镜像的步骤和我们的版本如下:
1. FROM docker.elastic.co/beats/metricbeat:8.6.2
2. COPY metricbeat.yml /usr/share/metricbeat/metricbeat.yml
3. USER root
4. RUN chown root /usr/share/metricbeat/metricbeat.yml
1. $ pwd
2. /Users/liuxg/data/metricbeat
3. $ ls
4. Dockerfile docker-compose.yml metricbeat.yml
这很简单,我们将基础 docker 镜像设置为 docker.elastic.co/beats/metricbeat:8.6.2。 然后我们将自定义的 metricbeat.yml 复制到镜像的 /usr/share/metricbeat 路径下。 最后使用 root 用户更改 metricbeat.yml 的访问权限并完成。
接下来是构建镜像,但是发出如下的命令:
如果一切顺利,我们的镜像很快就会建立起来了。
是时候启动服务并验证结果了:
docker-compose up
接下来,我们到 Kibana 中去查看:
很显然,这次我们看到了不一样的结果。
我们可以看到想要的指标信息。
Horray ~ 我们做到了,metricbeat 正在收集 elasticsearch 节点的指标。