1. 程式人生 > 實用技巧 >分散式日誌框架ELK搭建(上)

分散式日誌框架ELK搭建(上)

最近公司起的新專案,做了分散式部署,查日誌很不方便,看網上都說用ELK來做日誌收集比較好,就試著搭了一下。

ELK介紹

ELK是三個開源軟體的縮寫,分別為:Elasticsearch 、 Logstash以及Kibana , 它們都是開源軟體。

  1. Elasticsearch是個開源分散式搜尋引擎,提供蒐集、分析、儲存資料三大功能。它的特點有:分散式,零配置,自動發現,索引自動分片,索引副本機制,restful風格介面,多資料來源,自動搜尋負載等。
  2. Logstash 主要是用來日誌的蒐集、分析、過濾日誌的工具,支援大量的資料獲取方式。一般工作方式為c/s架構,client端安裝在需要收集日誌的主機上,server端負責將收到的各節點日誌進行過濾、修改等操作在一併發往elasticsearch上去。
  3. Kibana 也是一個開源和免費的工具,Kibana可以為 Logstash 和 ElasticSearch 提供的日誌分析友好的 Web 介面,可以幫助彙總、分析和搜尋重要資料日誌。

ELK三者之間的協作架構圖:

需求背景

  1. 業務發展越來越龐大,伺服器越來越多
  2. 各種訪問日誌、應用日誌、錯誤日誌量越來越多,導致運維人員無法很好的去管理日誌
  3. 開發人員排查問題,需要到伺服器上查日誌,不方便
  4. 運營人員需要一些資料,需要我們運維到伺服器上分析日誌

為什麼要用ELK

一般我們需要進行日誌分析場景:直接在日誌檔案中 grep、awk 就可以獲得自己想要的資訊。但在規模較大也就是日誌量多而複雜的場景中,此方法效率低下,面臨問題包括日誌量太大如何歸檔、文字搜尋太慢怎麼辦、如何多維度查詢。需要集中化的日誌管理,所有伺服器上的日誌收集彙總。常見解決思路是建立集中式日誌收集系統,將所有節點上的日誌統一收集,管理,訪問。大型系統通常都是一個分散式部署的架構,不同的服務模組部署在不同的伺服器上,問題出現時,大部分情況需要根據問題暴露的關鍵資訊,定位到具體的伺服器和服務模組,構建一套集中式日誌系統,可以提高定位問題的效率。

ELK安裝的準備工作

準備三臺linux虛擬機器

三臺虛擬機器,一主二從。

角色劃分

  1. 3臺機器全部安裝jdk1.8,因為elasticsearch是java開發的
  2. 3臺全部安裝elasticsearch (後續都簡稱為es)
  3. 10.167.201.57作為主節點
  4. 10.167.201.58以及10.167.201.59作為資料節點
  5. 主節點上需要安裝kibana
  6. 在10.167.201.58上安裝 logstash

ELK版本資訊

  1. Elasticsearch-6.0.0
  2. logstash-6.0.0
  3. kibana-6.0.0
  4. filebeat-6.0.0

配置三臺機器的hosts檔案內容如下:

$ vim /etc/hosts
10.167.201.57 master-node
10.167.201.58 data-node1
10.167.201.59 data-node2

然後三臺機器都得關閉防火牆或清空防火牆規則。

安裝Elasticsearch

安裝

這裡直接使用rpm方式安裝(三臺都需要裝)

[root@master-node ~]# wget httpss://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-6.0.0.rpm
[root@master-node ~]# rpm -ivh elasticsearch-6.0.0.rpm

配置ES

ES配置檔案在兩個地方

[root@master-node ~]# ll /etc/elasticsearch
總用量 16
-rw-rw---- 1 root elasticsearch 2869 2月  17 03:03 elasticsearch.yml 
-rw-rw---- 1 root elasticsearch 2809 2月  17 03:03 jvm.options
-rw-rw---- 1 root elasticsearch 5091 2月  17 03:03 log4j2.properties
[root@local ~]# ll /etc/sysconfig/elasticsearch 
-rw-rw---- 1 root elasticsearch 1613 2月  17 03:03 /etc/sysconfig/elasticsearch
[root@master-node ~]# 
  • elasticsearch.yml 檔案用於配置叢集節點等相關資訊的。
  • elasticsearch 檔案則是配置服務本身相關的配置,例如某個配置檔案的路徑以及java的一些路徑配置什麼的。

