移除旧的版本:
sudo yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-selinux \
docker-engine-selinux \
docker-engine
安装一些必要的系统工具:
sudo yum install -y yum-utils device-mapper-persistent-data lvm2
添加软件源信息:
sudo yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
更新 yum 缓存:
sudo yum makecache fast
安装 Docker-ce:
sudo yum -y install docker-ce
启动 Docker 后台服务:
sudo systemctl start docker
测试运行 hello-world
docker run hello-world
修改配置文件 vim /etc/sysctl.conf
tips:如果报错:vim: command not found 参照: https://www.jianshu.com/p/93fe144f5739
rpm -qa |grep vim
vim-minimal-7.0.109-6.el5
vim-common-7.0.109-7.2.el5
vim-enhanced-7.0.109-7.2.el5
#如果上面三条少了其中的某一条,就直接安装所有包
yum -y install vim*
添加或者修改 vm.max_map_count = 262144
使生效 sysctl -p
安装ELK有很多种方式,比如源码、rpm包,或docker;不过docker又分为了单个安装与ELK打包安装,我们通过docker打包安装,因为这样的方式相比来说最为简单,因为只需要下载镜像,然后运行起来就可以了
设置好加速地址之后,就可以开始拉取ELK镜像,参考命令如下:
docker pull sebp/elk
下载镜像之后可以使用docker的命令来验证是否成功,参考命令如下:
docker images
执行后docker返回结果如下
REPOSITORY TAG IMAGE ID CREATED SIZE
sebp/elk latest 99e6d3f782ad 2 months ago 2.06GB
hello-world latest fce289e99eb9 11 months ago 1.84kB
#在结果当中可以看出,ELK镜像已经下载下来,占用了将近2GB空间
运行此容器的时候,需要将宿主机的端口转发到该容器,其中ES端口为9200,kibana端口为5601,logbate端口为5044;
由于 docker 镜像是只读的,而容器又是随时创建删除,所以建议将配置文件和数据存放在宿主机,便于后期维护,因此还需要将宿主机目录挂载到容器当中。
先在宿主机创建挂载目录
cd /opt
mkdir elk-data
cd elk-data
mkdir conf
mkdir elasticsearch-data
mkdir logs
# 编辑nginx配置文件
vim /usr/local/nginx/conf/nginx.conf
1) 配置 nginx
下面是 nginx.conf 的配置内容:
#user root;
worker_processes 1;
#pid logs/nginx.pid;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
# 对日志格式化成json
log_format json '{"@timestamp":"$time_iso8601",'
'"@version":1,'
'"host":"$server_addr",'
'"client":"$remote_addr",'
'"size":$body_bytes_sent,'
'"responsetime":$request_time,'
'"domain":"$host",'
'"url":"$uri",'
'"status":"$status"}';
# 用于记录谁在什么时候做了什么
access_log /opt/elk-data/logs/access.log json;
server {
listen 0.0.0.0:80;
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
modsecurity on;
modsecurity_rules_file /usr/local/nginx/conf/modsecurity_includes.conf;
root html;
index index.html index.htm;
# proxy_pass http://127.0.0.1:8000
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}
测试 nginx 文件配置的正确性
/usr/local/nginx/sbin/nginx -t
出现下面这两行代码说明正确
Password:
nginx: the configuration file /usr/local/etc/nginx/nginx.conf syntax is ok
nginx: configuration file /usr/local/etc/nginx/nginx.conf test is successful
tips: 可以使用 ps aux|grep nginx 命令来查看nginx配置路径
2) logstash配置
logstash配置主要有三个地方要处理,首先是输入源在什么位置,然后是对数据进行过滤或者格式化,最后是需要将数据输出到什么地方;在下方的配置只做了其中两项,编辑配置文件命令参考如下:
修改宿主机刚才挂载的目录,在目录下创建conf目录,建立test.conf文件
vim /opt/elk-data/conf/test.conf
下面是 test.conf 的配置内容:
input {
file {
path => "/opt/logs/access.log" # 填写容器内部log文件路径
codec => "json"
}
}
output {
elasticsearch {
hosts => ["127.0.0.1:9200"]
}
stdout {
codec => rubydebug
}
}
3) 进入容器,启动logstash
前面已经将日志格式与logstash配置好,现在需要启动logstash开始收集日志,logstash挂载到容器内,需要先启动容器
docker run -p 5601:5601 -p 9200:9200 -p 5044:5044 -v /opt/elk-data/conf:/opt/conf -v /opt/elk-data/logs:/opt/logs -v /opt/elk-data/elasticsearch-data:/var/lib/elasticsearch -it -d --name elk sebp/elk
# 开启三个端口传递信息,挂载主机的三个路径下的所有文件,给容器重命名为elk,镜像为sebp/elk
启动logstash之前需要先进入容器里面,进入容器参考命令如下:
docker exec -it elk /bin/bash
删除02-beats-input.conf 关于ssl的三行设置,否则客户端需要另外配置证书相关配置项(每次重新创建容器都需要删除这三行设置)
vim /etc/logstash/conf.d/02-beats-input.con
需要关闭自动开启的 logstash,检查logstash,elasticsearch状态,保持elasticsearch开启,logstash关闭
service logstash stop
进入容器之后,需要启动logstash来收集数据,启动的时候需要带两个参数进去,第一个是logstash的数据暂存位置,第二个是使用的配置文件,因此构造的命令如下所示:
/opt/logstash/bin/logstash -f /opt/conf/test.conf --config.reload.automatic
#(如果配置文件有改动会自动加载)
复制会话,另起一个窗口请求nginx:
curl localhost:80
当数据导入之后,才可以使用kibana的图形化来查看数据了,所以首先确认一下ES中是否有数据,确认有数据后就可以进行绘图配置,配置完成之后就可以进行筛选日志等操作了。
当数据添加到ES服务器当中后,可以通过ES服务提供的URL来查看其中的数据,URL地址如下所示:
http://localhost:9200/_search?pretty
就会看到刚刚产生的日志内容,当看到total数量变大,并在下面的数据项中看到了nginx日志信息时,则代表导入数据成功了。
通过浏览器访问kibana,URL地址如下
http://127.0.0.1:5601/app/kibana#/management/kibana/index?_g=()
点击左侧导航栏的Discover链接,便可进入创建索引模式界面,可以选择索引查看相对应索引的数据
点击左侧导航栏的Management链接,点击页面Index Pattern链接,点击右上方Create index pattern,方框里面输入你创建的索引名字,点击Next step便创建kibana的索引完成,此时再次点击左侧导航栏的Discover链接,便可以看到刚才创建索引的一些视图,数据。
在图中有一个input输入框,可以在里面填写筛选所需要的关键词;如果没有筛选出结果,也可检查左侧的时间筛选项是否设置正确,默认显示最近十五分钟产生的数据 。
此处有对应的数据,说明收集成功。
filebeat 是用来转发和集中日志数据的轻量级服务。能监视指定的日志文件和位置。收集日志文件,并将它们转发到logstash或elasticsearch。
另装一个虚拟机作为客户端,上面的docker,logstash作为服务器。
部署流程:
filebeat文件配置:filebeat.yml
filebeat.inputs:
- type: log
enabled: true
paths:
- /usr/local/nginx/logs/access.log # 指定需要收集的日志文件的路径
fields:
indexname: nginx-access
fields:
host_ip: 192.168.194.5 #发送本机出口ip,便于服务器端方便筛选
output.logstash:
hosts: ["192.168.194.6:5044"] #指定日志服务器的ip:port
nginx文件配置(部分配置:json格式化,log存储路径):nginx.conf
log_format json '{"@timestamp":"$time_iso8601",'
'"@version":1,'
'"host":"$server_addr",'
'"client":"$remote_addr",'
'"size":$body_bytes_sent,'
'"responsetime":$request_time,'
'"domain":"$host",'
'"url":"$uri",'
'"status":"$status"}';
access_log /usr/local/nginx/logs/access.log json;
nginx改了配置需要重启下:
/usr/local/nginx/sbin/nginx -s reload
logstash文件配置:
input {
beats {
port => 5044 # 设置专用端口用于接收各个来源的日志
}
}
output {
elasticsearch {
index => "log_%{+YYYY.MM.dd}"
hosts => ["127.0.0.1:9200"] # 发送到本机的elasticsearch上
}
stdout { codec => rubydebug }
}
启动nginx(之前修改过nginx,需要重启后再启动)
curl localhost:80
启动成功后查看日志文件中是否收集到日志
[root@localhost filebeat-7.4.0-linux-x86_64]# cat /usr/local/nginx/logs/access.log
{"@timestamp":"2019-12-26T09:22:51+08:00","@version":1,"host":"127.0.0.1","client":"127.0.0.1","size":612,"responsetime":0.000,"domain":"localhost","url":"/index.html","status":"200"}
客户端启动 filebeat
./filebeat -e -c filebeat.yml -d "publish"
服务端启动logstash
/opt/logstash/bin/logstash -f /opt/conf/logstash.conf --config.reload.automatic
查看kibana,确认ES是否收集到
nginx.conf配置
user nobody;
worker_processes 1;
error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
pid logs/nginx.pid;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
#log_format main '$remote_addr - $remote_user [$time_local] "$request" '
# '$status $body_bytes_sent "$http_referer" '
# '"$http_user_agent" "$http_x_forwarded_for"';
#access_log logs/access.log main;
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65;
#gzip on;
log_format json '{"@timestamp":"$time_iso8601",'
'"@version":1,'
'"host":"$server_addr",'
'"client":"$remote_addr",'
'"size":$body_bytes_sent,'
'"responsetime":$request_time,'
'"domain":"$host",'
'"url":"$uri",'
'"status":"$status"}';
access_log /usr/local/nginx/logs/access.log json;
error_log /usr/local/nginx/logs/error.log;
server {
listen 80;
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
root html;
index index.html index.htm;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
# proxy the PHP scripts to Apache listening on 127.0.0.1:80
#
#location ~ \.php$ {
# proxy_pass http://127.0.0.1;
#}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
#location ~ \.php$ {
# root html;
# fastcgi_pass 127.0.0.1:9000;
# fastcgi_index index.php;
# fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
# include fastcgi_params;
#}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht {
# deny all;
#}
}
# another virtual host using mix of IP-, name-, and port-based configuration
#
#server {
# listen 8000;
# listen somename:8080;
# server_name somename alias another.alias;
# location / {
# root html;
# index index.html index.htm;
# }
#}
# HTTPS server
#
#server {
# listen 443 ssl;
# server_name localhost;
# ssl_certificate cert.pem;
# ssl_certificate_key cert.key;
# ssl_session_cache shared:SSL:1m;
# ssl_session_timeout 5m;
# ssl_ciphers HIGH:!aNULL:!MD5;
# ssl_prefer_server_ciphers on;
# location / {
# root html;
# index index.html index.htm;
# }
#}
}
filebeat.yml配置:
filebeat.inputs:
- type: log
enabled: true
paths:
- /usr/local/nginx/logs/access.log # 指定需要收集的日志文件的路径
fields:
indexname: nginx-access
- type: log
enabled: true
paths:
- /usr/local/nginx/logs/error.log # 指定需要收集的日志文件的路径
fields:
indexname: nginx-error
- type: log
enabled: true
paths:
- /var/log/jsac.agentjsac.info.log # 指定需要收集的日志文件的路径
fields:
indexname: jsac-agentjsac-info
- type: log
enabled: true
paths:
- /var/log/jsac.agentjsac.error.log # 指定需要收集的日志文件的路径
fields:
indexname: jsac-agentjsac-error
- type: log
enabled: true
paths:
- /var/log/jsac.agentjsac.debug.log # 指定需要收集的日志文件的路径
fields:
indexname: jsac-agentjsac-debug
- type: log
enabled: true
paths:
- /var/log/jsac.agentjsac.warn.log # 指定需要收集的日志文件的路径
fields:
indexname: jsac-agentjsac-warn
- type: log
enabled: true
paths:
- /var/log/jsac.driver-install.log # 指定需要收集的日志文件的路径
fields:
indexname: jsac-driver-install
- type: log
enabled: true
paths:
- /var/log/jsac.tsthostapi.debug.log # 指定需要收集的日志文件的路径
fields:
indexname: jsac-tsthostapi.debug
- type: log
enabled: true
paths:
- /var/log/jsac.tsthostapi.error.log # 指定需要收集的日志文件的路径
fields:
indexname: jsac-tsthostapi.error
- type: log
enabled: true
paths:
- /var/log/jsac.update.info.log # 指定需要收集的日志文件的路径
fields:
indexname: jsac-update.info
fields:
host_ip: 192.168.194.5 #发送本机出口ip,便于服务器端方便筛选
output.logstash:
hosts: ["192.168.194.6:5044"] #指定日志服务器的ip:port
logstash.conf配置:
input {
beats {
port => 5044
}
}
filter {
mutate {
rename => { "[host][name]" => "host" }
}
if [fields][indexname] == "nginx-error" {
grok {
match => {
"message" => "%{DATESTAMP:datetime}\s+\[%{LOGLEVEL:loglevel}\]\s+%{GREEDYDATA:error_reason}"
}
}
}
else if [fields][indexname] == "nginx-access" {
grok {
match => { "message" => "%{NGINXACCESS}" }
}
}
else if "agentjsac" in [fields][indexname] {
grok {
match => { "message" => "%{DATESTAMP:datetime} %{LOGLEVEL:loglevel} %{GREEDYDATA:reason}" }
}
}
else if "tsthostapi" in [fields][indexname] {
grok {
match => { "message" => "%{GREEDYDATA:description}" }
}
}
date {
match => [ "timestamp", "YY/MM/dd HH:mm:ss","YYYY-MM-dd HH:mm:ss", "dd/MMM/YYYY:HH:mm:ss Z" ]
}
mutate {
remove_field => ["host", "tags", "@version", "type"]
}
}
output {
elasticsearch {
action => "index"
index => "log_%{+YYYY.MM.dd}"
hosts => ["127.0.0.1:9200"]
}
stdout { codec => rubydebug }
}
服务端logstash启动:
/opt/logstash/bin/logstash -f /opt/conf/logstash.conf --config.reload.automatic
客户端filebeat启动:
./filebeat -e -c filebeat.yml -d "publish"
logstash收集并打印出日志:
kibana显示:
=======================================================================================================
参照:https://blog.51cto.com/chenx1242/1769724
error.log:
[emerg] 20952#0: unexpected "}" in /usr/local/nginx/conf/nginx.conf:87
# 这句话就说明在nginx.conf的87行里有一个 } 是错误的,检查一下}是不是多余了,或者;少了,这个错误的级别是emergency;
[emerg] 21023#0: "root" directive is duplicate in /usr/local/nginx/conf/nginx.conf:86
# 这句话就是说明在nginx.conf的第86行里root设定重复了,级别同样是emergency。以上两个都是书写的问题,很好纠正;
[notice] 21045#0: signal process started
# 这个意思是nginx已经在运行的状态下,被执行启动,这个不算致命错误;
nginx: [alert] could not open error log file: open()"/usr/local/nginx/logs/error.log" failed (13:Permissiondenied)
# 这个是说当前用户没有权限写入error.log的日志,解决方法要来权限就行了;
nginx: [error] open() "/usr/local/nginx/logs/nginx.pid" failed (2: No such file or directory)
# nginx提示无法找到nginx.pid这个文件了
#使用#/usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf,重新启动一下,就自动生成pid文件了。
=======================================================================================================
=======================================================================================================
=======================================================================================================
手机扫一扫
移动阅读更方便
你可能感兴趣的文章