在 Ubuntu 26.04 安裝 Elasticsearch 與 Kibana

這篇文章記錄如何在 Ubuntu 26.04 環境中安裝 Elasticsearch 與 Kibana,並完成基本的服務啟動、記憶體限制、設定檔調整,以及後續登入 Kibana 所需的密碼與 enrollment token 取得流程。

本文使用 Elastic 官方 APT 儲存庫安裝套件,版本來源為 packages/9.x/apt。安裝完成後,Elasticsearch 會啟用內建安全功能,因此後續需要透過重設密碼與建立 enrollment token 來完成 Kibana 的連線設定。


安裝必要套件與匯入 PGP 金鑰

首先更新本地套件清單,並安裝新增 APT 儲存庫時會用到的必要工具。接著下載 Elastic 官方 PGP 金鑰,並轉成 keyring 格式存放在系統路徑中,供後續套件來源驗證使用。

1
2
3
4
5
6
# 更新本地套件清單並安裝必備工具
sudo apt-get update
sudo apt-get install apt-transport-https gnupg wget -y

# 下載 Elasticsearch PGP 金鑰並存為 keyring
wget -qO - https://artifacts.elastic.co/GPG-KEY-elasticsearch | sudo gpg --dearmor -o /usr/share/keyrings/elasticsearch-keyring.gpg

加入 APT 儲存庫

接著將 Elastic 9.x 的 APT 儲存庫加入系統來源清單。這裡會指定前面匯入的 keyring,讓 apt 在安裝套件時能驗證來源。

1
echo "deb [signed-by=/usr/share/keyrings/elasticsearch-keyring.gpg] https://artifacts.elastic.co/packages/9.x/apt stable main" | sudo tee /etc/apt/sources.list.d/elastic-9.x.list

安裝 Elasticsearch 與 Kibana

儲存庫加入完成後,再次更新套件清單,接著安裝 Elasticsearch 與 Kibana。

1
2
sudo apt-get update
sudo apt-get install elasticsearch kibana -y

啟動 Elasticsearch 與 Kibana 服務

套件安裝完成後,先重新載入 systemd 設定,然後將 Elasticsearch 與 Kibana 設定為開機自動啟動,並立即啟動服務。若需要觀察 Elasticsearch 啟動狀態,可以使用 journalctl 查看服務日誌。

1
2
3
4
5
6
sudo systemctl daemon-reload

sudo systemctl enable elasticsearch.service
sudo systemctl start elasticsearch.service

sudo journalctl -u elasticsearch.service -f
1
2
3
4
5
6
sudo systemctl daemon-reload

sudo systemctl enable kibana.service
sudo systemctl start kibana.service

sudo journalctl -u kibana.service -f

限制 Elasticsearch 的記憶體使用量

Elasticsearch 預設會依照系統環境配置 JVM heap。若是在測試機或資源有限的環境中,可以透過 jvm.options.d 目錄新增設定檔,限制 Elasticsearch 的記憶體使用量。

1
2
3
4
sudo nano /etc/elasticsearch/jvm.options.d/heap.options

-Xms1g
-Xmx1g

調整設定

安裝完成後,Elasticsearch 與 Kibana 的主要設定檔分別位於以下路徑。若需要開放外部連線、調整節點名稱或設定 Kibana 監聽位址,可以從這兩個檔案開始修改。

Elasticsearch 設定

設定檔路徑:
/etc/elasticsearch/elasticsearch.yml

