通过 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:80
,GET
请求现在看起来像这样:
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的主要内容,如果未能解决你的问题,请参考以下文章
无法使用来自浏览器的入口访问我在 k8s 集群上的 grafana 仪表板
[k8s]dashboard1.8.1搭建( heapster1.5+influxdb+grafana)