Docker 安全及日志管理

在多数情况下,启动 Docker 容器时都以 root 用户权限在运行。那么用户使用 root 权限都可以做什么呢?例如:访问所有信息、修改任何内容、关闭机器、结束进程以及安装各种软件等。容器的安全性问题的根源在于容器和宿主机共享内核。如果容器里的应用导致 Linux 内核崩溃,那么整个系统可能都会崩溃。与虚拟机是不同的,虚拟机并没有与主机共享内核,虚拟机崩溃一般不会导致宿主机崩溃。本章将围绕 Docker 安全相关的问题进行介绍。

目录

一、Docker 安全相关介绍

1.1、Docker 容器与虚拟机的区别 

1)隔离与共享 

2)性能与损耗 

1.2、Docker 存在的安全问题 

1)Docker 自身漏洞 

2)Docker 源码问题 

1.3、Docker 架构缺陷与安全机制 

1)容器之间的局域网攻击 

2)DDoS 攻击资源耗尽 

3)有漏洞的系统调用 

4)共享 root 用户权限

1.4、Docker 安全基线标准 

1)内核级别

2)主机级别 

3)网络级别 

4)镜像级别 

5)容器级别 

6) 其他设置

二、容器相关的常用安全配置方法 

2.1、容器最小化 

2.2、DockerRemoteAPI 访问控制 

2.3、镜像安全

2.4、DockerClient 端与 Dockerdaemon 的通信安全 

2.5、Docker Bench for Security 介绍

三、Cgroup 资源配置方法 

3.1、使用 Stress 工具测试 CPU 和内存 

3.2、CPU 周期限制 

3.3、CPUCore 控制 

3.4、内存限制 

3.5、BlockIO 的限制 

3.6、bps 和 iops 的限制 

四、案例:基于 Docker 环境部署 ELKF 日志分析系统 

4.1、知识点介绍 

1)ELK(Elasticsearch、Logstash、Kibana) 

2)什么是 Filebeat 

3)Docker 日志管理缺陷 

4.2、案例环境 

1)案例实验环境 

2)案例需求 

3)案例实现思路 

4.3、案例实施 

1)系统环境准备 

2)基于 Dockerfile 构建 Elasticsearch 镜像 

3)基于 Dockerfile 构建 kibana 镜像 

4)基于 Dockerfile 构建 Logstash 镜像 

5)基于 Dockerfile 构建 Filebeat 镜像 

6)启动 nginx 容器作为日志输入源 

7)启动 Filebeat+ELK 日志收集环境 

8)kibana Web 管理 

9)kibana 图示分析 

一、Docker 安全相关介绍

1.1、Docker 容器与虚拟机的区别 

1)隔离与共享 

虚拟机通过添加 Hypervisor 层,虚拟出网卡、内存、CPU 等虚拟硬件,再在其上建立虚拟机,每个虚拟机都有自己的系统内核。而 Docker 容器则是通过隔离的方式,将文件系统、 进程、设备、网络等资源进行隔离,再对权限、CPU 资源等进行控制,最终让容器之间互不影响,容器无法影响宿主机。容器与宿主机共享内核、文件系统、硬件等资源。 

2)性能与损耗 

与虚拟机相比,容器资源损耗要少。同样的宿主机下,能够建立容器的数量要比虚拟机多。但是,虚拟机的安全性要比容器稍好,要从虚拟机攻破到宿主机或其他虚拟机,需要先攻破 Hypervisor 层,这是极其困难的。而 docker 容器与宿主机共享内核、文件系统等资源,更有可能对其他容器、宿主机产生影响。

1.2、Docker 存在的安全问题 

1)Docker 自身漏洞 

作为一款应用 Docker 本身实现上会有代码缺陷。CVE 官方记录 Docker 历史版本共有超过 20 项漏洞,可参见 Docker 官方网站。黑客常用的攻击手段主要有代码执行、权限提升、信息泄露、权限绕过等。目前 Docker 版本更迭非常快,Docker 用户最好将 Docker 升级为最新版本。 

2)Docker 源码问题 

Docker 提供了 Docker hub,可以让用户上传创建的镜像,以便其他用户下载,快速搭建环境。但同时也带来了一些安全问题。例如下面三种方式: 

  • 黑客上传恶意镜像

如果有黑客在制作的镜像中植入木马、后门等恶意软件,那么环境从一开始就已经不安全 了,后续更没有什么安全可言。

  • 镜像使用有漏洞的软件

DockerHub 上能下载的镜像里面,75% 的镜像都安装了有漏洞的软件。所以下载镜像后,需要检查里面软件的版本信息,对应的版本是否存在漏洞,并及时更新打上补丁。 

  • 中间人攻击篡改镜像 

镜像在传输过程中可能被篡改,目前新版本的 Docker 已经提供了相应的校验机制来预防这个问题。 

1.3、Docker 架构缺陷与安全机制 

Docker 本身的架构与机制就可能产生问题,例如这样一种攻击场景,黑客已经控制了宿主机上的一些容器,或者获得了通过在公有云上建立容器的方式,然后对宿主机或其他容器发起攻击。 

1)容器之间的局域网攻击 

主机上的容器之间可以构成局域网,因此针对局域网的 ARP 欺骗、嗅探、广播风暴等攻击方式便可以用上。所以,在一个主机上部署多个容器需要合理的配置网络,设置 iptable 规则。 

2)DDoS 攻击资源耗尽 

Cgroups 安全机制就是要防止此类攻击的,不要为单一的容器分配过多的资源即可避免此类问题。 

3)有漏洞的系统调用 

Docker 与虚拟机的一个重要的区别就是 Docker 与宿主机共用一个操作系统内核。一旦宿主内核存在可以越权或者提权漏洞,尽管 Docker 使用普通用户执行,在容器被入侵时, 攻击者还可以利用内核漏洞跳到宿主机做更多的事情。 

4)共享 root 用户权限

如果以 root 用户权限运行容器,容器内的 root 用户也就拥有了宿主机的 root 权限。 

1.4、Docker 安全基线标准 

根据 Docker 官方文档整理,下面从内核、主机、网络、镜像、容器以及其它等 6 个方面总结 Docker 安全基线标准。 

1)内核级别

  1. 及时更新内核。
  2. UserNameSpace(容器内的 root 权限在容器之外处于非高权限状态)。
  3. Cgroups(对资源的配额和度量)。
  4. SELiux/AppArmor/GRSEC(控制文件访问权限)。
  5. Capability(权限划分)。
  6. Seccomp(限定系统调用)。
  7. 禁止将容器的命名空间与宿主机进程命名空间共享。 

2)主机级别 

  1. 为容器创建独立分区。
  2. 仅运行必要的服务。
  3. 禁止将宿主机上敏感目录映射到容器。
  4. 对 Docker 守护进程、相关文件和目录进行审计。
  5. 设置适当的默认文件描述符数。
  6. 用户权限为 root 的 Docker 相关文件的访问权限应该为 644 或者更低权限。
  7. 周期性检查每个主机的容器清单,并清理不必要的容器。 