主要是設定 Elasticsearch 的各項參數,例如叢集名稱、節點名稱、資料路徑、日誌路徑、網路設定等。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
# ======================== Elasticsearch Configuration =========================
#
# NOTE: Elasticsearch comes with reasonable defaults for most settings.
# Before you set out to tweak and tune the configuration, make sure you
# understand what are you trying to accomplish and the consequences.
#
# The primary way of configuring a node is via this file. This template lists
# the most important settings you may want to configure for a production cluster.
#
# Please consult the documentation for further information on configuration options:
# https://www.elastic.co/guide/en/elasticsearch/reference/index.html
#
# ---------------------------------- Cluster -----------------------------------
#
# Use a descriptive name for your cluster:
#
cluster.name: elastic-demo
#
# ------------------------------------ Node ------------------------------------
#
# Use a descriptive name for the node:
#
node.name: node-1
#
# Add custom attributes to the node:
#
#node.attr.rack: r1
#
# ----------------------------------- Paths ------------------------------------
#
# Path to directory where to store the data (separate multiple locations by comma):
#
path.data: /var/lib/elasticsearch
#
# Path to log files:
#
path.logs: /var/log/elasticsearch
#
# ----------------------------------- Memory -----------------------------------
#
# Lock the memory on startup:
#
#bootstrap.memory_lock: true
#
# Make sure that the heap size is set to about half the memory available
# on the system and that the owner of the process is allowed to use this
# limit.
#
# Elasticsearch performs poorly when the system is swapping the memory.
#
# ---------------------------------- Network -----------------------------------
#
# By default Elasticsearch is only accessible on localhost. Set a different
# address here to expose this node on the network:
#
network.host: 0.0.0.0
#
# By default Elasticsearch listens for HTTP traffic on the first free port it
# finds starting at 9200. Set a specific HTTP port here:
#
http.port: 9200
#
# For more information, consult the network module documentation.
#
# --------------------------------- Discovery ----------------------------------
#
# Pass an initial list of hosts to perform discovery when this node is started:
# The default list of hosts is ["127.0.0.1", "[::1]"]
#
#discovery.seed_hosts: ["host1", "host2"]
#
# Bootstrap the cluster using an initial set of master-eligible nodes:
#
#cluster.initial_master_nodes: ["node-1", "node-2"]
#
# For more information, consult the discovery and cluster formation module documentation.
#
# ---------------------------------- Various -----------------------------------
#
# Allow wildcard deletion of indices:
#
#action.destructive_requires_name: false

#----------------------- BEGIN SECURITY AUTO CONFIGURATION -----------------------
#
# The following settings, TLS certificates, and keys have been automatically
# generated to configure Elasticsearch security features on 20-06-2026 06:50:40
#
# --------------------------------------------------------------------------------

# Enable security features
xpack.security.enabled: true

xpack.security.enrollment.enabled: true

# Enable encryption for HTTP API client connections, such as Kibana, Logstash, and Agents
xpack.security.http.ssl:
enabled: true
keystore.path: certs/http.p12

# Enable encryption and mutual authentication between cluster nodes
xpack.security.transport.ssl:
enabled: true
verification_mode: certificate
keystore.path: certs/transport.p12
truststore.path: certs/transport.p12
# Create a new cluster with the current node only
# Additional nodes can still join the cluster later
cluster.initial_master_nodes: ["node-1"]

# Allow HTTP API connections from anywhere
# Connections are encrypted and require user authentication
http.host: 0.0.0.0

# Allow other nodes to join the cluster from anywhere
# Connections are encrypted and mutually authenticated
transport.host: 0.0.0.0

#----------------------- END SECURITY AUTO CONFIGURATION -------------------------

Kibana 設定

設定檔路徑:
/etc/kibana/kibana.yml

主要是設定 Kibana 的各項參數,例如監聽位址、連線 Elasticsearch 的位置、日誌路徑等。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
# For more configuration options see the configuration guide for Kibana in
# https://www.elastic.co/guide/index.html

# =================== System: Kibana Server ===================
# Kibana is served by a back end server. This setting specifies the port to use.
server.port: 5601

# Specifies the address to which the Kibana server will bind. IP addresses and host names are both valid values.
# The default is 'localhost', which usually means remote machines will not be able to connect.
# To allow connections from remote users, set this parameter to a non-loopback address.
server.host: "0.0.0.0"

# Enables you to specify a path to mount Kibana at if you are running behind a proxy.
# Use the `server.rewriteBasePath` setting to tell Kibana if it should remove the basePath
# from requests it receives, and to prevent a deprecation warning at startup.
# This setting cannot end in a slash.
#server.basePath: ""

