ELK 收集 Docker 日志
文章目录00 收集日志的目的01 安装Docker环境1.1 Ubuntu18.04 安装Docker1.2 Docker安装Nginx镜像1.3 查看Docker镜像的日志文件02 Filebeat根据容器ID收集Docker日志03 Filebeat收集多个Docker容器日志3.1 启动多个容器3.2 配置Filebeat进行多容器日志收集04 根据服务类型收集多个Docker容器日志4.1
文章目录
00 收集日志的目的
日志的职责是记录离散事件,通过这些记录事后分析出程序的行为,譬如曾经调用过什么方法,曾经操作过哪些数据,等等。打印日志被认为是程序中最简单的工作之一,它无可或缺却不太被重视,调试问题时常有人会说 当初这里记得打点日志就好了 😵,可见这就是一项举手之劳的任务🙋。
输出日志的确很容易,但收集和分析日志却可能会很复杂,尤其随着容器化技术的迅猛发展,凭借 Docker 高效的部署和扩容的特点,一台计算机就可以同时使用多个容器,轻松地模拟出复杂的微服务架构。
这时,面对成千上万的节点,面对迅速滚动的事件信息,面对 TB 级别的日志数据,传输与收集都并不简单。对大多数程序员来说,分析日志也许就是最常遇见也最有实践性和可行性
的大数据系统了。
本文就是让你快速了解并上手实践,🎯 如何使用 ELK 高效搭建一个用于收集和分析 Docker 日志的日志管理系统 🎯
01 安装Docker环境
1.1 Ubuntu18.04 安装 Docker
Docker 的安装方式有很多,这里展示一种只用 C-V 操作的方式,方便偷懒 😛 😜 😝
其他系统的 Docker CE 的安装方式可以自己参考 官方文档
如果你还不是很了解 Docker 的基础概念和使用方法的话,也可以参考笔者之前写的博文 Docker 安装部署与基础操作 期待 一键三连
👍 💬 ⭐️
# 更新Apt源
sudo apt-get update
# 安装依赖包
sudo apt-get install apt-transport-https ca-certificates curl gnupg-agent software-properties-common
# 添加 Docker 的 GPG 密钥
curl -fsSL http://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | sudo apt-key add - # 阿里云
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add - # 官方
# 验证您现在是否拥有带有指纹的密钥
sudo apt-key fingerprint 0EBFCD88
# 设置稳定版仓库
sudo add-apt-repository "deb [arch=amd64] http://mirrors.aliyun.com/docker-ce/linux/ubuntu $(lsb_release -cs) stable" # 阿里云源
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" # 官方源
# 安装Docker-CE
sudo apt-get update
sudo apt-get -y install docker-ce
# 启动docker
sudo systemctl enable docker
sudo systemctl start docker
# docker配置国内镜像源
sudo vim /etc/docker/daemon.json
{"registry-mirrors":["http://registry.docker-cn.com"]} # 在daemon.json文件中添加镜像源
# 重新加载daemon文件
sudo systemctl daemon-reload
# 重启docker服务
sudo systemctl restart docker
# 查看是否配置成功
sudo docker info
1.2 Docker 安装 Nginx 镜像
我们还是以收集 Nginx 日志为示例,所以第一步我们需要使用 Docker 安装 Nginx
如果你还不了解 ELK 日志管理是什么东东❓欢迎参考笔者之前写的博文 ELK 简介与安装使用 期待 一键三连
👍 💬 ⭐️
如果你还不了解 Nginx 日志是啥样子❓ 不清楚使用 ELK 收集 Nginx 的方式❓ 那就又到了广告时间啦,欢迎参考笔者之前写的博文 ELK 收集 Nginx 日志 期待 一键三连
👍 💬 ⭐️
# 查看Nginx镜像可用版本
docker search nginx
# 拉取最新版的 Nginx 镜像
docker pull nginx:latest
# 查看本地镜像,查看是否已成功安装了 Nginx
docker images
# 运行容器
docker run --name nginx-docker -p 8080:80 -d nginx
运行容器命令run
的参数说明:
- –name nginx-test:容器名称。
- -p 8080:80: 端口进行映射,将本地 8080 端口映射到容器内部的 80 端口。
- -d nginx: 设置容器在在后台一直运行。
运行成功之后,可以在本地使用浏览器访问8080号端口,验证Nginx是否启动成功http://localhost:8080
1.3 查看 Docker 镜像的日志文件
和直接本地安装软件一样,使用 Docker 镜像安装软件的日志被记录在 Docker 的指定目录中/var/lib/docker/containers/
,在对应镜像 ID 目录下保存该镜像的日志
以 Nginx 镜像为例,查看 Docker 中 Nginx 的日志文件
# 进入Docker镜像目录
cd /var/lib/docker/containers/
# 进入指定镜像(通过镜像ID识别)目录
cd 1cf162f8275bf1e3332c8864c923b722d433f6aa0a724cbd19c03c22c1375691
# 查看日志
tail -f 1cf162f8275bf1e3332c8864c923b722d433f6aa0a724cbd19c03c22c1375691-json.log
# 得到如下输出结果,以Json格式保存的日志数据
{"log":"/docker-entrypoint.sh: Configuration complete; ready for start up\n","stream":"stdout","time":"2021-08-02T08:48:32.073222187Z"}
{"log":"2021/08/02 08:48:32 [notice] 1#1: using the \"epoll\" event method\n","stream":"stderr","time":"2021-08-02T08:48:32.087638853Z"}
{"log":"2021/08/02 08:48:32 [notice] 1#1: nginx/1.21.1\n","stream":"stderr","time":"2021-08-02T08:48:32.087953162Z"}
{"log":"2021/08/02 08:48:32 [notice] 1#1: built by gcc 8.3.0 (Debian 8.3.0-6) \n","stream":"stderr","time":"2021-08-02T08:48:32.087971584Z"}
{"log":"2021/08/02 08:48:32 [notice] 1#1: OS: Linux 4.15.0-151-generic\n","stream":"stderr","time":"2021-08-02T08:48:32.087977404Z"}
{"log":"2021/08/02 08:48:32 [notice] 1#1: getrlimit(RLIMIT_NOFILE): 1048576:1048576\n","stream":"stderr","time":"2021-08-02T08:48:32.08806543Z"}
{"log":"2021/08/02 08:48:32 [notice] 1#1: start worker processes\n","stream":"stderr","time":"2021-08-02T08:48:32.088352968Z"}
02 Filebeat 根据容器 ID 收集 Docker 日志
使用 Filebeat 采集日志其实就是一个配置工作 让他知道到哪个目录或文件中去找 👀 日志内容就可以了
为 Filebeat 的输入添加 docker 类型的日志收集配置如下
# 输入配置
filebeat.inputs:
- type: docker # docker类型
containers.ids:
- '1cf162f8275bf1e3332c8864c923b722d433f6aa0a724cbd19c03c22c1375691'
setup.kibana:
host: "172.16.255.131:5601"
# 输出配置
output.elasticsearch:
hosts: ["172.16.255.131:9200"]
index: "docker-nginx-access-%{[agent.version]}-%{+yyyy.MM}"
# 模板配置
setup.template.name: "docker"
setup.template.pattern: "docker-*"
setup.template.enabled: false
setup.template.overwrite: true
03 Filebeat 收集多个 Docker 容器日志
打一个算什么,要的是能打一群❗️
使用 ELK 收集多个容器日志的配置方式也很简单
3.1 启动多个容器
先启动多个容器,本测试中启动两个 Nginx 镜像如下
# 列出当前Docker中的容器
docker ps
# 从容器创建一个新的镜像
docker commit nginx-docker nginx:v2
# 查看新创建的镜像
root@master:/etc/filebeat$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx v2 2ecdbbcdc6d7 24 seconds ago 133MB
nginx latest 08b152afcfae 11 days ago 133MB
# 启动该镜像
docker run --name nginx-v2 -p 8081:80 -d nginx:v2
# 查看启动的镜像
root@master:/etc/filebeat$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
0a8f97993dc6 nginx:v2 "/docker-entrypoint.…" 37 seconds ago Up 36 seconds 0.0.0.0:8081->80/tcp, :::8081->80/tcp nginx-v2
1cf162f8275b nginx "/docker-entrypoint.…" 4 hours ago Up 4 hours 0.0.0.0:8080->80/tcp, :::8080->80/tcp nginx-docker
3.2 配置 Filebeat 进行多容器日志收集
当Docker中存在多个容器时,采用依据容器ID的方式进行日志采集会带来很多问题:
- 容器的数量很多时需要添加多个容器ID,容器日志收集过于复杂
- 容器会被删除,如果容器被删除,配置在Filebeat中的容器ID变得冗余
多个Docker容器收集Filebeat配置官方文档:官方文档
# Docker类型输入配置
- type: docker
combine_partial: true
containers:
path: "/var/lib/docker/containers"
# stream: "stdout" # 只收集正常日志 stderr标识错误日志
ids:
- "*"
tags: ["docker"]
output.elasticsearch:
hosts: ["172.16.255.131:9200"]
indices:
- index: "nginx-access-%{[agent.version]}-%{+yyyy.MM}"
when.contains:
tags: "access"
- index: "nginx-error-%{[agent.version]}-%{+yyyy.MM}"
when.contains:
tags: "error"
# 添加如下索引配置
- index: "docker-%{[agent.version]}-%{+yyyy.MM}"
when.contains:
tags: "docker"
04 根据服务类型收集多个 Docker 容器日志
不仅能释放范围攻击,精准打击
也不在话下 🎯 🎯 🎯
下面就介绍怎么根据服务类型来收集容器日志
4.1 直接配置 Filebeat 收集多容器日志的缺陷
使用 03 节中的多容器日志收集的方法,将所有Docker容器的日志都统一收集在同一个索引中存储;这样可能带来无法区分不同服务类型容器日志的问题,本节考虑将Docker容器中不同服务类型的日志收集区分开。
📌一种思路:📌 和区分 Nginx 正常日志和错误日志一样,通过在采集的日志条目中的字段进行区分不同类型的日志,但是需要手动设置
其实收集的日志本质上来说还是文件,而这个日志是以容器ID-json.log
命名存放在默认目录下的Json格式的文件,但是每个容器的ID都是不一样的,所以为了区分不同服务运行的不同容器,可以使用容器编排工具 docker-compose 通过给容器添加 labels
标签进行区分。
以此为基础,Filebeat 把容器当作普通 Json 格式来解析并传输到 ES 中。
4.2 安装与使用 docker-compose
如果你在问什么是 docker-compose
❓ 那就又到了广告时间啦,欢迎参考笔者之前写的博文 Docker Compose 容器编排基础使用 期待 一键三连
👍 💬 ⭐️
安装 docker-compose
这里使用 pip 安装 docker-compose
# 安装下载 pip
apt install python3-pip -y
pip3 install pip -U
# 更新库
apt-get update
# 升级 pip
pip install --upgrade pip
# 安装docker-compose
pip install docker-compose
# 检查是否安装成功
docker-compose -version
编排 docker-compose
编写 docker-compose,用两个Nginx模拟两个服务一个nginx服务一个db服务。创建配置文件 docker-compose.yml
root@master:/home/wang$ vim docker-compose.yml
在文件中编写如下内容
version: '3'
# 定义一个服务组,服务中包含哪些容器
services:
nginx:
# 容器名称
image: nginx:v2
# 设置labels
labels:
service: nginx
# logging设置增加labels.service
logging:
options:
labels: "services"
ports:
- "8081:80"
db:
image: nginx:latest
# 设置labels
labels:
service: db
# logging设置增加labels.service
logging:
options:
labels: "services"
ports:
- "8082:80"
启动 docker-compose
首先,关闭原先的容器并删除,因为他们会占用端口号
docker stop nginx-v2
docker stop nginx-docker
docker rm nginx-v2
docker rm nginx-docker
# 查看是否已经删除
docker ps -a
打开一个新窗口,启动 docker-compose,因为他是前台启动
docker-compose up
查看docker-compose根据编排创建的容器
root@master:/home/wang$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a02e09d7d62d nginx:latest "/docker-entrypoint.…" 5 minutes ago Up 5 minutes 0.0.0.0:8082->80/tcp, :::8082->80/tcp wang_db_1
b8705e247a70 nginx:v2 "/docker-entrypoint.…" 19 minutes ago Up 19 minutes 0.0.0.0:8081->80/tcp, :::8081->80/tcp wang_nginx_1
查看docker中Nginx镜像的日志可以看出,日志内容根据编排增加了labels
标签
4.3 配置 Filebeat 分服务收集 Docker 容器日志
使用容器编排工具 docker-compose 编排容器之后,可以看到 Docker 容器产生的日志中增加了labels
标签,在Filbeat中根据此标签区分不同服务。
另外值得注意的是,在本地保存的日志中可用于区分服务的标签com_docker_compose_service
和service
上有多级标签,完整标签为container.labels.com_docker_compose_service
或container.labels.service
。
进一步的说,可以看到 Dokcer容器日志的在本地保存时是以 Json 格式保存的,所以直接可以把他当成普通日志的方式,和收集 Nginx、Tomcat 等一样,采用type: log
的方式去收集 Docker 日志。
所以 Filebeat 的容器收集输入配置可以如下形式:
# ------------------------Docker-Services--------------------------------
- type: log
enabled: true
paths:
- /var/lib/docker/containers/*/*-json.log # 通配符*匹配容器ID,达到收集所有容器日志的目的
# type为log所以需要加上下面两行Json解析配置,否则日志被当成纯文本处理
json.keys_under_root: true
json.overwrite_keys: true
本测试还是基于 03 节中的容器日志收集配置为基础,对 Filebeat 增加配置如下
# 输入配置 保留原先配置不进行改变
- type: docker
combine_partial: true
containers:
path: "/var/lib/docker/containers"
# stream: "stdout" # 只收集正常日志 stderr标识错误日志
ids:
- "*"
# 输出配置
# ---------------------------- Elasticsearch Output ----------------------------
output.elasticsearch:
hosts: ["172.16.255.131:9200"]
indices:
- index: "docker-%{[agent.version]}-%{+yyyy.MM}"
when.contains:
tags: "docker"
# 增加如下几行索引配置,通过label标签判别不同服务
- index: "docker-nginx-%{[agent.version]}-%{+yyyy.MM}"
when.contains:
container.labels.service: "nginx" # nginx服务日志
- index: "docker-db-%{[agent.version]}-%{+yyyy.MM}"
when.contains:
container.labels.service: "db" # db服务日志
配置完成后重新启动 Filebeat,并在本地浏览器中访问8081和8082两个Nginx容器的端口,刷新页面向服务发送请求产生日志
systemctl restart filebeat
# 浏览器访问
http://172.16.255.131:8081
http://172.16.255.131:8081
使用 ES-head 查看容器日志被分服务收集如下图所示
4.4 配置 Filebeat 进一步区分不同容器服务的错误日志和正常日志
在 4.3 节成功分服务采集容器日志的基础上,进一步考虑将同一个服务的正常日志和错误日志区分开并分别存储。如下图所示,容器日志中stream
标签的内容区分了正常日志 stdout
和错误日志 stderr
。
为了在容器服务区分的基础上实现日志类型的区分,Filebeat 的输出配置中需要对索引配置进行多个条件限定,and
关系的条件只需要写在一起即可,对 Filebeat 输出配置如下
# 输出配置
# ---------------------------- Elasticsearch Output ----------------------------
output.elasticsearch:
hosts: ["172.16.255.131:9200"]
indices:
- index: "docker-nginx-access-%{[agent.version]}-%{+yyyy.MM}"
when.contains:
container.labels.service: "nginx"
stream: "stdout" # 进一步区分日志类型
- index: "docker-db-access%{[agent.version]}-%{+yyyy.MM}"
when.contains:
container.labels.service: "db"
stream: "stdout"
- index: "docker-nginx-error-%{[agent.version]}-%{+yyyy.MM}"
when.contains:
container.labels.service: "nginx"
stream: "stderr"
- index: "docker-db-error-%{[agent.version]}-%{+yyyy.MM}"
when.contains:
container.labels.service: "db"
stream: "stderr"
配置完成后删除之前的docker索引并重新启动 Filebeat,然后在本地浏览器中访问8081和8082两个Nginx容器的端口,刷新页面向服务发送请求产生日志
systemctl restart filebeat
# 浏览器访问
http://172.16.255.131:8081
http://172.16.255.131:8081
使用ES-head查看容器日志被分服务分类型收集如下图所示
参考资料
更多推荐
所有评论(0)