3)网络级别 

  1. 通过 iptables 设定规则实现禁止或允许容器之间网络流量。
  2. 允许 Dokcer 修改 iptables。
  3. 禁止将 Docker 绑定到其他 IP/Port 或者 UnixSocket。
  4. 禁止在容器上映射特权端口。
  5. 容器上只开放所需要的端口。
  6. 禁止在容器上使用主机网络模式。 

若宿主机有多个网卡,将容器进入流量绑定到特定的主机网卡上。

4)镜像级别 

  1. 创建本地镜像仓库服务器。
  2. 镜像中软件都为最新版本。
  3. 使用可信镜像文件,并通过安全通道下载。
  4. 重新构建镜像而非对容器和镜像打补丁。
  5. 合理管理镜像标签,及时移除不再使用的镜像。
  6. 使用镜像扫描。
  7. 使用镜像签名。 

5)容器级别 

  1. 容器最小化,操作系统镜像最小集。
  2. 容器以单一主进程的方式运行。
  3. 禁止 privileged 标记使用特权容器。
  4. 禁止在容器上运行 ssh 服务。
  5. 以只读的方式挂载容器的根目录系统。
  6. 明确定义属于容器的数据盘符。
  7. 通过设置 on-failure 限制容器尝试重启的次数。
  8. 限制在容器中可用的进程树,以防止 fork bomb。 

6) 其他设置

  1. 定期对宿主机系统及容器进行安全审计。
  2. 使用最少资源和最低权限运行容器。
  3. 避免在同一宿主机上部署大量容器,维持在一个能够管理的数量。
  4. 监控 Docker 容器的使用,性能以及其他各项指标。
  5. 增加实时威胁检测和事件响应功能。
  6. 使用中心和远程日志收集服务。 

二、容器相关的常用安全配置方法 

Docker 安全规则其实属于 Docker 安全基线的具体实现,对于 Docker 官方提出的方案,本章会直接给出实现方式。而对于第三方或者业界使用的方案,则只是介绍基本规则。 

2.1、容器最小化 

如果仅在容器中运行必要的服务,像 SSH 等服务是不能轻易开启去连接容器的。通常使用以下方式来进入容器。 

[root@centos7-13 ~]# docker exec -it mynginx /bin/bash

2.2、DockerRemoteAPI 访问控制 

Docker 的远程调用 API 接口存在未授权访问漏洞,至少应限制外网访问。建议使用 Socket 方式访问。首先在宿主机上监听内网 ip,docker daemon 启动方式如下。 

服务端 192.168.23.213 面操作

[root@centos7-13 ~]# systemctl stop docker
[root@centos7-13 ~]# dockerd -H unix:///var/run/docker.sock -H tcp://192.168.23.213:2375

然后在客户端 192.168.23.214 上面访问

[root@centos7-14 ~]# docker -H tcp://192.168.23.213:2375 images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
nginx               latest              e784f4560448        3 weeks ago         188MB

可以看到,服务端打开 API 接口后,从客户端远程访问服务端,可以对服务端上的 Docker 上面的资源进行操作

由于上面的操作是临时的,想要永久开启,修改配置文件如下 

[root@centos7-13 ~]# vim /usr/lib/systemd/system/docker.service
ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock -H tcp://192.168.23.213  //在此行后面添加 -H tcp://192.168.23.213

[root@centos7-13 ~]# systemctl daemon-reload
[root@centos7-13 ~]# systemctl start docker

2.3、镜像安全

下图是 Docker 镜像安全扫描原理图,在镜像仓库客户端使用证书认证,对下载的镜像进行检查。通过与 CVE 数据库同步扫描镜像,一旦发现漏洞则通知用户处理,或者直接阻止镜像继续构建。 

 Docker 镜像扫描安全原理图

如果公司使用的是自己的镜像源,可以跳过此步;否则,至少需要验证 baseimage 的 md5 等特征值,确认一致后再基于 baseimage 进一步构建。

一般情况下,要确保只从受信任的库中获取镜像,并且不要使用--insecure-registry=[] 参数。 

2.4、DockerClient 端与 Dockerdaemon 的通信安全 

按照 Docker 官方的说法,为了防止链路劫持、会话劫持等问题导致 Docker 通信时被中间人攻击,c/s 两端应该通过加密方式通讯。 

  • 配置证书-server上面操作 
[root@centos7-13 ~]# mkdir -p /path/to  //创建一个目录
[root@centos7-13 ~]# cd /path/to/  //进入目录 
[root@centos7-13 to]# openssl genrsa -aes256 -out ca-key.pem 4096  //创建根证书的秘钥文件
Generating RSA private key, 4096 bit long modulus
..........................................................................................................................................................................................................++
.......................................................++
e is 65537 (0x10001)
Enter pass phrase for ca-key.pem:  //设置一个密码:cisco@123
Verifying - Enter pass phrase for ca-key.pem:  //确认密码:cisco@123
[root@centos7-13 to]# openssl req -new -x509 -days 365 -key ca-key.pem -sha256 -subj "/CN=*" -out ca.pem  //生成根证书
Enter pass phrase for ca-key.pem:  //输入刚才创建的密码
[root@centos7-13 to]# ls
ca-key.pem  ca.pem
[root@centos7-13 to]# openssl genrsa -out server-key.pem 4096  //生产服务器证书的秘钥
Generating RSA private key, 4096 bit long modulus
...................++
.......................................................................................................................................++
e is 65537 (0x10001)

[root@centos7-13 to]# openssl req -new -sha256 \  //服务器证书的签发
>     -key server-key.pem \
>     -subj "/C=CN/OU=sz/O=sz/CN=CN" \
>     -reqexts SAN \
>     -config <(cat /etc/pki/tls/openssl.cnf \
>         <(printf "\n[SAN]\nsubjectAltName=DNS:*.kgc.com")) \
>     -out server.csr
[root@centos7-13 to]# openssl x509 -req -days 365 \
>     -in server.csr -out server-cert.pem \
>     -CA ca.pem -CAkey ca-key.pem -CAcreateserial \
>     -extensions SAN \
>     -extfile <(cat /etc/pki/tls/openssl.cnf <(printf "[SAN]\nsubjectAltName=DNS:*.kgc.com"))
Signature ok
subject=/C=CN/OU=sz/O=sz/CN=CN
Getting CA Private Key
Enter pass phrase for ca-key.pem:  //输入密码:cisco@123
[root@centos7-13 to]# ls
ca-key.pem  ca.pem  ca.srl  server-cert.pem  server.csr  server-key.pem
[root@centos7-13 to]# openssl genrsa -out key.pem 4096
Generating RSA private key, 4096 bit long modulus
............................++
.......................................................................................................++
e is 65537 (0x10001)
[root@centos7-13 to]# openssl req -subj "/CN=client" -new -key key.pem -out client.csr
[root@centos7-13 to]# echo extendedKeyUsage=clientAuth > extfile.cnf
[root@centos7-13 to]# openssl x509 -req -days 1000 -sha256 -in client.csr -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out cert.pem -extfile extfile.cnf
Signature ok
subject=/CN=client
Getting CA Private Key
Enter pass phrase for ca-key.pem:
[root@centos7-13 to]# ls
ca-key.pem  ca.pem  ca.srl  cert.pem  client.csr  extfile.cnf  key.pem  server-cert.pem  server.csr  server-key.pem
  • 配置 Docker 启动服务 
