首页 / 资讯中心 / 文章详情

ELK 8.x Linux 部署实战:从安全认证到证书配置的完整指南

ELK 8.x Linux 部署实战:从安全认证到证书配置的完整指南 ★ FEATURED ARTICLE
上个月我把一套跑了好几年的 7.x 日志平台重新搭成了 Elasticsearch Kibana Logstash 8.x 的组合部署在 Linux 服务器上。折腾完最大的感受是8.x 已经不是以前那个“装了就能 curl 通”的 ELK 了默认安全认证开着、证书自动生成、Kibana 和 Logstash 的连接方式也全都变了。这篇博客就是我这次从零部署 8.x 的完整实操记录包含核心配置、启动日志解读、常见报错和排查思路目标是让你在 Linux 上照着敲一遍就能跑通一条完整的日志链路。适合刚接手 8.x 的运维和开发同学也适合以前只玩过 7.x、准备升级的老手对照着排坑。1. 8.x 部署前必须搞懂的差异与版本规划1.1 安全认证默认开启别再想着先关掉在 7.x 时代xpack.security.enabled默认是 false很多人图省事装完先把它改成 false再裸奔跑起来。到了 8.x这个默认值直接翻转为 true而且不仅仅是认证HTTP 层的 HTTPS、节点间传输层的 TLS 都是默认开启的。也就是说你只要正常启动一个 8.x 集群就会自动生成 CA 证书、为elastic用户生成随机密码并用 HTTPS 暴露 9200 端口。我第一次装的时候还下意识去写xpack.security.enabled: false后来发现完全没必要。因为你关掉安全认证等于要同时处理 transport 和 http 两层 SSL 的禁用等以后想再开的时候又得重新生成证书、重置密码比一开始就在默认安全状态下操作麻烦得多。我的建议是8.x 一律保持默认安全配置把它当成既定前提然后在自动生成的证书体系上做二次调整。1.2 自带 JDK但 HTTPS 会陪你走完全程ES 8.x 的发行包里已经内置了 OpenJDK不再需要你手动安装 Java。但这里有一个坑如果在系统环境变量里配了JAVA_HOME指向了其他版本的 JDKES 启动时可能会优先使用外部 JDK版本不兼容就直接启动失败。所以我部署前会确认/etc/profile和 shell 配置里没有强行导出JAVA_HOME让 ES 自己使用包内的jdk/目录。另外9 版本起 Elasticsearch 对安全的要求更彻底但 8.x 里 HTTPS 已经贯穿始终。后面 Kibana 连 ES 要带https://Logstash 写 ES 要配 CA 证书这三个组件之间互相通信的设计和旧版本有质的区别。普通用户第一次跑通时最容易遗漏这些细节。1.3 版本选型三个组件尽量保持一致Elasticsearch、Kibana、Logstash 这三个组件的版本最好使用完全相同的版本号。比如我用的是 8.13.4那么 Kibana 和 Logstash 也尽量都用 8.13.4。不同小版本之间通常兼容但没必要省这一点风险。在选择具体小版本时生产环境不要追新等发布出来后几个修复版本再用。比如 8.x 系列刚出的时候部分小版本在磁盘水位、快照恢复等场景有回归问题稳定版本的运行表现好很多。另外7.17 是 7.x 的最后一个长期维护版本很多老项目还停留在上面如果你是从 7.17 升 8.x建议先把快照做好再按照官方升级路径逐级操作。2. Linux 环境准备与内核参数调优2.1 创建专用用户与目录Elasticsearch 不允许直接使用 root 用户运行这是启动时最常见的一道坎。我一般会单独建一个elk用户把所有组件都交给他管理既安全又方便排查权限问题。groupadd elk useradd -g elk -m -s /bin/bash elk mkdir -p /data/es/{data,logs,certs} mkdir -p /data/logs/app chown -R elk:elk /data /usr/local/etc这里有个细节不要为了省事把整个解压目录都 chown 给 root因为你之后如果要通过 systemd 管理服务账号对配置目录没有写权限启动时会报一些很奇怪的权限错误。更合理的做法是把安装目录和日志、证书、数据目录全部交给同一个账户。2.2 内核参数与系统限制ES 对操作系统有两个强制要求不满足就连启动都过不了。第一个是虚拟内存区域数sysctl -w vm.max_map_count262144 echo vm.max_map_count262144 /etc/sysctl.conf默认值通常是 65530ES 启动时如果发现低于 262144会直接报max virtual memory areas vm.max_map_count [65530] is too low, increase to at least [262144]。第二个是文件描述符和用户线程数限制cat /etc/security/limits.conf EOF elk soft nofile 65536 elk hard nofile 65536 elk soft nproc 4096 elk hard nproc 4096 EOF如果你用 systemd 启动还需要在 service 文件里加LimitNOFILE65536。很多人在/etc/security/limits.conf里配了但 systemd 管不到进程启动后依然只有 1024 的默认值。这一点非常隐蔽建议无论用哪种方式启动都先看一眼 ES 日志里的实际限制。生产环境里我还建议做一次 swap 控制。ES 对 swap 很敏感一旦发生内存交换查询性能和稳定性都会明显下降。可以在elasticsearch.yml里设置bootstrap.memory_lock: true或者直接把系统的vm.swappiness调低sysctl -w vm.swappiness102.3 端口规划与防火墙下面这张表是部署时需要用到的端口早一点规划好省得后面各个组件之间互相连不上端口组件用途对外放行建议9200ElasticsearchREST API、数据读写仅内网应用侧访问9300Elasticsearchtransport 节点间通信仅节点之间外部不需要5601KibanaWeb 访问入口运维网络 / 办公网5044LogstashBeats/Filebeat 数据接入仅日志采集器访问防火墙如果你用的是 firewalld可以这样放行firewall-cmd --permanent --add-port9200/tcp firewall-cmd --permanent --add-port9300/tcp firewall-cmd --permanent --add-port5601/tcp firewall-cmd --permanent --add-port5044/tcp firewall-cmd --reload需要注意的是如果这是云服务器除了操作系统防火墙安全组里也必须同步放行。我之前遇到过本机 curl 一切正常但另一台机器就是访问不了最后发现是安全组只放行了 Web 端口9200 根本没开放。3. Elasticsearch 8.x 部署与安全初始化3.1 下载安装与目录结构我习惯用 tar 包部署调试方便目录结构一眼就能看明白。从官方发布仓库下载 elasticsearch-8.x 的 Linux 压缩包后tar -zxf elasticsearch-8.13.4-linux-x86_64.tar.gz mv elasticsearch-8.13.4 /usr/local/elasticsearch chown -R elk:elk /usr/local/elasticsearch解压出来你会看到几个关键目录bin/启动脚本和运维命令所在config/全部配置文件包括随后自动生成的证书目录plugins/第三方插件存放位置jdk/内置 JDK3.2 elasticsearch.yml 核心配置配置文件位于config/elasticsearch.yml。单机测试环境我一般这样配cluster.name: elk-8-prod node.name: node-1 path.data: /data/es/data path.logs: /data/es/logs network.host: 127.0.0.1 http.port: 9200 transport.port: 9300 discovery.seed_hosts: [127.0.0.1] cluster.initial_master_nodes: [node-1] xpack.security.enabled: true xpack.security.transport.ssl.enabled: true xpack.security.http.ssl.enabled: true这里最容易卡住新手的是network.host。8.x 首次启动时如果network.host设置为回环地址127.0.0.1 或 ::1ES 会自动生成一套适用于本地通信的自签证书并打印初始密码。但如果一开始就设置成0.0.0.0或者某个局域网 IP启动时会遇到证书和地址不匹配的问题提示你当前自动生成的证书只适用于本地回环无法在非 loopback 地址上使用。所以我的步骤是先保持network.host: 127.0.0.1启动一次保存好初始密码确认集群正常后再说绑定网卡的事。要绑真实 IP再手工生成对应节点证书。3.3 首次启动与初始密码配置完成后先用 elk 用户以前台方式启动方便看日志su - elk -c /usr/local/elasticsearch/bin/elasticsearch第一次启动日志里会明确输出这么几行关键信息The generated password for the elastic user is: Jq2k...这里是一长串随机密码 The HTTP CA certificate SHA-256 fingerprint: a1:23:cd:45:...这个elastic用户初始密码是随机生成、只在第一次启动时输出的。我见过很多人启动日志刷过去了没注意后面想用 elastic 登录却被拒。如果你也忘记保存不要慌ES 提供了重置密码的命令在后面验证阶段讲。启动完成后另开一个终端验证集群curl -k https://127.0.0.1:9200 -u elastic:你的初始密码这里必须带-k因为证书是自签的URL 也必须是https://。返回一段带cluster_name和tagline的 JSON就说明 ES 已经正常起跑了。3.4 给 elastic 和 kibana_system 用户重置密码初始密码太难看也不方便后面 Logstash 和 Kibana 配置。我一般会立刻将密码改成自己设定的值/usr/local/elasticsearch/bin/elasticsearch-reset-password -u elastic -i-i表示交互式输入新密码。这个命令要在 ES 服务运行状态下执行。同时Kibana 连接 ES 时不会用 elastic 用户而是用内置的kibana_system用户。这个用户的密码也需要提前设置好/usr/local/elasticsearch/bin/elasticsearch-reset-password -u kibana_system -ikibana_system是内部账号不需要也不建议拿它登录网页。网页登录始终用elastic或你后来在 Kibana 里创建的其他用户。3.5 需要绑定非回环地址时如何扩展证书如果你需要让其他机器访问 ES不能一直用 127.0.0.1。正确做法是先用回环地址跑通并生成默认证书然后修改network.host为目标 IP再配合elasticsearch-certutil重新生成证书。通常流程是两步用elasticsearch-certutil ca生成一个私有 CA。用elasticsearch-certutil cert --ca ...给当前节点签发证书。然后把生成好的.p12或.crt/.key文件放到config/certs/并在elasticsearch.yml里更新对应的证书路径比如xpack.security.http.ssl.keystore.path: certs/elastic-certificates.p12 xpack.security.transport.ssl.keystore.path: certs/elastic-certificates.p12 xpack.security.transport.ssl.truststore.path: certs/elastic-certificates.p12如果只是内网测试不涉及跨节点通信这一步可以不用做。但如果你打算搭两个节点的集群节点间 transport 通信必须使用互相信任的证书否则 9300 端口之间会反复握手失败。很多集群一直卡在master_not_discovered_exception根本原因是 node-to-node 加密不匹配。3.6 验证集群健康curl -k -u elastic:你的密码 https://127.0.0.1:9200/_cluster/health?pretty如果是单节点且默认配置status 大概率是 yellow。这是因为默认每个索引会配置一个副本分片单节点上无法分配副本所以副本分片处于 unassigned 状态。这不是故障如果你介意可以把副本数设为 0curl -k -u elastic:你的密码 -H Content-Type: application/json \ -X PUT https://127.0.0.1:9200/_settings \ -d {index.number_of_replicas: 0}如果你想对所有索引生效也可以在创建索引模板时就设置number_of_replicas: 0。后面接数据时ES 就不会再报黄色健康状态。4. Kibana 8.x 接入与登录配置4.1 下载安装Kibana 的版本必须和 ES 保持一致我这里同样是 8.13.4tar -zxf kibana-8.13.4-linux-x86_64.tar.gz mv kibana-8.13.4 /usr/local/kibana chown -R elk:elk /usr/local/kibanaKibana 可以用 root 启动但那样需要加--allow-root生产环境还是交给普通用户。我用 elk 用户跑 Kibana 和 Logstash这样所有组件都归同一个账号管理证书和日志目录的权限冲突也少。4.2 kibana.yml 关键配置Kibana 的配置文件在config/kibana.yml。重点内容server.host: 0.0.0.0 server.port: 5601 server.name: kibana-node-1 elasticsearch.hosts: [https://127.0.0.1:9200] elasticsearch.username: kibana_system elasticsearch.password: 为kibana_system设置的密码 elasticsearch.ssl.certificateAuthorities: [/data/es/certs/http_ca.crt] xpack.security.encryptionKey: 随机生成的32位以上字符串 xpack.encryptedSavedObjects.encryptionKey: 随机生成的32位以上字符串 xpack.reporting.encryptionKey: 随机生成的32位以上字符串 i18n.locale: zh-CN这里有两个我反复踩过的坑。第一个是elasticsearch.hosts必须写成https://不是http://。8.x 的 ES 默认开着 HTTPS你写 http 的话Kibana 启动日志里会出现一堆connect ECONNREFUSED或者证书错误看起来像 ES 没启动实际是协议写错了。第二个是elasticsearch.ssl.certificateAuthorities。这个路径指向的是 ES 第一次启动时自动生成的 CA 证书一般可以从 ES 的config/certs/http_ca.crt拷贝出来放到/data/es/certs/下统一管理。如果你不指定 CAKibana 会因为无法验证 ES 证书而反复报错。xpack.security.encryptionKey这一类密钥Kibana 内置命令可以直接生成/usr/local/kibana/bin/kibana-encryption-keys --force运行后把输出的几个值填进配置文件即可。不配置的话多用户登录、安全功能相关操作会报 “Unable to encrypt sensitive information”。4.3 启动、登录与常见报错启动命令su - elk -c nohup /usr/local/kibana/bin/kibana /var/log/kibana.log 21 Kibana 启动比 ES 更慢大概需要半分钟到一分钟。刚启动时访问 5601经常会出现 “Kibana server is not ready yet” 的提示这是它还在等 ES 返回状态不代表故障。你可以看日志只要没有再刷报错稍等一下再刷新就好。浏览器访问地址是http://服务器IP:5601注意 Kibana 自身默认是 HTTP除非你显式配置server.ssl.enabled: true。首次登录需要输入 elastic 用户和密码。登录进去后会自动进入初始界面让你创建数据视图这一步先跳过等 Logstash 数据写入后再创建更合适。如果登录时报 “Username or password is incorrect”先排查是不是 elastic 密码错了如果报 “Kibana server is not ready yet” 刷不停用这段命令看底层状态curl -k -u elastic:你的密码 https://127.0.0.1:9200/_cluster/health?pretty curl -k -u elastic:你的密码 https://127.0.0.1:9200/_cat/indices?vES 健康且索引可见再回头看 Kibana 日志多数情况是kibana_system密码或者 CA 路径填错。4.4 与安全功能相关的扩展建议Kibana 接好后我一般会把默认密码换掉并在 Kibana 里创建两个不同角色的账号一个是管理员一个是只读用户。在管理界面找到 “Stack Management → Users”可以正常建用户和角色。只读角色只需要分配read和view_index_metadata权限这样日常排查问题的人不会误删索引。另外如果你给 Kibana 配置了 HTTPS则还需要在kibana.yml里设置server.ssl.certificate和server.ssl.key。这个证书可以用与 ES 同一套 CA 签发也可以用外部证书取决于你们的安全策略。测试环境没必要折腾这层保持 HTTP 即可。5. Logstash 8.x 管道配置实战5.1 安装与基础目录Logstash 的安装包和 ES 一样是 tar 包解压即用tar -zxf logstash-8.13.4-linux-x86_64.tar.gz mv logstash-8.13.4 /usr/local/logstash chown -R elk:elk /usr/local/logstashLogstash 的配置文件叫 pipeline核心目录作用如下config/存放 Logstash 主配置和 pipelines 配置pipeline/默认管道配置目录.conf文件会被自动加载jvm.optionsJVM 参数默认堆大小 1GB5.2 第一个管道stdin 到 stdout先做一个最简单的管道确定 Logstash 进程本身没问题su - elk -c /usr/local/logstash/bin/logstash -e input { stdin {} } output { stdout {} }启动完成后输入任意字符串回车能原样打印出来就说明 Logstash 工作正常。刚启动时日志刷得很慢别急着 CtrlCLogstash 本身就是一个“慢热”的 JVM 程序。5.3 写一个文件读取到 ES 的 pipeline测试环境我通常直接让 Logstash 读取某个目录下的日志文件解析后写入 ES。在pipeline/file-logs.conf里这样写input { file { path /data/logs/app/*.log start_position beginning sincedb_path /data/logstash/.sincedb } } filter { json { source message } date { match [log_time, ISO8601] target timestamp } mutate { remove_field [message, host] } } output { elasticsearch { hosts [https://127.0.0.1:9200] index app-logs-%{YYYY.MM.dd} user elastic password 你的密码 ssl_certificate_authorities [/data/es/certs/http_ca.crt] } }这里面几个配置解释一下start_position beginning表示从文件头开始读。如果不加这个默认从当前文件尾部开始前面的历史数据不会进入 ES。sincedb_path是 Logstash 记录文件读取位置的数据库。如果程序重启它从上一次的位置继续读避免重复消费。如果你测试时改了配置导致数据一直不更新可以把这个文件删掉再重启让 Logstash 重新读一遍。filter里的json插件会把日志内容按 JSON 解析如果你的日志本身就是{ log_time: 2025-01-01T10:00:00Z, message: ... }这种写法很合适。output里index使用日期变量每天自动创建一个新索引。%{YYYY.MM.dd}里的加号是日期格式前缀不要写成%{YYYY.MM.dd}否则生成不了正确索引名。写完后先做配置校验su - elk -c /usr/local/logstash/bin/logstash --config.test_and_exit -f /usr/local/logstash/pipeline/file-logs.conf没有输出ERROR再启动su - elk -c nohup /usr/local/logstash/bin/logstash --config.reload.automatic /var/log/logstash.log 21 --config.reload.automatic很有用后续修改配置文件不用重启进程会自动加载。5.4 用 beats 输入接收 Filebeat现在很多日志采集场景不是直接读文件而是由 Filebeat 监控文件再把数据发给 Logstash。Logstash 侧的配置是这样input { beats { port 5044 } } output { elasticsearch { hosts [https://127.0.0.1:9200] index filebeat-logs-%{YYYY.MM.dd} user elastic password 你的密码 ssl_certificate_authorities [/data/es/certs/http_ca.crt] } }这里beats输入插件默认监听 5044 端口如果 Filebeat 也在这台机器上直接就能把数据推过来。需要注意的是如果开启了 SSLbeats input 需要配置ssl_certificate和ssl_key这一套证书和之前 ES 的http_ca.crt不是一回事不要混用。内网测试可以暂时不开。5.5 内存与启动调优Logstash 默认 JVM 堆大小是 1GB如果你的机器内存只有 8GB同时跑着 ES 和 KibanaLogstash 很可能会因为堆内存设置太保守导致吞吐跟不上。可以修改config/jvm.options-Xms2g -Xmx2g建议堆大小不要超过物理内存的一半更不要超过 8GB。Logstash 本身还需要堆外内存做队列缓冲给操作系统预留余量很重要。调完重启 Logstash 再跑你会明显感觉到管道处理速度的变化。5.6 验证数据写入数据写进来后在 Kibana 里创建索引模式或者直接用 curl 看索引curl -k -u elastic:你的密码 https://127.0.0.1:9200/_cat/indices?v如果能看到app-logs-2025.05.xx或filebeat-logs-2025.05.xx这样的索引说明 Logstash 到 ES 的数据链路已经打通。然后用一个简单搜索验证数据curl -k -u elastic:你的密码 https://127.0.0.1:9200/app-logs-*/_search?pretty返回里有hits且total.value大于 0就完事了。6. 部署实录常见问题排查速查表以下问题是这一周部署过程中我实际遇到的按组件分类整理成速查表方便你以后直接查。现象可能原因处理方式ES 启动报vm.max_map_count过低内核默认值太小sysctl -w vm.max_map_count262144并写入/etc/sysctl.confES 启动报max file descriptors过低limits.conf 未配置或 systemd 未读取更新/etc/security/limits.confsystemd 加LimitNOFILE65536ES 启动报证书只适用于 loopback绑定了非回环 IP先用回环地址启动再手工签发节点证书忘记elastic初始密码启动日志没保存运行bin/elasticsearch-reset-password -u elastic -iKibana 报Kibana server is not ready yetES 未启动或kibana_system密码错先 curl 验证 ES再看 Kibana 日志重新设置用户密码Kibana 启动日志有 certificate 报错elasticsearch.hosts用了 http 或 CA 路径错改成 https指定http_ca.crt绝对路径Logstash 写 ES 报 401 Unauthorized用户密码错误或用户权限不够确认 elastic 密码或创建专门的写账号并分配合适权限Logstash 写 ES 报no active connectionshosts 协议不是 https / 网络不通确认hosts为https://开放 9200 端口ES 集群红色分片未分配磁盘水位或单节点副本查看_cat/allocation清理磁盘或把副本数设为 0索引突然变成只读磁盘超过 flood stage 水位线清理磁盘并执行设置移除index.blocks.read_only_allow_delete6.1 磁盘水位与只读索引这个坑在日志量大的环境特别容易触发。ES 默认磁盘空间超过 95% 时会触发flood_stage水位线然后自动把索引设置为只读防止数据继续写入导致磁盘彻底写满。很多新手看到cluster block: [FORBIDDEN/12/index read-only / allow delete (api)]就以为数据损坏了但其实只是自我保护。处理方法是先清理磁盘然后在水位恢复后解除只读curl -k -u elastic:你的密码 -X PUT https://127.0.0.1:9200/_all/_settings?expand_wildcardsall \ -H Content-Type: application/json \ -d {index.blocks.read_only_allow_delete: null}如果你只是临时测试不想被磁盘水位卡住可以把水位线调高curl -k -u elastic:你的密码 -X PUT https://127.0.0.1:9200/_cluster/settings?pretty \ -H Content-Type: application/json \ -d {persistent: {cluster.routing.allocation.disk.watermark.low: 90%, cluster.routing.allocation.disk.watermark.high: 95%, cluster.routing.allocation.disk.watermark.flood_stage: 98%}}但生产环境不建议默认可调得太高磁盘塞满了再事后处理代价远高于提前做生命周期清理。6.2 单节点集群为何一直黄绿反复单节点集群默认状态是 yellow因为副本分片无法分配。如果你只跑了一个 ES 节点还想要全绿我建议直接把副本数设成 0curl -k -u elastic:你的密码 -H Content-Type: application/json \ -X PUT https://127.0.0.1:9200/_template/my-single-node-template \ -d {index_patterns: [*], settings: {number_of_replicas: 0}}以后新建索引都会自动套用这个模板避免了每个索引都要手动跑一次设置命令。当然真正生产集群不能这样搞副本至少 1 份是为了节点故障时能恢复这个取舍要清楚。6.3 三组件资源竞争问题ES、Kibana、Logstash 都是吃内存的大户在同一台 16GB 机器上跑稍不注意就 OOM。我最后的分配方案是ES 堆内存 4GBKibana 默认 2GB 以内Logstash 堆内存 2GB把 Elasticsearch 的jvm.options里的-Xms/-Xmx都设为 4GBLogstash 的堆内存设置为 2GBKibana 不用特意配置默认够用。如果机器只有 8GB那就把 ES 调到 2GBLogstash 调到 1GB不要奢求边运行边开一堆后台任务。资源调优的优先级永远是 ES Logstash Kibana因为 ES 直接决定查询能力和数据可靠性。6.4 证书和密码的规范化管理部署 8.x 最核心的其实是证书和密码的记忆问题。我建议在任何环境落地时都建立一套固定流程ES 首次启动后立刻把elastic初始密码保存到本地密码管理工具。用elasticsearch-reset-password把elastic和kibana_system改成规范强密码。把 ES 生成的http_ca.crt统一复制到/data/es/certs/所有组件都从这个目录引用 CA。Logstash 写入 ES 时不要用 elastic 最大权限账号可以单独建一个logstash-writer角色只授予索引写入权限。这样做的好处是换机器、扩节点、迁移环境时你不用去翻 Logstash 和 Kibana 的配置里填的密码是哪一个。我在第一次部署时就是密码随手填三天后要扩容结果连自己填的密码都记不清了只能一把重置重来。这次 8.x 部署我前后用单机验证和生产两节点集群跑了两遍体会最深的不是命令行本身而是要把“默认安全开启”当成不可动摇的前提去接受ES 要证书Kibana 连 ES 要证书Logstash 写 ES 也要证书。证书确实是 8.x 最让人头大的部分但你只要把 CA 的路径固定下来、把密码流程规范化后面重新部署一套环境会非常快。
阅读完成 · 觉得有帮助?
咨询建站