概述
在單體服務中我們需要檢視日志隻需直接在日志檔案中 grep、awk 就可以獲得自己想要的資訊。
但是在微服務架構中,不同的服務子產品一般會部署多個節點,日志散落在多個節點的日志檔案中。一旦出現問題,我們就需要登入不同的服務節點分别檢視日志,非常之繁瑣。是以在微服務架構中,我們是需要建立集中式日志收集系統,将所有節點上的日志統一收集,管理,通路。
現在目前主流的分布式日志解決方案還是基于ELK(ElasticSearch、Logstash、Kibana),今天我們就動手搭建一個單機版的ELK日志收集系統并将我們的日志檔案內建進去。
ELK版本:7.13.4
ElasticSearch 安裝配置
說明:ElasticSearch7.13.4内置了JDK16,如果沒有特殊要求,直接使用預設JDK即可。本文中直接使用ElasticSearch的預設JDK16。
- 下載下傳
下載下傳位址:
https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-7.13.4-linux-x86_64.tar.gz- 上傳檔案并解壓縮
将下載下傳下來的ElasticSearch上傳至伺服器目錄/app/elasticsearch,并将其解壓
cd /app/elasticsearch
tar -zxvf elasticsearch-7.13.4-linux-x86_64.tar.gz
解壓完成後的目錄結構如下:
ll
total 319484
drwxr-xr-x 9 elastic elastic 4096 Jul 15 02:37 elasticsearch-7.13.4
-rw-r--r-- 1 root root 327143992 Aug 3 14:26 elasticsearch-7.13.4-linux-x86_64.tar.gz
- 建立ElasticSearch啟動使用者
ElasticSearch不允許使用root使用者啟動,是以我們需要建立一個elastic使用者用于啟動ElasticSearch,并授予使用者對應權限。
useradd elastic
chown -R elastic:elastic /app/elasticsearch/
- 修改es配置
配置檔案為:
/app/elasticsearch/elasticsearch-7.13.4/config/elasticsearch.yml
關鍵配置:
cluster.name: elk-application
node.name: node-1
network.host: 0.0.0.0
http.port: 9200
discovery.seed_hosts: ["127.0.0.1"]
cluster.initial_master_nodes: ["node-1"]
- 修改es的JVM參數
/app/elasticsearch/elasticsearch-7.13.4/config/jvm.options
配置内容:
-Xms4g
-Xmx4g
- 修改系統配置檔案
- 在
中增加如下配置/etc/sysctl.conf
vm.max_map_count = 655360
-
後面增加如下配置/etc/security/limits.conf
* soft memlock unlimited
* hard memlock unlimited
* hard nofile 65536
* soft nofile 65536
修改完成後需要使用指令
sysctl -p
重新加載配置。
- 切換elastic使用者并啟動ElasticSearch
su - elastic
cd /app/elasticsearch/elasticsearch-7.13.4/bin
./elasticsearch # 正常啟動,可以看到啟動日志
或者 ./elasticsearch -d # 背景啟動,看不到啟動日志
- 驗證安裝
在伺服器執行
curl 127.0.0.1:9200
指令,檢視輸出結果,如果輸出如下json資料,則表示啟動成功。
{
"name" : "node-1",
"cluster_name" : "elk-application",
"cluster_uuid" : "qvggIOwbTk6pVlxFlulqQg",
"version" : {
"number" : "7.13.4",
"build_flavor" : "default",
"build_type" : "tar",
"build_hash" : "c5f60e894ca0c61cdbae4f5a686d9f08bcefc942",
"build_date" : "2021-07-14T18:33:36.673943207Z",
"build_snapshot" : false,
"lucene_version" : "8.8.2",
"minimum_wire_compatibility_version" : "6.8.0",
"minimum_index_compatibility_version" : "6.0.0-beta1"
},
"tagline" : "You Know, for Search"
}
如果你伺服器已經安裝好了JDK環境并且想使用自己的JDK,可以修改配置中的
/app/elasticsearch/elasticsearch-7.13.4/bin
elasticsearch-env
。
在配置ES_CLASSPATH="$ES_HOME/lib/*"之後加入
ES_JAVA_HOME=/app/elasticsearch/elasticsearch-7.13.4/jdk # 修改為你自己的jdk位址
Kibana 安裝配置
将下載下傳下來的Kibana上傳至伺服器目錄/app/Kibana,并将其解壓
cd /app/kibana
tar -zxvf kibana-7.13.4-linux-x86_64.tar.gz
- 修改配置檔案
/kibana/kibana-7.13.4-linux-x86_64/config/kibana.yml
# 端口
server.port: 5601
# 指定本機ip讓外部能通路
server.host: "0.0.0.0"
# 請求資料指向的elasticsearch伺服器
elasticsearch.hosts: ["http://ip:9200"]
# 中文漢化
i18n.locale: "zh-CN"
這幾個配置在配置檔案中被注釋掉了,直接放開注釋做相應的修改即可。
- 建立kibana啟動使用者
Kibana預設情況下也不允許使用root使用者啟動,你可以選擇在啟動指令後加上
--allow-root
參數,不過為了規範,我們還是建立一個獨立使用者用于啟動Kibana,并授予使用者對應權限。
useradd kibana
chown -R kibana:elastic /app/kibana/
- 切換使用者并使用啟動kibana
su - kibana # 切換使用者
./kibana
或者 ./kibana &
或者 ./kibana --allow-root # 未設定獨立使用者,不建議使用
- 通路
通過浏覽器輸入
http://ip:5601/
即可通路kibana