[root@centos7-13 to]# vim /lib/systemd/system/docker.service 
......//省略部分内容
ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock --tlsverify --tlscacert=/path/to/ca.pem --tlscert=/path/to/server-cert.pem --tlskey=/path/to/server-key.pem -H tcp://0.0.0.0:2376  //在此行后面加上 --tlsverify --tlscacert=/path/to/ca.pem --tlscert=/path/to/server-cert.pem --tlskey=/path/to/server-key.pem -H tcp://0.0.0.0:2376
......//省略部分内容
[root@centos7-13 to]# systemctl daemon-reload
[root@centos7-13 to]# systemctl restart docker
  • 复制证书到 client 端 
[root@centos7-13 to]# scp ca.pem root@192.168.23.214:/etc/docker/
[root@centos7-13 to]# scp cert.pem root@192.168.23.214:/etc/docker/
[root@centos7-13 to]# scp key.pem root@192.168.23.214:/etc/docker/
  •  客户端配置
[root@centos7-14 ~]# vim /etc/hosts
......//省略部分内容
192.168.23.213 master  master.kgc.com
  • 验证 
[root@centos7-14 ~]# cd /etc/docker/
[root@centos7-14 docker]# docker --tlsverify --tlscacert=ca.pem --tlscert=cert.pem --tlskey=key.pem -H tcp://master.kgc.com:2376 images
REPOSITORY                      TAG                 IMAGE ID            CREATED             SIZE
127.0.0.1/kgc/nginx             v1                  e784f4560448        3 weeks ago         188MB
nginx                           latest              e784f4560448        3 weeks ago         188MB
goharbor/redis-photon           v2.3.1              4a0d49a4ece0        2 years ago         191MB


[root@centos7-14 docker]# docker --tlsverify --tlscacert=ca.pem --tlscert=cert.pem --tlskey=key.pem -H tcp://master.kgc.com:2376 ps -a
CONTAINER ID        IMAGE                                  COMMAND                  CREATED             STATUS                            PORTS                       NAMES
4fd14b0e035d        goharbor/nginx-photon:v2.3.1           "nginx -g 'daemon of…"   25 hours ago        Restarting (1) 47 seconds ago                                 nginx
4fb8d9745905        goharbor/harbor-jobservice:v2.3.1      "/harbor/entrypoint.…"   25 hours ago        Up 4 seconds (health: starting)                               harbor-jobservice
4a9149271f2f        goharbor/harbor-core:v2.3.1            "/harbor/entrypoint.…"   25 hours ago        Exited (137) 10 minutes ago                                   harbor-core

2.5、Docker Bench for Security 介绍

Docker Bench for Security 是一个脚本,它是在生产环境中常见的测试检查部署 Docker 容器的最佳安全实践,测试都是自动化的,受 CIS Docker 1.13 基准的启发而来。 

要使用 docker-slim,从 Github 下载其二进制文件。二进制文件可用于 Linux 和 Mac。下载二进制文件后,将其添加到环境变量 PATH 中。 

[root@centos7-13 ~]# ls | grep docker
docker-bench-security-master.zip
[root@centos7-13 ~]# unzip docker-bench-security-master.zip 
[root@centos7-13 ~]# cd docker-bench-security-master
[root@centos7-13 docker-bench-security-master]# sh docker-bench-security.sh 
# --------------------------------------------------------------------------------------------
# Docker Bench for Security v1.3.6
#
# Docker, Inc. (c) 2015-2024
#
# Checks for dozens of common best-practices around deploying Docker containers in production.
# Based on the CIS Docker Benchmark 1.3.1.
# --------------------------------------------------------------------------------------------

Initializing 2024-05-31T16:27:46+08:00


Section A - Check results

[INFO] 1 - Host Configuration
[INFO] 1.1 - Linux Hosts Specific Configuration
WARNING: bridge-nf-call-iptables is disabled
WARNING: bridge-nf-call-ip6tables is disabled
[WARN] 1.1.1 - Ensure a separate partition for containers has been created (Automated)
[INFO] 1.1.2 - Ensure only trusted users are allowed to control Docker daemon (Automated)
[INFO]       * Users: 
[WARN] 1.1.3 - Ensure auditing is configured for the Docker daemon (Automated)
[WARN] 1.1.4 - Ensure auditing is configured for Docker files and directories -/run/containerd (Automated)
[WARN] 1.1.5 - Ensure auditing is configured for Docker files and directories - /var/lib/docker (Automated)
[WARN] 1.1.6 - Ensure auditing is configured for Docker files and directories - /etc/docker (Automated)
[WARN] 1.1.7 - Ensure auditing is configured for Docker files and directories - docker.service (Automated)
[INFO] 1.1.8 - Ensure auditing is configured for Docker files and directories - containerd.sock (Automated)
[INFO]        * File not found
[WARN] 1.1.9 - Ensure auditing is configured for Docker files and directories - docker.socket (Automated)
[INFO] 1.1.10 - Ensure auditing is configured for Docker files and directories - /etc/default/docker (Automated)
[INFO]        * File not found
[INFO] 1.1.11 - Ensure auditing is configured for Dockerfiles and directories - /etc/docker/daemon.json (Automated)
[INFO]        * File not found
[WARN] 1.1.12 - 1.1.12 Ensure auditing is configured for Dockerfiles and directories - /etc/containerd/config.toml (Automated)
[INFO] 1.1.13 - Ensure auditing is configured for Docker files and directories - /etc/sysconfig/docker (Automated)
[INFO]        * File not found
[WARN] 1.1.14 - Ensure auditing is configured for Docker files and directories - /usr/bin/containerd (Automated)
[WARN] 1.1.15 - Ensure auditing is configured for Docker files and directories - /usr/bin/containerd-shim (Automated)
[WARN] 1.1.16 - Ensure auditing is configured for Docker files and directories - /usr/bin/containerd-shim-runc-v1 (Automated)
[WARN] 1.1.17 - Ensure auditing is configured for Docker files and directories - /usr/bin/containerd-shim-runc-v2 (Automated)
[WARN] 1.1.18 - Ensure auditing is configured for Docker files and directories - /usr/bin/runc (Automated)
......//省略部分内容

执行这个脚本可以检查宿主机内容器和镜像的安全 

该脚本的构建符合 POSIX 2004 标准,因此它应该可以在任何 Unix 平台上移植。 


三、Cgroup 资源配置方法 

Docker 通过 Cgroup 来控制容器使用的资源配额,包括 CPU、内存、磁盘三大方面, 基本覆盖了常见的资源配额和使用量控制。 

