ELK搭建环境之配置logstash监听文件并利用grok插件进行切割利于统计

一、配置ELK环境在logstash和elasticsearch之间建立通信,并能查看对应的索引、日志信息

1.本地下载logstash6.4.2运行包,不会装请移步 (ElasticSearch+LogStash+Kibana)ELK搭建在Mac/Linux系统上6.4.2版本

2.解压并进行基础配置,配置如下:

默认配置文件在安装目录 logstash6.4.2/config/logstash-sample.conf

# 监听本地目录下的test.log日志文件
input {
  file {
      path => ["/Users/chenhailong/daily-test/test.log"]
  }
}
# 配置日志发送的目标elasticsearch服务
output {
  elasticsearch {
    hosts => ["http://xxxx.xx.xxx.xx:9200"]
    index => "grok-test"
    user => "username"
    password => "password"
  }
}

3.确保elasticsearch服务是可以访问的,(开启代理、翻墙、防火墙、IP不通可能造成无法通信)

在浏览器键入对应地址:http://xxxx.xx.xxx.xx:9200

显示如下:

{
  "name" : "wqbVDEq",
  "cluster_name" : "elasticsearch",
  "cluster_uuid" : "lq8YkTH4Q7eslqvd0pn9Kg",
  "version" : {
    "number" : "6.4.2",
    "build_flavor" : "default",
    "build_type" : "tar",
    "build_hash" : "04711c2",
    "build_date" : "2018-09-26T13:34:09.098244Z",
    "build_snapshot" : false,
    "lucene_version" : "7.4.0",
    "minimum_wire_compatibility_version" : "5.6.0",
    "minimum_index_compatibility_version" : "5.0.0"
  },
  "tagline" : "You Know, for Search"
}

4.在客户端保证有效的日志文件,日志记录有序的生成。

客户端的

日志文件为:/Users/chenhailong/daily-test/test.log

日志格式为:2018-12-31,16:12:1546245470 INFO sdklog &event_id=10003&uuid=90b7786d-a905-48aa-93e9-bc1cf64ffce2&event_type=2&device_id=37037&session_id=1545899195566_37037&uid=2D9CBA4701227157E050840AF2422B52&date=2018-12-27&time=16:26:36&ts=1545899196409&

在需要测试时,执行脚本追加日志记录务必保证日志文件中有新的追加记录,确保监听到了新的数据。否则,没有新数据可能看不到效果

5.启动logstash

#指定配置文件启动

./bin/logstash -f ../conf/logstash-sample.conf

6.如果一切顺利的话,可以在kibana控制台看到相关信息

a. kibana 》系统管理 》 Index Mangement 》 可以搜索查看到对应的 “grok-test” 索引名称
b. kibana 》系统管理 》 Index Patterns 》可以创建索引前缀
c. kibana 》发现 》 可以搜索到 “grok-test”索引文件下的所有日志记录,如下

未分类

二:对日志进行切割

1.前期了解:

https://github.com/logstash-plugins/logstash-patterns-core/blob/master/patterns/grok-patterns

2.在kibana后台 》开发工具 》 Grok Debugger进行测试,如下图

不会用,请移步 使用kibana的开发工具console做一些elasticsearch的基本查询和设置

未分类

3.日志切割请参考,注意格式

%{TIMESTAMP_ISO8601:date} %{LOGLEVEL:level} %{WORD:type} &event_id=%{NUMBER:event_id}&uuid=%{USERNAME:uuid}&event_type=%{INT:event_type}&device_id=%{INT:device_id}&session_id=%{USERNAME:session_id}&uid=%{WORD:uid}&date=%{USERNAME:ymd}&time=%{TIME:time}&ts=%{NUMBER:ts}&url=%{URI:url}

4.修改配置文件,增加grok插件

# Sample Logstash configuration for creating a simple
# Beats -> Logstash -> Elasticsearch pipeline.

input {
  file {
      path => ["/Users/chenhailong/daily-test/test.log"]
  }
}

filter {
  #定义数据的格式
  grok {
    match => { "message" => "%{TIMESTAMP_ISO8601:date} %{LOGLEVEL:level} %{WORD:type} &event_id=%{NUMBER:event_id}&uuid=%{USERNAME:uuid}&event_type=%{INT:event_type}&device_id=%{INT:device_id}&session_id=%{USERNAME:session_id}&uid=%{WORD:uid}&date=%{USERNAME:ymd}&time=%{TIME:time}&ts=%{NUMBER:ts}&url=%{URI:url}"}
  }
}

output {
  elasticsearch {
    hosts => ["http://xxx.xx.xxx.xx:9200"]
    index => "grok-test"
    user => "username"
    password => "password"
  }
}

5.打开kibana 》 发现 》 搜索grok-test索引

会发现日志已经按照设定的格式进行切切割。这样就可以进行数据的报表分析,更加直观化。更有效的利用日志数据。

不局限于日常日志,也可以针对性的记录相关业务数据。

未分类

6.配置文件中还可以增加多种插件配合处理

具体可以移步查看官方文件,更加详细,更加专业

https://www.elastic.co/guide/en/logstash/current/filter-plugins.html

至此:ELK的学习使用就告一段落,有需要再去细致研究。

Linux搭建ELK日志收集系统:FIlebeat+Redis+Logstash+Elasticse

Centos7部署ELK日志收集系统

一、ELK概述

