通过 k8s 代理访问 Grafana API

Posted

技术标签:

【中文标题】通过 k8s 代理访问 Grafana API【英文标题】:Accessing the Grafana API through k8s proxy 【发布时间】:2020-01-05 14:53:52 【问题描述】:

我在 kubernetes 中运行 Grafana v6.2.4,使用基本身份验证。我想使用 k8s 代理进行测试(即kubectl proxy --port=8080)。我已将GF_SERVER_ROOT_URL 环境变量更改为:


    "name": "GF_SERVER_ROOT_URL",
    "value": "http://localhost:8080/api/v1/namespaces/my-namespace/services/grafana-prom:80/proxy/"

这使我可以通过浏览器http://localhost:8080/api/v1/namespaces/my-namespace/services/grafana-prom:80/proxy/ 登录并使用 Grafana。

但是,我想通过 API 使用它。如果我向http://localhost:8080/api/v1/namespaces/my-namespace/services/grafana-prom:80/proxy/api/dashboards/db 发送请求,我会返回


    "message": "Unauthorized"

但是,如果我设置了一个 kubernetes 端口转发并将相同的请求发送到http://localhost:30099/api/dashboards/db,那么它会成功。

除了 GF_SERVER_ROOT_URL 之外,是否还有其他环境变量我应该更改,以便 API 服务器根通过 k8s 代理,即 http://localhost:8080/api/v1/namespaces/my-namespace/services/grafana-prom:80/proxy/api/dashboards/db?我看过here,但找不到。

否则通过k8s代理访问API的正确方法是什么?

我应该补充一点,我特别想使用kubetctl proxy 作为kubectl port-forward 的替代品,所以我希望在这里找到建议的替代品https://***.com/a/45189081/1011724

【问题讨论】:

您是如何为 API 请求发送身份验证的? 基本身份验证,使用邮递员。我对代理和端口转发都使用了相同的方法,并且端口转发身份验证有效。 我的猜测:某些东西修改了Authorization 请求标头(可能添加了 Bearer 令牌),因此 Grafana 无法识别它。尝试在 Grafana pod 中嗅探请求并检查请求标头。 【参考方案1】:

我尝试在 minikube 中复制此内容,我可能已经找到了您通过 API 服务器代理(使用 kubectl proxy)的请求未获得正确授权的原因。

运行以下curl-command:

curl -H "Authorization: Bearer <TOKEN>" http://localhost:8080/api/v1/namespaces/my-namespace/services/grafana-prom:80/proxy/api/dashboards/home

并使用tcpdump 捕获带有tcpdump -vvvs 0 -l -A -i any 的Pod 中的请求,产生以下结果:

GET /api/dashboards/home HTTP/1.1                                                                            
Host: localhost:8080                                                                                                 
User-Agent: curl/7.58.0                                                                                              
Accept: */*                                                                                                          
Accept-Encoding: gzip                                                                                                
X-Forwarded-For: 127.0.0.1, 192.168.99.1                                                                             
X-Forwarded-Uri: /api/v1/namespaces/my-namespace/services/grafana-prom:80/proxy/api/dashboards/home

这个GET 请求没有Authorization 标头(导致401 Unauthorized)所以基本上API 服务器似乎在将请求传递到Pod 时剥离了这个HTTP 标头。

如果我改用 kubectl port-forward -n my-namespace svc/grafana-prom 8080:80GET 请求现在看起来像这样:

GET /api/dashboards/home HTTP/1.1                                                                            
Host: localhost:8080                                                                                                 
User-Agent: curl/7.58.0                                                                                              
Accept: */*                                                                                                          
Authorization: Bearer <TOKEN>

在写这个答案时,我在 k/k repo #38775 中发现了这个问题,引用其中一个 cmets:

这是按预期工作的。通过 apiserver “代理”不会让您获得标准代理行为(保留端到端的授权标头),因为 API 没有被用作标准代理

这基本上意味着 kubectl proxy 在尝试通过它进行授权时将不起作用,它不是“常规”反向代理,并且可能有充分的理由不会保留 Authorization 标头。

请注意,我使用curl 测试了令牌和基本授权,尽管上面使用了基于令牌的身份验证。

希望这能把事情弄清楚一点!

【讨论】:

谢谢,我不确定我是否理解所有这些。但是当我阅读它时,我不能通过 kubectl 代理使用 Grafana API 的底线是什么? 另外,我使用的是基本身份验证,而不是令牌,以防万一发生任何变化。 很抱歉关于令牌的混淆,我使用Authorization: Basic 标头使用curl 对此进行了测试,我得到了相同的结果。是的,最重要的是您不能按预期使用kubectl proxy,因为Authorization 标头已被剥离。作为旁注,发送任何其他任意 HTTP 标头在通过 API 服务器代理时保持原样。我会更新答案。 啊好吧,可惜了。谢谢!

以上是关于通过 k8s 代理访问 Grafana API的主要内容,如果未能解决你的问题,请参考以下文章

nginx 反向代理grafana

nginx代理grafana

无法使用来自浏览器的入口访问我在 k8s 集群上的 grafana 仪表板

[k8s]dashboard1.8.1搭建( heapster1.5+influxdb+grafana)

通过k8s的编排文件部署grafana,重置密码后登录,浏览器报Unauthorized

在自己的应用里集成grafana