Kubernetes 环境下 Elasticsearch 证书过期导致 Kibana 无法登录的排查与修复
前言
在 Kubernetes 日志平台中,Kibana 无法登录是一个比较常见但又容易误判的问题。
很多时候,表面现象看起来像是账号密码错误,实际上问题可能出在 Kibana 与 Elasticsearch 之间的 HTTPS 证书链上。
这次故障的核心问题,就是 Elasticsearch 证书过期,导致 Kibana 无法完成 TLS 校验,最终表现为平台登录失败。
本文记录一次完整的排查与修复过程,供后续类似问题参考。
一、环境说明
本次环境部署在 Kubernetes logging 命名空间,主要组件包括:
-
Elasticsearch
-
Kibana
-
Filebeat
资源类型如下:
-
StatefulSet/elasticsearch-master -
Deployment/kibana-kibana -
DaemonSet/filebeat-filebeat
这说明当前环境属于 自建 / Helm + StatefulSet 部署模式,而不是 ECK Operator 托管模式。
这一区别非常重要,因为自建模式下 证书不会自动轮换,需要手工维护。
二、问题现象
现场故障表现如下:
-
Kibana 页面可以打开,但输入账号密码后无法正常登录
-
Elasticsearch、Kibana、Filebeat 的 Pod 基本都在运行
-
Kibana 日志中持续出现以下报错:
certificate has expired
unable to verify the first certificate
从现象上看,很容易误以为是:
-
用户名密码错误
-
Elasticsearch 认证异常
-
Kibana 自身故障
但实际上,这类报错已经明确指向了 TLS 证书校验失败。
三、问题分析
1. 为什么 Kibana 无法登录
Kibana 的登录认证并不是完全独立完成的。
用户在页面输入账号密码后,Kibana 需要调用 Elasticsearch 进行认证。
如果 Kibana 与 Elasticsearch 之间的 HTTPS 连接存在问题,比如:
-
证书过期
-
CA 不受信任
-
证书链不完整
那么认证请求在真正校验账号密码之前,就已经失败了。
也就是说,这次“无法登录”并不是典型的账号问题,而是 Kibana 无法通过 HTTPS 正常连接 Elasticsearch。
2. 证书是否真的过期
为了确认是不是证书问题,首先查看 Elasticsearch 当前实际加载的证书:
curl -k -u elastic:你的密码 https://10.233.52.179:9200/_ssl/certificates?pretty
返回结果显示,当前加载的以下证书都已过期:
-
/usr/share/elasticsearch/config/certs/ca.crt -
/usr/share/elasticsearch/config/certs/tls.crt
这一步基本可以直接定性:
Elasticsearch 当前挂载的 CA 证书和服务端证书都已过期。
3. 证书来自哪里
继续查看 Elasticsearch 的 StatefulSet 配置:
kubectl -n logging get sts elasticsearch-master -o yaml | egrep -A5 -B2 "secretName:|mountPath:|xpack.security|ssl"
可以确认:
-
证书挂载目录为
/usr/share/elasticsearch/config/certs -
使用的 Secret 为
elasticsearch-master-certs -
HTTP 和 Transport 层都使用该 Secret 中的:
-
ca.crt -
tls.crt -
tls.key
-
这说明问题已经非常明确:
本次故障的根因,就是
elasticsearch-master-certs这套证书已过期。
四、解决思路
由于本次不只是服务端证书 tls.crt 过期,连签发它的 ca.crt 也已经过期,因此不再适合继续沿用旧 CA。
正确的处理方式是:
-
重新生成新的 CA
-
使用新的 CA 重新签发 Elasticsearch 证书
-
更新 Kubernetes Secret
-
重启 Elasticsearch
-
重启 Kibana,使其重新加载新的 CA 信任链
五、解决过程
1. 确认资源状态
先确认环境中的组件状态:
kubectl get all -n logging
确认当前环境为自建 StatefulSet/Deployment 模式,而非 ECK。
2. 确认 Elasticsearch 当前证书已过期
curl -k -u elastic:你的密码 https://10.233.52.179:9200/_ssl/certificates?pretty
确认:
-
ca.crt已过期 -
tls.crt已过期
3. 确认证书 Secret 来源
kubectl -n logging get sts elasticsearch-master -o yaml | egrep -A5 -B2 "secretName:|mountPath:|xpack.security|ssl"
确认 Elasticsearch 使用的证书 Secret 为:
elasticsearch-master-certs
4. 在 Elasticsearch Pod 中生成新证书
进入 Elasticsearch Pod:
kubectl -n logging exec -it elasticsearch-master-0 -- bash
创建工作目录:
mkdir -p /tmp/es-cert-renew
cd /tmp/es-cert-renew
创建实例配置文件:
cat > instances.yml <<'EOF'
instances:
- name: elasticsearch-master
dns:
- elasticsearch-master
- elasticsearch-master.logging
- elasticsearch-master.logging.svc
- elasticsearch-master.logging.svc.cluster.local
- elasticsearch-master-0
- elasticsearch-master-0.elasticsearch-master-headless
- elasticsearch-master-0.elasticsearch-master-headless.logging
- elasticsearch-master-0.elasticsearch-master-headless.logging.svc
- elasticsearch-master-0.elasticsearch-master-headless.logging.svc.cluster.local
ip:
- 10.233.52.179
EOF
生成新的 CA:
/usr/share/elasticsearch/bin/elasticsearch-certutil ca --pem --days 1095 --out /tmp/es-cert-renew/ca.zip
unzip -o /tmp/es-cert-renew/ca.zip -d /tmp/es-cert-renew/ca
使用新 CA 生成 Elasticsearch 证书:
/usr/share/elasticsearch/bin/elasticsearch-certutil cert --pem \
--ca-cert /tmp/es-cert-renew/ca/ca/ca.crt \
--ca-key /tmp/es-cert-renew/ca/ca/ca.key \
--days 1095 \
--in /tmp/es-cert-renew/instances.yml \
--out /tmp/es-cert-renew/es.zip
unzip -o /tmp/es-cert-renew/es.zip -d /tmp/es-cert-renew/es
find /tmp/es-cert-renew -type f | sort
5. 导出新证书到宿主机
mkdir -p /root/es-cert-renew-20260415
cd /root/es-cert-renew-20260415
kubectl -n logging exec elasticsearch-master-0 -- cat /tmp/es-cert-renew/ca/ca/ca.crt > ca.crt
kubectl -n logging exec elasticsearch-master-0 -- cat /tmp/es-cert-renew/es/elasticsearch-master/elasticsearch-master.crt > tls.crt
kubectl -n logging exec elasticsearch-master-0 -- cat /tmp/es-cert-renew/es/elasticsearch-master/elasticsearch-master.key > tls.key
检查新证书:
openssl x509 -in ca.crt -noout -dates -subject -issuer
openssl x509 -in tls.crt -noout -dates -subject -issuer
6. 备份并更新 Elasticsearch Secret
先备份原有 Secret:
kubectl -n logging get secret elasticsearch-master-certs -o yaml > /root/elasticsearch-master-certs.bak.yaml
然后更新 Secret:
kubectl -n logging create secret generic elasticsearch-master-certs \
--from-file=ca.crt=ca.crt \
--from-file=tls.crt=tls.crt \
--from-file=tls.key=tls.key \
--dry-run=client -o yaml | kubectl apply -f -
7. 重启 Elasticsearch
kubectl -n logging rollout restart statefulset/elasticsearch-master
kubectl -n logging rollout status statefulset/elasticsearch-master
kubectl -n logging get pod -n logging -w
重启后,Elasticsearch 一度出现 Running 0/1,但继续查看日志后发现:
-
节点已正常启动
-
已完成主节点选举
-
9200/9300 已正常监听
-
索引已恢复
-
Elasticsearch 已进入
started状态
说明证书更新已经成功,只是 readiness probe 在等待集群状态恢复。
8. 再次验证 Elasticsearch 新证书是否生效
curl -k -u elastic:你的密码 https://10.233.52.179:9200/_ssl/certificates?pretty
确认新证书的有效期已经更新。
9. 检查 Kibana 的 CA 配置
查看 Kibana Deployment:
kubectl -n logging get deploy kibana-kibana -o yaml | egrep -A8 -B3 "elasticsearch.ssl|ELASTICSEARCH|certificateAuthorities|verificationMode|secretName|mountPath"
确认 Kibana 已配置:
-
ELASTICSEARCH_HOSTS=https://elasticsearch-master:9200 -
ELASTICSEARCH_SSL_CERTIFICATEAUTHORITIES=/usr/share/kibana/config/certs/ca.crt
并且挂载的 Secret 也是:
elasticsearch-master-certs
说明 Kibana 的证书信任路径本身没有问题。
10. 重启 Kibana
虽然 Secret 已经更新,但 Kibana 进程仍可能继续持有旧的 TLS 信任状态,因此需要重启 Kibana:
kubectl -n logging rollout restart deployment/kibana-kibana
kubectl -n logging rollout status deployment/kibana-kibana
kubectl -n logging get pod -n logging -w
11. 验证 Kibana 日志和登录情况
查看 Kibana 最新日志:
kubectl -n logging logs deploy/kibana-kibana --tail=200 | egrep "certificate|x509|security_exception|unable to verify|No living connections|expired|SSL|tls"
确认以下错误已消失:
certificate has expired
unable to verify the first certificate
随后再次访问 Kibana 页面,确认已恢复正常登录。
六、处理结果
最终结果如下:
-
Elasticsearch 新证书已成功生效
-
Kibana 已重新加载新的 CA 证书
-
Kibana 不再报证书校验错误
-
平台恢复正常登录
七、经验总结
这次问题有几个典型经验:
1. 自建 Elasticsearch 证书不会自动续期
只要不是 ECK,就必须自己维护证书生命周期。
2. Kibana 登录失败不一定是账号问题
出现 certificate、x509、unable to verify 时,应优先排查 TLS 证书链。
3. 更新 ES 证书后,Kibana 也需要同步处理
即使 Kibana 配置没问题,也需要重启以重新加载新的 CA。
4. 建议建立证书到期告警
至少应对以下证书设置提前预警:
-
Elasticsearch HTTP 证书
-
Elasticsearch CA 证书
-
Kibana 对外证书
-
Ingress / 代理层证书
结语
这次故障的本质并不复杂,但排查过程中很容易被“登录失败”这个表象误导。
真正的问题并不是账号本身,而是 Kibana 与 Elasticsearch 之间的 HTTPS 信任链失效。
遇到类似问题时,建议优先确认三件事:
-
Elasticsearch 当前实际加载的证书是否过期
-
Kibana 是否信任当前 CA
-
证书更新后,相关组件是否已重启并重新加载配置
把这三步走清楚,问题基本都能快速收敛。
更多推荐
所有评论(0)