ELK是一组开源软件的简称,其包括Elasticsearch、Logstash 和 Kibana。ELK最近几年发展迅速,已经成为目前最流行的集中式日志解决方案。

  • Elasticsearch: 能对大容量的数据进行接近实时的存储,搜索和分析操作。 本项目中主要通过Elasticsearch存储所有获取的日志。
  • Logstash: 数据收集引擎,它支持动态的的从各种数据源获取数据,并对数据进行过滤,分析,丰富,统一格式等操作,然后存储到用户指定的位置。
  • Kibana: 数据分析与可视化平台,对Elasticsearch存储的数据进行可视化分析,通过表格的形式展现出来。
  • Filebeat: 轻量级的开源日志文件数据搜集器。通常在需要采集数据的客户端安装Filebeat,并指定目录与日志格式,Filebeat就能快速收集数据,并发送给logstash进行解析,或是直接发给Elasticsearch存储。
  • Redis:NoSQL数据库(key-value),也数据轻型消息队列,不仅可以对高并发日志进行削峰还可以对整个架构进行解耦

传统ELK的经典框架

未分类

单一的架构,logstash作为日志搜集器,从数据源采集数据,并对数据进行过滤,格式化处理,然后交由Elasticsearch存储,kibana对日志进行可视化处理。

新型ELK框架

未分类

Filebeats是一种轻量级的日志搜集器,其不占用系统资源,自出现之后,迅速更新了原有的elk架构。Filebeats将收集到的数据发送给Logstash解析过滤,在Filebeats与Logstash传输数据的过程中,为了安全性,可以通过ssl认证来加强安全性。之后将其发送到Elasticsearch存储,并由kibana可视化分析。

二、新型ELK搭建详细过程

实验环境:

未分类

下面是搭建过程中所需程序安装包:
https://pan.baidu.com/s/1w02WtUAqh9yX4TChyMLa5Q 密码:g0p9

1.客户端部署filebeat:

yum -y install filebeat
#查看配置文件所在位置
rpm -qc filebeat

2.修改配置文件使filebeat获取的日志进入redis:

注:此处演示获取spring cloud框架中eureka日志,其他程序日志都可相同方法获取

vim /etc/filebeat/filebeat.yml
#修改的内容有一家几个字段
enabled:true
paths:程序日志路径
output.redis:日志输出地方
                    hosts:redis所在服务器IP
                    port:redis端口
                    key:redis中的key

未分类

3.源码安装redis:

解压redis程序包:

tar zxf redis-3.2.9.tar.gz –C /usr/local/src

编译redis:

cd /usr/local/src/redis-3.2.9
make && make install
ln –s /usr/local/src/redis-3.2.9 /usr/local/redis

注:redis安装时有的缺少语言环境会出错,有的会出现奇奇怪怪的问题,只要复制Error到往上搜索下就能轻易解决,在此不多做解释

修改redis配置文件:

vim /usr/local/redis/redis.conf
#修改内容如下:
daemonize yes                           #开启后台运行
timeout 120                                #超时时间
bind 0.0.0.0                                #任何地址IP都可以登录redis
protected-mode no                     #关闭redis保护机制否则在没有密码校验情况下redis远程登录失败

注:此处是做演示,如果是线上部署elk建议开启持久化机制,保证数据不丢失

4.登录测试redis是否可以正常写入数据:

未分类

5.启动filebeat看看redis是否能接收到数据:

启动filebeat:

systemctl start filebeat

6.进入redis查看是否有数据:

#执行命令:
keys *                          #查看所有key,此操作为慢查询,若redis跑了大量线上业务请不要进行此操做
lrange eureka-log 0 -1 #查询key所有数据,若filebeat启动时间过长请勿进行此操作

未分类

7.安装jdk1.8:

解压jdk安装包并创建软连接:

tar zxf /usr/local/src/jdk-8u131-linux-x64.tar.gz –C /usr/local/
ln -s /usr/local/jdk1.8.0_91/ /usr/local/jdk

配置环境变量:

vim /etc/profile
#修改内容如下:
JAVA_HOME=/usr/local/jdk
export JRE_HOME=/usr/local/jdk/jre
export CLASSPATH=.:$JAVA_HOME/lib:$JRE_HOME/lib:$CLASSPATH
export PATH=$PATH:$JAVA_HOME/bin:$JRE_HOME/bin

重新载入环境变量:

source /etc/profile

查看jdk是否安装成功:

java -version

未分类

8.安装Elasticsearch:

解压安装包并改名:

unzip elasticsearch-5.6.3.zip -d /usr/local/
mv /usr/local/ elasticsearch-5.6.3 /usr/local/elasticsearh

修改ES配置文件:

vim /usr/local/elasticsearch/config/elasticsearch.yml

#这里指定的是集群名称,需要修改为对应的,开启了自发现功能后,ES会按照此集群名称进行集群发现
cluster.name: my-application
node.name: node-1

#目录需要手动创建
path.data: /opt/elk/data
path.logs: /opt/elk/logs

#ES监听地址任意IP都可访问
network.host: 0.0.0.0
http.port: 9200

#若是集群,可在里面引号中添加,逗号隔开
discovery.zen.ping.unicast.hosts: [“192.168.3.205”]

# enable cors,保证_site类的插件可以访问es    
http.cors.enabled: true             #手动添加
http.cors.allow-origin: “*”         #手动添加