# Specifies whether Kibana should rewrite requests that are prefixed with
# `server.basePath` or require that they are rewritten by your reverse proxy.
# Defaults to `false`.
#server.rewriteBasePath: false

# Specifies the public URL at which Kibana is available for end users. If
# `server.basePath` is configured this URL should end with the same basePath.
#server.publicBaseUrl: ""

# The maximum payload size in bytes for incoming server requests.
#server.maxPayload: 1048576

# The Kibana server's name. This is used for display purposes.
server.name: "kibana-demo"

# Block requests to specific routes (exact path match, evaluated before auth).
# server.excludeRoutes: ["/api/status"]

# =================== System: Kibana Server (Optional) ===================
# Enables SSL and paths to the PEM-format SSL certificate and SSL key files, respectively.
# These settings enable SSL for outgoing requests from the Kibana server to the browser.
#server.ssl.enabled: false
#server.ssl.certificate: /path/to/your/server.crt
#server.ssl.key: /path/to/your/server.key

# =================== System: Elasticsearch ===================
# The URLs of the Elasticsearch instances to use for all your queries.
#elasticsearch.hosts: ["https://127.0.0.1:9200"]

# If your Elasticsearch is protected with basic authentication, these settings provide
# the username and password that the Kibana server uses to perform maintenance on the Kibana
# index at startup. Your Kibana users still need to authenticate with Elasticsearch, which
# is proxied through the Kibana server.
#elasticsearch.username: "kibana_system"
#elasticsearch.password: "pass"

# Kibana can also authenticate to Elasticsearch via "service account tokens".
# Service account tokens are Bearer style tokens that replace the traditional username/password based configuration.
# Use this token instead of a username/password.
# elasticsearch.serviceAccountToken: "my_token"

# Time in milliseconds to wait for responses from the back end or Elasticsearch. This value
# must be a positive integer.
#elasticsearch.requestTimeout: 30000

# The maximum number of sockets that can be used for communications with elasticsearch.
# Defaults to `800`.
#elasticsearch.maxSockets: 1024

# Specifies whether Kibana should use compression for communications with elasticsearch
# Defaults to `false`.
#elasticsearch.compression: false

# List of Kibana client-side headers to send to Elasticsearch. To send *no* client-side
# headers, set this value to [] (an empty list).
#elasticsearch.requestHeadersWhitelist: [ authorization ]

# Header names and values that are sent to Elasticsearch. Any custom headers cannot be overwritten
# by client-side headers, regardless of the elasticsearch.requestHeadersWhitelist configuration.
#elasticsearch.customHeaders: {}

# Time in milliseconds for Elasticsearch to wait for responses from shards. Set to 0 to disable.
#elasticsearch.shardTimeout: 30000

# =================== System: Elasticsearch (Optional) ===================
# These files are used to verify the identity of Kibana to Elasticsearch and are required when
# xpack.security.http.ssl.client_authentication in Elasticsearch is set to required.
#elasticsearch.ssl.certificate: /path/to/your/client.crt
#elasticsearch.ssl.key: /path/to/your/client.key

# Enables you to specify a path to the PEM file for the certificate
# authority for your Elasticsearch instance.
#elasticsearch.ssl.certificateAuthorities: [ "/path/to/your/CA.pem" ]

# To disregard the validity of SSL certificates, change this setting's value to 'none'.
#elasticsearch.ssl.verificationMode: full

# =================== System: Logging ===================
# Set the value of this setting to off to suppress all logging output, or to debug to log everything. Defaults to 'info'
#logging.root.level: debug

# Enables you to specify a file where Kibana stores log output.
logging:
appenders:
file:
type: file
fileName: /var/log/kibana/kibana.log
layout:
type: json
root:
appenders:
- default
- file
# policy:
# type: size-limit
# size: 256mb
# strategy:
# type: numeric
# max: 10
# layout:
# type: json

# Logs queries sent to Elasticsearch.
#logging.loggers:
# - name: elasticsearch.query
# level: debug

# Logs http responses.
#logging.loggers:
# - name: http.server.response
# level: debug

