Rsyslog+kafka+ELK(单节点)部署

开源产品:Rsyslog、Kafka、ELK
处理流程为:Vm Rsyslog–> Rsyslog Server –omkafka–> Kafka –> Logstash –> Elasticsearch –> Kibana
ps:omkafka模块在rsyslog v8.7.0之后的版本才支持

环境:

ELK SERVER 10.10.27.123
Rsyslog Server 10.10.27.121
Rsyslog client 10.10.27.122

rsyslog日志收集

Rsyslog是高速的日志收集处理服务,它具有高性能、安全可靠和模块化设计的特点,能够接收来自各种来源的日志输入(例如:file,tcp,udp,uxsock等),并通过处理后将结果输出的不同的目的地(例如:mysql,mongodb,elasticsearch,kafka等),每秒处理日志量能够超过百万条。
Rsyslog作为syslog的增强升级版本已经在各linux发行版默认安装了,无需额外安装

1、rsyslog服务端

~]# cat /etc/rsyslog.conf 
# Provides UDP syslog reception
$ModLoad imudp
$UDPServerRun 514

# Provides TCP syslog reception
$ModLoad imtcp
$InputTCPServerRun 514

~]# cat /etc/rsyslog.d/default.conf
#### GLOBAL DIRECTIVES ####
# Use default timestamp format  # 使用自定义的日志格式
$ActionFileDefaultTemplate RSYSLOG_TraditionalFileFormat
$template myFormat,"%timestamp% %fromhost-ip% %syslogtag% %msg%\n"
$ActionFileDefaultTemplate myFormat

# 根据客户端的IP单独存放主机日志在不同目录,rsyslog需要手动创建
$template RemoteLogs,"/data/rsyslog/%fromhost-ip%/%fromhost-ip%_%$YEAR%-%$MONTH%-%$DAY%.log"
# 排除本地主机IP日志记录,只记录远程主机日志
:fromhost-ip, !isequal, "127.0.0.1" ?RemoteLogs
~]# systemctl restart rsyslog

为了把rsyslog server收集的日志数据导入到ELK中,需要在rsyslog server使用到omkafka的模块

~]# yum -y install rsyslog-kafka
~]# cat /etc//rsyslog.d/kafka.conf
# 加载omkafka和imfile模块
module(load="omkafka")
module(load="imfile")
 
# nginx template
template(name="SystemlogTemplate" type="string" string="%hostname%<-+>%syslogtag%<-+>%msg%\n")
 
# ruleset
ruleset(name="systemlog-kafka") {
    #日志转发kafka
    action (
        type="omkafka"
	template="SystemlogTemplate"
        topic="system-log"
        broker="10.10.27.123:9092"
    )
}

input(type="imfile" Tag="Systemlog" File="/data/rsyslog/*/*.log" Ruleset="systemlog-kafka"

~]# systemctl restart rsyslog

2、 Rsyslog客户端

~]# cat /etc/rsyslog.conf #追加一行
*.*	@10.10.27.121:514
#所有日志通过UDP传输给rsyslog server
~]# systemctl restart rsyslog

至此,rsyslog准备完毕,验证/data/rsyslog下是否产生日志文件

kafka搭建

1、搭建kafka依赖的zookeeper

~]# docker login
~]# docker pull wurstmeister/zookeeper
~]# mkdir -p /data/zookeeper
~]# docker run -d \
--name zookeeper \
--net=host \
-p 2181:2181 \
--restart always \
-v /data/zookeeper:/data/zookeeper \
-e ZOO_PORT=2181 \
-e ZOO_DATA_DIR=/data/zookeeper/data \
-e ZOO_DATA_LOG_DIR=/data/zookeeper/logs \
-e ZOO_MY_ID=1 \
-e ZOO_SERVERS="server.1=10.10.27.123:2888:3888" \
wurstmeister/zookeeper:latest

参数说明:
--net=host: 容器网络设置为 host, 能够和宿主机共享网络
-p 2181:2181: 容器的 2181 端口映射到宿主机的 2181 端口
-v /data/zookeeper:/data/zookeeper:容器的/data/zookeeper 目录挂载到宿主机的 /data/zookeeper 目录
ZOO_PORT:zookeeper 的运行端口
ZOO_DATA_DIR:数据存放目录
ZOO_DATA_LOG_DIR: 日志存放目录
ZOO_MY_ID:zk 的节点唯一标识
ZOO_SERVERS:zk 集群服务配置