安全加強
我們剛剛部署的Kibana是不需要密碼就可以登入的,這樣誰都可以kibana通路并且更改索引資料,在生産環境中為了保證資料的安全,我們必須得給kibana加上密碼,保證使用者登入後可進行操作。
主要是利用elasticsearch自帶的xpack作為權限驗證功能。操作步驟如下:
1. 修改ES配置開啟
X-PACK
修改ElasticSearch的配置檔案,
/app/elasticsearch/elasticsearch-7.13.4/config/elasticsearch.yml
,開啟x-pack
xpack.security.enabled: true
xpack.security.transport.ssl.enabled: true
2. 重新開機ElasticSearch
./bin/elasticsearch -d
3. 初始化使用者密碼
cd /app/elasticsearch/elasticsearch-7.13.4/bin
./elasticsearch-setup-passwords interactive
執行後會出現下面的内容,讓你設定對應的密碼,輸入 y 繼續
Initiating the setup of passwords for reserved users elastic,apm_system,kibana,kibana_system,logstash_system,beats_system,remote_monitoring_user.
You will be prompted to enter passwords as the process progresses.
Please confirm that you would like to continue [y/N]y
...
Changed password for user [apm_system]
Changed password for user [kibana_system]
Changed password for user [kibana]
Changed password for user [logstash_system]
Changed password for user [beats_system]
Changed password for user [remote_monitoring_user]
Changed password for user [elastic]
4. 設定證書
啟用x-pack後ElasticSearch的啟動日志會報
Caused by: javax.net.ssl.SSLHandshakeException: No available authentication scheme
的異常,原因是因為缺少CA憑證,是以我們需要給其生成一個。
./bin/elasticsearch-certutil ca
看到提示後直接回車即可,不用設定密碼
If you elect to generate PEM format certificates (the -pem option), then the output will
be a zip file containing individual files for the CA certificate and private key
Please enter the desired output file [elastic-stack-ca.p12]: # 直接回車
Enter password for elastic-stack-ca.p12 : # 直接回車
之後我們在ElasticSearch的安裝目錄下會看到這個證書檔案
elastic-stack-ca.p12
現在我們借助生成的這個證書檔案生成p12秘鑰
./bin/elasticsearch-certutil cert --ca elastic-stack-ca.p12
看到提示後還是直接回車,不設定密碼
Enter password for CA (elastic-stack-ca.p12) : # 直接回車
Please enter the desired output file [elastic-certificates.p12]: # 回車
Enter password for elastic-certificates.p12 : # 回車
# 檔案路徑
Certificates written to /app/elasticserach/elasticsearch-7.13.4/elastic-certificates.p12
此時檔案如下:
在config目錄下建立
certs
目錄,并将生成的秘鑰檔案拷貝進去
mkdir certs
cp ../elastic-certificates.p12 certs/elastic-certificates.p12
再次修改ElasticSearch的配置檔案
elasticsearch.yml
中xpack相關配置
xpack.security.enabled: true
xpack.security.transport.ssl.enabled: true
xpack.security.transport.ssl.verification_mode: certificate
xpack.security.transport.ssl.keystore.path: certs/elastic-certificates.p12
xpack.security.transport.ssl.truststore.path: certs/elastic-certificates.p12
接着再次重新開機ElasticSearch後錯誤消失。
5. 修改Kibana配置
修改kibana配置檔案
/app/kibana/kibana-7.13.4-linux-x86_64/config/kibana.yml
elasticsearch.username: "elastic"
elasticsearch.password: "changeMe"
5. 重新啟動kibana
6. 驗證
使用curl通路ElasticSearch提示需要密碼
{
"error": {
"root_cause": [
{
"type": "security_exception",
"reason": "missing authentication credentials for REST request [/]",
"header": {
"WWW-Authenticate": "Basic realm=\"security\" charset=\"UTF-8\""
}
}
],
"type": "security_exception",
"reason": "missing authentication credentials for REST request [/]",
"header": {
"WWW-Authenticate": "Basic realm=\"security\" charset=\"UTF-8\""
}
},
"status": 401
}
帶上密碼後重新調用,顯示正常
curl --user elastic:password http://ip:9200/
{
"name" : "node-1",
"cluster_name" : "efk-application",
"cluster_uuid" : "qvggIOwbTk6pVlxFlulqQg",
"version" : {
"number" : "7.13.4",
"build_flavor" : "default",
"build_type" : "tar",
"build_hash" : "c5f60e894ca0c61cdbae4f5a686d9f08bcefc942",
"build_date" : "2021-07-14T18:33:36.673943207Z",
"build_snapshot" : false,
"lucene_version" : "8.8.2",
"minimum_wire_compatibility_version" : "6.8.0",
"minimum_index_compatibility_version" : "6.0.0-beta1"
},
"tagline" : "You Know, for Search"
}
重新登入kibana需要使用密碼,需要使用elastic賬戶登入
登入後在kibana中可以對使用者和角色進行管理。
Logstash安裝配置
将下載下傳下來的logstash上傳至伺服器目錄
/app/logstash
,并将其解壓
cd /app/logstash
tar -zxvf logstash-7.13.4-linux-x86_64.tar.gz
/app/logstash/logstash-7.13.4/config
中複制
logstash-sample.conf
為
logstash.conf
,并修改裡面的内容:
cp logstash-sample.conf logstash.conf
input {
beats {
port => 5044
}
}
output {
elasticsearch {
hosts => ["http://ip:9200"]
index => "%{[@metadata][beat]}-%{[@metadata][version]}-%{+YYYY.MM.dd}"
user => "elastic"
password => "password"
}
}
主要修改host、user、password的屬性值。
- 啟動logstash
./logstash -f ../config/logstash.conf
通過上面的安裝配置我們已經将ELK環境搭建完畢,接下來需要将日志內建進來。
內建日志
日志接入到ELK有多種形式,最常見的就是使用FileBeat。此時Filebeat扮演日志代理的角色,安裝在生成日志檔案的計算機上,跟蹤它們,并将資料轉發到Logstash以進行更進階的處理,或者直接轉發到Elasticsearch進行索引。
這種方式實作比較簡單,在我 “運維監控” 系列文章中有詳細介紹,感興趣的同學可以移步檢視。
ELK實戰二 - 日志內建今天我們介紹另外一種方式,使用
logstash-logback-encoder
直接将logback日志推送到logstash。
配置 logstash 輸出到 elasticsearch
操作步驟如下:
- 引入logstash插件包
<dependency>
<groupId>net.logstash.logback</groupId>
<artifactId>logstash-logback-encoder</artifactId>
<version>6.6</version>
</dependency>
- 修改logback-spring.xml,配置logstash到appender
<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="false">
<!--定義日志檔案的存儲位址 -->
<property name="LOG_HOME" value="./logs" />
<property name="LOG_NAME" value="cloud_gateway" />
<springProperty scope="context" name="applicationName" source="spring.application.name"/>
...
<!--LogStash-->
<appender name="logstash" class="net.logstash.logback.appender.LogstashTcpSocketAppender">
<!--logstash的請求位址-->
<destination>172.xx.0.xxx:5064</destination>
<encoder charset="UTF-8" class="net.logstash.logback.encoder.LogstashEncoder">
<customFields>{"serverName":"${applicationName}"}</customFields>
</encoder>
</appender>
<!-- 日志輸出級别 -->
<root level="INFO">
...
<appender-ref ref="logstash"/>
</root>
</configuration>
檔案中删除了不相關的配置,值得注意的是這裡定義了一個靜态常量
appllicationName
,從配置檔案中讀取
spring.application.name
的值,并通過
customFields
自定義字段
serverName
傳輸到了logstash。
- 修改logstash的配置檔案,logstash.conf
input {
tcp {
port => 5064
codec => json_lines
type => "cloud_alibaba"
}
}
output {
# 如果不需要列印可以直接删除
stdout{
codec => rubydebug
}
# 通過type用于區分不同來源的日志
if [type] == "cloud_alibaba"{
elasticsearch {
hosts => ["http://localhost:9200"]
index => "%{[serverName]}-%{+YYYY.MM.dd}"
user => "elastic"
password => "changeMe"
}
}
}
logstash需要使用tcp協定接受logstash傳來的日志,并使用
customFields
中定義的
serverName
動态建立索引。
- 重新啟動logstash 以及後端服務
通過logstash的啟動面闆可以看到日志已經傳輸到了ElasticSearch,并且已經使用cloud-gateway作為索引名。
kibana操作
日志傳輸到ElasticSearch後我們就需要借助kibana将日志展示出來。
首先我們需要登入kibana,建立索引模式
使用
cloud-gateway-*
作為索引名稱,然後點下一步并儲存。
然後就可以在Discover中檢視日志了。
可以通過左側添加對應的字段。
當然也可以流式傳輸實時檢視日志
至于kibana的其他功能就需要各位自己去摸索了。
logback動态讀取logstash的路徑
上面我們配置logstash輸出到elasticsearch的時候是直接寫死了
destination
的配置
<destination>172.xx.0.xxx:5064</destination>
那在實際開發的時候我們肯定不能這樣,環境不同
logstash
的路徑也不同,是以我們需要從nacos配置中心讀取對應logstash的位址。
小提示,springboot讀取配置檔案是有優先級的,如果使用預設的logback.xml或者logback-spring.xml為配置檔案名則會讀取不到nacos上的配置,他會先于配置中心加載。是以我們這裡需要使用自定義配置檔案。
- 修改nacos配置中心service對應的配置檔案,配置自定義日志名稱以及logstash的路徑
logging:
config: classpath:logback-custom.xml
logstash:
destination: 172.xx.0.xxx:5064
- 修改日志配置檔案為
logback-custom.xml
- 在logback-custom.xml中定義常量,從配置中心讀取配置,并修改
屬性的值destination
<springProperty scope="context" name="logstashDestination" source="logstash.destination"/>
...
<destination>${logstashDestination}</destination>
通過上面三步操作,我們的logback就可以直接從nacos配置檔案中加載logstash的相關配置了。
好了,今天的文章就到這裡了,希望能對你有所幫助。最後,我是飄渺Jam,一名寫代碼的架構師,做架構的程式員,期待您的轉發與關注,當然也可以添加我的個人微信 jianzh5,咱們一起聊技術!
小結
ELK集中式日志是分布式架構中必不可少的一個元件,本文詳細介紹了ELK基礎環境的安裝配置,希望對各位有所幫助。最後,我是飄渺Jam,一名寫代碼的架構師,做架構的程式員,期待您的轉發與關注,當然也可以添加我的個人微信 jianzh5,咱們一起聊技術!