VictoriaLogs vector 采集报 TLS 证书验证失败的排查记录

VictoriaLogs vector 采集报 TLS 证书验证失败的排查记录

记录时间:2026-09-23
环境:测试集群(二进制部署 K8s 1.28.15,麒麟 V10 SP3,ARM64,Docker 28.0.4 + cri-dockerd,3 master + 3 node);VictoriaLogs 集群 helm chart victoria-logs-cluster 0.2.8(v1.52.0);chart 自带 vector 0.57.0-distroless-libc

一、问题现象

VictoriaLogs 集群部署完成后,开启 chart 自带的 vector(DaemonSet)采集容器日志。Pod 全部 Running,但日志采集一直不入库。看 vector Pod 日志,kubernetes_logs source 在反复重试,报错核心信息:

Watcher Stream received an error. Retrying. error=InitialListFailed(...)
X509VerifyResult { code: 18, error: "self-signed certificate" }

我的第一反应:测试集群是二进制部署的自签证书环境,八成是 vector 连 apiserver 的 TLS 链路有问题。

二、排查过程

vector 报错后我先查了它的机制:kubernetes_logs source 经 K8s API 取 Pod 元数据,默认走 in-cluster 配置。查官方 issue 发现 vector 有个已知问题(#15725):它的 kube-rs 客户端走 in-cluster 时不加载 SA 卷的 ca.crt,自签 CA 集群会验证失败,需要显式挂 kubeconfig。我按官方建议挂了 kubeconfig(内嵌集群 CA),报错还是原封不动。

于是我在 master 节点直接验证证书链:

echo | openssl s_client -connect 192.168.120.51:6443 -CAfile /etc/kubernetes/ssl/ca.pem 2>&1 | grep "Verify return"
Verify return code: 18 (self signed certificate)

连 master 本机用集群自己的 CA 都验证不过 apiserver 证书。到这里确定了,问题在 apiserver 证书本身,不在 vector。顺着证书查下去定位到根因(见下节),修完证书后 vector 正常采集入库。

三、根因分析

cfssl 签发的证书不带 AKI,叠加 CA 与证书 subject 撞名,触发 openssl 的”无 AKI 且 issuersubject 即自签”判定规则,openssl 系客户端全部验证失败。

层 结论
集群证书体系 没坏。apiserver 旧证书是 ca.pem 合法签发的
vector 自身 有已知缺陷(issue #15725),in-cluster 不加载 SA 卷 ca.crt,必须显式 kubeconfig
根因 cfssl 无 AKI + subject 撞名 + openssl 启发式判定,三者叠加

三组对照实验把这个结论钉死了(同一张 ca.pem、同一套 cfssl 签发流程、同样不带 AKI,唯一变量是证书 subject 是否与 CA 撞名):

openssl verify -CAfile /etc/kubernetes/ssl/ca.pem /etc/etcd/ssl/etcd.pem
# /etc/etcd/ssl/etcd.pem: OK(CN=etcd,不撞名)

openssl verify -CAfile /etc/kubernetes/ssl/ca.pem /etc/kubernetes/ssl/kube-controller-manager.pem
# OK(CN=system:kube-controller-manager,不撞名)

openssl verify -CAfile /etc/kubernetes/ssl/ca.pem /etc/kubernetes/ssl/kube-apiserver.pem.bak.0923
# error 18 at 0 depth lookup: self signed certificate(CN=kubernetes,撞名)

不撞名的全过、撞名的报 18,说明 cfssl 签的证书签名没有问题,是 openssl 的判定规则在撞名场景误判。

四、解决方案

  1. vector 侧(永久依赖):kubeconfig ConfigMap 挂载 + kube_config_file 显式指定(绕 vector 自身缺陷);certificate-authority-data 内嵌 ca.pem(集群标准信任)。文件已落仓库 victoria-logs/xc-test/vector-kubeconfig.yaml
  2. 集群侧(治本):openssl 原生重签三台 apiserver 证书(含 SKI/AKI/SAN),证书+私钥成对滚动替换,详见部署笔记《二进制部署K8s1.28集群(arm64版).md》的「证书签发与滚动替换」章节
  3. 新部署方案(演进定稿):apiserver 证书 CN 改为 kube-apiserver(kubeadm 标准),与 CA 不撞名后 cfssl 签发即可,不再需要 openssl 特殊命令;同步改 conf 的 --requestheader-allowed-names=kube-apiserver(聚合层联动)。部署笔记正文已按此定稿

五、验证

# 三台 master 全部通过(治本完成的标志)
for h in 51 52 53; do echo "== host$h =="; echo | openssl s_client -connect 192.168.120.$h:6443 -CAfile /etc/kubernetes/ssl/ca.pem 2>&1 | grep "Verify return"; done
# 预期三行 Verify return code: 0 (ok)

# 全集群证书终验(2026-09-23 实测全 OK)
for f in /etc/kubernetes/ssl/*.pem; do
  case "$f" in *key.pem|*ca.pem) continue;; esac
  openssl verify -CAfile /etc/kubernetes/ssl/ca.pem "$f" 2>&1 | head -1
done
# admin / kube-apiserver(openssl 重签版)/ controller-manager /
# kubelet-client / kube-proxy / kube-scheduler 全部 OK
# 旧证书备份 .pem.bak.0923 不匹配 *.pem 未被列出,单独验过报 18(撞名实锤)

# vector 采集入库(流字段花括号快查)
curl -s -u <vmauth账号>:<vmauth密码> "http://<vmlogs入口域名>/select/logsql/query" \
  -d 'query={kubernetes.pod_namespace="monitoring"}' | head -c 1500

六、注意事项

  • 二进制部署环境新组件接入先查它的 TLS 栈:Go 系客户端与 openssl 系客户端对同一张证书的验证结论可能相反,不要用”kubectl 正常”推断”证书没问题”
  • 控制面证书替换必须证书+私钥成对操作,且两者都要先备份。漏私钥 apiserver 起不来,报错是 private key does not match public key
  • 证书重签的生死判据是 openssl verify -CAfile ca.pem <证书> 出 OK,出不了 OK 绝不替换进集群
  • vector 的 kubeconfig ConfigMap 更新后 Pod 不会自动重载(进程启动时只读一次),需要重建 Pod
  • 无 CA 可用时,可以把服务器证书本身当信任锚临时兜底,但终态必须回归 CA 信任

七、参考资料

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