☰
Grafana 8.0.6插件签名Missing signature故障排查与解决全解析
2026/10/21 17:13:50 网站建设 项目流程

上周把一台内网监控服务器上的 Grafana 从 7.5 升到 8.0.6,重启完第一眼差点以为面板被清空了——所有自研数据源插件全部变成“Missing signature(缺少签名)”,不但数据源连不上,一整面监控大屏全是“无法加载插件”的红字。后来花了大半天才把问题彻底解决,也顺手把 8.0 系列签名校验的机制摸了个透。这篇就把整个排查链路和几种可行解法写清楚,给正在被 Grafana 8.0.x 插件签名问题卡住的朋友当个参考。无论你是从 7.x 直接升级上来的老用户,还是刚在新环境装完 Grafana 就遇到同样报错的新手,这篇文章应该能帮你少走不少弯路。

1. 故障现场:8.0.6 启动后插件列表一片红

1.1 报错长什么样:UI 呈现和启动日志的两种说法

先说 UI 侧。登录 Grafana 后,在 Configuration → Plugins 页面里,出问题的插件会多出来一行醒目的状态标记,常见文案是 “Missing signature” 或 “Unsigned plugin”。官方汉化后的界面会显示“缺少签名”或者“未签名插件”之类的字样。插件卡片无论怎么刷新都是灰色,点进详情页后右侧还会出现一个签名校验失败的提示块,上面写着类似 “This plugin has an unsigned signature or does not have a signature” 的话。此时你就算在数据源页面手动创建连接,也会发现下拉列表里那几个数据源类型的选项直接消失了,因为对应的插件根本没有被加载进来。

日志侧的报错更有参考价值。在 Grafana 启动阶段的日志输出里,会明确看到类似下面的内容:

level=warn msg="Plugin signature verification failed" pluginID=example-monitor-datasource level=error msg="Failed to load plugin" pluginID=example-monitor-datasource error="plugin is unsigned or has an invalid signature"

如果开了 debug 级别的日志,还会看到更详细的校验过程,比如下面这几行:

level=debug msg="Reading plugin manifest" pluginID=example-monitor-datasource path=/var/lib/grafana/plugins/example-monitor-datasource level=debug msg="Plugin signature verification failed" pluginID=example-monitor-datasource error="unsigned plugin does not have a signature file"

这里要注意一个细节:报错信息虽然写在日志里,但 Grafana 不会因为这个启动失败而直接宕掉,它只是把插件停用。所以很多人的第一反应是“服务正常,只是插件坏了”,容易往插件版本、兼容性方向去查,反而漏掉了签名这个最简单的原因。

1.2 触发时机:升级到 8.0.6 后一夜之间全变红

我这次踩坑最典型的触发路径就是从旧版本升级。7.x 时代对未签名插件基本是睁一只眼闭一只眼,插件只要能跑就让你跑,签名只是背景板。可 8.0 开始,官方对插件签名验证的态度一下子收紧了很多,默认情况下未签名或无法验证签名的插件是不允许被加载的。于是你什么都没动,插件还是那批插件,配置还是那份配置,升级完重启,插件却集体“阵亡”了。

还有另一种触发场景是全新安装后手工放插件。比如从网上下载了一个第三方插件的 zip 包,解压丢进插件目录,结果一启动就报 Missing signature。这种情况一般不是插件作者故意不签名,而是打包的人漏了签名文件,或者是下载渠道本身不完整。还有一种常见情况:某些离线环境下用旧版本插件包硬装到 8.0.6 上,旧包根本没有 carry 签名信息,自然也被拦了下来。

2. 为什么 8.0 系列突然对签名这么较真

2.1 签名的本质:防篡改而不是防安装

先把签名校验的定位说清楚。Grafana 的插件签名机制,本质上解决的是“这个插件是否被可信渠道验证过”的问题,而不是“这个插件能不能装”的问题。你可以把它类比成药品的防伪码:药盒上有防伪码不代表这药就一定有效,但它能防止有人在运输和转手过程中把里面的药片换成别的东西。

具体到实现层面,一个带签名的插件目录里会包含签名文件(通常是signature.json以及配套的哈希文件),里面记录了插件文件清单和每个文件的哈希值。Grafana 启动时会把当前插件目录里的文件重新计算哈希,然后和签名文件里记录的哈希做比对。一旦发现文件对不上,基本可以断定插件包被人改过或传输损坏了,这时候最安全的做法就是拒绝加载。

8.0 系列把这条规则从“建议遵守”变成了“默认执行”。这背后其实是安全策略的转变:插件运行在 Grafana 进程内部,权限跟 Grafana 本身一样大。一旦某个插件被人篡改,它不仅可能读取你的监控数据,还可能拿到服务器上的敏感配置。所以宁可错杀,也不放行。

