概述
在單體服務中我們需要查看日誌只需直接在日誌文件中 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 安裝配置
- 下載
下載地址:https://artifacts.elastic.co/downloads/kibana/kibana-7.13.4-linux-x86_64.tar.gz
- 上傳文件並解壓縮
將下載下來的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安裝配置
- 下載
下載地址:https://artifacts.elastic.co/downloads/logstash/logstash-7.13.4-linux-x86_64.tar.gz
- 上傳文件並解壓縮
將下載下來的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進行索引。
這種方式實現比較簡單,在我 “運維監控” 系列文章中有詳細介紹,感興趣的同學可以移步查看。
今天我們介紹另外一種方式,使用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"></appender-ref>
</root>
</springproperty></property></property></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的相關配置了。
小結
ELK集中式日誌是分佈式架構中必不可少的一個組件,本文詳細介紹了ELK基礎環境的安裝配置,希望對各位有所幫助。最後,我是飄渺Jam,一名寫代碼的架構師,做架構的程序員,期待您的轉發與關注,當然也可以添加我的個人微信 jianzh5,咱們一起聊技術!