企業級應用——ELK(一):ELK的部署

  ELK是Elasticsearch、Logstash、Kibana的簡稱,這三者是核心套件,但並非全部。
  Elasticsearch是實時全文搜索和分析引擎,提供蒐集、分析、存儲數據三大功能;是一套開放REST和JAVA API等結構提供高效搜索功能,可擴展的分佈式系統。它構建於Apache Lucene搜索引擎庫之上。
  Logstash是一個用來蒐集、分析、過濾日誌的工具。它支持幾乎任何類型的日誌,包括系統日誌、錯誤日誌和自定義應用程序日誌。它可以從許多來源接收日誌,這些來源包括 syslog、消息傳遞(例如 RabbitMQ)和JMX,它能夠以多種方式輸出數據,包括電子郵件、websockets和Elasticsearch。
  Kibana是一個基於Web的圖形界面,用於搜索、分析和可視化存儲在 Elasticsearch指標中的日誌數據。它利用Elasticsearch的REST接口來檢索數據,不僅允許用戶創建他們自己的數據的定製儀表板視圖,還允許他們以特殊的方式查詢和過濾數據。

ELK架構

  通常來說,只使用這三個組件就可以進行日誌收集了,不過在企業實際生產中,需要用到ELK做集中日誌收集的話,日誌的產生量都是驚人的,所以通常情況下會需要緩存層來防止elasticsearch被壓垮。架構如下圖所示。(也可以通過filebeat來收集日誌。)
ELK架構

ELK的部署

  需要注意的是,ELK的這三個組件版本要一致,否則可能會出現一些不必要的問題。我們這裏選用最新版本7.5.1爲例,演示主機均爲ubuntu1804。

Elasticsearch

  我們這裏用兩臺主機來搭建一個elasticsearch集羣,一般來說因爲他的選舉機制,elasticsearch集羣都是3、5、7奇數個,不過2臺主機也可以使用,我們這裏節約主機使用兩臺主機做演示,IP分別爲192.168.32.41192.168.32.42

  官網下載鏈接爲https://www.elastic.co/cn/downloads/elasticsearch
  我們這裏選擇deb安裝包安裝,也可以選用源碼tar包自己解壓安裝。

wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-7.5.1-amd64.deb

  這個版本的deb包是自帶java環境(openjdk11)的,如果主機已經預製java環境,可以去官網下載no-java的版本,使用jdk8的時候有warning,說未來版本將不支持jdk8,建議使用jdk11及以上。

dpkg -i elasticsearch-7.5.1-amd64.deb

  elasticsearch的配置文件路徑爲/etc/elasticsearch/elasticsearch.yml,需要修改的不多,將集羣主機IP設置好就可以了,如下所示

root@elasticsearch1:~# grep "^[a-Z]" /etc/elasticsearch/elasticsearch.yml
cluster.name: ELK-CLuster      #集羣名稱,名稱相同即屬於是同一個集羣
node.name: node-1                 #本機在集羣內的節點名稱
path.data: /elasticsearch/data
path.logs: /elasticsearch/logs
bootstrap.memory_lock: true   #服務啓動的時候鎖定足夠的內存, 防止數據寫入swap
network.host: 0.0.0.0
http.port: 9200
discovery.seed_hosts: ["192.168.32.41","192.168.32.42"]
cluster.initial_master_nodes: ["node-1","node-2"]

  我這裏是單獨創建了一個日誌路徑和數據路徑,方便管理,並修改屬主賦予權限。

mkdir -p /elasticsearch/{data,logs}
chown -R elasticsearch:elasticsearch /elasticsearch

  除了在配置文件中設置bootstrap.memory_lock: true以外,還需要在啓動配置文件中設置允許無限制使用內存,否則啓動檢查就會報錯,導致服務起不來。

vim /usr/lib/systemd/system/elasticsearch.service
LimitMEMLOCK=infinity

  而且根據官方文檔https://www.elastic.co/guide/en/elasticsearch/reference/current/heap-size.html,最大30G 以內的內存。
  在一般使用中,使用最大內存和最小內存都設置爲2G就可以了。

vim /etc/elasticsearch/jvm.options
-Xms2g
-Xmx2g

  另一臺主機也同樣配置,記得修改node.name,之後就可以啓動elasticsearch了。

systemctl enable --now elasticsearch

  在任意主機使用curl命令可以檢查集羣的健康狀態。

curl -sXGET http://192.168.32.41:9200/_cluster/health?pretty=true

  獲取到的是一個 json 格式的返回值,那就可以通過 python 對其中的信息進行分析,例如對 status 進行分析,如果等於 green(綠色)就是運行在正常,等於yellow(黃色)表示副本分片丟失, red(紅色)表示主分片丟失。
  至此,elasticsearch服務的部署就算是完成了。