如果需要部署zookeeper集群:其他 2 个节点同理部署, 只需要修改 ZOO_MY_ID; 节点 2:ZOO_MY_ID=2,节点 3:ZOO_MY_ID=3

验证

~]# docker exec -it zookeeper /bin/bash
bash # cd /opt/zookeeper-3.4.13/bin
bash # zkServer.sh status
ZooKeeper JMX enabled by default
Using config: /opt/zookeeper-3.4.13/bin/../conf/zoo.cfg
Mode: standalone

2、搭建kafka

~]# mkdir -p /data/kafka
~]# docker pull wurstmeister/kafka
~]# docker run -d \
--name kafka \
--net=host \
--restart always \
-v /data:/data \
-e KAFKA_BROKER_ID=1 \
-e KAFKA_PORT=9092 \
-e KAFKA_HEAP_OPTS="-Xms1g -Xmx1g" \
-e KAFKA_HOST_NAME=10.10.27.123 \
-e KAFKA_ADVERTISED_HOST_NAME=10.10.27.123 \
-e KAFKA_LOG_DIRS=/data/kafka \
-e KAFKA_ZOOKEEPER_CONNECT="10.10.27.123:2181" \
wurstmeister/kafka:latest

参数说明:
--net=host: 容器网络设置为 host, 能够和宿主机共享网络
-v /data:/data:容器的/data 目录挂载到宿主机的 /data 目录
KAFKA_BROKER_ID:kafka 的 broker 集群标识, 每台节点 broker 不一样
KAFKA_PORT:kafka 运行端口
KAFKA_HEAP_OPTS:kafka 启动时的 jvm 大小
KAFKA_HOST_NAME:kafka 主机名称,这里随便写,但是要与主机 IP 做 dns 映射
KAFKA_LOG_DIRS:kafka 日志存储目录
KAFKA_ZOOKEEPER_CONNECT:kafka 运行在 zk 里面,zk 提供的连接地址,集群的话写多个地址,逗号隔开

如果需要部署zookeeper集群:其他 2 个节点同理部署, 只需要修改 KAFKA_BROKER_ID、KAFKA_HOST_NAME、KAFKA_ADVERTISED_HOST_NAME 对应的值即可

验证

进入 kafka 容器
~]# docker exec -it kafka /bin/bash
bash-4.4# bin/kafka-topics.sh --list --zookeeper 10.10.27.123:2181
__consumer_offsets
log-api
system-log  #rsyslog自动创建的topic

ELK搭建

1、搭建elasticsearch

~]# docker pull elasticsearch:7.7.0
~]# mkdir /data/es/conf -p
~]# cd /data/es/conf
~]# vim elasticsearch.yml
cluster.name: es-cluster
network.host: 10.10.27.123
http.cors.enabled: true
http.cors.allow-origin: "*"
network.publish_host: 10.10.27.123
discovery.zen.minimum_master_nodes: 1
discovery.zen.ping.unicast.hosts: ["10.10.27.123"]
discovery.type: single-node

多节点集群使用以下配置:
~]# vim elasticsearch.yml
#集群名称,多个节点用一个名称
cluster.name: es-cluster
## es 1.0 版本的默认配置是 “0.0.0.0”,所以不绑定 ip 也可访问
network.host: 0.0.0.0
node.name: master
#跨域设置
http.cors.enabled: true
http.cors.allow-origin: "*"
node.master: true
node.data: true
network.publish_host: 192.168.1.140
discovery.zen.ping.unicast.hosts: ["192.168.1.140,192.168.1.142,192.168.1.147"]
discovery.zen.minimum_master_nodes: 1

~]# docker run -d \
--name=elasticsearch -p 9200:9200 -p 9300:9300 -p 5601:5601 \
--net=host \
--restart always \
-e ES_JAVA_OPTS="-Xms1g -Xmx1g" \   #启动内存设置
-v /data/es/conf/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml \
-v /data/es/data:/usr/share/elasticsearch/data \
elasticsearch:7.7.0

