體驗 Elasticsearch 的魅力 – Part 1 :: Docker

目的

目前手上專案系統的 Log 仍然存在 MS SQL Server 裡。原因是因為系統後台一開始就建置了 Log 查詢的頁面功能。讓管理人員可以查詢系統登入、運作狀況以及 API 交換的每一筆訊息紀錄。這功能讓技術克服人員與開發人員很方便的進來系統撈取 Debug 錯誤時所需的有用資訊。

在初期快速開發的階段這些功能都是用 Entity Framework 建造以求開發迅速。但當系統上線後每日運轉下來 Log 的成長量也已大大超乎預期。雖然已經因為資料庫負荷沉重把 Log 搬離主要的交易資料庫放在較為次級的 SQL Server。但每日都有相當成長量讓我們不得不面對找尋完善的 Log 管理機制。

這個測試,我們需要在不改變系統功能的前提下評估:

  1. Elasticsearch 的 REST API 是否足夠讓我們建置客製化的 API 來包裝讓並使用現有系統後台 Log 查詢機制來查詢 (不再用 Linq + Entity Framework 查 SQL Server)。
  2. Elasticsearch 完全替代 MS SQL 來存 Log:
    1. 備份與資料維護
    2. Clustering
    3. Failover 機制
    4. SSRS 報表的替代方案

相關應用

  • Docker
  • Elasticsearch
  • Kibana
  • Logstash

動手

首先我們需要把 Elasticsearch 與 Kibana 設定好,然後倒一些 Log 進 Elasticsearch 並且試試 Kibana 上的查詢功能。

這篇先寫第一部分,關於 Docker 的使用與設定。

設定 Docker

用 Docker 來測試 ELK。可以避免在日常開發機器上裝太多不常用的系統服務。

Docker Repository 上已經有許多 ELK 的 Image, 我選了 sebp/elk,並有提供詳細的 文件說明

這個 docker image 上有所有 ELK Stack,啟動時需要指定開啟各服務所需要的連接埠讓本機可與 Container 溝通。執行方式如下:

docker run -p 5601:5601 -p 9200:9200 -p 5044:5044 -it --name elk sebp/elk

指定三個連接埠 (-p) 分別代表:

  • 9200: Elasticsearch
  • 5601: Kibana
  • 5044: Logstash beats

Dockerfile

這個測試主要的目的是學習如何使用 ELK 達成目的。在不修改任何程式的前提下,第一階段要取得Log 資料須由 MS SQL 匯出到 Logstash。

因為有些 Container 相關的設定,所以我用了 Dockerfile 來把設定檔塞到 Container 裡:

FROM sebp/elk
# 在Container 建立一個工作資料夾,我們在本機編輯好的設定檔與其他必要檔案都可透過這個資料夾與Container交換
RUN mkdir /workspace
WORKDIR /workspace
ADD . /workspace

#另外我在本機有編輯了 logstash 的設定檔需要一開始就塞進 Container 裡。這邊可以將檔案加到指定的 Container 上的路徑
ADD logstash-mssql.conf /etc/logstash/conf.d/logstash-mssql.conf

#這個測試會用到 logstash 的 JDBC plugin。用以下這個步驟安裝
RUN gosu logstash /opt/logstash/bin/logstash-plugin install logstash-input-jdbc

logstash-input-jdbc 並沒有包含不同資料庫所需要的驅動程式。我們所使用的資料庫是 SQL Server。我們需要自己 下載 JDBC 驅動程式。

下載後解開壓縮檔把 sqljdbc42.jar 跟 Dockerfile 放在同一個資料夾。

docker-compose

目前只有一個 image/container,應該是用不到 docker-compose 來管理。但用 docker-compose 可以幫助我們記得要指定的連接埠。省的啟動 container 得打一大串指令。

version: '2'
services:
elk:
build: . # 要 docker-compose 執行時建置同目錄下的 Dockerfile
container_name: elk # 幫 Container 命名,之後比較好打指令
volumes:
- .:/workspace # 將本地資料夾掛在Container的 /workspace 資料夾下 [host:container]
ports:
- "9200:9200" # 對應本地與 Container 的連接埠
- "5601:5601"
- "5044:5044"

同樣跟 Dockerfile 放一起。在該資料夾下執行

docker-compose up

就可以啟動 container

設定 Logstash

sebp/elk 裡已經設定好一些 Logstash 設定檔。可以抓 beats, 系統記錄檔等等,並會把結果輸出在 localhost:9200 的 Elasticsearh 。在 container 裡的 /etc/logstash/conf.d/ 可以找到這些設定檔。之前提到需要撈 SQL Server 的設定檔也需要放在 /etc/logstash/conf.d/ Logstash 啟動時方可一併載入。

Docerfile 裡的 ADD logstash-mssql.conf /etc/logstash/conf.d/logstash-mssql.conf 這行就是要幫我們在 container 建立時把同資料夾裡的 logstash-mssql.conf 塞到 Container 的 /etc/logstash/conf.d/ 資料夾。

以下是我們設定 Logstash 撈取 SQL Server 資料庫的設定檔:

 
input{
  jdbc {
    jdbc_driver_library => "/workplace/sqljdbc42.jar"
    jdbc_driver_class => "com.microsoft.sqlserver.jdbc.SQLServerDriver"
    jdbc_connection_string => "jdbc:sqlserver://10.0.75.1:1433;databaseName=LogDatabase"
    jdbc_user => "sa"
    jdbc_password => "sa"
    jdbc_validate_connection => true
    statement => "SELECT * FROM Logs"
  }
}

output {
  elasticsearch {
    hosts => "localhost:9200"
    index => "apilogs"
    document_id => "%{id}"
    document_type => "ApiLog"
  }
}

jdbc 區段可設定資料抓取方式。以及 SQL Server 伺服器的連線資訊。這邊要注意 SQL Server 是在本機 (Windows) 上執行的 SQL Server Express。從 Container 裡面用 JDBC 連線到 SQL Server 需要透過 HTTP 通訊協定,但 SQL SERVER 預設是禁止 HTTP 連線存取的。所以我們還需要修改一下 SQL SERVER 的設定:

Sql Server Configuration Manager > SQL Server Network Configuration > Protocols for MSSQLSERVER > TCP/IP 設為 Enabled 後重新啟動資料庫服務即可。

另外,我的 docker container 與本機 連線的方式 用的是 Bridge Driver。可以在本機使用 docker network inspect bridge 指令來查看網路介面的設定狀況。

回到 Logstash config 檔:

jdbc_connection_string => "jdbc:sqlserver://10.0.75.1:1433;databaseName=LogDatabase"
在這裡我直接將連線資訊指向 Docker 在 Host 機器上安裝的網路介面。

statement => "SELECT * FROM Logs"
撈資料時使用的 SQL Statement

設定檔好之後,可以使用 Logstash 的指令來跑跑看︰

首先我們要取得 Container 的 Shell 指令介面,在Windows 的指令模式下輸入:

docker exec -it elk /bin/bash

首先確保 Dockerfile 所執行複製進 Container 是正確的 Logstash .conf 檔,可用 vim 等純文字編輯程式開來看看:

vim /etc/logstash/conf.d/logstash-mssql.conf

無誤後 :q! 退出 vim 就可跑跑 Logstash 看看效果如何了

/opt/logstash/bin/logstash -f /etc/logstash/conf.d/logstash-mssql.conf