Logstash

  logstash也是一個基於java的插件式服務,很多功能都是依靠於插件來實現的,我們安裝官方的安裝包,大部分常用插件都是已經預置了,如果還有其他的功能需求,就需要去官網或者github下載插件了。這些之後再說,我們先去官網上將Logstash7.5.1安裝包下載下來並部署上。

wget https://artifacts.elastic.co/downloads/logstash/logstash-7.5.1.deb

  logstash也同樣需要java環境

apt update
apt install openjdk-8-jdk

  或者安裝oracle的jdk,生產環境還是推薦使用oracle公司的jdk,更加穩定。然後安裝logstash

dpkg -i logstash-7.5.1.deb

  對於logstash的配置也很少,不做修改也可以使用,不過我們這裏同樣還是修改一下數據目錄和日誌目錄

root@logstash1:~# grep "^[a-Z]" /etc/logstash/logstash.yml
path.data: /logstash/data
path.logs: /logstash/logs

  修改屬主

mkdir -p /logstash/{data,logs}
chown -R /logstash

  logstash的默認執行程序路徑爲/usr/share/logstash/bin/logstash,這其實也是一個shell腳本文件,腳本中調用java的類庫。

root@logstash1:~# /usr/share/logstash/bin/logstash --help
Thread.exclusive is deprecated, use Thread::Mutex
WARNING: Could not find logstash.yml which is typically located in 
$LS_HOME/config or /etc/logstash. You can specify the path using --path.settings.
 Continuing using the defaults
Usage:
    bin/logstash [OPTIONS]

Options:
    -n, --node.name NAME          Specify the name of this logstash instance, 
                                  if no value is given
                                  it will default to the current hostname.
                                   (default: "logstash1")
    -f, --path.config CONFIG_PATH Load the logstash config from a specific file
                                  or directory.  If a directory is given, all
                                  files in that directory will be concatenated
                                  in lexicographical order and then parsed as a
                                  single config file. You can also specify
                                  wildcards (globs) and any matched files will
                                  be loaded in the order described above.
    -e, --config.string CONFIG_STRING Use the given string as the configuration
                                  data. Same syntax as the config file. If no
                                  input is specified, then the following is
                                  used as the default input:
                                  "input { stdin { type => stdin } }"
                                  and if no output is specified, then the
                                  following is used as the default output:
                                  "output { stdout { codec => rubydebug } }"
                                  If you wish to use both defaults, please use
                                  the empty string for the '-e' flag.
                                   (default: nil)

  不過常用的選項也就-e-f,分別是通過命令行指定參數或者通過文件來指定配置參數。我們可以使用命令來測試

/usr/share/logstash/bin/logstash -e 'input { stdin{} } output { stdout{ codec => rubydebug }}' 

輸出日誌
  通過標準輸入輸入信息,並通過標準輸出返回日誌信息。同樣,我們也可以調用input的file插件和output的file插件實現從文件中讀取數據,或者寫入文件。這樣就可以實現對日誌文件的抓取了。我們可以先嚐試抓取系統日誌如syslog

/usr/share/logstash/bin/logstash -e 'input { file { path => "/var/log/syslog"} } output { stdout{ codec => rubydebug }}' 

  哈,系統日誌如果太多,估計會刷屏的。
  不過剛纔那些都只是一些基本用法而已,而實際生產中,我們肯定不能使用命令行來手動獲取數據,我們需要的是一個可靠的服務,來幫我們自動抓取日誌並篩選過濾,這就需要我們使用配置文件來設置了。
  例如我們要做的抓取本機的nginx的訪問日誌、錯誤日誌還有系統日誌,並傳遞至之前配好的elasticsearch中。
  那就在路徑/etc/logstash/conf.d/目錄下,創建一個新的配置文件,使用systemd啓動時會自動讀取conf.d下的配置文件。

vim /etc/logstash/conf.d/nginx.conf
input {
  file { 
    path => "/var/log/syslog"
    stat_interval => 3
    start_position => "beginning"
    type => "syslog"
  }
  file { 
    path => "/apps/nginx/logs/access_json.log"
    stat_interval => 3
    start_position => "beginning"
    codec => "json"
    type => "nginx_accesslog"
  }
  file { 
    path => "/apps/nginx/logs/error.log"
    stat_interval => 3
    start_position => "beginning"
    type => "nginx_errorlog"
  }
}