2.2 三类签名和默认允许策略

Grafana 插件签名分为几类,8.0 版本里处理策略也不太一样。我用一张表格来对照说明:

签名类型代表含义8.0.6 默认加载策略
官方签名由 Grafana 官方渠道发布并签名允许加载
社区签名收录在官方插件库,由社区维护者签名允许加载
私有签名插件作者自行签名,但不在官方可信链上默认拒绝
无签名插件包内完全没有签名文件默认拒绝
签名校验失败有签名文件但哈希不匹配或证书链验证不过默认拒绝

从这张表就能看出来,报 Missing signature 的不一定都是“没签名文件”的情况。它涵盖的范围很广:可能是完全没签名,可能是签名不被可信链认可,可能是插件被改动了导致校验失败。所以排查时不能只盯着“补一个签名文件”这个方向。

2.3 “Missing signature”和“unsigned”究竟是不是一回事

很多人在论坛里看到别人讨论 unsigned plugin 和 Missing signature,以为这是两个不同的问题,其实在 Grafana 8.0.6 的语境下,它们经常指向同一个结果:插件没有可用的有效签名,所以不加载。

我在实际排查中还发现一个容易混淆的点:有些插件明明下载页面标注了“Signed”,但解压后依然报 Missing signature。原因通常是这类插件是“私有签名(private signature)”,签名本身没问题,只是 Grafana 8.0.6 的默认策略不认它。换句话说,签名有两种含义:一是“有没有签”,二是“签名的来源链可不可信”。截图里一排 Missing signature 的插件,里面既有真没签名的,也有签了但来源不信任的。这两种情况的解法也不完全一样,后面的章节我会分别展开。

3. 最直接的改法:放行未签名插件的两种配置

3.1 grafana.ini 加一行:plugins 段的最简单改动

如果插件本身是可信的,或者只是内网使用、不需要对外分发,最快的恢复手段就是通过配置放行未签名插件。找到 Grafana 的主配置文件grafana.ini(Linux 默认在/etc/grafana/grafana.ini,Windows 一般装在安装目录的conf下),在[plugins]段里加一行:

[plugins] allow_loading_unsigned_plugins = example-monitor-datasource

保存后重启 Grafana 服务:

sudo systemctl restart grafana-server

这里有几个细节值得注意。第一,配置的键叫allow_loading_unsigned_plugins,别漏了中间的unsigned,也别拼成unsigned_plugin,少一个 s 都不行。第二,如果有多个插件需要放行,用英文逗号分隔,写成这样:

allow_loading_unsigned_plugins = example-monitor-datasource,example-log-datasource,example-backend-datasource

第三,这个参数是精确匹配插件 ID,不是匹配显示名称。有人会把插件在 UI 上显示的中文名或英文名抄进来,那就完全无效。插件 ID 通常和插件目录名一致,最可靠的方式是看插件目录下的plugin.json文件里的"id"字段。

3.2 Docker 环境变量写法:GF_ 前缀的转换规则

如果你和我一样是容器化部署,直接改grafana.ini不仅麻烦,容器重建后还容易丢配置。更规范的做法是用环境变量传入。

Grafana 环境变量有一个固定的转换规则:配置项如果写成[plugins]段下的allow_loading_unsigned_plugins,对应环境变量就是GF_PLUGINS_ALLOW_LOADING_UNSIGNED_PLUGINS。简单来说就是把点号变成下划线,整段大写,然后加上GF_前缀。

在 docker-compose.yml 文件里可以这样写:

environment: - GF_PLUGINS_ALLOW_LOADING_UNSIGNED_PLUGINS=example-monitor-datasource,example-log-datasource

注意几个我踩过的坑。首先是拼写,ALLOW_LOADING_UNSIGNED_PLUGINS结尾的 PLUGINS 一定带 S。其次是值里面不要随意加空格,比如写成example-monitor-datasource, example-log-datasource,后面的插件 ID 可能带上前导空格导致匹配失败。第三是如果 compose 文件里这段环境变量写错,直接结果就是插件仍然报错,而且日志里没有任何提示告诉你“配置没生效”,只能靠docker exec进容器查看环境变量来确认:

docker exec -it <容器名> env | grep GF_PLUGINS

如果看到输出里有你写的变量,说明配置进去了,再去看插件状态。

3.3 UI 上的快捷入口和它的适用边界