Cgroup 是 ControlGroups 的缩写,是 Linux 内核提供的一种可以限制、记录、隔离进程组所使用的物理资源(如 CPU、内存、磁盘 IO 等等) 的机制,被 LXC、docker 等很多项目用于实现进程资源控制。Cgroup 本身是提供将进程进行分组化管理的功能和接口的基础结构,I/O 或内存的分配控制等具体的资源管理是通过该功能来实现的。这些具体的资源管理功能称为 Cgroup 子系统,有以下几大子系统实现: 

  1. blkio:设置限制每个块设备的输入输出控制。例如:磁盘,光盘以及 usb 等等。
  2. CPU:使用调度程序为 cgroup 任务提供 CPU 的访问。
  3. cpuacct:产生 cgroup 任务的 CPU 资源报告。
  4. cpuset:如果是多核心的 CPU,这个子系统会为 cgroup 任务分配单独的 CPU 和内存。
  5. devices:允许或拒绝 cgroup 任务对设备的访问。
  6. freezer:暂停和恢复 cgroup 任务。
  7. memory:设置每个 cgroup 的内存限制以及产生内存资源报告。
  8. net_cls:标记每个网络包以供 cgroup 方便使用。
  9. ns:命名空间子系统。
  10. perf_event:增加了对每个 group 的监测跟踪的能力,可以监测属于某个特定的group 的所有线程以及运行在特定 CPU 上的线程。 

下面开始利用 Stress 压力测试工具来测试 CPU 和内存使用状况。 

3.1、使用 Stress 工具测试 CPU 和内存 

使用 Dockerfile 来创建一个基于 Centos 的 stress 工具镜像。 

[root@centos7-13 ~]# mkdir stress
[root@centos7-13 ~]# cd stress/
[root@centos7-13 stress]# vim Dockerfile
FROM centos:7.9.2009
MAINTAINER 5CC
RUN yum -y install wget && wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo && wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo && yum -y install stress

[root@centos7-13 stress]# docker build -t centos:stress .

使用如下命令创建容器,命令中的--cpu-shares 参数值不能保证可以获得 1 个 vcpu 或者多少 GHz 的 CPU 资源,它仅是一个弹性的加权值。 

[root@centos7-13 stress]# docker run -itd --cpu-shares 100 centos:stress

默认情况下,每个 Docker 容器的 CPU 份额都是 1024。单独一个容器的份额是没有意义的。只有在同时运行多个容器时,容器的 CPU 加权的效果才能体现出来。例如,两个容器 A、 B 的 CPU 份额分别为 1000 和 500,在 CPU 进行时间片分配的时候,容器 A 比容器 B 多一倍的机会获得 CPU 的时间片。但分配的结果取决于当时主机和其他容器的运行状态, 实际上也无法保证容器 A 一定能获得 CPU 时间片。比如容器 A 的进程一直是空闲的,那么容器 B 是可以获取比容器 A 更多的 CPU 时间片的。极端情况下,例如主机上只运行了一个容器,即使它的 CPU 份额只有 50,它也可以独占整个主机的 CPU 资源。 

Cgroups 只在容器分配的资源紧缺时,即在需要对容器使用的资源进行限制时,才会生效。因此,无法单纯根据某个容器的 CPU 份额来确定有多少 CPU 资源分配给它,资源分配结果取决于同时运行的其他容器的 CPU 分配和容器中进程运行情况。

可以通过 cpushare 可以设置容器使用 CPU 的优先级,比如启动了两个容器及运行查看 CPU 使用百分比。

[root@centos7-13 stress]# docker run -itd --name cpu512 --cpu-shares 512 centos:stress stress -c 10
[root@centos7-13 stress]# docker run -itd --name cpu1024 --cpu-shares 1024 centos:stress stress -c 10

使用 docker stats 命令查看容器资源占用情况 

[root@centos7-13 stress]# docker stats
CONTAINER ID        NAME                CPU %               MEM USAGE / LIMIT   MEM %               NET I/O             BLOCK I/O           PIDS
e9d6dc083c73        cpu1024             133.03%             336KiB / 1.934GiB   0.02%               656B / 0B           0B / 0B             11
f9fc78dff55f        cpu512              65.14%              332KiB / 1.934GiB   0.02%               656B / 0B           0B / 0B             11

从上面的结果可以看出该案例中开启了 10 个 stress 进程,目的是充分让系统资源变得紧张。只有这样竞争资源,设定的资源比例才可以显现出来。如果只运行一个进程,会自动分配到空闲的 CPU,这样比例就无法看出来。由于案例的环境不一样,可能导致上面容器中占用 CPU 百分比会不同。但是,从 cpushare 来看两个容器总比例一定会是 1:2。 

3.2、CPU 周期限制 

Docker 提供了--cpu-period、--cpu-quota 两个参数控制容器可以分配到的 CPU 时钟周期。 

  1. --cpu-period 是用来指定容器对 CPU 的使用要在多长时间内做一次重新分配。
  2. --cpu-quota 是用来指定在这个周期内,最多可以有多少时间用来跑这个容器。与 –cpu-shares 不同的是,这种配置是指定一个绝对值,容器对 CPU 资源的使用绝对不会超过配置的值。 

cpu-period 和 cpu-quota 的单位为微秒(μs)。cpu-period 的最小值为 1000 微秒,最大值为 1 秒(10^6 μs),默认值为 0.1 秒(100000 μs)。cpu-quota 的值默认为 -1,表示不做控制。cpu-period 和 cpu-quota 参数一般联合使用。 

例如:容器进程需要每 1 秒使用单个 CPU 的 0.2 秒时间,可以将 cpu-period 设置为1000000(即 1 秒),cpu-quota 设置为 200000(0.2 秒)。当然,在多核情况下,如果允许容器进程完全占用两个 CPU, 则可以将 cpu-period 设置为 100000( 即 0.1 秒), cpu-quota 设置为 200000(0.2 秒)。 

[root@centos7-13 ~]# docker run -itd --cpu-period 100000 --cpu-quota 200000 centos:stress
[root@centos7-13 ~]# docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
bf6f76212190        centos:stress       "/bin/bash"         41 seconds ago      Up 40 seconds                           vigorous_easley
[root@centos7-13 ~]# docker exec -it bf6f76212190 /bin/bash
[root@bf6f76212190 /]# cat /sys/fs/cgroup/cpu/cpu.cfs_period_us 
100000
[root@bf6f76212190 /]# cat /sys/fs/cgroup/cpu/cpu.cfs_quota_us  
200000

3.3、CPUCore 控制 

对多核 CPU 的服务器,Docker 还可以控制容器运行使用哪些 CPU 内核,即使用 –cpuset-cpus 参数。这对具有多 CPU 的服务器尤其有用,可以对需要高性能计算的容器进行性能最优的配置。 

  • 查看宿主机内核 
[root@centos7-13 ~]# cat /proc/cpuinfo | grep processor
processor	: 0
processor	: 1

可以看到,我的宿主机有两个内核,编号分别是 0 和 1 

执行以下命令表示创建的容器只能用 0 这个内核。

[root@centos7-13 ~]# docker run -itd --name cpu1 --cpuset-cpus 0 centos:stress

最终生成的 cgroup 的 CPU 内核配置如下: 

[root@centos7-13 ~]# docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
ab5688a8ffcc        centos:stress       "/bin/bash"         32 seconds ago      Up 31 seconds                           cpu1
[root@centos7-13 ~]# docker exec -it ab5688a8ffcc /bin/bash
[root@ab5688a8ffcc /]# cat /sys/fs/cgroup/cpuset/cpuset.cpus
0