# Centos6不支持SecComp,而ES5.2.0默认bootstrap.system_call_filter为true进行检测,所以导致检测失败,失败后直接导致ES不能启动
bootstrap.memory_lock: false        #手动添加
bootstrap.system_call_filter: false     #手动添加

注:ES启动的时候回占用特别大的资源所以需要修改下系统参数,若不修改资源启动会异常退出

9.修改系统参数:

vim /etc/sysctl.conf
#添加参数
vm.max_map_count=655360

重新载入配置:

sysctl –p

10.修改资源参数:

vim /etc/security/limits.conf
#修改

*   soft    nofile  65536
*   hard        nofile  131072  
*   soft        nproc   65536
*   hard        nproc   131072 

如:

未分类

11.设置用户资源参数:

vim /etc/security/limits.d/20-nproc.conf
#添加
elk     soft    nproc       65536

12.创建用户并赋权:

useradd elk
groupadd elk
useradd elk -g elk

13.创建数据和日志目录并修改目录权限:

mkdir –pv /opt/elk/{data,logs}
chown –R elk:elk /opt/elk
chown –R elk:elk /usr/local/elasticsearch

14.切换用户并后台启动ES:(elk用户修改了资源参数,如不切位elk用户启动会暴毙)

su elk
nohup /opt/app/elasticsearch-5.6.3/bin/elasticsearch >> /dev/null 2>&1 &

15.查看ES状况:

方法一、
curl 'http://[ES IP]:9200/_search?pretty'

方法二、
#网页访问:
http://[ES IP]:9200/_search?pretty

16.安装logstash:

解压并创建软连接:

tar /usr/local/src/logstash-5.3.1.tar.gz –C /usr/local/
ln –s /usr/local/logstash-5.3.1 /usr/local/logstash

测试logstash是否可用:

/usr/local/logstash/bin/logstash -e 'input { stdin { } } output { stdout {} }'

未分类

在此创建主配文件进行测试:

vim /usr/local/logstash/config/logstash-simple.conf
#内容如下:
input { stdin { } }
output {
    stdout { codec=> rubydebug }
}

使用logstash参数-f读取配置文件进行测试:

/usr/local/logstash/bin/logstash -f /usr/local/logstash/config/logstash-simple.conf

未分类

此时说明我们的logstash是完全没有问题了,可以进行日志收集了

17.创建配置文件获取redis日志的数据:

配置文件如下:

vim /usr/local/logstash/config/redis-spring.conf 
input {
  redis {
    port => "6379"
    host => "192.168.3.205"
    data_type => "list"
    type => "log"
    key => "eureka-log"
  }
}
output {
  elasticsearch {
     hosts => "192.168.3.205:9200"
     index => "logstash1-%{+YYYY.MM.dd}"
  }
}

通过配置文件启动服务查看效果:

/usr/local/logstash/bin/logstash -f /usr/local/logstash/config/redis-spring.conf

结果如下:

未分类

此时我们再去查看reids中key:(此时已经没有数据了,数据已经被logstash取完)

未分类

18.使用curl 查看ES是否接受到数据

curl http://192.168.3.205:9200/_search?pretty

结果如下:

未分类

此时说明我们logstash从redis中取数据,在把数据推到ES中是ok的!

19.安装ES插件:(elasticsearch-head)

注:head安装需要从国外网站拉去东西,可能网速过慢导致安装失败(可以多试几次),下面有几种方法安装:

方法一、
导入node-v8.2.1.tar.gz phantomjs-2.1.1-linux-x86_64.tar.bz2 安装包
安装node:
tar zxvf node-v8.2.1.tar.gz
cd node-v8.2.1/
./configure && make && make install 

安装phantomjs:
tar jxvf phantomjs-2.1.1-linux-x86_64.tar.bz2
cd phantomjs-2.1.1-linux-x86_64/bin/
cp phantomjs /usr/local/bin/

导入es-head程序包并解压:
unzip master.zip –d /usr/local/
cd elasticsearch-head/
npm install
npm run start &

查看端口状态:(端口默认9100)
netstat –anpt | grep 9100

方法二、
git clone git://github.com/mobz/elasticsearch-head.git
cd elasticsearch-head
npm install
npm run start
netstat –anpt | grep 9100

方法三、
拉镜像:
docker push mobz/elasticsearch-head:5
启动镜像:
docker run -p 9100:9100 mobz/elasticsearch-head:5
web访问测试:
http://IP:9100

20.Elasticsearch-head安装成功Web访问结果如下:

未分类

查看刚刚从logstash推到ES中的数据:

未分类

21.安装kibana

解压并安装kibana:

tar -zxvf /usr/local/src/kibana-5.3.1-linux-x86_64.tar.gz -C /usr/local/

修改kibana配置文件:

vim /usr/local/kibana-5.3.1-linux-x86_64/config/kibana.yml

修改内容如下:

server.port: 5601                                                            #开启默认端口5601
server.host: “192.168.3.205”                                    #kibana站点IP
elasticsearch.url: http://192.168.3.205:9200        #只想ES服务所在IP Port
kibana.index: “.kibana”

后台启动kibana:

nohup /usr/local/kibana-5.3.1-linux-x86_64/bin/kibana >> /dev/null 2>&1 &

查看端口监听:

netstat –anot | grep 5601

结果如:(此结果表示kibana启动成功)

未分类