Grafana 8.0.6 其实提供了一个不用改配置的临时候方案:插件详情页右侧会出现一个 “Allow unsigned plugin” 的按钮(在签名校验失败时才会出现)。点击后 Grafana 会记录这个插件的放行状态,插件立即重新加载,不需要重启服务。

这个按钮我很推荐在“只想快速验证插件是不是能跑”的时候用。但要注意它的局限性:它记录的是运行时状态,不是持久化配置。如果你后面容器重建、数据目录重置,或者通过配置管理工具重新拉取配置,这个放行状态大概率会丢。而且当你需要批量放行十几个插件时,一个个点按钮的操作体验也很差。所以我的建议是,UI 按钮只当作临时救急手段,线上环境还是老老实实走配置文件或环境变量。

4. 更稳妥的做法:让插件重新获得有效签名

4.1 从官方插件库重装插件

放行只是绕过了签名检查,并没有让插件本身变成“有签名”的状态。如果这是个正经的第三方插件,而且官方已经提供了签名版本,我更推荐直接重装,让它恢复合法身份。

用 Grafana 自带的命令工具就能完成:

grafana-cli plugins install <plugin-id> grafana-cli plugins upgrade <plugin-id>

前面是安装,后面是升级版本。如果是重装同一版本,可以先卸载:

grafana-cli plugins uninstall <plugin-id>

然后再 install。重装之后,再去插件目录看一眼签名相关文件是否生成,比如signature.json。这类从官方渠道拉的插件通常会自动带上签名,重装一次基本就能解决。

我实测下来,有些老插件在旧版本时根本没有签名,升级到新版本后才会获得签名。如果你手里正好是这样一批插件,单纯在配置文件里放行只是暂时的,最好在维护窗口里把插件版本统一升一遍。

4.2 离线安装:把 zip 包里的签名文件对齐

内网环境没法访问外网插件库,离线安装是最常见的插件部署方式。但离线包的来源五花八门,很容易踩签名缺文件的坑。

我建议把离线安装后的检查顺序固定下来。第一步,解压 zip 到插件目录后,先确认插件目录下有plugin.json,并且里面有个字段能体现签名状态。第二步,用下面的命令看 Grafana 实际识别到的插件状态:

grafana-cli plugins ls

如果列表里对应插件显示unsigned,那就是签名缺失或不被信任。第三步,检查压缩包完整性,重新从可靠渠道下载一次,有时候只是下载中断导致文件不全。

还要注意一个非常隐蔽的情况:某些极老的插件包是在签名机制出现之前打包的,本身就没有签名文件。这种包在 8.0.6 上无论怎么重装都是撬不出签名的,只能靠allow_loading_unsigned_plugins放行,或者联系插件作者获取带签名的新包。

4.3 自研插件怎么搭一套可解释的签名流程

团队内部自研的数据源插件、app 插件,在 8.0.6 下最容易触发 Missing signature。因为它们默认走的是私有签名或未签名通道,8.0 策略默认拒绝。开发调试阶段写allow_loading_unsigned_plugins是最省事的,但长期维护不能一直靠放行,风险在于人人都能往 Grafana 里塞未签名插件,签名体系就形同虚设。

如果你想给自研插件建立正式签名路径,方向是向官方插件库提交收录申请,走官方签名流程。这条路周期长、审核严,适合打算对外分发的插件。如果只是公司内部使用,也可以考虑用签名工具给插件打私人签名,再在 Grafana 侧维护信任链。但这一步配置复杂度不低,很多团队最后还是会选择“配置文件里放行特定几个内部插件 ID”的折中方案,我个人的建议是:先确认这个插件只会存在于受控环境,再决定要不要投入精力做正规签名。

另外一个开发小技巧:grafana-cli plugins verify <plugin-id>可以手动触发一次签名校验。这个命令在离线环境下经常返回失败,因为签名校验可能需要联网查询证书状态或撤销列表。遇到这种情况不要慌,先确认 Grafana 自身能联网,再确认插件包没被改过,否则容易把“校验命令报错”误判成“插件坏了”。

5. 改完配置仍然报错的排查顺序

5.1 第一层:配置文件是否真的被读到

最让人上火的情况就是:配置改了、重启了,插件还是红色。这时候先别怀疑配置内容,先确认它有没有被 Grafana 真正加载。启动日志里通常会打印配置文件的实际读取路径,比如开头会有类似这样的一行:

level=info msg="Starting Grafana" version=8.0.6 commit=... level=info msg="Config overrides" ...

如果日志里出现的路径和你改的文件不是同一个,说明你的配置写错地方了。还有一种可能是命令行启动时用--config参数指定了其他配置文件,优先级会盖过默认路径。最简单的验证方法是临时把配置文件里某段改成一个明显值,比如往[plugins]段写个注释块,重启后看日志里插件加载行为是否变化。如果完全没变,那就说明你改的文件压根没生效。