可以看到,此容器只能使用宿主机的 0 号内核 

通过下面指令可以看到容器中进程与 CPU 内核的绑定关系,达到绑定 CPU 内核的目的。 

[root@centos7-13 ~]# docker exec ab5688a8ffcc taskset -c -p 1
pid 1's current affinity list: 0

3.4、内存限制 

与操作系统类似,容器可使用的内存包括两部分:物理内存和 Swap。 Docker 通过下面两组参数来控制容器内存的使用量。 

  • -m 或 --memory:设置内存的使用限额,例如 100M、1024M。
  • --memory-swap:设置 内存+swap 的使用限额。 

执行如下命令允许该容器最多使用 200M 的内存和 300M 的 swap。 

[root@centos7-13 ~]# docker run -itd --name test  -m 200M --memory-swap=300M centos:stress stress -c 10

查看 

[root@centos7-13 ~]# docker stats
CONTAINER ID        NAME                CPU %               MEM USAGE / LIMIT     MEM %               NET I/O             BLOCK I/O           PIDS
48071b89e132        test                199.11%             336KiB / 200MiB       0.16%               656B / 0B           0B / 0B             11

可以看到第四列,最多可以使用 200M 内存 

注意:如果让工作线程分配的内存超过 300M,分配的内存超过限额,stress 线程报错,容器退出。 

3.5、BlockIO 的限制 

默认情况下,所有容器能平等地读写磁盘,可以通过设置 --blkio-weight 参数来改变容器 block IO 的优先级。 

--blkio-weight 与 --cpu-shares 类似,设置的是相对权重值,默认为 500。在下面的例子中,容器 A 读写磁盘的带宽是容器 B 的两倍。 

[root@centos7-13 ~]# docker run -d --name container_A --blkio-weight 600 centos:stress stress -c 10
[root@centos7-13 ~]# docker exec -it container_A /bin/bash
[root@c380dbccf32d /]# cat /sys/fs/cgroup/blkio/blkio.weight
600

[root@centos7-13 ~]# docker run -d --name container_B --blkio-weight 300 centos:stress stress -c 10
[root@centos7-13 ~]# docker exec -it container_B /bin/bash
[root@82e691cd8502 /]# cat /sys/fs/cgroup/blkio/blkio.weight
300

3.6、bps 和 iops 的限制 

bps 是 byte per second,每秒读写的数据量。iops 是 io per second,每秒 IO 的次数。 

可通过以下参数控制容器的 bps 和 iops:

  • --device-read-bps,限制读某个设备的 bps。
  • --device-write-bps,限制写某个设备的 bps。
  • --device-read-iops,限制读某个设备的 iops。
  • --device-write-iops,限制写某个设备的 iops。 

下面的示例是限制容器写 /dev/sda 的速率为 5 MB/s。 

[root@centos7-13 ~]# docker run -d --name web01 --device-write-bps /dev/sda:5MB nginx
[root@centos7-13 ~]# docker exec -it web01 /bin/bash
root@d6568d1381f5:/# dd if=/dev/zero of=test bs=1M count=100 oflag=direct
100+0 records in
100+0 records out
104857600 bytes (105 MB, 100 MiB) copied, 20.0135 s, 5.2 MB/s

通过 dd 命令测试在容器中写磁盘的速度。因为容器的文件系统是在 host/dev/sda 上的,在容器中写文件相当于对 host /dev/sda 进行写操作。另外,oflag=direct 指定用 direct IO 方式写文件,这样 --device-write-bps 才能生效。 

结果表明限速 5MB/s 左右。

作为对比测试,如果不限速,结果如下。 

[root@centos7-13 ~]# docker run -d --name web02 nginx
[root@centos7-13 ~]# docker exec -it web02 /bin/bash
root@756587ec29b6:/# dd if=/dev/zero of=test bs=1M count=100 oflag=direct
100+0 records in
100+0 records out
104857600 bytes (105 MB, 100 MiB) copied, 0.193351 s, 542 MB/s

关于 iops 的用法和 bps 类似,可以查阅相关资料,本章将不再详细介绍。 

在前面课程中,已经详细介绍了 ELK 各个组件之间的关系,并且可以通过 ELK 收集简单的系统日志, 其中只有 Logstash、Elasticsearch 和 Kibana 实例。这种架构非常简单并且有缺陷。初学者可以搭建这个架构,了解 ELK 是如何工作的。本章基于 Docker + ELKF 架构详细介绍生产环境下的日志收集与分析。 

四、案例:基于 Docker 环境部署 ELKF 日志分析系统 

日志采集的工具有很多种,如 Fluentd、Flume、Logstash、Betas 等等。引入 Filebeat 作为日志搜集器,主要是为了解决 Logstash 开销大的问题。启动一个 Logstash 就需要消耗 500M 左右的内存,而 Filebeat 只需要 10 来 M 内存资源。常用的 ELK 日志采集方案中,大部分的做法就是将所有节点的日志内容通过 Filebeat 送到 Kafka 消息队列, 再使用 Logstash 集群读取消息队列内容, 根据配置文件进行过滤。然后将过滤之后的文件输送到 Elasticsearch 中,通过 Kibana 去展示。所以在企业中通常使用 Docker + ELKF 架构实现日志收集与分析。 

4.1、知识点介绍 

1)ELK(Elasticsearch、Logstash、Kibana) 

在前面课程中已经详细介绍过, 具体原理性知识点本章不再展开, 只会体现 Docker 构建 ELK 环境实现过程。 

2)什么是 Filebeat 

Filebeat 是 ELK 组件的新成员, 也是 Beat 成员之一。基于 Go 语言开发,无任何依赖,并且比 Logstash 更加轻量, 不会带来过高的资源占用, 非常适合安装在生产机器上。轻量意味着简单,Filebeat 并没有集成和 Logstash 一样的正则处理功能, 而是将收集的日志原样输出。 

以下是 Filebeat 的工作流程:当开启 Filebeat 程序的时候,它会启动一个或多个检测进程 (prospectors) 找到指定的日志目录或文件。对于探测器找出的每一个日志文件,Filebeat 启动读取进程(harvester)。每读取一个日志文件的新内容,便发送这些新的日志数据到处理程序(spooler)。最后,Filebeat 会发送数据到指定的地点(比如 logstash、elasticserach)。 

正是以上原因, 目前, Filebeat 已经完全替代了 Logstash 成为新一代的日志采集器。同时,鉴于它的轻量、安全等特点,越来越多人开始使用它。 

本节将详细讲解如何部署基于 Filebeat 的 ELK 集中式日志分析系统,具体架构如下图所示。 

 基于 ELKF 集群架构

3)Docker 日志管理缺陷 

ELK 架构适合于日志规模比较庞大的情况。但由于 Logstash 日志解析节点和 Elasticsearch 的负荷比较重,可将其配置为集群模式,以分担负荷。引入消息队列,均衡了网络传输,从而降低了网络闭塞, 尤其是丢失数据的可能性, 但依然存在 Logstash 占用系统资源过多的问题。

4.2、案例环境 