使用Web访问kibana:

http://[Kibana IP]:5601

初次访问结果如:(刚访问的时候没有创建索引所以没有看不到数据)

未分类

根据logstash配置文件中index设置索引:
首先查看logstash中的index:

未分类

Kibana中创建index:

未分类

下面按照1,2,3,4顺序进行设置:

未分类

此时我们在返回Discover在里面我们就可以看到数据了:

未分类

至此我们的ELK就安装OK了。

k8s的初步部署zipkin和elk

kubernates的部署

一、界面部署

1、创建

点击右上角创建按钮

未分类

2、设置创建的参数

选择创建的方式可以为输入yaml配置,上传yaml文件和界面配置。

①界面创建

未分类

应用名称

这个是部署pod的名称
- 容器镜像
输入要部署的容器的镜像地址
- 容器组个数
这个参数是k8s要保证运行的pod数量,如果指定3,它会创建3个Pod,并且持续监控它们。如果某个Pod不响应,那么Replication Controller会替换它,保持总数为3。如果之前不响应的Pod恢复了,现在就有4个Pod了,那么Replication Controller会将其中一个终止保持总数为3。
- 服务
选择内部或者外部,内部服务将使得集群外部请求不能访问到pod,外部则会暴露nodePort使得外部机器可访问,服务中的端口类型共有3种:

1)nodePort
 外部机器可访问的端口。
比如一个Web应用需要被其他用户访问,那么需要配置type=NodePort,而且配置nodePort=30001,那么其他机器就可以通过浏览器访问scheme://node:30001访问到该服务,例如http://node:30001。
 例如MySQL数据库可能不需要被外界访问,只需被内部服务访问,那么不必设置NodePort
2)targetPort
 容器的端口(最根本的端口入口),与制作容器时暴露的端口一致(DockerFile中EXPOSE),例如docker.io官方的nginx暴露的是80端口。
3)port
 kubernetes中的服务之间访问的端口,尽管mysql容器暴露了3306端口(参考https://github.com/docker-library/mysql/的DockerFile),但是集群内其他容器需要通过33306端口访问该服务,外部机器不能访问mysql服务,因为他没有配置NodePort类型

- 保密字典
当要拉取私有服务器的镜像的时候需要用户名密码,在k8s中这个是通过配置保密字典secret来实现的。
K8s 中Secret是一个包含少量敏感信息如密码,令牌,或秘钥的对象。这些信息可能被保存在 pod 定义或者 docker 镜像中,把这些信息保存在 Secret对象中,可以在这些信息被使用时加以控制,并可以降低信息泄露的风险。
创建保密字典的方式有很多种,我是通过命令行的方式配置的:

kubectl create secret docker-registry regsecret --docker-server=repo.gildata.com --docker-username=chenyang --docker-password=xxxx [email protected]

这行命令是创建了一个名为regsecret的保密字典,--docker-server表示为仓库地址,--docker-username是用户账户,--docker-password为账户密码,--docker-email用户邮箱。

这个配置完之后,在k8s的界面上就可以看到我们配置的保密字典:

未分类

在界面上选择的时候可以点击下面的高级按钮选择相应的保密字典:

未分类

选择刚刚创建的保密字典:

未分类

这样私有仓库的镜像就可以拉取了。

②yaml配置
1)zipkin的Deployment配置:

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: zipkin
spec:
  replicas: 1
  template:
    metadata:
      labels:
        k8s-app: zipkin
    spec:
      containers:
      - name: zipkin
        image: openzipkin/zipkin
        ports:
          - containerPort: 9411
            hostPort: 9411

我在这里直接用Deployment来管理pod,Deployment为Pod和ReplicaSet提供了一个声明式定义(declarative)方法,用来替代以前的ReplicationController来方便的管理应用。典型的应用场景包括:

  • 定义Deployment来创建Pod和ReplicaSet
  • 滚动升级和回滚应用
  • 扩容和缩容
  • 暂停和继续Deployment

把这段配置文件提交在k8s管理界面的yaml文件框里面,或者直接是提交本地yaml文件,这两种方法大同小异。

