# ELK 部屬 & 設定
[TOC]
## 部屬
### 部屬順序
> 依目前使用需求
:::info
需確認版本互相支援,[官方資料](https://www.elastic.co/support/matrix#matrix_jvm)
:::
1. Elasticsearch
2. Kibana
3. Beats (filebeat)
### 初始流程總覽(不含設定細節)
#### 1. 啟用核心服務
- 啟用 Elasticsearch
- 使用 CLI 修改 `kibana_system` 密碼(Kibana 與 ES 連線用)
- 啟用 Kibana,指定 `kibana_system` 為連線帳號
- 使用 `elastic` 登入 Kibana UI
#### 2. 權限角色與使用者建立
##### ➤ 建立角色(Roles)
1. 建立接近 `superuser` 的角色(如有特殊需求)
2. 建立 `filebeat_setup` 角色
3. 建立 `filebeat_writer` 角色
##### ➤ 建立使用者並分配角色
1. `admin_user`:給予接近 `superuser` 的角色 (如有特殊需求)
2. `filebeat_setup`:給予 `filebeat_setup` + `kibana_admin` + `ingest_admin`
3. `filebeat_writer`:給予 `filebeat_writer`
> 💡 `kibana_admin` 與 `ingest_admin` 是為了 setup 時能導入 template、dashboard、pipeline
##### ➤ 其他使用者管理
- 視情況修改 `beats_system` 密碼(Stack Monitoring 使用,通常是 Metricbeat/Filebeat)
#### 3. 建立基礎資源(如果使用自訂 index)
- 建立自定 `index template`(若非使用 `filebeat-*` 為前綴)
- 建立對應的 ILM Policy 並在 template 中引用
#### 4. 部署 Filebeat
- 啟用需要的 module(例如 elasticsearch, kibana, nginx, system 等)
- 使用 `filebeat_setup` 帳號,執行 `filebeat setup -e`
- ✅ 匯入 dashboard 至 Kibana
- ✅ 建立 `filebeat-8.x` 的 index template
- ✅ 建立 `filebeat-8.x` 的 datastream(若使用 ILM + datastream)
- ✅ 建立 `filebeat` 專用 ILM Policy(預設只包含 hot phase,後續調整policy)
#### 5. 啟用 Filebeat 傳送資料
- 使用 `filebeat_writer` 帳號執行 filebeat 主服務,開始發送 logs 到 Elasticsearch
---
### 基本需求
#### ports
| 預設Port | 元件 | 用途 | 可設定參數 |
|:-------- |:------------- |:----------------------------------------------------------------:| ---------- |
| 9200 | Elasticsearch | 給外部服務(Kibana、Logstash、curl)使用的 REST API 介面 | http.port |
| 9300 | Elasticsearch | 節點之間通訊的 Transport API(intra-cluster / Java client 使用) | transport.port |
| 5601 | Kibana | Kibana 的 HTTP 存取介面(Web UI) | server.port |
#### Bootstrap checks
Elasticsearch 啟用會有一系列的啟用檢查,會根據 [Developemtn / Production mode](##Development-Mode-vs-Production-Mode) 有差異
這些檢查是要確保可以最佳使用 Elasticsearch
:::warning
如果設定single-node,會被認為是開發模式,
在正式環境使用single-node,需透過設定JVM.options,啟用bootstrap checks
```bash
# config/jvm.options
-Des.enforce.bootstrap.checks=true
```
```yaml
# docker compose
environment:
- discovery.type=single-node
- ES_JAVA_OPTS=-Des.enforce.bootstrap.checks=true
```
:::
:::spoiler Heap size check
- :information_source: -Xms & -Xmx 需設定一樣
- JVM 啟動時,如果 初始(-Xms)與最大 heap 大小(-Xmx)不同,JVM 執行期間可能會 resize heap → 導致停頓。
- 如果有啟用 bootstrap.memory_lock: true,resize heap 還會導致 heap 區塊鎖定錯誤。
:::
:::spoiler File descriptor check
- :information_source: Elasticsearch 一個節點可能同時打開非常多檔案(shard segments、網路 socket、log、index file...)
- :information_source: Linux 預設限制每個 process 能開的檔案數量(通常太低)
- :warning: 至少需要 `65535`
```yaml
elasticsearch:
ulimits:
nofile:
soft: 65535
hard: 65535
```
:::
:::spoiler Memory lock check
> 當 JVM 執行 major GC 時,會觸碰到整個 heap 的記憶體區塊。
> 如果某些 heap pages 被 swap 到 disk,會造成 GC 期間大量 I/O,導致性能下降。
> 如果不是透過docker設定,須設定 systemd(避免被限制 memlock )
```yaml
# 防止 elasticsearch 使用 swap
elasticsearch:
environment:
- bootstrap.memory_lock=true # 避免 JVM heap 被 swap 掉
ulimits:
memlock:
soft: -1 # 對應 Linux mlock,需要 -1(無上限)
hard: -1 # 對應 Linux mlock,需要 -1(無上限)
```
:::
:::spoiler Maximum number of threads check
> Elasticsearch 的請求會被拆分成多個階段、送進不同的 thread pool executors(像是 search、write、management...)。
> 因此它需要建立大量 thread,來應付並行操作。
> 如果系統限制 thread 數過低(例如 nproc 限制),就會造成啟動失敗或服務異常。
- elasticsearch 建議至少 4096
```yaml
elasticsearch:
ulimits:
nproc: 65535 # 建議設成更高一點,例如 65535 與 nofile 設定一致
```
:::
::: spoiler Max file size check
Elasticsearch 的 shard segment files 和 translog 可能會非常大(數 GB 以上),如果作業系統限制了每個檔案的大小,會導致:
- 寫入失敗
- 索引建立異常
- 資料遺失風險
將最大檔案大小(fsize)設定為 unlimited,讓 Elasticsearch 能自由寫入大型 segment。
```bash
# /etc/security/limits.conf:
elasticsearch soft fsize unlimited
elasticsearch hard fsize unlimited
```
```yaml
elasticsearch:
ulimits:
fsize:
soft: -1
hard: -1
```
:::
:::spoiler Max virtual memory check
- Elasticsearch 與 Lucene 使用 mmap 加速資料查詢(memory-mapped IO),需要足夠的虛擬地址空間。
- 若虛擬記憶體限制太小,將導致查詢失敗或 mapping 錯誤。
- 建議設定為 unlimited:
```yaml
ulimits:
as:
soft: -1
hard: -1
```
:::
:::spoiler Max map count check
- Elasticsearch 使用 mmap 將 index segment 映射到記憶體中,每個映射需要一個記憶體區塊(memory-mapped area)。
- 若 Linux 設定的 vm.max_map_count 過小,將導致映射失敗與錯誤。
- 建議設定
```bash
sudo sysctl -w vm.max_map_count=262144
# 永久設定
echo "vm.max_map_count=262144" | sudo tee -a /etc/sysctl.conf
sudo sysctl -p
```
:warning: 此設定無法透過 docker-compose 設定,必須在主機執行。
:::
:::spoiler Client JVM check
- Elasticsearch 僅支援運行於 Server JVM。
- :information_source: 現代作業系統預設會使用 Server JVM,不需額外設定。
:::
:::spoiler Use serial collector check
- Java 有多種 Garbage Collector(GC),而 Serial GC 是最輕量、單執行緒的版本,若 Elasticsearch 使用 Serial GC,會嚴重降低效能,因此預設會進行檢查並阻止啟動。
- :information_source: 若使用 Elastic 官方映像或官方建議的 OpenJDK 版本,預設就會是 G1GC,不需額外設定。
:::
:::spoiler System call filter check
- Elasticsearch 在啟動時會安裝系統層級的 system call filter
- 確保 ES 成功啟用了 syscall 過濾器
- 如果因為系統設定或權限限制,這些過濾器無法安裝,Elasticsearch 會啟動失敗
:::
:::spoiler OnError and OnOutOfMemoryError checks
- Elasticsearch 禁止使用 OnError 或 OnOutOfMemoryError,因其依賴執行外部指令(fork/exec),與系統呼叫過濾機制(seccomp)衝突。
- :information_source: 只要不設定相關參數就沒問題
:::
:::spoiler Early-access check
- Elasticsearch 不允許在 early-access(EA)版本的 JDK 上運行,這些版本尚未正式發佈,穩定性與安全性無法保證。
- :information_source: 官方安裝或官方docker image 就沒問題
:::
:::spoiler All permission check
- 若在 JVM 啟動時指定的 policy file 中包含 java.security.AllPermission,Elasticsearch 將拒絕啟動。
- 預設情況下(包含 Elastic 官方映像)並未授予 AllPermission,因此這項檢查通常不會觸發。
:::
:::spoiler Discovery Configuration Check
- 當 Elasticsearch 啟動時,會試圖與其他節點建立叢集。如果沒有正確設定 discovery 會有問題
- 如果是單節點啟用加上 discovery.type: single-node
:::
:::spoiler Encrypt sensitive data check
- :information_source: 未使用 Watcher,可跳過此檢查。
:::
:::spoiler Role mappings check
- :information_source: elasticsearch 預設有 native realms & file realms
- :information_source: 沒有使用其他的realms不會觸發此檢查
> [!Note]
> Realm 是 Elasticsearch 處理使用者認證的模組。
:::
::: spoiler PKI realm check
- :information_source: 未啟用 xpack.security.authc.realms.pki,此檢查不會觸發。
:::
:::spoiler SSL/TLS check
- 當你啟用 Elasticsearch 的安全功能(xpack.security.enabled: true)時,Elasticsearch 預設會要求節點之間的通訊必須使用加密 (TLS)
- 要通過check,需要針對 `transport` 加上TLS
```yaml
xpack.security.enabled: true
xpack.security.transport.ssl.enabled: true
xpack.security.transport.ssl.verification_mode: certificate
xpack.security.transport.ssl.key: certs/node.key
xpack.security.transport.ssl.certificate: certs/node.crt
xpack.security.transport.ssl.certificate_authorities: [ "certs/ca.crt" ]
```
> [!Warning]
> 這是針對「節點間通訊」(9300 port)的加密,不是 HTTP API(9200)那邊。
:::
::: spoiler Token SSL check
- 若啟用內建 token 認證服務(access token、Kibana 登入等),則 必須 同時啟用 HTTP 層的 HTTPS:
```yaml
xpack.security.authc.token.enabled: true
xpack.security.http.ssl.enabled: true
```
- :warning: 若未啟用 HTTPS 則無法使用 token 功能,Elasticsearch 將拒絕啟動。
- :information_source: 不使用 token 的話,可關閉該功能以略過此檢查:
```yaml
xpack.security.authc.token.enabled: false
```
:::
#### 啟用後檢查 log
```bash
# 啟動後可以透過 log 搜尋以下關鍵字
docker logs -f elasticsearch | grep -i "bootstrap"
# 或透過 API 檢查是否成功啟動
curl -u user:pass http://localhost:9200/_cluster/health?pretty
```
### Elasticsearch & Kibana Docker compose 配置啟用
:::danger
1. 如果elasticsearch.yml 相關設定是透過掛載檔案的,必須設定 network.host: 0.0.0.0 或其他ip,否則其他 container 都會連不到
2. 官方建議 log4j2.properties 使用預設即可,不需要調整或掛載檔案
- 如果是本機安裝,會寫檔到 $ES_HOME/logs
- 如果是 docker 安裝預設是 stdout,透過 docker logs 查看
- docker 如果要跟本機安裝一樣寫擋,帶入變數ES_LOG_STYLE=file
:::
#### 單節點測試(快速啟用)
```yaml
services:
elasticsearch:
image: docker.elastic.co/elasticsearch/elasticsearch:8.11.1
container_name: es-dev
environment:
# 關閉安全機制,不需要帳號密碼
- xpack.security.enabled=false
# 單節點啟用
- discovery.type=single-node
# 依需求調整記憶體需求,container的一半
- ES_JAVA_OPTS=-Xms2g -Xmx2g
ports:
- "9200:9200"
- "9300:9300"
mem_limit: 4g
volumes:
- es-data:/usr/share/elasticsearch/data
kibana:
image: docker.elastic.co/kibana/kibana:8.11.1
container_name: kibana-dev
environment:
- ELASTICSEARCH_HOSTS=http://elasticsearch:9200
ports:
- "5601:5601"
depends_on:
- elasticsearch
volumes:
es-data:
```
#### 單節點正式環境
```yaml
services:
elasticsearch:
image: docker.elastic.co/elasticsearch/elasticsearch:8.11.1
container_name: es-prod
environment:
# 單節點啟用
- discovery.type=single-node
# 啟用安全設定
- xpack.security.enabled=true
# docker 啟用預設 log 是 stdout,如果要改為寫檔需加入此變數
- ES_LOG_STYLE=file
# 如果啟用bootstrp check,transport 需要加上 SSL 使用 elasticsearch cli 自簽
- xpack.security.transport.ssl.enabled=true
- xpack.security.transport.ssl.verification_mode=certificate
- xpack.security.transport.ssl.keystore.path=elastic-certificates.p12
- xpack.security.transport.ssl.truststore.path=elastic-certificates.p12
# 1. 依需求調整記憶體需求,container的一半,2. 啟用bootstrp check
- ES_JAVA_OPTS=-Xms4g -Xmx4g -Des.enforce.bootstrap.checks=true
# 確保ES不使用SWAP
- bootstrap.memory_lock=true
# 如果沒有預先給定一個密碼,elastic 會有一個隨機密碼,需要後續處理
- ELASTIC_PASSWORD=changeme
# 啟用監控 Elasticsearch 狀態,多節點建議使用MetricBeat處理
- xpack.monitoring.collection.enabled=true
ulimits:
memlock:
soft: -1
hard: -1
nofile:
soft: 65535
hard: 65535
nproc: 65535
fsize:
soft: -1
hard: -1
as:
soft: -1
hard: -1
ports:
- "9200:9200"
- "9300:9300"
mem_limit: 8g
volumes:
- es-data:/usr/share/elasticsearch/data
# - es-logs:/usr/share/elasticsearch/logs # 如果有調整為寫檔,將logs接出來持久化
- ./certs/elastic-certificates.p12:/usr/share/elasticsearch/config/elastic-certificates.p12:ro # TLS 憑證
# - ./ealsticsearch/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml # 有需要才掛載
kibana:
image: docker.elastic.co/kibana/kibana:8.11.1
container_name: kibana-prod
environment:
- SERVER_NAME=kibana
- ELASTICSEARCH_HOSTS=https://elasticsearch:9200
# 官方建議使用 kibana_system,建立 kibana 與 elasticsearch 的連線
- ELASTICSEARCH_USERNAME=kibana_system
# ⚠️手動建立 kibana_system 密碼
- ELASTICSEARCH_PASSWORD=set_kibana_password
# 如果使用container 並且啟用 monitor
- monitoring.ui.container.elasticsearch.enabled= true
# - ELASTICSEARCH_SSL_CERTIFICATEAUTHORITIES=/usr/share/kibana/config/ca.crt # 內網使用
ports:
- "5601:5601"
volumes:
- kibana-data:/usr/share/kibana/data
# - ./kibana/kibana.yml:/usr/share/kibana/config/kibana.yml:ro 有需要才掛載
# - kibana-logs:/usr/share/kibana/logs # 開啟 log 檔輸出再加
# - ./certs/ca.crt:/usr/share/kibana/config/ca.crt:ro # elasticsearch 有啟用http.ssl 才需要
depends_on:
- elasticsearch
volumes:
es-data:
es-logs:
kibana-data:
# kibana-plugins:
# kibana-logs:
```
:::warning
主機上設定:
```bash
sudo sysctl -w vm.max_map_count=262144
```
:::
##### 產生憑證
- 本地搭建
```bash
# 1. 產生 CA(自己就是憑證授權中心),預設名稱 elastic-stack-ca.p12,會在$ES_HOME/elasticsearch資料夾
./bin/elasticsearch-certutil ca
# 2. 產生節點使用憑證,預設名稱 elastic-certificates.p12 ,
# 如果產生在$ES_HOME/elasticsearch資料夾,要移去$ES_HOME/elasticsearch/config
./bin/elasticsearch-certutil cert --ca elastic-stack-ca.p12
```
- docker 啟用,在elasticsearch啟用前,先使用docker啟用elasticsearch指令產生憑證
```bash
#1. 在當前路徑建立本機放憑證的資料夾
mkdir -p ./certs
#2. 使用 Docker 執行 certutil 產生 CA
docker run --rm -v ${PWD}/certs:/usr/share/elasticsearch/config \
docker.elastic.co/elasticsearch/elasticsearch:8.11.1 \
bin/elasticsearch-certutil ca --silent --out config/elastic-stack-ca.p12 --pass ""
#3. 利用剛剛產生的CA,使用 Docker 再產生節點用憑證
docker run --rm -v ${PWD}/certs:/usr/share/elasticsearch/config \
docker.elastic.co/elasticsearch/elasticsearch:8.11.1 \
bin/elasticsearch-certutil cert --ca config/elastic-stack-ca.p12 \
--ca-pass "" --silent --out config/elastic-certificates.p12 --pass ""
```
##### 手動建立 kibana_system 密碼
> [!Warning]
> kibana_system 是連線使用,登入 kibana UI 使用 elastic 或另外建立帳號
> [!Tip]
> 加上 -i 代表要自行輸入密碼,沒有 -i 會隨機給一組密碼
```bash
# Docker 容器內執行
docker exec -it es-prod bin/elasticsearch-reset-password -u kibana_system -i
```
```bash
# 也可以透過api更新
curl -X POST http://localhost:9200/_security/user/kibana_system/_password \
-u elastic:your_password \
-H "Content-Type: application/json" \
-d '{"password" : "new_password"}'
```
## 確認elasticsearch(ES)是否執行中
```bash
# 沒有使用TLS
curl -u [user]:[password] http://localhost:9200
# 有使用 TLS + 驗證 CA 憑證
curl -cacert $ES_HOME/config/certs/http_ca.crt -u [user]:[password] https://localhost:9200
# 確認叢集是否健康
curl http://localhost:9200/_cluster/health
```
正常 Response:
```json
{
"name": "faa534e37683",
"cluster_name": "docker-cluster",
"cluster_uuid": "9UBFxQXhSiiyJwzX1kCuzg",
"version": {
"number": "8.11.1",
"build_flavor": "default",
"build_type": "docker",
"build_hash": "6f9ff581fbcde658e6f69d6ce03050f060d1fd0c",
"build_date": "2023-11-11T10:05:59.421038163Z",
"build_snapshot": false,
"lucene_version": "9.8.0",
"minimum_wire_compatibility_version": "7.17.0",
"minimum_index_compatibility_version": "7.0.0"
},
"tagline": "You Know, for Search"
}
```
## elasticsearch 預設會將所有相關的設定&資料都放在同一個目錄下面
```bash
$ES_HOME/
├── bin/
├── config/
├── data/
├── logs/
├── plugins/
```
| 資料夾 | 用途 | 可設定參數 |
|:------------ |:--------------------------------------------------------------------------------------------- |:----------------------- |
| home | Elasticsearch 的主目錄($ES_HOME),解壓縮後的資料夾路徑 | |
| bin | elasticsearch執行檔與工具,例如 elasticsearch(啟動 ES)、elasticsearch-plugin(安裝 plugin) | |
| config | 設定檔放這裡 | ES_PATH_CONF 環境變數 |
| data | 存放所有索引資料(如 shards、segments),相當重要不要進去改資料 | path.data |
| logs | Elasticsearch 的 log 檔儲存路徑 | path.logs |
| plugins | 所有已安裝的 Plugin 都會存放在這個資料夾,每個 plugin 是一個子資料夾 | |
| repo | Snapshot 快照備份的位置,可設多個資料夾做為 repository,通常是 NFS 或掛載的磁碟目錄 | path.repo |
如果使用 docker 正式環境務必依照預設路徑或設定參數將 data, logs 接出來持久化,其他依照使用需求
設定檔主要有3種
| 設定檔 | 功能 |
|:----------------- |:----------------------------------------- |
| elasticsearch.yml | 主要設定(叢集、節點、network、xpack 等) |
| jvm.options | JVM 相關設定(記憶體大小、GC、Java 參數) |
| log4j2.properties | Log 設定(log 等級、格式、輸出路徑等) |
## 設定方式
Elasticsearch 設定分為2種
> elasticsearch.yml → 適合 靜態、開機時就要生效的設定
> /_cluster/settings → 適合 動態、可即時修改的設定(不重啟)
部分只能靜態設定,部分只能動態
部分可以靜態設定後,透過動態API覆蓋
### 動態設定
> 可以在 Elasticsearch 執行中(不重啟)即時修改。
設定方式透過API設定:
```bash
# 範例
PUT _cluster/settings
{
"persistent": {
"cluster.routing.allocation.enable": "all"
},
"transient": {
"logger._root": "DEBUG"
}
}
```
### 整理表格
| 設定方式 | 用途 | 是否可在執行中改變 | 是否需重啟 | 實例 |
|:----------------- |:-------- |:------------------- |:---------- |:---------------------------- |
|`elasticsearch.yml` | 靜態設定 | 不可 | 需重啟 | cluster.name, network.host |
| `_cluster/settings` | 動態設定 | 可立即生效 | 不需重啟 | cluster.routing.*, indices.* |
| `API Transient` | 暫時有效 | (重啟即失效) | 不需重啟 | 開發/測試時用 |
| `API Persistent` | 長期有效 | (會儲存在 config) | 不需重啟 | 正式部署使用 |
### 靜態設定
> 只能在未啟動的節點上(或需重啟)生效的設定。
設定方式透過 elasticsearch.yml 設定
## 官方列舉重要設定及注意事項
Elasticsearch 只需要很少的配置就可以開始使用,但是在生產中使用叢集之前必須考慮許多事項:
### Path settings(路徑設定)
```yaml
path:
data: /var/data/elasticsearch
logs: /var/log/elasticsearch
```
:::warning
不要在 elasticsearch 啟用後修改任何路徑。
絕對不要動 /data 內的資料,需要備份請使用ES的 Snapshot and restore 相關機制
:::
### Cluster name setting (叢集名稱)
- 一個節點要加入叢集,必須和其他節點使用相同的 cluster.name
- 更改叢集名稱需要重啟所有節點(full cluster restart),建議一開始就設好,不要輕易變更
- 預設值是 `elasticsearch`,但建議修改為能夠代表用途的名稱,例如:
```yaml
cluster.name: logging-prod
```
### Node name setting (節點名稱)
- node.name 是這台節點的唯一標識符(對人類與 API 都可辨識)
- 預設是主機名稱,但可以自己指定更清楚的名稱
```yaml
node.name: prod-data-2
```
### Network host setting
- 預設是 127.0.0.1 or [::1]
- 只要調整成其他IP,elasticsearch 就會進入 production mode
```yaml
network.host: 192.168.1.10
```
### Development Mode vs Production Mode
#### Development Mode
- 是 elasticsearch 啟用預設狀態(當沒設定 network.host 時)
- 錯誤設定只會顯示警告(warning)
- 可以啟動但不保證穩定性
- 適合本機測試、單節點快速試用
:::warning
Development Mode (沒有調整ip),除了本機服務其他機器是沒有辦法連到的,就算是同一個內網也不行
:::
#### Production Mode
- 當你設定了 network.host 為非 loopback(如 0.0.0.0、內網 IP),會`自動切換`為生產模式
- 所有警告(如 bootstrap checks)會升級為例外(exception) 拋錯
- 有錯會阻止 Elasticsearch 啟動,這是為了避免部署錯誤造成資料損毀
### Discovery and cluster formation settings
> 在正式部署多節點叢集時,為了讓節點之間彼此發現並進行第一次 master 選舉,需要設定以下參數:
:::success
如果你是單節點部署的 Elasticsearch:
> 你可以完全不需要設定 discovery.seed_hosts 和 cluster.initial_master_nodes
> 會自動加自己選為 master 節點
> 只要加一行:
```yaml
discovery.type: single-node
```
:::
#### discovery.seed_hosts
> 定義哪些節點可以被當作「入口節點」來發現其他節點
- 可以寫 IP、FQDN(完整網域)、或 IPv6(需用 [] 包起來)
- 須為 可能成為 master 的節點
- 支援多筆 DNS IP 對應(例如用於雲端自動發現)
#### cluster.initial_master_nodes
> 用於「第一次叢集啟動」時,指定參與第一次 master 選舉的節點(必填!)
- :warning: 這個參數只需要在第一次建立新叢集時設定
- :white_check_mark: 設定值必須與每個節點的 node.name 完全相符(區分大小寫)
- :x: 成功建立後必須刪除此參數,否則未來重啟或擴充會出錯
- :x: 不可設定在非 master-eligible 節點上(如 ingest-only 節點)
| 節點數 | cluster.initial_master_nodes 要填多少? | 說明 |
| -------------- |:-------------------------------------------- |:---------------------------------------------------- |
| 1 台(單節點) | 不需要設定,改用 discovery.type: single-node | 單機免選舉 |
| 2 台 | 填 2 台節點的 node.name (不要設定偶數) | 雙節點也需要明確選舉(設定奇數個節點,選舉才會正常) |
| 3 台 | 填 3 台節點的 node.name | 所有要參與第一次投票的節點都要列出 |
| 5 台 | 填 5 台節點的 node.name | 所有要參與第一次投票的節點都要列出 |
#### 範例
```yaml
node.name: master-node-a
discovery.seed_hosts:
- 192.168.1.11 # port 預設為 9300,可省略
- [0:0:0:0:0:ffff:c0a8:10c]:9301
cluster.initial_master_nodes:
- master-node-a
- master-node-b
- master-node-c
```
:::info
- `discovery.seed_hosts` 負責「找到其他節點」
- `cluster.initial_master_nodes` 負責「誰可以投票選 master(僅第一次)」
- 依照上面的範例,啟用後就可以comment或移除掉,只有第一次啟用需要
```yaml
# cluster.initial_master_nodes:
# - master-node-a
# - master-node-b
# - master-node-c
```
:::
:::warning
新節點加入時要填`cluster.initial_master_nodes`嗎?
*不用也不能填!!!*
:::
#### 如何確認選舉結果
1. 用 API 查詢 master 節點
```bash
curl -u [user]:[password] http://[任一節點IP]:9200/_cat/master?v
```
2. 查詢叢集狀態
```bash
curl -u [user]:[password] http://[IP]:9200/_cluster/health?pretty
```
3. 透過 Kibana Dev Tools
進入 Kibana → Dev Tools 輸入:
```bash
GET /_cat/master?v
```

### JVM Heap size settings
> 如果都沒有設定,預設是主機記憶體的一半,官方建議,其他留給OS
- 如果ES node有特定設定不同的 roles,可以依據 roles 調整,沒有特別設定,一半就是安全牌
- :warning: 若 ES_JAVA_OPTS 設定高於 mem_limit,會導致容器啟動失敗(OutOfMemoryError)
- 若要覆寫預設堆大小,請設定最小和最大堆大小設定 Xms 和 Xmx。最小值和最大值必須相同。
:::spoiler :information_source: 如果使用docker,依照 container mem_limit 為主,預設為 mem_limit 的一半
假設container mem_limit設定 6G,可以手動設定 3~4G
範例:
```yaml
elasticsearch:
image: docker.elastic.co/elasticsearch/elasticsearch:8.11.1
environment:
- discovery.type=single-node
- ES_JAVA_OPTS=-Xms4g -Xmx4g
mem_limit: 6g
```
:::
### Temporary Directory 設定說明
- Elasticsearch 啟動時會在系統暫存目錄(例如 /tmp)下建立一個私有暫存目錄
- 某些 Linux 發行版會定期清理 /tmp 內未使用的檔案/目錄
- 這可能導致 Elasticsearch 還在執行中,但暫存目錄被清掉,而導致某些功能(如 snapshot、ML)失敗
#### 解決方式
1. 如果是用 .deb 或 .rpm 安裝(搭配 systemd 啟動)沒問題,系統會自動幫你排除這個目錄的清除機制
2. 用 .tar.gz 安裝 或 自己手動執行
建議你自己設定一個 專屬 temp 目錄,並透過 $ES_TMPDIR 指定給 Elasticsearch:
```bash
mkdir -p /var/tmp/elasticsearch-tmp
chown elasticsearch:elasticsearch /var/tmp/elasticsearch-tmp
chmod 700 /var/tmp/elasticsearch-tmp
export ES_TMPDIR=/var/tmp/elasticsearch-tmp
```
3. 如果是docker啟用
- Docker 容器中的 temp 目錄會是容器內部的 /tmp
**問題是:**容器重啟時 /tmp 裡的檔案會被清空,等於這個目錄不是「持久化」的
- 可能導致:
snapshot、reindex、plugin 等操作失敗
報錯訊息像是 No such file or directory, permission denied
- 掛 volume + 設定 $ES_TMPDIR
```yaml
services:
elasticsearch:
image: docker.elastic.co/elasticsearch/elasticsearch:8.11.1
container_name: elasticsearch
environment:
- ES_TMPDIR=/usr/share/elasticsearch/tmp
volumes:
- ./elasticsearch/data:/usr/share/elasticsearch/data
- ./elasticsearch/tmp:/usr/share/elasticsearch/tmp
ports:
- "9200:9200"
```
## 其他目前常使用到設定
### Security
透過xpack.security做相關設定
- 付費功能(都沒有用到)
- xpack.security.audit.*
- xpack.security.authc.realms.ldap.*
- xpack.security.authz.store.roles.index.*
- xpack.security.dls_fls.*(document/field level security)
- General security settings (一般安全設定)
- `xpack.security.enabled`
- Type: `Static`, Boolean
- Default: `true`
- 授權需求: Basic(免費)
- 說明: 啟用整體安全功能(帳號、認證、TLS 等),==不開啟將無任何安全保護!!!==。