配置叢集主節點的yml配置檔案:

[root@master-node ~]# vim /etc/elasticsearch/elasticsearch.yml  # 增加或更改以下內容
cluster.name: master-node  # 叢集中的名稱
node.name: master  # 該節點名稱
node.master: true  # 意思是該節點為主節點
node.data: false  # 表示這不是資料節點
network.host: 0.0.0.0  # 監聽全部ip,在實際環境中應設定為一個安全的ip
https.port: 9200  # es服務的埠號
discovery.zen.ping.unicast.hosts: ["10.167.201.57", "10.167.201.58", "10.167.201.59"] # 配置自動發現
[root@master-node ~]# 

兩個從節點的yml配置檔案僅僅有兩處改動:

[root@data-node1 ~]# vim /etc/elasticsearch/elasticsearch.yml
cluster.name: master-node  # 叢集中的名稱
node.name: data-node1  # 該節點名稱
node.master: false  # 意思是該節點為主節點
node.data: true  # 表示這不是資料節點
network.host: 0.0.0.0  # 監聽全部ip,在實際環境中應設定為一個安全的ip
https.port: 9200  # es服務的埠號
discovery.zen.ping.unicast.hosts: ["10.167.201.57", "10.167.201.58", "10.167.201.59"] # 配置自動發現
[root@data-node2 ~]# vim /etc/elasticsearch/elasticsearch.yml
cluster.name: master-node  # 叢集中的名稱
node.name: data-node2  # 該節點名稱
node.master: false  # 意思是該節點為主節點
node.data: true  # 表示這不是資料節點
network.host: 0.0.0.0  # 監聽全部ip,在實際環境中應設定為一個安全的ip
https.port: 9200  # es服務的埠號
discovery.zen.ping.unicast.hosts: ["10.167.201.57", "10.167.201.58", "10.167.201.59"] # 配置自動發現

完成以上的配置之後,到主節點上,啟動es服務:

systemctl start elasticsearch.service

啟動排錯

我這裡啟動主節點的時候沒有啟動成功,於是檢視es的日誌,但是卻並沒有生成,那就只能去看系統日誌了:

[root@master-node ~]# ls /var/log/elasticsearch/
[root@master-node ~]# tail -n50 /var/log/messages

錯誤日誌如下:


如圖,可以看到是JDK的路徑配置得不對,沒法在PATH裡找到相應的目錄。於是檢視JAVA_HOME環境變數的值指向哪裡:

[root@master-node ~]# echo $JAVA_HOME
/usr/local/jdk1.8/
[root@master-node ~]# ls /usr/local/jdk1.8/
bin        db       javafx-src.zip  lib      man          release  THIRDPARTYLICENSEREADME-JAVAFX.txt
COPYRIGHT  include  jre             LICENSE  README.html  src.zip  THIRDPARTYLICENSEREADME.txt
[root@master-node ~]# 

發現指向的路徑並沒有錯,那就可能是忘記在profile裡寫export了,於是在profile的末尾加上了這一句:

export JAVA_HOME JAVA_BIN JRE_HOME PATH CLASSPATH

使用source命令重新載入了profile之後,重新啟動es服務,但是依舊啟動不起來,於是我發現我忽略了一條錯誤日誌:


這是無法在環境變數中找到java可執行檔案,那就好辦了,做一個軟連結過去即可:

[root@master-node ~]# ln -s /usr/local/jdk1.8/bin/java /usr/bin/

再次啟動es服務,這次就終於啟動成功了:

[root@master-node ~]# systemctl restart elasticsearch.service 
[root@master-node ~]# ps aux |grep elasticsearch
elastic+   2655  9.4 31.8 3621592 1231396 ?     Ssl  15:42   0:14 /bin/java -Xms1g -Xmx1g -XX:+UseConcMarkSweepGC -XX:CMSInitiatingOccupancyFraction=75 -XX:+UseCMSInitiatingOccupancyOnly -XX:+AlwaysPreTouch -Xss1m -Djava.awt.headless=true -Dfile.encoding=UTF-8 -Djna.nosys=true -XX:-OmitStackTraceInFastThrow -Dio.netty.noUnsafe=true -Dio.netty.noKeySetOptimization=true -Dio.netty.recycler.maxCapacityPerThread=0 -Dlog4j.shutdownHookEnabled=false -Dlog4j2.disable.jmx=true -Djava.io.tmpdir=/tmp/elasticsearch.4M9NarAc -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/var/lib/elasticsearch -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintTenuringDistribution -XX:+PrintGCApplicationStoppedTime -Xloggc:/var/log/elasticsearch/gc.log -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=32 -XX:GCLogFileSize=64m -Des.path.home=/usr/share/elasticsearch -Des.path.conf=/etc/elasticsearch -cp /usr/share/elasticsearch/lib/* org.elasticsearch.bootstrap.Elasticsearch -p /var/run/elasticsearch/elasticsearch.pid --quiet
root       2735  0.0  0.0 112660   968 pts/0    S+   15:44   0:00 grep --color=auto elasticsearch
[root@master-node ~]# netstat -lntp |grep java  # es服務會監聽兩個埠
tcp6       0      0 :::9200                 :::*                    LISTEN      2655/java           
tcp6       0      0 :::9300                 :::*                    LISTEN      2655/java           
[root@master-node ~]# 

9300埠是叢集通訊用的,9200則是資料傳輸時用的。主節點啟動成功後,依次啟動其他節點即可。

curl檢視es叢集

叢集的健康檢查

[root@master-node ~]# curl '10.167.201.57:9200/_cluster/health?pretty'
{
  "cluster_name" : "master-node",
  "status" : "green",  # 為green則代表健康沒問題,如果是yellow或者red則是叢集有問題
  "timed_out" : false,  # 是否有超時
  "number_of_nodes" : 3, # 叢集中的節點數量
  "number_of_data_nodes" : 2, # 叢集中data節點的數量
  "active_primary_shards" : 0,
  "active_shards" : 0,
  "relocating_shards" : 0,
  "initializing_shards" : 0,
  "unassigned_shards" : 0,
  "delayed_unassigned_shards" : 0,
  "number_of_pending_tasks" : 0,
  "number_of_in_flight_fetch" : 0,
  "task_max_waiting_in_queue_millis" : 0,
  "active_shards_percent_as_number" : 100.0
}
[root@master-node ~]# 

叢集的詳細資訊

[root@master-node ~]# curl '10.167.201.57:9200/_cluster/state?pretty'
{
  "cluster_name" : "master-node",
  "compressed_size_in_bytes" : 354,
  "version" : 4,
  "state_uuid" : "QkECzZHVQJOXB7K_9CgXYQ",
  "master_node" : "SGez5oKUTa2eIijLp8MsLQ",
  "blocks" : { },
  "nodes" : {
    "4sJURH6cTsykgLberJ6pVw" : {
      "name" : "data-node1",
      "ephemeral_id" : "t16_uw92T5ajJqp2HWodrg",
      "transport_address" : "10.167.201.57:9300",
      "attributes" : { }
    },
    "SGez5oKUTa2eIijLp8MsLQ" : {
      "name" : "master",
      "ephemeral_id" : "eJZX20tpSNyJCHgBIC4x4Q",
      "transport_address" : "10.167.201.57:9300",
      "attributes" : { }
    },
    "nZ4L5-KwSdirnluhJTGn7Q" : {
      "name" : "data-node2",
      "ephemeral_id" : "pQENcoUcRY6fTs7SamX2KQ",
      "transport_address" : "10.167.201.59:9300",
      "attributes" : { }
    }
  },
  "metadata" : {
    "cluster_uuid" : "jZPv-awrQDe163Nu3y2hHw",
    "templates" : { },
    "indices" : { },
    "index-graveyard" : {
      "tombstones" : [ ]
    }
  },
  "routing_table" : {
    "indices" : { }
  },
  "routing_nodes" : {
    "unassigned" : [ ],
    "nodes" : {
      "nZ4L5-KwSdirnluhJTGn7Q" : [ ],
      "4sJURH6cTsykgLberJ6pVw" : [ ]
    }
  },
  "restore" : {
    "snapshots" : [ ]
  },
  "snapshot_deletions" : {
    "snapshot_deletions" : [ ]
  },
  "snapshots" : {
    "snapshots" : [ ]
  }
}
[root@master-node ~]# 

瀏覽器檢視

顯示出來的也是一堆字串,如果要這些資訊能以圖形化的方式顯示出來,那就需要安裝kibana來展示這些資料了。