附:k8s的pod的配置所有选项介绍:

 # yaml格式的pod定义文件完整内容:
 apiVersion: v1          #必选,版本号,例如v1
 kind: Pod             #必选,Pod
 metadata:             #必选,元数据
   name: string          #必选,Pod名称
   namespace: string       #必选,Pod所属的命名空间
   labels:             #自定义标签
     - name: string       #自定义标签名字
   annotations:          #自定义注释列表
     - name: string
 spec:                #必选,Pod中容器的详细定义
   containers:           #必选,Pod中容器列表
   - name: string        #必选,容器名称
     image: string       #必选,容器的镜像名称
     imagePullPolicy: [Always | Never | IfNotPresent]  #获取镜像的策略 Alawys表示下载镜像 IfnotPresent表示优先使用本地镜像,否则下载镜像,Nerver表示仅使用本地镜像
     command: [string]       #容器的启动命令列表,如不指定,使用打包时使用的启动命令
     args: [string]         #容器的启动命令参数列表
     workingDir: string      #容器的工作目录
     volumeMounts:         #挂载到容器内部的存储卷配置
     - name: string         #引用pod定义的共享存储卷的名称,需用volumes[]部分定义的的卷名
       mountPath: string     #存储卷在容器内mount的绝对路径,应少于512字符
       readOnly: boolean     #是否为只读模式
     ports:              #需要暴露的端口库号列表
     - name: string         #端口号名称
       containerPort: int    #容器需要监听的端口号
       hostPort: int        #容器所在主机需要监听的端口号,默认与Container相同
       protocol: string      #端口协议,支持TCP和UDP,默认TCP
     env:              #容器运行前需设置的环境变量列表
     - name: string        #环境变量名称
       value: string       #环境变量的值
     resources:          #资源限制和请求的设置
       limits:           #资源限制的设置
         cpu: string       #Cpu的限制,单位为core数,将用于docker run --cpu-shares参数
         memory: string      #内存限制,单位可以为Mib/Gib,将用于docker run --memory参数
       requests:         #资源请求的设置
         cpu: string       #Cpu请求,容器启动的初始可用数量
         memory: string      #内存清楚,容器启动的初始可用数量
     livenessProbe:        #对Pod内个容器健康检查的设置,当探测无响应几次后将自动重启该容器,检查方法有exec、httpGet和tcpSocket,对一个容器只需设置其中一种方法即可
       exec:             #对Pod容器内检查方式设置为exec方式
         command: [string]   #exec方式需要制定的命令或脚本
       httpGet:            #对Pod内个容器健康检查方法设置为HttpGet,需要制定Path、port
         path: string
         port: number
         host: string
         scheme: string
         HttpHeaders:
         - name: string
           value: string
       tcpSocket:            #对Pod内个容器健康检查方式设置为tcpSocket方式
          port: number
        initialDelaySeconds: 0   #容器启动完成后首次探测的时间,单位为秒
        timeoutSeconds: 0      #对容器健康检查探测等待响应的超时时间,单位秒,默认1秒
        periodSeconds: 0       #对容器监控检查的定期探测时间设置,单位秒,默认10秒一次
        successThreshold: 0
        failureThreshold: 0
        securityContext:
          privileged: false
     restartPolicy: [Always | Never | OnFailure] #Pod的重启策略,Always表示一旦不管以何种方式终止运行,kubelet都将重启,OnFailure表示只有Pod以非0退出码退出才重启,Nerver表示不再重启该Pod
     nodeSelector: obeject     #设置NodeSelector表示将该Pod调度到包含这个label的node上,以key:value的格式指定
     imagePullSecrets:         #Pull镜像时使用的secret名称,以key:secretkey格式指定
     - name: string
     hostNetwork: false        #是否使用主机网络模式,默认为false,如果设置为true,表示使用宿主机网络
     volumes:              #在该pod上定义共享存储卷列表
     - name: string          #共享存储卷名称 (volumes类型有很多种)
       emptyDir: {}          #类型为emtyDir的存储卷,与Pod同生命周期的一个临时目录。为空值
       hostPath: string        #类型为hostPath的存储卷,表示挂载Pod所在宿主机的目录
         path: string        #Pod所在宿主机的目录,将被用于同期中mount的目录
       secret:             #类型为secret的存储卷,挂载集群与定义的secre对象到容器内部
         scretname: string  
         items:     
         - key: string
           path: string
       configMap:          #类型为configMap的存储卷,挂载预定义的configMap对象到容器内部
         name: string
         items:
         - key: string
           path: string    

2)service配置

在pod成功部署之后,就需要为这个pod配置service。

Kubernete Service 是一个定义了一组Pod的策略的抽象,我们也有时候叫做宏观服务。这些被服务标记的Pod都是(一般)通过label Selector决定的。

举个例子,我们假设后台是一个图形处理的后台,并且由3个副本。这些副本是可以相互替代的,并且前台并不需要关心使用的哪一个后台Pod,当这个承载前台请求的pod发生变化时,前台并不需要直到这些变化,或者追踪后台的这些副本,这些都是通过服务来定位追踪的。

简单地说,服务就是请求到pod的一座桥梁,请求并不需要关心自己会请求到哪个pod,这些对于用户和请求来说都是不可见的,用户也不会感觉到这是一个集群,一个请求过来,service会自动分配到哪个pod上。

service的yaml配置文件:

apiVersion: v1
kind: Service
metadata:
 name: zipkin
 labels:
   k8s-app: zipkin
spec:
 type: LoadBalancer
 ports:
 - port: 9411
   targetPort: 9411
   nodePort: 30002
 selector:
  k8s-app: zipkin

2)ConfigMap配置

ConfigMap用于保存配置数据的键值对,可以用来保存单个属性,也可以用来保存配置文件。ConfigMap跟secret很类似,但它可以更方便地处理不包含敏感信息的字符串。

简单的说,相对于docker-compose的配置文件在文件目录下面,k8s的配置文件放到了自己的配置字典里面。

下面是ConfigMap的配置

apiVersion: v1
kind: ConfigMap
metadata:
  name: logstash-config
  namespace: default
data:
  logstash.yml: |
    http.host: "0.0.0.0"
    path.config: /usr/share/logstash/pipeline
  logstash.conf: |
    input {
        tcp {
            port => 5000
            codec => json_lines {
                charset => "UTF-8"
            }
        }
    }
    output {
        elasticsearch {
            hosts => "elasticsearch:9200"
        }
    }

logstash-config表示配置字典的名称。

data里面每一个key-value键值对都会生成一个文件,key为文件名,value为内容。

同样的,在点击上传之后,会在配置字典菜单中生成相应的配置字典。如图所示:

未分类

这样就可以在deployment中引用这个配置字典:

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: logstash
spec:
  replicas: 1
  template:
    metadata:
      labels:
        k8s-app: logstash
    spec:
      containers:
      - name: logstash
        image: docker.elastic.co/logstash/logstash:6.2.3
        ports:
          - containerPort: 5000
            hostPort: 5000
        env:
          - name: ES_JAVA_OPTS
            value: "-Xmx256m -Xms256m"
        volumeMounts:
          - name: logstash-volume1   #volumes中配的volume名字
            mountPath: /usr/share/elasticsearch/config   #在容器内部的配置文件存放地址
          - name: logstash-volume2   #volumes中配的volume名字
            mountPath: /usr/share/logstash/pipeline     #在容器内部的配置文件存放地址
        imagePullSecrets:
          - name: regsecret   #  保密字典
      volumes:
      - name: logstash-volume1  #这个是现在自定义的volume的名字,方便在volumeMounts中引用
        configMap:
          name: logstash-config   #这个就是之前配的配置字典
          items:
          - key: logstash.yml  #配置字典里面对应的key
            path: config
      - name: logstash-volume2   #这个是现在自定义的volume的名字,方便在volumeMounts中引用
        configMap:
          name: logstash-config   #这个就是之前配的配置字典
          items:
          - key: logstash.conf   #配置字典里面对应的ke
            path: pipeline

3、部署

配置好之后点击部署,然后查看概况,状态图都为绿色,容器组的状态为running,这样就部署成功了,如图:

未分类

可以进行访问Zipkin,输入http://10.106.0.51:32552,这里的32552即为nodePort:

未分类

当在后期需要调整node的数量的时候,可以在deployment中调整数量,如图所示:

未分类

第二步:

未分类

你离ELK只有一句docker-compose的距离

未分类

引言

刚接触Elk的时候,我用github.com/deviantony/…,部署了第一个测试环境,这是一个很优秀的项目,几乎没什么配置就可以部署成功。
但有一个问题就是对于一个初学者如此洁净的环境,我完全不知道从何入手,也弄不清这个框架的优势是什么(连个Dashboard样本都没有)。还有 x-pack 的配置,metricbeat 的接入都踩过不少坑,才部署成一个像样的学习环境。之后在写 docker-compose.yml 脚本的时候又是各种踩雷,终于实现了快速一键部署。同时支持 DaoCloud 的 Stack 脚本 持续集成
在这里分享给大家,好像想入坑的同学少走些弯路。

你需要准备什么

一个 docker 环境, 还有…… 没了

注:win 和 macOS 下不支持 docker-metricbeat 的 system 监控,需手动关闭

我要怎么做

在这里看下注意事项

本地部署

$ git clone "https://github.com/wilfordw/docker-elk-example.git"
$ cd docker-elk-example
$ docker-compose up -d

DaoCloud Stack 部署

先下载项目到服务器,复制项目绝对路径

$ git clone "https://github.com/wilfordw/docker-elk-example.git"
$ cd docker-elk-example
$ pwd

把 dao-docker-compose.yml 内容复制进 Stack 的 YAML, 把上面克隆项目的 pwd 替换里面的 /root/app/docker-elk/, 点击部署就可以

想要自己创建镜像也可以,把你创建好的镜像地址替换 yml 里的 image

部署完可以看到什么?

未分类

未分类

未分类

未分类

未分类

未分类

继续更新

目前只做了 System Docker Nginx 的监控案列, 之后会继续集成

  • Metricbeat Mysql 监听
  • Metricbeat NodeJs 监听
  • Metricbeat Golang 监听
  • Metricbeat Kubernetes 监听
  • X-pack 权限解析
  • ELK 集群

分布式实时日志分析解决方案ELK部署架构

一、概述

ELK 已经成为目前最流行的集中式日志解决方案,它主要是由Beats、Logstash、Elasticsearch、Kibana等组件组成,来共同完成实时日志的收集,存储,展示等一站式的解决方案。本文将会介绍ELK常见的架构以及相关问题解决。

  1. Filebeat:Filebeat是一款轻量级,占用服务资源非常少的数据收集引擎,它是ELK家族的新成员,可以代替Logstash作为在应用服务器端的日志收集引擎,支持将收集到的数据输出到Kafka,Redis等队列。
  2. Logstash:数据收集引擎,相较于Filebeat比较重量级,但它集成了大量的插件,支持丰富的数据源收集,对收集的数据可以过滤,分析,格式化日志格式。
  3. Elasticsearch:分布式数据搜索引擎,基于Apache Lucene实现,可集群,提供数据的集中式存储,分析,以及强大的数据搜索和聚合功能。
  4. Kibana:数据的可视化平台,通过该web平台可以实时的查看 Elasticsearch 中的相关数据,并提供了丰富的图表统计功能。

二、ELK常见部署架构

2.1、Logstash作为日志收集器

这种架构是比较原始的部署架构,在各应用服务器端分别部署一个Logstash组件,作为日志收集器,然后将Logstash收集到的数据过滤、分析、格式化处理后发送至Elasticsearch存储,最后使用Kibana进行可视化展示,这种架构不足的是:Logstash比较耗服务器资源,所以会增加应用服务器端的负载压力。

未分类

2.2、Filebeat作为日志收集器

