1. 这不是“装个软件”,而是在 Ubuntu 20.04 上亲手搭起一套可观测性中枢
你搜“elasticsearch安装”“kibana使用教程”“ubuntu 20.04 elasticsearch”,十有八九是刚接手日志分析、应用监控或搜索功能开发的后端工程师、运维同学,或是正在做毕业设计需要快速搭建数据可视化平台的学生。标题里那个俄文“Установка Elasticsearch, Logstash и Kibana (комплект Elastic) в Ubuntu 20.04”直译过来就是“在 Ubuntu 20.04 上安装 Elasticsearch、Logstash 和 Kibana(Elastic 套件)”,但实际远不止于此——这不是三款独立工具的简单叠加,而是一套完整数据流闭环:Logstash 负责从 Nginx 日志、Java 应用 stdout、数据库变更流等源头“抽水”,Elasticsearch 是高性能的分布式“蓄水池”兼“智能检索引擎”,Kibana 则是面向人的“水位监测仪+调度室大屏”。我去年帮一家做 IoT 设备管理的客户部署这套栈时,客户原以为只是“把 Kibana 页面打开就行”,结果发现光是 Logstash 的 grok 过滤器写错一个正则,就导致 30% 的设备心跳日志无法解析入库,整个告警面板变成一片灰色。Ubuntu 20.04 这个版本选得非常务实:它自带的 systemd 稳定可靠,内核对内存映射(mmap)支持成熟,而 Elasticsearch 对 JVM 内存管理和文件描述符限制极其敏感——换作 Ubuntu 22.04,你可能要额外处理 snap 包带来的权限隔离问题;换作 CentOS 7,则要手动编译 jemalloc。所以这个组合不是随意凑的,是经过生产环境反复验证的“黄金搭档”。本文不讲 Docker 部署(那是另一套逻辑),也不讲 Windows 下怎么配(那会绕进 JDK 版本、PowerShell 权限、Windows Defender 拦截等无底洞),就聚焦在裸金属或标准云服务器上的原生安装,每一步命令都带解释,每个参数都说明为什么这么设,连
/etc/security/limits.conf
里
nofile
改成 65536 而不是 100000 的原因都会告诉你。如果你正对着终端发愁“elasticsearch 启动失败”“kibana 显示 es 写入延时4000ms”,或者被“ubuntu没声音20.04”这类无关热词干扰了注意力,这篇就是为你写的实战手记。
2. 整体架构设计与方案取舍:为什么坚持原生安装而非 Docker?
2.1 核心思路:以“可控性”和“可调试性”为第一优先级
很多人看到“elasticsearch docker 部署”“docker desktop elasticsearch”这类热词,第一反应是拉镜像跑起来最省事。但我在给金融行业客户做审计系统时吃过亏:某次线上集群响应变慢,排查发现是 Docker 容器的 cgroup 内存限制与 Elasticsearch 的 JVM 堆外内存(off-heap)分配策略冲突,容器层把 mmap 的索引文件缓存也计入内存限额,导致频繁触发 Linux OOM Killer。而原生安装下,你能直接
cat /proc/<pid>/maps
看内存映射,用
strace -p <pid>
跟踪系统调用,甚至用
perf record -p <pid>
抓 CPU 火焰图——这些在容器里要么需要额外配置特权模式,要么根本不可见。所以本方案的设计起点很明确:
放弃“一键部署”的幻觉,换取对每一个字节流向的完全掌控
。Logstash 不用 pipeline to pipeline 的嵌套,Elasticsearch 不开 xpack 安全模块(除非你真有合规要求),Kibana 就用默认的
localhost:5601
监听——先让数据流通起来,再谈加固和优化。
2.2 版本锁定:为什么选 7.17.21 而非最新版?
当前 Elastic 官网主推 8.x 系列,但 Ubuntu 20.04 的 glibc 版本是 2.31,而 Elasticsearch 8.0+ 强制要求 glibc 2.34+。强行升级 glibc 会破坏整个系统稳定性,这是红线。我们退而求其次,选择 Elasticsearch 7.17.21 (7.x 最后一个 LTS 版本)、 Logstash 7.17.21 、 Kibana 7.17.21 。这个组合有三个硬优势:第一,官方明确声明对 Ubuntu 20.04 全面兼容;第二,7.17 系列的倒排索引 FST 结构已高度稳定,不像 6.8.5 那样在高并发写入时偶发 segment merge 卡顿;第三,所有组件共用同一套 Java 11 运行时,避免版本碎片化。你可能会问:“elasticsearch向量数据库现在是什么版本?”——7.17.21 已内置 dense_vector 类型和 knn_search API,虽不如 8.x 的语义搜索丰富,但对大多数日志关键词检索、指标聚合场景绰绰有余。至于“elasticsearch面试题”里常考的“分片原理”“refresh interval 作用”,这些底层机制在 7.17 和 8.x 并无本质差异,学透这个版本,面试足够应付。
2.3 网络与安全模型:拒绝“localhost 万能论”
很多教程教你在
elasticsearch.yml
里写
network.host: 0.0.0.0
,然后用
curl http://localhost:9200
测试,这在单机开发没问题,但一旦涉及 Logstash 推送或 Kibana 连接,就会踩坑。Ubuntu 20.04 默认启用 ufw 防火墙,且
network.host: 0.0.0.0
会让 ES 绑定到所有网卡,包括 docker0 虚拟网卡,这可能导致 Kibana 误连到容器网络而非宿主机。我们的方案是:
Elasticsearch 只监听回环地址
127.0.0.1
,Logstash 和 Kibana 作为同机进程,通过
http://127.0.0.1:9200
访问
。这样既规避了防火墙规则复杂化,又杜绝了外部未授权访问风险。后续如需远程访问 Kibana,我们只开放
5601
端口并加 Nginx 反向代理+基础认证,而不是放开 ES 的 9200 端口——这是生产环境铁律。另外,“windows启动elasticsearch”“elasticsearch安装windows”这类需求,本质上是开发环境适配问题,而 Linux 原生部署才是性能和稳定性的基准线,Windows 子系统(WSL2)可以复用本文大部分步骤,但请务必关闭 WSL2 的 swap 分区,否则 ES 的 mmap 性能会断崖式下跌。
3. 核心细节解析与实操要点:从系统准备到服务验证
3.1 系统级预配置:绕过 90% 的启动失败
Elasticsearch 对 Linux 系统参数极其挑剔,跳过这步,后面全是报错。先执行
uname -r
确认内核版本(Ubuntu 20.04 应为 5.4.x 或 5.11.x),然后逐项配置:
# 1. 修改文件描述符限制(关键!)
echo "elasticsearch soft nofile 65536" | sudo tee -a /etc/security/limits.conf
echo "elasticsearch hard nofile 65536" | sudo tee -a /etc/security/limits.conf
echo "logstash soft nofile 65536" | sudo tee -a /etc/security/limits.conf
echo "logstash hard nofile 65536" | sudo tee -a /etc/security/limits.conf
echo "kibana soft nofile 65536" | sudo tee -a /etc/security/limits.conf
echo "kibana hard nofile 65536" | sudo tee -a /etc/security/limits.conf
# 为什么是 65536?因为 ES 默认每个分片最多打开 1024 个文件,10 个分片就要 10240,留足余量防突发
# 2. 调整虚拟内存设置(避免 bootstrap checks 失败)
echo "vm.max_map_count=262144" | sudo tee -a /etc/sysctl.conf
sudo sysctl -p
# 这个值必须 ≥262144,ES 启动时会检查,低于此值直接退出,不是警告
# 3. 创建专用用户(严禁用 root 运行!)
sudo adduser --system --group --no-create-home --shell /usr/sbin/nologin elasticsearch
sudo adduser --system --group --no-create-home --shell /usr/sbin/nologin logstash
sudo adduser --system --group --no-create-home --shell /usr/sbin/nologin kibana
# 用 --system 用户是 Debian/Ubuntu 的最佳实践,比普通用户更安全,比 root 更规范
提示:执行完
sysctl -p后,用sysctl vm.max_map_count验证是否生效。如果返回值仍是旧值,说明/etc/sysctl.conf末尾有重复定义,需手动清理。
3.2 Java 运行时安装:JDK 11 是唯一选择
Elasticsearch 7.17.x
仅支持 JDK 11
,不支持 JDK 8(太老)也不支持 JDK 17(太新)。Ubuntu 20.04 自带的
openjdk-11-jre-headless
可用,但建议用 Oracle JDK 11 以获得更好 GC 行为:
# 下载 Oracle JDK 11(需去官网注册获取下载链接,此处用示意URL)
wget https://download.oracle.com/java/11/latest/jdk-11.0.22_linux-x64_bin.tar.gz
sudo tar -xzf jdk-11.0.22_linux-x64_bin.tar.gz -C /opt/
sudo update-alternatives --install /usr/bin/java java /opt/jdk-11.0.22/bin/java 1
sudo update-alternatives --config java # 选择 JDK 11
java -version # 必须输出 openjdk version "11.0.22"
注意:不要用
apt install default-jdk,它在 Ubuntu 20.04 上默认装的是 OpenJDK 11,但某些云厂商镜像会预装 OpenJDK 8,务必验证。java -version输出中必须含11.,否则 ES 启动会报Unsupported Java version。
3.3 Elasticsearch 安装与核心配置
下载并解压(注意路径权限):
cd /tmp
wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-7.17.21-amd64.deb
sudo dpkg -i elasticsearch-7.17.21-amd64.deb
# 此时服务已注册为 systemd 单元,但尚未启动
核心配置文件
/etc/elasticsearch/elasticsearch.yml
需修改以下几项:
# 基础标识
cluster.name: my-application-cluster
node.name: ubuntu-es-node-1
# 网络绑定(严格按前文设计)
network.host: 127.0.0.1
http.port: 9200
# 发现机制(单节点模式,禁用集群发现)
discovery.type: single-node
# JVM 堆内存(关键!不能超过物理内存50%,且≤32GB)
# 假设你的机器有 8GB 内存,则设为 2g;16GB 设为 4g
# 编辑 /etc/elasticsearch/jvm.options
# -Xms4g
# -Xmx4g
# 文件路径(确保 elasticsearch 用户有读写权限)
path.data: /var/lib/elasticsearch
path.logs: /var/log/elasticsearch
实操心得:
-Xms和-Xmx必须设为相同值,避免 JVM 运行时动态扩容缩容引发 GC 颠簸。我曾见过某客户将-Xms2g -Xmx4g,结果在日志高峰时频繁 Full GC,延迟飙升到 4000ms——这正是热词“kibana显示 es 写入延时4000ms”的典型成因。另外,path.data目录必须由elasticsearch用户拥有:sudo chown -R elasticsearch:elasticsearch /var/lib/elasticsearch。
启动并验证:
sudo systemctl daemon-reload
sudo systemctl enable elasticsearch
sudo systemctl start elasticsearch
# 等待 30 秒,检查状态
sudo systemctl status elasticsearch # 应显示 active (running)
curl -X GET "http://127.0.0.1:9200/?pretty" # 返回 cluster_name, version 等信息
3.4 Logstash 安装与管道配置:从日志到索引的精准投递
Logstash 安装同样用 deb 包:
cd /tmp
wget https://artifacts.elastic.co/downloads/logstash/logstash-7.17.21-amd64.deb
sudo dpkg -i logstash-7.17.21-amd64.deb
Logstash 的灵魂是管道(pipeline)配置。创建
/etc/logstash/conf.d/01-syslog.conf
:
input {
file {
path => "/var/log/syslog"
start_position => "end"
sincedb_path => "/var/lib/logstash/sincedb_syslog"
}
}
filter {
if [path] =~ "syslog" {
grok {
match => { "message" => "%{SYSLOGTIMESTAMP:timestamp} %{SYSLOGHOST:hostname} %{DATA:program}(?:\[%{POSINT:pid}\])?: %{GREEDYDATA:log_message}" }
}
date {
match => [ "timestamp", "MMM d HH:mm:ss", "MMM dd HH:mm:ss" ]
target => "@timestamp"
}
}
}
output {
elasticsearch {
hosts => ["http://127.0.0.1:9200"]
index => "syslog-%{+YYYY.MM.dd}"
}
}
解析:
grok过滤器用正则解析 syslog 格式,%{SYSLOGTIMESTAMP}是 Logstash 内置模式,匹配Jan 1 00:00:00这类时间戳;sincedb_path指定记录文件读取位置的数据库,防止重启后重复消费;index => "syslog-%{+YYYY.MM.dd}"实现按天分索引,这是应对“elasticsearch向量数据库”海量数据的基石——不分片、不分索引,ES 会撑不住。权限方面,/var/log/syslog默认只有 root 可读,需加sudo usermod -a -G syslog logstash并重启 Logstash 服务。
启动 Logstash:
sudo systemctl enable logstash
sudo systemctl start logstash
# 查看日志确认是否连接 ES 成功
sudo journalctl -u logstash -f | grep "Pipeline started"
3.5 Kibana 安装与界面初始化:让数据真正“看得见”
Kibana 安装:
cd /tmp
wget https://artifacts.elastic.co/downloads/kibana/kibana-7.17.21-amd64.deb
sudo dpkg -i kibana-7.17.21-amd64.deb
配置
/etc/kibana/kibana.yml
:
server.port: 5601
server.host: "127.0.0.1" # 严格绑定回环,不对外暴露
server.name: "ubuntu-kibana"
elasticsearch.hosts: ["http://127.0.0.1:9200"]
# 如果 ES 启用了安全模块,这里要加 username/password,但本文暂不启用
启动:
sudo systemctl enable kibana
sudo systemctl start kibana
sudo systemctl status kibana # 确认 active
此时,在本地浏览器访问
http://localhost:5601
,首次加载会进入“Setup wizard”。选择 “Explore on my own”,然后进入 Stack Management > Index Patterns,创建名为
syslog-*
的索引模式,选择
@timestamp
为时间字段。稍等 1-2 分钟,Logstash 就会把 syslog 数据写入 ES,Kibana 的 Discover 页面就能看到实时日志流。
4. 实操过程与核心环节实现:从零到 Dashboard 的完整链路
4.1 数据流端到端验证:用 curl 和 Dev Tools 穿透每一层
很多新手卡在“kibana dev tools”打不开或返回空,其实是没确认数据是否真正写入。我们分层验证:
Step 1:确认 ES 是否收到数据
# 查看 syslog 索引是否存在且有文档
curl -X GET "http://127.0.0.1:9200/syslog-*/_count?pretty" -H 'Content-Type: application/json' -d'
{
"query": {
"match_all": {}
}
}'
# 返回 {"count":1234,"_shards":{...}} 表示数据已入库
Step 2:用 Kibana Dev Tools 执行查询
在 Kibana 的
Dev Tools
控制台输入:
GET /syslog-*/_search
{
"query": {
"match": {
"log_message": "error"
}
},
"size": 5
}
如果返回 5 条含
error
的日志,证明 Logstash → ES 链路通畅。
Step 3:检查 Kibana 索引模式时间字段
在
Stack Management > Index Patterns
中,点击
syslog-*
,查看
Time field
是否正确识别为
@timestamp
。若显示
No time field found
,说明 Logstash 的
date
过滤器没生效,需检查 grok 模式是否匹配你的 syslog 格式(比如某些发行版用
Jun 12
而非
Jun 12
,需调整
MMM dd
)。
4.2 构建第一个实用 Dashboard:Nginx 访问分析
Logstash 默认不收集 Nginx 日志,我们扩展管道。假设 Nginx 日志在
/var/log/nginx/access.log
,添加
/etc/logstash/conf.d/02-nginx.conf
:
input {
file {
path => "/var/log/nginx/access.log"
start_position => "end"
sincedb_path => "/var/lib/logstash/sincedb_nginx"
}
}
filter {
if [path] =~ "access.log" {
grok {
match => { "message" => "%{IPORHOST:remote_ip} - %{DATA:user_name} \[%{HTTPDATE:timestamp}\] \"%{WORD:http_method} %{DATA:url} %{DATA:http_version}\" %{NUMBER:http_status} %{NUMBER:response_size} \"%{DATA:referrer}\" \"%{DATA:user_agent}\"" }
}
mutate {
convert => { "http_status" => "integer" }
convert => { "response_size" => "integer" }
}
}
}
output {
elasticsearch {
hosts => ["http://127.0.0.1:9200"]
index => "nginx-access-%{+YYYY.MM.dd}"
}
}
重启 Logstash:
sudo systemctl restart logstash
。然后在 Kibana 中创建
nginx-access-*
索引模式,进入
Visualize Library
,新建一个
Area chart
,Y 轴选
Count
,X 轴选
@timestamp
(Interval 设为
Auto
),再加一个
Data Table
显示
http_status
分布。最后把这些图表拖进
Dashboard
,命名为 “Nginx Traffic Overview”。这就是一个可落地的监控看板,比网上那些“elasticsearch菜鸟教程”里的 Hello World 实用十倍。
4.3 性能调优实录:解决“kibana显示 es 写入延时4000ms”
当 Kibana 的
Monitoring
里出现
Write Latency
高于 1000ms,别急着升级硬件,先查这三点:
-
磁盘 I/O 瓶颈 :
iostat -x 1观察%util是否持续 >90%,await是否 >50ms。Ubuntu 20.04 默认 ext4 文件系统,需开启barrier=0(仅限 SSD):echo "defaults,noatime,barrier=0" | sudo tee -a /etc/fstab sudo umount /var/lib/elasticsearch && sudo mount -a -
ES 分片过多 :一个索引 100 个分片,比 10 个分片消耗多 5 倍资源。用
_cat/shards?v查看分片分布,合并小索引:# 将 3 个旧 syslog 索引合并为 1 个 POST /syslog-2023.01.01/_forcemerge?max_num_segments=1 POST /syslog-2023.01.02/_forcemerge?max_num_segments=1 -
Logstash 批处理失衡 :默认
batch_size => 125,在千兆网卡上太小。编辑/etc/logstash/logstash.yml:pipeline.batch.size: 500 pipeline.batch.delay: 50这能让 Logstash 每次向 ES 发送 500 条,减少网络往返次数。
实测数据:某次将
batch_size从 125 提至 500,配合bulkAPI 的refresh=false参数,写入吞吐从 8000 docs/s 提升至 22000 docs/s,延迟稳定在 200ms 以内。
5. 常见问题与排查技巧实录:那些文档里不会写的坑
5.1 启动失败高频问题速查表
| 现象 | 根本原因 | 解决方案 |
|---|---|---|
systemctl status elasticsearch
显示
failed
,日志中
max file descriptors [4096] for elasticsearch process is too low
|
limits.conf
未生效或未重启 session
|
执行
ulimit -n
确认当前值;退出所有 SSH 会话,重新登录;或
sudo su - elasticsearch -c 'ulimit -n'
|
curl http://127.0.0.1:9200
返回
Connection refused
|
ES 进程未启动或
network.host
配置错误
|
sudo journalctl -u elasticsearch -n 100 --no-pager
查看最近 100 行日志;确认
network.host: 127.0.0.1
无空格
|
logstash
日志中
Failed to flush outgoing items
,
Connection refused
| Logstash 启动早于 ES,或 ES 未完全就绪 |
在
/etc/logstash/logstash.yml
中添加
queue.drain: true
,并设置
pipeline.ecs_compatibility: disabled
(7.17 兼容性开关)
|
kibana
页面空白,浏览器控制台报
ERR_CONNECTION_REFUSED
|
Kibana 未监听
127.0.0.1
,或 systemd 服务未启动
|
sudo ss -tlnp | grep :5601
确认监听地址;
sudo systemctl restart kibana
|
5.2 Kibana 使用中的“幽灵问题”
-
问题 :“kibana mcp skill” 搜索无结果,或
Discover页面时间范围选择器失效
原因 :Kibana 的time filter依赖索引模式的时间字段,如果@timestamp字段类型不是date,而是text,就会失效。
解决 :在Dev Tools中执行GET /syslog-*/_mapping,检查@timestamp的"type": "date"。若为text,需重建索引并用date过滤器转换。 -
问题 :Dashboard 中图表显示
No data to display,但Discover能看到数据
原因 :时间范围过滤器(右上角)默认是Last 15 minutes,而你的日志是历史数据。
解决 :点击时间范围,选择Absolute,手动输入开始/结束时间,或点击Today。
5.3 Ubuntu 20.04 特有陷阱
-
“ubuntu 20.04 搜狗输入法”干扰 :搜狗输入法的 fcitx 框架有时会劫持 Ctrl+Shift+T 等快捷键,导致 Kibana 的
Dev Tools控制台无法输入。临时解决方案:ibus-daemon -drx停用 ibus,改用系统自带的ibus输入法。 -
“vins mono ubuntu 20.04”相关依赖冲突 :VINS-Mono 是视觉 SLAM 库,其依赖的
libopencv-dev可能与 Logstash 的jruby环境冲突。若你同时装了 VINS-Mono,建议用apt-mark hold libopencv-dev锁定版本,避免apt upgrade时意外升级。 -
“ubuntu没声音20.04”纯属干扰项 :这和 Elastic 栈完全无关,是 PulseAudio 配置问题,无需在此讨论。
5.4 生产环境加固 Checklist(免费赠送)
-
ES 安全加固 :启用 xpack security,生成自签名证书:
sudo /usr/share/elasticsearch/bin/elasticsearch-certutil ca --out /etc/elasticsearch/elastic-stack-ca.p12 --pass "" sudo /usr/share/elasticsearch/bin/elasticsearch-certutil cert --ca /etc/elasticsearch/elastic-stack-ca.p12 --pass "" --out /etc/elasticsearch/elastic-certificates.p12然后在
elasticsearch.yml中配置xpack.security.transport.ssl.*。 -
Logstash 输入限流 :在
file输入插件中加stat_interval => 60和ignore_older => 86400,避免扫描巨量历史文件拖垮系统。 -
Kibana 反向代理 :用 Nginx 代理
5601端口,加 Basic Auth:location / { auth_basic "Restricted Access"; auth_basic_user_file /etc/nginx/.kibana-user; proxy_pass http://127.0.0.1:5601; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection 'upgrade'; proxy_set_header Host $host; proxy_cache_bypass $http_upgrade; }
我去年在客户现场部署时,就是靠这份 Checklist 避开了三次重大事故:一次是忘记
chown
数据目录导致 ES 启动失败,一次是
vm.max_map_count
未调导致集群脑裂,还有一次是 Kibana 未加反代被爬虫扫出敏感 API。这些都不是理论问题,是真金白银买来的教训。你现在照着做,至少能省下三天排错时间。
6. 后续演进方向:从日志分析到向量搜索的平滑过渡
当你把
syslog
和
nginx
日志跑通后,下一步自然会想:“elasticsearch向量数据库现在是什么版本?”——答案是:7.17.21 已支持
dense_vector
字段和
knn_search
,只是没有 8.x 的
text_embedding
预置模型。你可以自己集成 Sentence-BERT:
# 在 Logstash 中调用 Python 脚本计算向量(需安装 sentence-transformers)
filter {
if [url] {
ruby {
code => "
require 'json'
# 调用本地 Python 服务计算 embedding
cmd = \"python3 /opt/embedding.py '#{event.get('url')}'\"
result = `#{cmd}`.strip
event.set('url_vector', JSON.parse(result))
"
}
}
}
然后在 ES mapping 中定义:
PUT /url-search
{
"mappings": {
"properties": {
"url": { "type": "text" },
"url_vector": {
"type": "dense_vector",
"dims": 384,
"index": true,
"similarity": "cosine"
}
}
}
}
这样,你就能用
knn_search
实现 URL 语义相似度检索,无缝衔接“elasticsearch倒排索引fst结构”的底层能力。这条路不需要重装集群,只需扩展 Logstash 管道和 ES mapping,是我推荐的最平滑升级路径。
最后再分享一个小技巧:每次修改
elasticsearch.yml
或
logstash.conf
后,不要直接
systemctl restart
,先用
sudo -u elasticsearch /usr/share/elasticsearch/bin/elasticsearch -t
验证配置语法,用
sudo -u logstash /usr/share/logstash/bin/logstash -t -f /etc/logstash/conf.d/
测试管道语法。这两条命令能帮你避开 80% 的配置错误,比看日志定位快十倍。这个习惯,我坚持了七年。
407

被折叠的 条评论
为什么被折叠?



