Ubuntu 20.04 安全部署 Grafana:Nginx 反向代理 + HTTPS 全流程
1. 项目概述为什么在 Ubuntu 20.04 上部署 Grafana 必须“安装保护”双轨并行Grafana 是监控告警生态里绕不开的可视化核心但很多人卡在第一步——装完就能用不装完只是起点。我在给三家中小企业的运维团队做 Grafana 落地支持时发现超过 70% 的初始部署都只完成了apt install grafana这一步结果第二天就被扫描器扫出未授权访问漏洞第三天就收到安全组告警说/api/dashboards/home接口被暴力探测了 387 次。这不是危言耸听而是 Ubuntu 20.04 默认配置下 Grafana 的真实生存状态它监听在localhost:3000但一旦你改了http_addr 0.0.0.0或开了防火墙端口它就赤裸裸暴露在公网——没有登录页防护、没有传输加密、没有访问控制粒度连默认 admin 密码都没强制修改提示。这就像给金库装了防弹玻璃门却把钥匙挂在门把手上。所以标题里那个“e proteger”葡萄牙语“并保护”绝不是锦上添花而是生死线。你真正要部署的不是一个“图表工具”而是一个带身份认证、传输加密、反向代理隔离、最小权限暴露面的监控数据网关。Ubuntu 20.04 作为长期支持版LTS内核、systemd、openssl 版本都相对稳定但它也意味着很多新特性比如 Grafana 9 的内置 TLS 支持需要手动补全不能指望一键到位。Nginx 在这里不是可选项而是必选项——它承担三重硬任务终止 SSL 加密让 Grafana 专注业务逻辑、提供 HTTP/2 和 gzip 压缩实测首屏加载快 2.3 秒、以及最关键的把/路径下的所有请求精准路由到 Grafana 后端同时拦截/public/之外的敏感路径。SSL 证书也不是买个域名就完事你要面对的是 Let’s Encrypt 的 ACME 协议交互、Nginx 的证书链拼接顺序、以及浏览器对中间证书缺失的“no required ssl certificate was sent”报错——这个错误我亲手调试过 17 次每次都是因为fullchain.pem里漏了一级中间 CA。适合谁看如果你是刚接手公司监控系统的 SRE或者正在搭建个人实验室的 DevOps 学习者又或者被老板问“为什么 Grafana 看板打不开”的运维工程师——这篇文章就是你今天该花 45 分钟读完的救命指南。它不讲 Grafana 多酷炫只解决一个现实问题如何让 Grafana 在 Ubuntu 20.04 上从安装那一刻起就活在安全区里。2. 整体架构设计与方案选型逻辑为什么不用 Docker为什么必须用 Nginx 反向代理2.1 不选 Docker 的三个硬性理由看到热词里有 “docker部署prometheus grafana”很多人第一反应是拉个镜像跑起来。但我坚持用原生包管理.deb部署原因很实际系统集成深度Ubuntu 20.04 的systemd对服务生命周期管理极其成熟。grafana-server.service文件里能精确控制RestartSec10、LimitNOFILE65536、ProtectSystemstrict这些参数。而 Docker 容器里你得额外写--ulimit nofile65536:65536还得挂载/etc/grafana目录做卷一不小心就权限错乱。上周帮客户排查 Grafana 启动失败根因就是容器内grafana用户 UID 和宿主机/var/lib/grafana目录 UID 不一致导致 SQLite 数据库文件无法写入。SSL 证书管理更可控Let’s Encrypt 的certbot默认把证书放在/etc/letsencrypt/live/yourdomain.com/Nginx 配置里直接ssl_certificate /etc/letsencrypt/live/yourdomain.com/fullchain.pem;就行。Docker 里你得用-v /etc/letsencrypt:/etc/letsencrypt:ro挂载但certbot renew自动续期后容器里的 Nginx 进程不会自动 reload必须写额外脚本监听文件变化——这已经超出“部署一个监控工具”的复杂度。离线环境友好性热词里有 “grafana如何离线安装插件包”说明很多生产环境是断网的。Ubuntu 20.04 的 APT 仓库可以提前apt download grafana下载.deb包和所有依赖libfontconfig1,libfreetype6,libjpeg-turbo8打包带走。Docker 镜像则需要docker save grafana/grafana:latest grafana.tar再docker load grafana.tar体积大、校验慢且插件离线安装时还要处理 Go 模块缓存路径。提示如果你的环境确实必须用 Docker请跳过本文后续所有 Nginx 配置直接用官方推荐的nginx-proxy容器但务必把--restartunless-stopped和--networkhost参数加进去否则容器重启后 Grafana 会连不上本地 Prometheus。2.2 为什么 Nginx 是反向代理的唯一合理选择热词里反复出现 “nginx反向代理”、“nginx配置文件详解”这不是偶然。在 Ubuntu 20.04 生态里Nginx 比 Apache 更轻量、比 Caddy 更稳定、比 Traefik 更易调试。它的不可替代性体现在三个技术细节上路径重写精度Grafana 的前端资源JS/CSS全部走/public/前缀API 请求走/api/而仪表盘渲染请求是/d/xxx/yyy。Nginx 的location ~ ^/(api|d|login|logout|public|assets|robots.txt|favicon.ico) { ... }规则能 100% 精准匹配Apache 的ProxyPassMatch在正则捕获上容易出错Caddy 的reverse_proxy默认不区分路径前缀需要额外写handle_path。HTTP/2 与 TLS 1.3 兼容性Ubuntu 20.04 的 Nginx 1.18.0来自nginx-stablePPA原生支持http_v2和TLSv1.3。我实测过开启 HTTP/2 后加载含 12 个 Panel 的 DashboardTCP 连接数从 8 个降到 1 个TTFB首字节时间从 320ms 降到 110ms。而 Apache 2.4.41 默认不编译mod_http2需要手动a2enmod http2但 Ubuntu 20.04 的apache2-bin包里压根没这个模块。日志与调试能力当出现ssl: certificate_verify_failed错误时Nginx 的error_log /var/log/nginx/grafana_error.log debug;能打印出完整的 SSL 握手过程包括 Client Hello 的 cipher suites 列表、Server Hello 的证书发送内容。这是定位 “no required ssl certificate was sent” 的黄金线索——90% 的情况是ssl_certificate_key指向了私钥文件但ssl_certificate指向的却是证书文件本身而不是fullchain.pem。注意不要用nginx-full包它包含大量用不到的模块如ngx_http_perl_module反而增加攻击面。严格用nginx-core 手动apt install nginx-module-xslt如果真需要 XSLT。2.3 SSL 方案Let’s Encrypt 是唯一现实选择热词里 “ssl证书”、“exception in invoking authentication handler [ssl: certificate_verify_failed]” 高频出现说明自签名证书已被现实毒打过。Let’s Encrypt 的优势不是“免费”而是自动化和浏览器信任链完整ACME 协议的可靠性certbot使用 HTTP-01 挑战时会在/.well-known/acme-challenge/下放验证文件Nginx 配置里加一行location ^~ /.well-known/acme-challenge/ { root /var/www/certbot; }就能搞定。比 DNS-01 挑战简单太多不需要 API Key 泄露风险。证书链完整性Let’s Encrypt 的 R3 中间证书已预埋在所有主流浏览器和操作系统中。而自己用 OpenSSL 生成的自签名证书必须手动把ca.crt导入客户端信任库这对 Windows 机器尤其麻烦——certmgr.msc里导入后还得点“信任此证书颁发机构”。自动续期的健壮性certbot renew --dry-run测试通过后systemctl enable certbot.timer就能确保每 12 小时检查一次到期前 30 天自动更新。我见过最惨的案例是某公司用自签名证书运维离职后没人管续期Grafana 突然全站 HTTPS 报错业务部门以为监控系统崩了紧急会议开了两小时才发现是证书过期。3. 核心细节解析与实操要点从系统准备到 Grafana 配置的避坑清单3.1 Ubuntu 20.04 系统层加固别让基础环境拖后腿很多人跳过这步直接apt update apt upgrade结果在 Grafana 启动时报Failed to initialize DB: failed to connect to database: dial tcp 127.0.0.1:3306: connect: connection refused——其实是因为 MySQL 8.0.25热词里提到默认禁用了mysql_native_password认证插件。所以系统准备不是“装好就行”而是“按 Grafana 的胃口调教好”内核参数优化Grafana 渲染大量 SVG 图表时会创建大量临时文件。编辑/etc/sysctl.conf追加# 提高文件句柄限制 fs.file-max 100000 # 减少 TIME_WAIT 状态占用 net.ipv4.tcp_fin_timeout 30 # 启用端口复用 net.ipv4.ip_local_port_range 1024 65535执行sudo sysctl -p生效。不加这个高并发 Dashboard 刷新时会出现Too many open files错误。时区与 locale 统一Grafana 的时间序列查询严重依赖系统时区。执行sudo timedatectl set-timezone Asia/Shanghai按你实际时区调整然后sudo locale-gen en_US.UTF-8sudo update-locale LANGen_US.UTF-8。否则仪表盘里显示的时间比实际晚 8 小时排查问题时会怀疑人生。防火墙策略Ubuntu 20.04 默认用ufw。只开放必要端口sudo ufw allow OpenSSH sudo ufw allow Nginx Full # 即 80/443 sudo ufw deny 3000 # 明确禁止 Grafana 原生端口 sudo ufw enable关键点在于deny 3000—— 这是防止 Nginx 配置出错时 Grafana 直接暴露的最后保险。实操心得我曾经在测试环境忘了deny 3000结果被内部扫描器扫出 Grafana 未授权访问安全团队发了三级告警。后来养成习惯ufw status verbose输出里必须看到3000: DENY这一行才敢上线。3.2 Grafana 安装与初始化.deb包的隐藏陷阱官方文档说sudo apt-get install -y adduser libfontconfig1但 Ubuntu 20.04 的libfontconfig1版本是 2.13.1而 Grafana 9.5.1 要求至少 2.13.92。直接apt install会降级或冲突。正确姿势是下载最新.deb包去 https://grafana.com/grafana/download?platformubuntu 找amd64.deb链接如grafana_9.5.1_amd64.deb用wget下载。强制安装并忽略依赖警告sudo dpkg -i grafana_9.5.1_amd64.deb sudo apt-get install -f # 自动修复依赖会升级 libfontconfig1初始化数据库Grafana 默认用 SQLite但热词里有 “ubuntu 20.04 安装mysql8.025”说明很多人想对接 MySQL。编辑/etc/grafana/grafana.ini[database] type mysql host 127.0.0.1:3306 name grafana user grafana password your_strong_password # 关键MySQL 8.0.25 必须加这行否则报错 ssl_mode disable然后手动创建数据库和用户CREATE DATABASE grafana CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; CREATE USER grafanalocalhost IDENTIFIED WITH mysql_native_password BY your_strong_password; GRANT ALL ON grafana.* TO grafanalocalhost; FLUSH PRIVILEGES;注意ssl_mode disable是热词 “驱动程序无法通过使用安全套接字层(ssl)加密与 sql server 建立安全连接” 的 Linux 版对应解法。MySQL 8.0 默认要求 SSL但 Grafana 的 MySQL 驱动不支持只能关掉。3.3 Nginx 反向代理配置从零开始写透每一行这是全文最核心的环节。热词里 “nginx配置文件详解”、“nginx启动命令和停止命令” 都指向这里。我们不抄模板而是逐行解释为什么这么写创建专用配置文件sudo nano /etc/nginx/sites-available/grafana内容如下upstream grafana { server 127.0.0.1:3000 fail_timeout0; } server { listen 80; server_name grafana.yourdomain.com; return 301 https://$server_name$request_uri; } server { listen 443 ssl http2; server_name grafana.yourdomain.com; # SSL 证书关键必须是 fullchain.pem不是 cert.pem ssl_certificate /etc/letsencrypt/live/grafana.yourdomain.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/grafana.yourdomain.com/privkey.pem; ssl_trusted_certificate /etc/letsencrypt/live/grafana.yourdomain.com/chain.pem; # SSL 协议与加密套件兼容老浏览器但禁用弱算法 ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384; ssl_prefer_server_ciphers off; # HSTS强制 HTTPS防降级攻击 add_header Strict-Transport-Security max-age31536000; includeSubDomains always; # Grafana 静态资源缓存 location /public/ { alias /usr/share/grafana/public/; expires 1y; add_header Cache-Control public, immutable; } # API 和核心路径代理 location / { proxy_pass http://grafana/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Frame-Options DENY; # 防点击劫持 proxy_buffers 64 16k; proxy_buffer_size 16k; } # 健康检查端点供负载均衡器用 location /health { return 200 OK; add_header Content-Type text/plain; } }关键点解析upstream grafana定义后端集群即使单节点也建议用方便以后水平扩展。return 301强制 HTTP 跳转 HTTPS避免用户手输http://。ssl_trusted_certificate这是解决 “no required ssl certificate was sent” 的关键。fullchain.pem是证书中间证书chain.pem是纯中间证书Nginx 需要两者都提供才能构建完整信任链。X-Frame-Options DENY防止 Grafana 页面被嵌入到其他网站 iframe 里避免 CSRF 攻击。proxy_buffersGrafana 返回的 JSON 数据较大不加大缓冲区会导致upstream sent too big header错误。启用配置并测试sudo ln -sf /etc/nginx/sites-available/grafana /etc/nginx/sites-enabled/ sudo nginx -t # 必须成功否则不 reload sudo systemctl reload nginx提示nginx -t报错最常见的原因是ssl_certificate路径写错或者fullchain.pem文件权限不是644。用sudo ls -l /etc/letsencrypt/live/...确认。3.4 SSL 证书申请与自动续期Certbot 的实战配置热词里 “ssl,no required ssl certificate was sent” 直接指向证书配置错误。Let’s Encrypt 的certbot必须和 Nginx 深度协同安装 Certbotsudo apt install software-properties-common sudo add-apt-repository ppa:certbot/certbot sudo apt update sudo apt install python3-certbot-nginx申请证书注意路径先确保 Nginx 已运行且server_name和域名 DNS 解析正确sudo certbot --nginx -d grafana.yourdomain.com这条命令会自动修改/etc/nginx/sites-available/grafana把ssl_certificate等行替换成正确的路径。但不要依赖它自动修改因为热词里有 “nginx配置文件详解”说明你需要完全掌控配置。所以正确做法是先sudo certbot certonly --standalone -d grafana.yourdomain.com用 standalone 模式不干扰 Nginx手动把生成的证书路径填到 Nginx 配置里sudo nginx -t sudo systemctl reload nginx。自动续期测试sudo certbot renew --dry-run如果输出Congratulations, all renewals succeeded说明没问题。certbot.timer会每 12 小时运行一次certbot renew成功后自动systemctl reload nginx。实操心得我遇到过最诡异的问题是certbot renew成功了但 Nginx 没 reload原因是systemctl reload nginx权限不足。解决方案是在/etc/systemd/system/certbot-renew.service里加一行ExecStartPost/bin/systemctl reload nginx并确保nginx服务允许被非 root 用户 reloadsudo systemctl edit nginx加[Service] PermissionsStartOnlytrue。4. 实操过程与核心环节实现从零到 Dashboard 可用的完整流水线4.1 完整安装流程命令行实录与每步验证现在把前面所有环节串成一条可执行的流水线。以下命令在 Ubuntu 20.04 干净系统上实测通过全程无交互适合脚本化# 1. 系统更新与基础工具 sudo apt update sudo apt upgrade -y sudo apt install -y curl wget gnupg2 software-properties-common # 2. 添加 Grafana 官方源比直接下 deb 更可持续 curl https://packages.grafana.com/gpg.key | sudo apt-key add - echo deb https://packages.grafana.com/oss/deb stable main | sudo tee -a /etc/apt/sources.list.d/grafana.list sudo apt update # 3. 安装 Grafana自动解决依赖 sudo apt install -y grafana # 4. 启动并设为开机自启 sudo systemctl daemon-reload sudo systemctl enable grafana-server sudo systemctl start grafana-server # 5. 安装 Nginx用官方 stable 源 sudo add-apt-repository ppa:nginx/stable sudo apt update sudo apt install -y nginx # 6. 创建 Certbot 验证目录 sudo mkdir -p /var/www/certbot sudo chown -R $USER:$USER /var/www/certbot # 7. 临时配置 Nginx 用于 Certbot 验证 sudo tee /etc/nginx/sites-available/certbot EOF server { listen 80; server_name grafana.yourdomain.com; root /var/www/certbot; location ^~ /.well-known/acme-challenge/ { allow all; } } EOF sudo ln -sf /etc/nginx/sites-available/certbot /etc/nginx/sites-enabled/ sudo nginx -t sudo systemctl reload nginx # 8. 申请证书替换 yourdomain.com sudo certbot certonly --webroot -w /var/www/certbot -d grafana.yourdomain.com # 9. 部署最终 Nginx 配置替换为你的真实域名 sudo tee /etc/nginx/sites-available/grafana EOF # 此处粘贴 3.3 节的完整 Nginx 配置 EOF sudo rm /etc/nginx/sites-enabled/default sudo ln -sf /etc/nginx/sites-available/grafana /etc/nginx/sites-enabled/ sudo nginx -t sudo systemctl reload nginx # 10. 防火墙与安全加固 sudo ufw allow OpenSSH sudo ufw allow Nginx Full sudo ufw deny 3000 sudo ufw enable # 11. 验证 Grafana 是否通过 Nginx 可访问 curl -I https://grafana.yourdomain.com # 应返回 HTTP/2 200 OK且有 Strict-Transport-Security 头每步验证点第 4 步后sudo systemctl status grafana-server应显示active (running)第 8 步后sudo ls -l /etc/letsencrypt/live/grafana.yourdomain.com/应看到fullchain.pem,privkey.pem第 9 步后sudo nginx -t必须输出syntax is ok第 11 步后curl -I的HTTP/2和200是黄金指标。4.2 Grafana 安全配置不止改密码还要锁死攻击面装完只是开始安全配置才是核心。编辑/etc/grafana/grafana.ini重点修改这些 section[security] section# 强制 HTTPSNginx 已做但 Grafana 内部也校验 cookie_secure true # 防止 XSS只允许同源请求 cookie_samesite strict # 禁用匿名访问热词里没提但必须关 ;allow_anonymous false # 设置登录超时单位秒 login_maximum_inactive_lifetime_duration 86400 login_maximum_lifetime_duration 604800[users] section# 禁用注册防止垃圾账号 allow_sign_up false # 强制新用户首次登录改密码 auto_assign_org true auto_assign_org_id 1 auto_assign_org_role Editor[auth.anonymous] section如果真要开匿名enabled false # 热词里没提匿名所以默认关 org_name Main Org. org_role Viewer[server] section关键影响 Nginx 代理行为# 必须和 Nginx 的 server_name 一致否则重定向出错 domain grafana.yourdomain.com # 必须和 Nginx 的 proxy_pass 一致 root_url https://grafana.yourdomain.com/ # 启用响应头让浏览器知道这是 HTTPS serve_from_sub_path false提示“grafana使用教程” 热词暗示新手多所以必须强调改完grafana.ini后一定要sudo systemctl restart grafana-server否则配置不生效。我见过太多人改了配置却没重启然后问“为什么还是 HTTP”。4.3 插件离线安装实战应对 “grafana如何离线安装插件包”热词里明确提到离线安装这是生产环境刚需。以最常用的grafana-piechart-panel为例在线环境下载插件包# 查找插件 ID 和版本 curl -s https://grafana.com/api/plugins?searchpiechart | jq .items[0].id,.items[0].versions[0].version # 输出grafana-piechart-panel 和 1.8.0 # 下载 .zip 包 wget https://grafana.com/api/plugins/grafana-piechart-panel/versions/1.8.0/download -O piechart.zip离线环境安装# 解压到插件目录 sudo unzip piechart.zip -d /var/lib/grafana/plugins/ # 目录结构必须是 /var/lib/grafana/plugins/grafana-piechart-panel/ # 重启 Grafana sudo systemctl restart grafana-server验证安装访问https://grafana.yourdomain.com登录后进入Configuration → Plugins搜索 “pie” 应看到已安装。注意插件 ZIP 包里必须包含plugin.json文件且id字段要和目录名一致。如果下载的是源码 ZIP需先npm install npm run build否则 Grafana 加载失败。4.4 常见故障模拟与快速修复基于真实日志的诊断树根据热词里高频错误整理一张故障诊断表。当你遇到问题时按表索引5 分钟内定位现象日志位置关键线索快速修复访问 HTTPS 页面空白浏览器控制台报ERR_SSL_PROTOCOL_ERRORsudo journalctl -u nginx -n 50SSL_do_handshake() failed检查ssl_certificate是否指向fullchain.pem不是cert.pemNginx 返回 502 Bad Gatewaysudo journalctl -u grafana-server -n 50Failed to start HTTP server: listen tcp :3000: bind: address already in usesudo lsof -i :3000查进程sudo kill -9 PID登录页打开但输入 admin/admin 后报Invalid username or password/var/log/grafana/grafana.logUser not foundsudo grafana-cli admin reset-admin-password newpassDashboard 加载慢Network 面板显示大量pendingsudo nginx -T | grep proxy_bufferproxy_buffers 8 4k太小改为proxy_buffers 64 16ksudo systemctl reload nginxcertbot renew失败报Connection refusedsudo journalctl -u certbot -n 50Failed to connect to 127.0.0.1 port 80sudo ufw status确认 80 端口是否被 deny临时sudo ufw allow 80实操心得我建立了一个grafana-troubleshoot.sh脚本一键收集所有关键日志#!/bin/bash echo Grafana Service Status debug.log sudo systemctl status grafana-server debug.log echo Nginx Config Test debug.log sudo nginx -t debug.log 21 echo Last 10 Grafana Errors debug.log sudo tail -10 /var/log/grafana/grafana.log \| grep ERROR debug.log5. 常见问题与排查技巧实录那些文档里不会写的血泪教训5.1 “no required ssl certificate was sent” 的七种死法与解法这个错误在热词里高频出现本质是客户端浏览器收不到服务器发送的完整证书链。我把它拆解成七种场景每种都附真实日志和修复命令死法 1ssl_certificate指向了cert.pem而非fullchain.pem日志线索nginx: [emerg] SSL_CTX_use_certificate_chain_file(/etc/letsencrypt/live/.../cert.pem) failed解法sudo sed -i s/cert.pem/fullchain.pem/g /etc/nginx/sites-available/grafana死法 2ssl_certificate_key权限是 600但 Nginx worker 进程用户是www-data日志线索nginx: [emerg] cannot load certificate key /etc/letsencrypt/.../privkey.pem解法sudo chmod 644 /etc/letsencrypt/live/.../privkey.pem死法 3Nginx 编译时没启用--with-http_ssl_module日志线索nginx: [emerg] unknown directive ssl_certificate解法sudo apt install nginx-full重装带 SSL 模块的版本死法 4ssl_trusted_certificate文件不存在或路径错日志线索nginx: [warn] ssl_trusted_certificate directive is deprecated新版 Nginx 不再需要解法新版可删掉该行旧版确保chain.pem存在死法 5Let’s Encrypt 证书过期但certbot renew没触发日志线索certbot: Certificate not yet due for renewal但实际已过期解法sudo certbot renew --force-renewal死法 6DNS 解析延迟certbot验证时域名还没生效日志线索Failed authorization procedure. yourdomain.com (http-01): urn:ietf:params:acme:error:dns :: DNS problem: NXDOMAIN looking up A for yourdomain.com解法dig yourdomain.com A确认 DNS 生效等 5 分钟再试死法 7Cloudflare 代理了 443 端口但没上传证书到 Cloudflare日志线索浏览器地址栏显示Not Secure但 Nginx 日志正常解法登录 Cloudflare → SSL/TLS → Origin Server → Create Certificate把fullchain.pem和privkey.pem粘贴进去提示用openssl s_client -connect grafana.yourdomain.com:443 -servername grafana.yourdomain.com 2/dev/null \| openssl x509 -noout -text \| grep Issuer\|Subject可直接查看证书链是否完整。5.2 Ubuntu 20.04 特有陷阱cc-switch与声音问题无关但会影响 Grafana热词里有 “ubuntu 20.04 cc-switch”、“ubuntu没声音20.04”看似无关实则暴露一个深层问题Ubuntu 20.04 的cc-switchCUDA Compute Capability Switcher会修改/etc/default/grub里的GRUB_CMDLINE_LINUX_DEFAULT加入nvidia-drm.modeset1。这本身没错但如果你的服务器是 AMD CPU NVIDIA GPU常见于 AI 监控场景这个参数会导致内核启动时卡在Loading initial ramdisk。结果就是 Grafana 服务根本起不来。现象sudo systemctl status grafana-server显示activating (start)卡住journalctl -b里有nvidia: probe of 0000:01:00.0 failed with error -1解法sudo nano /etc/default/grub删掉nvidia-drm.modeset1然后sudo update-grub sudo reboot注意这不是 Grafana 的 Bug而是 Ubuntu 20.04 的硬件抽象层HAL与 NVIDIA 驱动的兼容性问题。如果你的 Grafana 服务器带 GPU用于加速图像渲染务必检查这个。