该架构与第一种架构唯一不同的是:应用端日志收集器换成了Filebeat,Filebeat轻量,占用服务器资源少,所以使用Filebeat作为应用服务器端的日志收集器,一般Filebeat会配合Logstash一起使用,这种部署方式也是目前最常用的架构。

未分类

2.3、引入缓存队列的部署架构

该架构在第二种架构的基础上引入了Kafka消息队列(还可以是其他消息队列),将Filebeat收集到的数据发送至Kafka,然后在通过Logstasth读取Kafka中的数据,这种架构主要是解决大数据量下的日志收集方案,使用缓存队列主要是解决数据安全与均衡Logstash与Elasticsearch负载压力。

未分类

2.4、以上三种架构的总结

第一种部署架构由于资源占用问题,现已很少使用,目前使用最多的是第二种部署架构,至于第三种部署架构个人觉得没有必要引入消息队列,除非有其他需求,因为在数据量较大的情况下,Filebeat 使用压力敏感协议向 Logstash 或 Elasticsearch 发送数据。如果 Logstash 正在繁忙地处理数据,它会告知 Filebeat 减慢读取速度。拥塞解决后,Filebeat 将恢复初始速度并继续发送数据。

三、问题及解决方案

问题:如何实现日志的多行合并功能?

系统应用中的日志一般都是以特定格式进行打印的,属于同一条日志的数据可能分多行进行打印,那么在使用ELK收集日志的时候就需要将属于同一条日志的多行数据进行合并。

解决方案:使用Filebeat或Logstash中的multiline多行合并插件来实现

在使用multiline多行合并插件的时候需要注意,不同的ELK部署架构可能multiline的使用方式也不同,如果是本文的第一种部署架构,那么multiline需要在Logstash中配置使用,如果是第二种部署架构,那么multiline需要在Filebeat中配置使用,无需再在Logstash中配置multiline。

1、multiline在Filebeat中的配置方式

filebeat.prospectors:
    -
       paths:
          - /home/project/elk/logs/test.log
       input_type: log 
       multiline:
            pattern: '^['
            negate: true
            match: after
output:
   logstash:
      hosts: ["localhost:5044"]
  • pattern:正则表达式
  • negate:默认为false,表示匹配pattern的行合并到上一行;true表示不匹配pattern的行合并到上一行
  • match:after表示合并到上一行的末尾,before表示合并到上一行的行首

如:

pattern: '['
negate: true
match: after

该配置表示将不匹配pattern模式的行合并到上一行的末尾

2、multiline在Logstash中的配置方式

input {
  beats {
    port => 5044
  }
}

filter {
  multiline {
    pattern => "%{LOGLEVEL}s*]"
    negate => true
    what => "previous"
  }
}

output {
  elasticsearch {
    hosts => "localhost:9200"
  }
}

(1)Logstash中配置的what属性值为previous,相当于Filebeat中的after,Logstash中配置的what属性值为next,相当于Filebeat中的before。
(2)pattern => “%{LOGLEVEL}s*]” 中的LOGLEVEL是Logstash预制的正则匹配模式,预制的还有好多常用的正则匹配模式,详细请看:https://github.com/logstash-plugins/logstash-patterns-core/tree/master/patterns

问题:如何将Kibana中显示日志的时间字段替换为日志信息中的时间?

默认情况下,我们在Kibana中查看的时间字段与日志信息中的时间不一致,因为默认的时间字段值是日志收集时的当前时间,所以需要将该字段的时间替换为日志信息中的时间。

解决方案:使用grok分词插件与date时间格式化插件来实现

在Logstash的配置文件的过滤器中配置grok分词插件与date时间格式化插件,如:

input {
  beats {
    port => 5044
  }
}

filter {
  multiline {
    pattern => "%{LOGLEVEL}s*][%{YEAR}%{MONTHNUM}%{MONTHDAY}s+%{TIME}]"
    negate => true
    what => "previous"
  }

  grok {
    match => [ "message" , "(?<customer_time>%{YEAR}%{MONTHNUM}%{MONTHDAY}s+%{TIME})" ]
  }

  date {
        match => ["customer_time", "yyyyMMdd HH:mm:ss,SSS"] //格式化时间
        target => "@timestamp" //替换默认的时间字段
  }
}

output {
  elasticsearch {
    hosts => "localhost:9200"
  }
}

如要匹配的日志格式为:“[DEBUG][20170811 10:07:31,359][DefaultBeanDefinitionDocumentReader:106] Loading bean definitions”,解析出该日志的时间字段的方式有:

① 通过引入写好的表达式文件,如表达式文件为customer_patterns,内容为:
CUSTOMER_TIME %{YEAR}%{MONTHNUM}%{MONTHDAY}s+%{TIME}
注:内容格式为:[自定义表达式名称] [正则表达式]
然后logstash中就可以这样引用:

filter {
  grok {
      patterns_dir => ["./customer-patterms/mypatterns"] //引用表达式文件路径
      match => [ "message" , "%{CUSTOMER_TIME:customer_time}" ] //使用自定义的grok表达式
  }
}

② 以配置项的方式,规则为:(?<自定义表达式名称>正则匹配规则),如:

filter {
  grok {
    match => [ "message" , "(?<customer_time>%{YEAR}%{MONTHNUM}%{MONTHDAY}s+%{TIME})" ]
  }
}

问题:如何在Kibana中通过选择不同的系统日志模块来查看数据