# Logs system usage information.
#logging.loggers:
# - name: metrics.ops
# level: debug

# Enables debug logging on the browser (dev console)
#logging.browser.root:
# level: debug

# =================== System: Other ===================
# The path where Kibana stores persistent data not saved in Elasticsearch. Defaults to data
#path.data: data

# Specifies the path where Kibana creates the process ID file.
pid.file: /run/kibana/kibana.pid

# Set the interval in milliseconds to sample system and process performance
# metrics. Minimum is 100ms. Defaults to 5000ms.
#ops.interval: 5000

# Specifies locale to be used for all localizable strings, dates and number formats.
# Supported languages are the following: English (default) "en", Chinese "zh-CN", Japanese "ja-JP", French "fr-FR", German "de-DE".
#i18n.locale: "en"

# =================== Frequently used (Optional)===================

# =================== Saved Objects: Migrations ===================
# Saved object migrations run at startup. If you run into migration-related issues, you might need to adjust these settings.

# The number of documents migrated at a time.
# If Kibana can't start up or upgrade due to an Elasticsearch `circuit_breaking_exception`,
# use a smaller batchSize value to reduce the memory pressure. Defaults to 1000 objects per batch.
#migrations.batchSize: 1000

# The maximum payload size for indexing batches of upgraded saved objects.
# To avoid migrations failing due to a 413 Request Entity Too Large response from Elasticsearch.
# This value should be lower than or equal to your Elasticsearch cluster’s `http.max_content_length`
# configuration option. Default: 100mb
#migrations.maxBatchSizeBytes: 100mb

# The number of times to retry temporary migration failures. Increase the setting
# if migrations fail frequently with a message such as `Unable to complete the [...] step after
# 15 attempts, terminating`. Defaults to 15
#migrations.retryAttempts: 15

# =================== Search Autocomplete ===================
# Time in milliseconds to wait for autocomplete suggestions from Elasticsearch.
# This value must be a whole number greater than zero. Defaults to 1000ms
# unifiedSearch.autocomplete.valueSuggestions.timeout: 1000

# Maximum number of documents loaded by each shard to generate autocomplete suggestions.
# This value must be a whole number greater than zero. Defaults to 100_000
#unifiedSearch.autocomplete.valueSuggestions.terminateAfter: 100000

設定 Elasticsearch 密碼

Elasticsearch 安裝後會啟用安全功能,因此需要重設 elastic 使用者密碼。若要手動指定密碼,可以使用互動模式執行重設指令。

隨機生成密碼

1
sudo /usr/share/elasticsearch/bin/elasticsearch-reset-password -u elastic

互動式生成密碼

1
sudo /usr/share/elasticsearch/bin/elasticsearch-reset-password -u elastic -i

驗證 Elasticsearch 狀態

啟動 Elasticsearch 後,可以透過瀏覽器檢查狀態,確認服務是否正常運作。

{% asset_img elk_install_8.jpg "驗證 Elasticsearch 狀態" %}

初始化 Kibana

取得 Kibana enrollment token

完成 Elasticsearch 密碼設定後,接著建立 Kibana 初始化所需的 enrollment token。

1
sudo /usr/share/elasticsearch/bin/elasticsearch-create-enrollment-token -s kibana

輸入 enrollment token

開啟瀏覽器,輸入 http://<Kibana IP>:5601 進入 Kibana 初始化畫面,選擇使用 enrollment token 方式登入,並輸入前面建立的 token。

取得並輸入驗證碼

接著需要輸入 Kibana 驗證碼。驗證碼可以從 Kibana 服務日誌中取得。

查看 Kibana 服務日誌的指令如下,請在另一個終端機執行,並觀察日誌輸出。

1
sudo journalctl -u kibana.service -f

完成初始化並登入 Kibana

提交 enrollment token 與驗證碼後,等待 Kibana 完成初始化設定。

初始化完成後,重新登入 Kibana,並使用 elastic 使用者與前面設定的密碼登入。

完成登入後,即可進入 Kibana 管理介面,開始使用 Elasticsearch 與 Kibana 的各項功能。

參考資料