5.2 第二层:插件 ID 是否写对

前文提过,allow_loading_unsigned_plugins匹配的是插件 ID,不是显示名。这里我再给一个更细致的判断方法:打开插件详情页,看浏览器地址栏。URL 里通常会带一个?type=xxxx或者/plugins/xxxx之类的路径,这个xxxx才是插件 ID。也可以在服务器上直接查看:

cat /var/lib/grafana/plugins/example-monitor-datasource/plugin.json | grep '"id"'

输出的"id"值就是要填进配置里的值。我见过一个案例,插件目录叫domino-datasource,plugin.json里的 id 却叫domino-backend-datasource,两者不一致,导致有人按目录名去填配置,结果怎么填都不生效。

5.3 第三层:插件目录与权限问题

签名校验除了比对哈希,还需要完整读取插件目录里的所有文件。如果 Grafana 进程对插件目录没有读权限,或者目录里某些文件权限是 000,校验会因为无法读取文件而失败,表现上仍然是 Missing signature 或签名校验失败。

这一步在容器环境里尤其容易踩。我们常用的做法是挂载一个卷到/var/lib/grafana/plugins,如果宿主机目录权限不对,容器里的 grafana 用户就读不了。可以按下面的方式调整:

chmod -R 755 /var/lib/grafana/plugins chown -R 472:472 /var/lib/grafana/plugins

注意容器里 grafana 用户的 UID 通常是 472,这一点在不同镜像里可能不同。如果你不确定,先进容器执行id看当前用户。

还有一种情况:docker-compose 里声明的卷覆盖了插件目录,导致容器启动时插件目录是空挂载,插件文件根本没进来。这种情况下日志里甚至不会出现签名校验失败,而是提示“插件目录不存在”或“插件未找到”,比较容易区分。

5.4 两类“长得像签名问题”的问题

排查到后面,我建议大家对照三种不同报错做区分,避免在错误的道路上花时间:

报错特征根因对应解法
Missing signature / Unsigned plugin签名缺失或被拒绝放行或重装带签名版本
Plugin requires a newer version of Grafana插件版本与 Grafana 版本不兼容升级插件版本
Missing license / Invalid license企业版插件授权失效检查并更新 license 配置

我在升级后第一次排查时,一度以为是插件版本太老不兼容,反复折腾插件版本,结果发现根因只是签名问题。后来我把上面这张表贴在排查文档里,之后团队遇到类似问题,一眼就能定位到方向,排查速度提升了一大截。

6. 这次踩坑后我留下的两条固化经验

6.1 升级前先扫描插件清单

现在我在做 Grafana 大版本升级前,一定会先花两分钟跑一遍插件扫描:

grafana-cli plugins ls

这条命令会列出所有已安装插件以及它们的签名状态。我建议重点筛选出标记为unsigned或private的插件,提前汇总成一份放行清单。升级后如果这些插件报 Missing signature,直接把清单里的插件 ID 填进配置文件的allow_loading_unsigned_plugins里,不用再临时去翻 UI 和日志。

这个习惯在升级 8.0.6 这种签名策略收紧的版本里尤其有用。它能把“升级后一片红”变成“升级前就有预期”,整个故障恢复时间从一个大半天压缩到十几分钟。

6.2 统一管理 Grafana 配置文件的建议

接着上面的经验,我后来把所有 Grafana 的插件放行配置都收口到环境变量里管。不管是用 docker-compose 还是 Kubernetes 的 ConfigMap,环境变量天然比直接改配置文件更适合版本化管理和回溯。特别是自研插件数量多、需要频繁加新插件 ID 的团队,把配置写进版本控制,每次改动人人都能看到,也方便回滚。

顺带提一个小技巧:allow_loading_unsigned_plugins里的插件 ID 如果写错了,Grafana 不会报错,只会安静地继续拦截。所以每次配置变更后,我习惯顺手跑一遍grafana-cli plugins ls确认目标插件的状态已经变为signed(或不再出现在异常列表里)。把“改配置”和“验证结果”当成一体,能有效避免改完就忘、改错也不自知的局面。

这次踩坑最大的收获,是我终于理解了 Grafana 8.0 之后插件签名校验的真实意图。它确实给刚接触 Grafana 的人添了不少麻烦,但从长期安全角度看,这套机制迫使所有插件来源变得可追溯、内容变得可验证。对于内部自研插件占比较高的团队,与其纠结怎么绕过,不如先把合法签名流程铺起来,后续的运维成本反而更低。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询