一般在Kibana中显示的日志数据混合了来自不同系统模块的数据,那么如何来选择或者过滤只查看指定的系统模块的日志数据?

解决方案:新增标识不同系统模块的字段或根据不同系统模块建ES索引

1、新增标识不同系统模块的字段,然后在Kibana中可以根据该字段来过滤查询不同模块的数据

这里以第二种部署架构讲解,在Filebeat中的配置内容为:

filebeat.prospectors:
    -
       paths:
          - /home/project/elk/logs/account.log
       input_type: log 
       multiline:
            pattern: '^['
            negate: true
            match: after
       fields: //新增log_from字段
         log_from: account

    -
       paths:
          - /home/project/elk/logs/customer.log
       input_type: log 
       multiline:
            pattern: '^['
            negate: true
            match: after
       fields:
         log_from: customer
output:
   logstash:
      hosts: ["localhost:5044"]

通过新增:log_from字段来标识不同的系统模块日志

2、根据不同的系统模块配置对应的ES索引,然后在Kibana中创建对应的索引模式匹配,即可在页面通过索引模式下拉框选择不同的系统模块数据。

这里以第二种部署架构讲解,分为两步:
① 在Filebeat中的配置内容为:

filebeat.prospectors:
    -
       paths:
          - /home/project/elk/logs/account.log
       input_type: log 
       multiline:
            pattern: '^['
            negate: true
            match: after
       document_type: account

    -
       paths:
          - /home/project/elk/logs/customer.log
       input_type: log 
       multiline:
            pattern: '^['
            negate: true
            match: after
       document_type: customer
output:
   logstash:
      hosts: ["localhost:5044"]

通过document_type来标识不同系统模块

② 修改Logstash中output的配置内容为:

output {
  elasticsearch {
    hosts => "localhost:9200"
    index => "%{type}"
  }
}

在output中增加index属性,%{type}表示按不同的document_type值建ES索引

四、总结

本文主要介绍了ELK实时日志分析的三种部署架构,以及不同架构所能解决的问题,这三种架构中第二种部署方式是时下最流行也是最常用的部署方式,最后介绍了ELK作在日志分析中的一些问题与解决方案,说在最后,ELK不仅仅可以用来作为分布式日志数据集中式查询和管理,还可以用来作为项目应用以及服务器资源监控等场景,更多内容请看官网。

ELK之Logstash安装与配置及使用

1、Logstash介绍

Logstash 是开源的服务器端数据处理管道,能够同时 从多个来源采集数据、转换数据,然后将数据发送到您最喜欢的 “存储库” 中。(我们的存储库当然是 Elasticsearch。)

2、安装jdk

# yum -y install java-1.8.0  
# java -version  
java version "1.8.0_51"  
Java(TM) SE Runtime Environment (build 1.8.0_51-b16)  
Java HotSpot(TM) 64-Bit Server VM (build 25.51-b03, mixed mode)  

3、安装logstash

# wget https://artifacts.elastic.co/downloads/logstash/logstash-6.0.0.tar.gz  
# tar zxf logstash-6.0.0.tar.gz -C /Data/apps/  

配置logstash的环境变量

# echo "export PATH=$PATH:/Data/apps/logstash-6.0.0/bin" > /etc/profile.d/logstash.sh  
# . /etc/profile  

4、查看帮助

# logstash --help

未分类

5、logstash常用参数

-e :指定logstash的配置信息,可以用于快速测试;
-f :指定logstash的配置文件;可以用于生产环境;

6、启动logstash

6.1 通过-e参数指定logstash的配置信息,用于快速测试,直接输出到屏幕。–quiet:日志输出安静模式

$ logstash -e "input {stdin{}} output {stdout{}}" --quiet

6.2

$ logstash -e 'input{stdin{}}output{stdout{codec=>rubydebug}}'

7、logstash以配置文件方式启动

$ vim logstash.conf  
input { stdin {} }  
output {  
   stdout { codec=> rubydebug }  
}  
$ logstash -f logstash.conf --quie  
yes ,i can  
{  
      "@version" => "1",  
          "host" => "wechat1-dev.bj1.xxxx.net",  
    "@timestamp" => 2017-11-25T10:28:38.763Z,  
       "message" => "yes ,i can"  
}  

8、更多样例

请参考官方文档样例:https://www.elastic.co/guide/en/logstash/current/config-examples.html

8.1 样例 elasticsearch

input { stdin { } }  
output {  
  elasticsearch { hosts => ["localhost:9200"] }  
  stdout { codec => rubydebug }  
}  

8.2 样例 access_log

input {  
  file {  
    path => "/tmp/access_log"  
    start_position => "beginning"  
  }  
}  


filter {  
  if [path] =~ "access" {  
    mutate { replace => { "type" => "apache_access" } }  
    grok {  
      match => { "message" => "%{COMBINEDAPACHELOG}" }  
    }  
  }  
  date {  
    match => [ "timestamp" , "dd/MMM/yyyy:HH:mm:ss Z" ]  
  }  
}  


output {  
  elasticsearch {  
    hosts => ["localhost:9200"]  
  }  
  stdout { codec => rubydebug }  
}  

8.3 写入redis

input { stdin { } }  
output {  
    stdout { codec => rubydebug }  
    redis {  
        host => '192.168.1.104'  
        data_type => 'list'  
        key => 'logstash:redis'  
    }  
}