启动过程会有报错,提前做以下操作
~]# mkdir /data/es/data
~]# chmod u+x /data/es/data
~]# vim /etc/sysctl.conf
vm.max_map_count=655350
~]# sysctl -p

如果需要部署zookeeper集群:其他 2 个节点同样的部署思路,只需要修改 elasticsearch 的配置文件中的 node.name 和 network.publish_host

2、部署kibana

~]# docker pull daocloud.io/library/kibana:7.7.0
~]# mkdir -p /data/kibana/conf
~]# vi /data/kibana/conf/kibana.yml
server.port: 5601
server.host: "0.0.0.0"
# ES
elasticsearch.hosts: ["http://10.10.27.123:9200"]  
i18n.locale: "zh-CN"
xpack.security.enabled: false
ps:多集群可忽略此配置文件,使用默认即可

~]# docker run -d \
--restart always \
--name kibana \
--network=container:elasticsearch \   #容器网络要和连接的 es 容器共享网络
-v /data/kibana/config:/usr/share/kibana/config \
daocloud.io/library/kibana:7.7.0

3、部署logstash

~]# docker pull daocloud.io/library/logstash:7.7.0
~]# mkdir /data/logstash/conf -p
~]# vim logstash.conf
input{
   kafka{
        topics => ["system-log"]   #必须可前文的topic统一
        bootstrap_servers => ["10.10.27.123:9092"]
    }
}
output{
    elasticsearch {
        hosts => ["10.10.27.123:9200"]
        index => "system-log-%{+YYYY.MM.dd}"
        }
   stdout {
    codec => rubydebug
  }
}

~]# docker run -d \
--restart always \
--name logstash \
--net=host \
--link elasticsearch \
-v /data/logstash/conf/logstash.conf:/usr/share/logstash/pipeline/logstash.conf \
daocloud.io/library/logstash:7.7.0

kibana添加索引

 

微信截图_20240118175914 微信截图_20240118175924

镜像下载

由于中国下载docker镜像很慢,配置镜像仓库

--registry-mirror=https://registry.docker-cn.com

建议在本地电脑,比如win10中安装windows版docker,配置好上面镜像仓库地址(setting-Docker Engine),打开powershell进行下载打包镜像:

PS C:\Users\suixin> docker pull kibana:7.7.0
PS C:\Users\suixin> docker save -o kibana.gz kibana:7.7.0

然后上传到服务器导入:

# docker load -i kibana.gz

Mysql 8.0 关闭binlog日志

Mysql8.0默认开启binlog记录功能,导致磁盘空间占用很大,8.0关闭的方式跟之前5.x的不太一样。

1.清除binlog文件

$ mysql -u root -p
#进入数据库查看log_bin状态
mysql> show variables like ‘log_bin';
+—————+——-+
| Variable_name | Value |
+—————+——-+
| log_bin | ON |
+—————+——-+
1 row in set (0.01 sec)

#查看现有在用的binlog日志
mysql> show master logs;
+—————+————+———–+
| Log_name | File_size | Encrypted |
+—————+————+———–+
| binlog.000020 | 1073742151 | No |
| binlog.000021 | 1073747018 | No |
| binlog.000022 | 1073930151 | No |
| binlog.000023 | 1073733807 | No |
+—————+————+———–+
4 rows in set (0.03 sec)

#手动清除binlog日志
mysql> reset master;
Query OK, 0 rows affected (0.02 sec)

#退出mysql
mysql> \q

2.关闭

#编辑配置文件/etc/my.cnf,添加disable_log_bin,有些版本可能是:skip-log-bin
$ vim /etc/my.cnf
[mysqld]
#
# Remove leading # and set to the amount of RAM for the most important data
# cache in MySQL. Start at 70% of total RAM for dedicated server, else 10%.
# innodb_buffer_pool_size = 128M
#
# Remove the leading “# ” to disable binary logging
# Binary logging captures changes between backups and is enabled by
# default. It’s default setting is log_bin=binlog
disable_log_bin
#skip-log-bin

#重启mysql服务
$ service mysqld restart

$ mysql -u root -p
#再次进入数据库查看log_bin状态
mysql> show variables like ‘log_bin';
+—————+——-+
| Variable_name | Value |
+—————+——-+
| log_bin | OFF |
+—————+——-+
1 row in set (0.01 sec)