1)案例实验环境 

主机 操作系统 主机名 / IP 地址 主要软件及版本 硬件要求
服务器 CentOS 7.9-x86_64 localhost / 192.168.23.213 Docker-ce-19.03.15 4G内存

2)案例需求 

  1. 利用 ELKF 收集容器里面的日志。
  2. 通过 Kibana 将收集到日志做图表分析。 

3)案例实现思路 

  1. 准备系统环境。
  2. 构建 ELKF 组件镜像。
  3. 创建 ELKF 容器收集容器里面的 Nginx 日志。
  4. 创建 Kibana 图形展示。 

4.3、案例实施 

基于 Docker 环境部署 ELKF 日志分析系统,实现日志分析功能。 

1)系统环境准备 

  • 安装 Docker
[root@localhost ~]# yum install -y yum-utils device-mapper-persistent-data lvm2  //安装必要的一些系统工具
[root@localhost ~]# yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo  //添加 Docker 源
[root@localhost ~]# yum -y install docker-ce-19.03.15 docker-ce-cli-19.03.15  //安装 Docker
[root@localhost ~]# mkdir -p /etc/docker
[root@localhost ~]# vim /etc/docker/daemon.json  //添加阿里的镜像加速器
{
  "registry-mirrors": ["https://z1qbjqql.mirror.aliyuncs.com"]
}
[root@localhost ~]# systemctl daemon-reload
[root@localhost ~]# systemctl enable --now docker
  • 创建所需要的映射目录 
[root@localhost ~]# mkdir -p /var/log/Elasticsearch
[root@localhost ~]# chmod -R 777 /var/log/Elasticsearch
  • 修改系统参数 
[root@localhost ~]# vim /etc/sysctl.conf
......//省略部分内容
vm.max_map_count=655360  //最后添加此行
[root@localhost ~]# sysctl -p
[root@localhost ~]# vim /etc/security/limits.conf
......//省略部分内容
文件最后添加以下几行
* soft nofile 65535
* hard nofile 65535
* soft nproc 65535
* hard nproc 65535
* soft memlock unlimited
* hard memlock unlimited
  • 单独创建 ELK-kgc 网络桥接 
[root@localhost ~]# docker network create ELK-kgc
151cae1aaecbcf04837913cf434d11365222bb446505f2382804b78cf61d5c14
[root@localhost ~]# docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
151cae1aaecb        ELK-kgc             bridge              local
961fcb574f8a        bridge              bridge              local
27f5ea461abe        host                host                local
56f4a5370c69        none                null                local

2)基于 Dockerfile 构建 Elasticsearch 镜像 

  • 创建 Elasticsearch 工作目录 
[root@localhost ~]# mkdir -p /root/ELK/Elasticsearch
[root@localhost ~]# cd /root/ELK/Elasticsearch/
  • 上传 Elasticsearch 的源码包和 Elasticsearch 配置文件到 /root/ELK/Elasticsearch 目录下, 所需文件如下。 
[root@localhost Elasticsearch]# ll
总用量 27872
-rw-r--r-- 1 root root 28535876 5月  15 2018 elasticsearch-6.1.0.tar.gz
-rw-r--r-- 1 root root     3017 5月  15 2018 elasticsearch.yml
  • 编写 Elasticsearch 的 Dockerfile 文件 