output {
  if [type] == "syslog" {
  elasticsearch {
    hosts => ["192.168.32.41:9200"]
    index => "syslog-%{+YYYY.MM.dd}"
  }}
  if [type] == "nginx_accesslog" {
  elasticsearch {
    hosts => ["192.168.32.41:9200"]
    index => "nginx_accesslog-%{+YYYY.MM.dd}
  }}
  if [type] == "nginx_errorlog" {
  elasticsearch {
    hosts => ["192.168.32.41:9200"]
    index => "nginx_accesslog-%{+YYYY.MM.dd}
  }}
}

  logstash支持條件判斷,多輸入以及多輸出,設定type規則,來將每一類日誌分類在不同的索引,且支持java的時間變量,可以實現根據日期歸檔每一天的日誌,方便查看和統計。
  我們可以使用命令來測試腳本的語法是否正確,如果不加-t可以直接以前臺進程的方式啓動logstash,不過會佔據終端,但測試的時候還是蠻方便的。

/usr/share/logstash/bin/logstash -f /etc/log/logstash/conf,d/nginx.conf -t

  不過僅僅是這樣,是無法統計具體訪問時間、訪問ip及訪問路徑的詳細信息的,我們需要將nginx的日誌序列化,或者說是儲存爲json格式。
  所以修改nginx的配置文件,將日誌格式修改一下。

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"';

    log_format access_json '{"@timestamp":"$time_iso8601",'
        '"host":"$server_addr",'
        '"clientip":"$remote_addr",'
        '"size":$body_bytes_sent,'
        '"responsetime":$request_time,'
        '"upstreamtime":"$upstream_response_time",'
        '"upstreamhost":"$upstream_addr",'
        '"http_host":"$host",'
        '"uri":"$uri",'
        '"domain":"$host",'
        '"xff":"$http_x_forwarded_for",'
        '"referer":"$http_referer",'
        '"tcp_xff":"$proxy_protocol_addr",'
        '"http_user_agent":"$http_user_agent",'
        '"status":"$status"}';

    access_log  /apps/nginx/logs/access_json.log  access_json;

  PS:加入的屬性名稱不要有type,否則會影響到logstash做type判斷。然後記得在配置文件中註明輸入信息爲json格式。看到如下信息,則說明日誌被成功拆解。

{
    "http_user_agent" => "Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:69.0) Gecko/20100101 Firefox/69.0",
               "path" => "/apps/nginx/logs/access_json.log",
         "@timestamp" => 2020-01-03T08:17:47.000Z,
       "upstreamhost" => "-",
                "xff" => "-",
       "responsetime" => 0.0,
               "size" => 0,
             "status" => "304",
          "http_host" => "192.168.32.51",
           "clientip" => "192.168.32.1",
             "domain" => "192.168.32.51",
            "tcp_xff" => "",
               "host" => "192.168.32.51",
           "@version" => "1",
                "uri" => "/index.html",
            "referer" => "-",
       "upstreamtime" => "-"
}

  使用systemctl enable --now logstash啓動logstash服務,過一會,日誌就寫入elasticsearch服務器中了,最好將/etc/systemd/system/logstash.service文件的中啓動用戶組都改爲root,避免因爲權限問題,導致無法讀取數據。
  我記得之前遇到過一次,命令行可以正常使用logstash,不過使用systemd啓動就一直報錯,logstash: could not find java; set JAVA_HOME or ensure java is in PATH,明明環境變量都是正常的,後來在/usr/share/logstash/bin/logstash腳本文件中加了一個JAVA_HOME=/usr/local/jdk環境變量就好了,而之後配的時候就沒有遇到這個問題了,這就很奇怪了。

Kibana

  日誌信息都已經寫到elasticsearch服務器中了,不過我們怎麼纔可以看到具體的日誌信息呢?這就需要藉助日誌展示工具Kibana了。
  雖然elasticsearch可視化工具也有不少,例如head、kopf、cerebro等等,不過他們都是監控elasticsearch集羣狀態的,對日誌做展示分析的還是首推開源的官方組件Kibana。
  同樣下載kibana7.5.1版本

https://artifacts.elastic.co/downloads/kibana/kibana-7.5.1-amd64.deb

  配置上也很簡單,設置監聽IP及端口,設置elasticsearch主機地址,最後再將語言環境改爲中文就可以啓動kibana服務了。

root@kibana1:~# grep "^[a-Z]" /etc/kibana/kibana.yml
server.port: 5601
server.host: "0.0.0.0"
elasticsearch.hosts: ["http://192.168.32.41:9200"]
i18n.locale: "zh-CN"

  瀏覽器訪問kibana主機的5601端口。
  創建索引模式,依次添加索引。
kibana
  然後點左邊第一個(最上面)的那個discover圖標,就可以看到數據了。點擊更改,選擇對應的索引,還可以創建各種視圖等一系列功能這裏就不再詳細講解了。都比較簡單。
  至此ELK的初步部署就算完成了。

發佈了43 篇原創文章 · 獲贊 52 · 訪問量 9176
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章