#查看binlog日志报错提醒没有开启binlog
mysql> show master logs;
ERROR 1381 (HY000): You are not using binary logging

3.清理binlog

除了使用reset master清理日志文件之外,还可以按照日期清理:

purge master logs before ‘2024-01-18 00:00:00′;

ELK日志系统架构:Elasticsearch、Logstash、Kibana

ElasticSearch 安装

1、下载 ElasticSearch,本文使用的版本为 5.5.1。

2、配置

path.data: /data/es #数据路径
path.logs: /data/logs/es #日志路径
network.host: 本机地址 #服务器地址
http.port: 9200 #端口

如果不修改配置的话,默认的数据和日志都位于elasticsearch文件夹下。

默认地址会使用 192.168.0.1 的地址,此时ElasticSearch运行于开发模式,只能从本机访问。如果修改为生产地址,就会进入生产模式,并且运行 bootstrap check 。

3、启动

./bin/elasticsearch

注意,elasticsearch 不能使用 root 用户启动,使用其他用户启动,要注意有文件夹的读写权限。

我在安装过程中还出现了下面几个警告信息

[2017-08-07T09:13:59,951][WARN ][o.e.b.JNANatives         ] unable to install syscall filter: 
java.lang.UnsupportedOperationException: seccomp unavailable: requires kernel 3.5+ with CONFIG_SECCOMP and CONFIG_SECCOMP_FILTER compiled in
    at org.elasticsearch.bootstrap.SystemCallFilter.linuxImpl(SystemCallFilter.java:350) ~[elasticsearch-5.5.1.jar:5.5.1]
    at org.elasticsearch.bootstrap.SystemCallFilter.init(SystemCallFilter.java:638) ~[elasticsearch-5.5.1.jar:5.5.1]
    at org.elasticsearch.bootstrap.JNANatives.tryInstallSystemCallFilter(JNANatives.java:245) [elasticsearch-5.5.1.jar:5.5.1]
    at org.elasticsearch.bootstrap.Natives.tryInstallSystemCallFilter(Natives.java:113) [elasticsearch-5.5.1.jar:5.5.1]
    at org.elasticsearch.bootstrap.Bootstrap.initializeNatives(Bootstrap.java:111) [elasticsearch-5.5.1.jar:5.5.1]
    at org.elasticsearch.bootstrap.Bootstrap.setup(Bootstrap.java:194) [elasticsearch-5.5.1.jar:5.5.1]
    at org.elasticsearch.bootstrap.Bootstrap.init(Bootstrap.java:351) [elasticsearch-5.5.1.jar:5.5.1]
    at org.elasticsearch.bootstrap.Elasticsearch.init(Elasticsearch.java:123) [elasticsearch-5.5.1.jar:5.5.1]
    at org.elasticsearch.bootstrap.Elasticsearch.execute(Elasticsearch.java:114) [elasticsearch-5.5.1.jar:5.5.1]
    at org.elasticsearch.cli.EnvironmentAwareCommand.execute(EnvironmentAwareCommand.java:67) [elasticsearch-5.5.1.jar:5.5.1]
    at org.elasticsearch.cli.Command.mainWithoutErrorHandling(Command.java:122) [elasticsearch-5.5.1.jar:5.5.1]
    at org.elasticsearch.cli.Command.main(Command.java:88) [elasticsearch-5.5.1.jar:5.5.1]
    at org.elasticsearch.bootstrap.Elasticsearch.main(Elasticsearch.java:91) [elasticsearch-5.5.1.jar:5.5.1]
    at org.elasticsearch.bootstrap.Elasticsearch.main(Elasticsearch.java:84) [elasticsearch-5.5.1.jar:5.5.1]
[2017-08-01T14:10:57,843][WARN ][o.e.b.BootstrapChecks    ] [VAfWGGZ] max file descriptors [65535] for elasticsearch process is too low, increase to at least [65536]
[2017-08-01T14:10:57,844][WARN ][o.e.b.BootstrapChecks    ] [VAfWGGZ] max number of threads [1024] for user [maserati] is too low, increase to at least [2048]
[2017-08-01T14:10:57,844][WARN ][o.e.b.BootstrapChecks    ] [VAfWGGZ] max virtual memory areas vm.max_map_count [65530] is too low, increase to at least [262144]
[2017-08-01T14:10:57,844][WARN ][o.e.b.BootstrapChecks    ] [VAfWGGZ] system call filters failed to install; check the logs and fix your configuration or disable system call filters at your own risk