[root@localhost Elasticsearch]# vim Dockerfile
FROM centos:7.9.2009
MAINTAINER shikun.zhou@bdqn.cn
RUN yum -y install java-1.8.0-openjdk vim telnet lsof
ADD elasticsearch-6.1.0.tar.gz /usr/local/
RUN cd /usr/local/elasticsearch-6.1.0/config
RUN mkdir -p /data/behavior/log-node1
RUN mkdir /var/log/elasticsearch
COPY elasticsearch.yml /usr/local/elasticsearch-6.1.0/config/
RUN useradd es && chown -R es:es /usr/local/elasticsearch-6.1.0/
#RUN sed -i s/"#cluster.name: my-application"/"cluster.name: my-elk"/g /usr/local/elasticsearch-6.1.0/config/elasticsearch.yml
#RUN sed -i s/"#node.name: node-1"/"node.name: node-1"/g               /usr/local/elasticsearch-6.1.0/config/elasticsearch.yml
#RUN sed -i s/"#network.host: 192.168.0.1"/"network.host: 0.0.0.0"/g   /usr/local/elasticsearch-6.1.0/config/elasticsearch.yml
#RUN sed -i s/"#http.port: 9200"/"http.port: 9200"/g                   /usr/local/elasticsearch-6.1.0/config/elasticsearch.yml
RUN chmod +x /usr/local/elasticsearch-6.1.0/bin/*
RUN chown -R es:es /var/log/elasticsearch/
RUN chown -R es:es /data/behavior/log-node1/
RUN sed -i s/-Xms1g/-Xms2g/g /usr/local/elasticsearch-6.1.0/config/jvm.options
RUN sed -i s/-Xmx1g/-Xmx2g/g /usr/local/elasticsearch-6.1.0/config/jvm.options
EXPOSE 9200
EXPOSE 9300
CMD su es /usr/local/elasticsearch-6.1.0/bin/elasticsearch
#CMD ["/usr/local/elasticsearch-6.1.3/bin/elasticsearch","-d"]
  • 构建 Elasticsearch 镜像 
[root@localhost Elasticsearch]# docker build -t elasticsearch .
[root@localhost Elasticsearch]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED              SIZE
elasticsearch       latest              f34004aff932        About a minute ago   773MB
centos              7.9.2009            eeb6ee3f44bd        2 years ago          204MB

3)基于 Dockerfile 构建 kibana 镜像 

  • 创建 kibana 工作目录 
[root@localhost ~]# mkdir -p /root/ELK/kibana
[root@localhost ~]# cd /root/ELK/kibana/
  • 编写 kibana 的 Dockerfile 文件 
[root@localhost kibana]# vim Dockerfile
FROM centos:7.9.2009
MAINTAINER shikun.zhou@bdqn.cn
RUN yum -y install java-1.8.0-openjdk vim telnet lsof
ADD kibana-6.1.0-linux-x86_64.tar.gz /usr/local/
RUN cd /usr/local/kibana-6.1.0-linux-x86_64
RUN sed -i s/"#server.name: \"your-hostname\""/"server.name: kibana-hostname"/g /usr/local/kibana-6.1.0-linux-x86_64/config/kibana.yml
RUN sed -i s/"#server.port: 5601"/"server.port: 5601"/g /usr/local/kibana-6.1.0-linux-x86_64/config/kibana.yml
RUN sed -i s/"#server.host: \"localhost\""/"server.host: 0.0.0.0"/g /usr/local/kibana-6.1.0-linux-x86_64/config/kibana.yml
RUN sed -ri '/elasticsearch.url/ s/^#|"//g' /usr/local/kibana-6.1.0-linux-x86_64/config/kibana.yml
RUN sed -i s/localhost:9200/elasticsearch:9200/g /usr/local/kibana-6.1.0-linux-x86_64/config/kibana.yml
#RUN useradd es && chown -R es:es /usr/local/elasticsearch-6.1.3/
EXPOSE 5601
#CMD su es /usr/local/elasticsearch-6.1.3/bin/elasticsearch
CMD ["/usr/local/kibana-6.1.0-linux-x86_64/bin/kibana"]
  • 上传 kibana 的源码包 

上传 kibana 的源码包到 /root/ELK/kibana 目录下, 所需文件如下: 

[root@localhost kibana]# ll
总用量 64408
-rw-r--r-- 1 root root      983 6月  25 2022 Dockerfile
-rw-r--r-- 1 root root 65947685 5月  15 2018 kibana-6.1.0-linux-x86_64.tar.gz
  • 构建 kibana 镜像 
[root@localhost kibana]# docker build -t kibana .
[root@localhost kibana]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
kibana              latest              14bdf13e1cac        5 seconds ago       958MB
elasticsearch       latest              f34004aff932        9 minutes ago       773MB
centos              7.9.2009            eeb6ee3f44bd        2 years ago         204MB

4)基于 Dockerfile 构建 Logstash 镜像 

  • 创建 Logstash 工作目录 
[root@localhost ~]# mkdir -p /root/ELK/Logstash
[root@localhost ~]# cd /root/ELK/Logstash/
  • 编写 Logstash 的 Dockerfile 文件 
[root@localhost Logstash]# vim Dockerfile
FROM centos:7.9.2009
MAINTAINER shikun.zhou@bdqn.cn
RUN yum -y install java-1.8.0-openjdk vim telnet lsof
ADD logstash-6.1.0.tar.gz /usr/local/
RUN cd /usr/local/logstash-6.1.0
ADD run.sh /run.sh
RUN chmod 755 /*.sh
EXPOSE 5044
CMD ["/run.sh"]
  • 创建 CMD 运行的脚本文件 
[root@localhost Logstash]# vim run.sh
#!/bin/bash
/usr/local/logstash-6.1.0/bin/logstash -f /opt/logstash/conf/nginx-log.conf
  • 上传 Logstash 的源码包 

上传 logstash 的源码包到 /root/ELK/logstash 目录下, 所需文件如下。 

[root@localhost Logstash]# ll
总用量 107152
-rw-r--r-- 1 root root       255 6月  25 2022 Dockerfile
-rw-r--r-- 1 root root 109714065 5月  15 2018 logstash-6.1.0.tar.gz
-rw-r--r-- 1 root root        88 5月  15 2018 run.sh
  • 构建 Logstash 镜像 
[root@localhost Logstash]# docker build -t logstash .
[root@localhost Logstash]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
logstash            latest              8f9de11ce648        6 seconds ago       906MB
kibana              latest              14bdf13e1cac        6 minutes ago       958MB
elasticsearch       latest              f34004aff932        15 minutes ago      773MB
centos              7.9.2009            eeb6ee3f44bd        2 years ago         204MB
  • Logstash 配置文件详解 

logstash 功能非常强大,不仅仅是分析传入的文本,还可以作监控与告警之用。现在介绍 logstash 的配置文件及其使用经验。

logstash 默认的配置文件不需要修改,只需要启动的时候指定一个配置文件即可!比如 run.sh 脚 本中指定 /opt/logstash/conf/nginx-log.conf。注意:文件中包含了 input、filter、output 三部分,其中 filter 不是必须的。

[root@localhost ~]# mkdir -p /opt/logstash/conf
[root@localhost ~]# vim /opt/logstash/conf/nginx-log.conf
input {
  beats {
    port => 5044
  }
}

filter {
    if "www-bdqn-cn-pro-access" in [tags] {
        grok {
                match => {"message" => '%{QS:agent} \"%{IPORHOST:http_x_forwarded_for}\" - \[%{HTTPDATE:timestamp}\] \"(?:%{WORD:verb} %{NOTSPACE:request}(?: HTTP/%{NUMBER:http_version})?|-)\" %{NUMBER:response} %{NUMBER:bytes} %{QS:referrer} %{IPORHOST:remote_addr}:%{POSINT:port} %{NUMBER:remote_addr_response} %{BASE16FLOAT:request_time}'}
        }
    }
    urldecode {all_fields => true}
    date {
      match => [ "timestamp" , "dd/MMM/YYYY:HH:mm:ss Z" ]
    }
    useragent {
      source => "agent"
      target => "ua"
    }
}


output {
  if "www-bdqn-cn-pro-access" in [tags] {
    elasticsearch {
      hosts => ["elasticsearch:9200"]
      manage_template => false
      index => "www-bdqn-cn-pro-access-%{+YYYY.MM.dd}"
    }
}
}

 注意:使用 nginx-log.conf 文件拷贝时,match 最长的一行自动换行问题。

5)基于 Dockerfile 构建 Filebeat 镜像 

  • 创建 Filebeat 工作目录 
[root@localhost ~]# mkdir -p /root/ELK/Filebeat
[root@localhost ~]# cd /root/ELK/Filebeat/
  • 编写 Filebeat 的 Dockerfile 文件 
[root@localhost Filebeat]# vim Dockerfile
FROM centos:7.9.2009
MAINTAINER shikun.zhou@bdqn.cn
RUN yum -y install java-1.8.0-openjdk vim telnet lsof
ADD filebeat-6.1.0-linux-x86_64.tar.gz /usr/local/
RUN cd /usr/local/filebeat-6.1.0-linux-x86_64
RUN mv /usr/local/filebeat-6.1.0-linux-x86_64/filebeat.yml /root/
COPY filebeat.yml /usr/local/filebeat-6.1.0-linux-x86_64/
ADD run.sh /run.sh
RUN chmod 755 /*.sh
CMD ["/run.sh"]
  • 创建 CMD 运行的脚本文件 
[root@localhost Filebeat]# vim run.sh
#!/bin/bash
/usr/local/filebeat-6.1.0-linux-x86_64/filebeat -e -c /usr/local/filebeat-6.1.0-linux-x86_64/filebeat.yml
  • 上传 Filebeat 的源码包和 Filebeat 配置文件 

上传 Filebeat 的源码包和 Filebeat 配置文件到 /root/ELK/Filebeat 目录下,所需文件如下: 

[root@localhost Filebeat]# ll
总用量 11660
-rw-r--r-- 1 root root      392 6月  25 2022 Dockerfile
-rw-r--r-- 1 root root 11926942 5月  15 2018 filebeat-6.1.0-linux-x86_64.tar.gz
-rw-r--r-- 1 root root      183 6月  25 2022 filebeat.yml
-rw-r--r-- 1 root root      118 5月  15 2018 run.sh
  • 构建 Filebeat 镜像 
[root@localhost Filebeat]# docker build -t filebeat .
[root@localhost Filebeat]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
filebeat            latest              e4a4342ab6bb        4 seconds ago       757MB
logstash            latest              8f9de11ce648        4 hours ago         906MB
kibana              latest              14bdf13e1cac        4 hours ago         958MB
elasticsearch       latest              f34004aff932        4 hours ago         773MB
centos              7.9.2009            eeb6ee3f44bd        2 years ago         204MB
  • Filebeat 配置文件详解 
[root@localhost Filebeat]# cat filebeat.yml 
filebeat.prospectors:
- input_type: log
  paths:
    - /var/log/nginx/www.bdqn.cn-access.log
  tags: www-bdqn-cn-pro-access 
  clean_*: true

output.logstash:
  hosts: ["logstash:5044"]

每个 Filebeat 可以根据需求的不同拥有一个或多个 prospectors,其他配置信息含义如下: 

  1. input_type:输入的内容,主要为逐行读取的 log 格式与标准输入 stdin。
  2. paths:指定需要读取日志的路径,如果路径拥有相同的结构,则可以使用通配符。
  3. tags:为该路径的日志添加自定义 tags。
  4. clean_:Filebeat 在 /var/lib/filebeat/registry 下有一个注册表文件,它记录着 Filebeat 读取过的文件,还有已经读取的行数等信息。如果日志文件是定时分割,而且数量会 随之增加,那么该注册表文件也会慢慢增大。随着注册表文件的增大,会导致 Filebeat 检索的性能下降。
  5. output.logstash:定义内容输出的路径,这里主要输出到 Elasticsearch。 
  6. hosts:指定服务器地址。 

Filebeat 配置文件配置完成后,即可启动 Filebeat 容器服务。 

6)启动 nginx 容器作为日志输入源 

使用 docker run 命令启动一个 nginx 容器。 

[root@localhost ~]# docker run -itd -p 80:80 --network ELK-kgc -v /var/log/nginx:/var/log/nginx --name nginx-ELK nginx

本地目录 /var/log/nginx 必须挂载到 Filebeat 容器中,让 Filebeat 可以采集到日志目录。 

手动模拟生产环境几条日志文件作为 nginx 容器所产生的站点日志,同样注意拷贝的时候换行的问题。 

[root@localhost ~]# vim /var/log/nginx/www.bdqn.cn-access.log
"YisouSpider""106.11.155.156" - [18/Jul/2018:00:00:13 +0800] "GET /applier/position?gwid=17728&qyid=122257 HTTP/1.0" 200 9197 "-" 192.168.168.108:80 200 0.032
"-" "162.209.213.146" - [18/Jul/2018:00:02:11 +0800] "GET //tag/7764.shtml HTTP/1.0" 200 24922 "-" 192.168.168.108:80 200 0.074
"YisouSpider" "106.11.152.248" - [18/Jul/2018:00:07:44 +0800] "GET /news/201712/21424.shtml HTTP/1.0" 200 8821 "-" 192.168.168.110:80 200 0.097
"YisouSpider" "106.11.158.233" - [18/Jul/2018:00:07:44 +0800] "GET /news/201301/7672.shtml HTTP/1.0" 200 8666 "-" 192.168.168.110:80 200 0.111
"YisouSpider" "106.11.159.250" - [18/Jul/2018:00:07:44 +0800] "GET /news/info/id/7312.html HTTP/1.0" 200 6617 "-" 192.168.168.110:80 200 0.339
"Mozilla/5.0 (compatible;SemrushBot/2~bl;+http://www.semrush.com/bot.html)" "46.229.168.83" - [18/Jul/2018:00:08:57 +0800] "GET /tag/1134.shtml HTTP/1.0" 200 6030 "-" 192.168.168.108:80 200 0.079

7)启动 Filebeat+ELK 日志收集环境 

注意启动顺序和查看启动日志。 

  • 启动 Elasticsearch 
[root@localhost ~]# docker run -itd -p 9200:9200 -p 9300:9300 --network ELK-kgc -v /var/log/elasticsearch:/var/log/elasticsearch --name Elasticsearch elasticsearch
  • 启动 kibana 
[root@localhost ~]# docker run -itd -p 5601:5601 --network ELK-kgc --name kibana kibana
  • 启动 logstash 
[root@localhost ~]# docker run -itd -p 5044:5044 --network ELK-kgc -v /opt/logstash/conf:/opt/logstash/conf --name logstash logstash
  • 启动 filebeat 
[root@localhost ~]# docker run -itd --network ELK-kgc -v /var/log/nginx:/var/log/nginx --name Filebeat filebeat

8)kibana Web 管理 

因为 Kibana 的数据需要从 Elasticsearch 中读取,所以需要 Elasticsearch 中有数据才能创建索引,创建不同的索引区分不同的数据集。 

  • 浏览器输入 http://192.168.23.213:5601 访问 kibana 控制台。在 Management 中找到 Index patterns,单击进去可以看到类似以下图片中的界面,填写 www-bdqn-cn-pro-access-*作为索引,如下图所示。 

 添加索引

  • 在 Time Filter field name 选项框中选中 I don't want to use the Time Filter 这个选项,如下图所示。在 kibana 中,默认通过时间戳来排序。如果将日志存入 Elasticsearch 的时候没有指定 @timestamp 字段的内容,则 Elasticsearch 会分配接收到该日志时的时间作为该日志 @timestamp 的值。 

 选择时间过滤字段名

  • 单击”Create index pattern”按钮,创建 www-bdqn-cn-pro-access 索引后界面效果如下图所示。 

 索引创建完毕

  • 单击 Discover 标签,可能会看不到数据。需要将时间轴选中为“Thisyear”才可以看到的内容,显示的条数和日志的条数一致。具体时间轴的选择可以根据当前时间和日志里面的访问时间进行推算,如下图所示。 

 查看日志(1)

从上图中看到有数据但并不代表正常,因为数据都会通过 logstash 处理进入 Elasticsearch 中存储。但是不一定是通过上面编写的正则表达式处理后的数据,所以还需要观察左侧的字段是否含有正则表达式中所定义的字段。如果有,则说明正常,界面的效果如下图所示。 

查看日志(2) 

9)kibana 图示分析 

打开 kibana 的管理界面,单击 visualize 标签→Create a visualization,选择饼状图 pie, 添加索引 www-bdqn-cn-pro-access-*,点开 SplitSlices,选择 Terms,再从 Field 选择, http_x_forworded_for.keyword,最后点上面三角按钮即可生成访问最多的 5 个公网 IP 地址, 如下图所示。 

 Kinaba 图形展示分析内容

相关推荐

  1. Docker安全日志管理

    2024-06-06 15:46:02       75 阅读
  2. Docker】进阶之路:(十)Docker日志管理

    2024-06-06 15:46:02       42 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-06-06 15:46:02       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-06-06 15:46:02       100 阅读
  3. 在Django里面运行非项目文件

    2024-06-06 15:46:02       82 阅读
  4. Python语言-面向对象

    2024-06-06 15:46:02       91 阅读

热门阅读

  1. 常用系统命令/参数/工具统计

    2024-06-06 15:46:02       31 阅读
  2. MyBatis 入门详解

    2024-06-06 15:46:02       31 阅读
  3. 政府窗口服务第三方评估报告如何写

    2024-06-06 15:46:02       29 阅读
  4. 【Linux】System V 消息队列(不重要)

    2024-06-06 15:46:02       29 阅读
  5. 服务器硬件介绍(2)

    2024-06-06 15:46:02       33 阅读
  6. 电商运营-2024年6月1日

    2024-06-06 15:46:02       31 阅读