针对文件描述符,调成 65536 ulimit -n 65536,如果提示没有权限,则可以在用户的 .bash_profile 中增加一行,退出用户重新登陆就可以。

针对 max number of threads 问题,修改 /etc/security/limits.d/90-nproc.conf 。

*          soft    nproc     2048
root       soft    nproc     unlimited

针对 max virtual memory areas ,修改 /etc/sysctl.conf。如果没有,就新增一行。

vm.max_map_count = 262144

针对 system_call_filter 可以,通过修改配置文件(elasticsearch.yml)关掉这个参数。

bootstrap.system_call_filter: false 

4、访问,出现下面的结果表示启动成功。

[root@iZ627x15h6pZ cloud]# curl http://localhost:9200
{
  "name" : "VAfWGGZ",
  "cluster_name" : "elasticsearch",
  "cluster_uuid" : "J9Tm5R2zRt2PkOSwtXj5Wg",
  "version" : {
    "number" : "5.5.1",
    "build_hash" : "19c13d0",
    "build_date" : "2017-07-18T20:44:24.823Z",
    "build_snapshot" : false,
    "lucene_version" : "6.6.0"
  },
  "tagline" : "You Know, for Search"
}

Logstash 安装

1、下载并解压 Logstash,本文用的 Logstash-5.5.1 版本

2、创建一个简单的配置文件 logstash_test.conf

input { stdin { } }
output {
  stdout { codec => rubydebug }
}

3、启动 logstash

./bin/logstash -f logstash_test.conf 

出现这些信息,表示启动成功了。

[2017-08-01T13:58:38,437][INFO ][logstash.pipeline        ] Pipeline main started
The stdin plugin is now waiting for input:
[2017-08-01T13:58:38,532][INFO ][logstash.agent           ] Successfully started Logstash API endpoint {:port=>9600}

4、与ElasticSearch配合。

Kibana 安装

1、下载 Kibana

2、修改配置

//启动端口 因为端口受限 所以变更了默认端口
server.port: 5601
//启动服务的ip
server.host: "本机ip"
//elasticsearch地址
elasticsearch.url: "http://localhost:9200”

3、启动程序

./bin/kibana

4、访问查看Kibana启动是否成功,并检索查看数据

http://localhost:5601

参考资料:
1、Download Logstash
2、ElasticSearch Download

rsyslog queue队列权威指南

实际上,队列在整个日志的生命周期中都存在,它是Rsyslog的核心,一般情况下,我们感觉不到它的存在;然而,从日志的产生到被处理的过程,都必须经过两个队列,一个是主消息队列(main message queue),另一个是动作队列(action queue)。通过下面的图片,可以理解得更加清楚:

[图片1]

从上图中可以看到,日志产生后,先经过预处理器然后就被压入main message queue等待后续的处理,在进入action queue之前,日志被解析器和过滤器处理,它们的作用是读取rsyslog.conf配置文件中设置的规则,和日志中的内容进行对比,然后发送到合适的action queue,一旦日志进入到这个action queue之后,就会从主消息队列中删除。

日志真正被处理的阶段发生在进入action queue之后,action processor(动作处理器)会从action queue中获取最先进入队列的日志进行处理,根据规则进行日志的输出,例如写入文件,录入数据库、发送到远程服务器,甚至是把它们丢弃。

rsyslog.conf中每一条规则的action都有一个action queue,这种queue默认类型是direct queue,但严格来说,它不属于队列,虽然名字中有queue字样。direct queue通常处理简单的行为,例如把日志写入本地文件。

在direct queue下,同一条日志如果被多个动作处理器消费,这个时候,同一条日志会被复制到各个动作队列中,那么可能会造成的现象是,当你使用discard丢弃日志的时候,会发现discard指令没有生效,原因是:discard指令丢弃的是原始日志的副本,而原始的日志会继续活动在原来的工作流中。

 
Copyright © 2008-2021 lanxinbase.com Rights Reserved. | 粤ICP备14086738号-3 |