代理 K8S 应用程序委托对来自其他 pod 的请求进行身份验证

Posted

技术标签:

【中文标题】代理 K8S 应用程序委托对来自其他 pod 的请求进行身份验证【英文标题】:Proxy K8S app delegating authentication of requests from other pods 【发布时间】:2019-09-15 04:13:43 【问题描述】:

背景

我有一个 K8S 集群,其中包含许多不同的 pod,它们有自己特定的服务帐户、集群角色和集群角色绑定,因此它们可以直接使用 K8S REST API 执行各种读/写请求。可以发出一些复杂的请求,我想做一个函数来包装复杂的逻辑。但是,集群中的各种服务是用多种(即 6 种以上)编程语言编写的,并且(目前)似乎还没有一种简单的方法可以让所有这些服务直接重用这些代码。

我正在考虑创建一个“代理”微服务,它公开自己的 REST API,并代表客户端发出必要的请求并处理“复杂逻辑”。


问题

唯一的问题是,在当前的部署模型下,客户端可以请求代理微服务执行客户端本身无权发出的 HTTP 请求。


问题

对于一个 pod 是否有一种简单/直接的方式,例如,识别客户端 pod,并执行某种查询/result-of-policy 操作(即通过将身份验证委托给 K8S 集群身份验证机制本身)确定它是否应该接受来自客户端 pod 的请求?


【问题讨论】:

【参考方案1】:

Kubernetes Authentication 模型表示特定用户或服务帐户如何在 k8s 集群中获得授权,但是 Authorization 方法确定是否来自集群访问者的初始请求,旨在对集群资源/对象执行一些操作,有足够的权限使之成为可能。

由于您在整个集群中为每个 Pod 使用了特定的服务帐户并授予它们特定的 RBAC 规则,因此可以使用 SelfSubjectAccessReview API 来检查对 k8s REST API 的请求和确定客户端的 Pod 服务帐户是否具有对目标的 Pod 命名空间执行任何操作的适当权限。

这可以通过使用kubectl auth can-i subcommand 提交用于模拟用户的基本信息来实现。

我假设您还可以在 HTTP 请求模式中查询 k8s 授权 API 组,然后解析 JSON/YAML 格式的结构化数据,如下例所示:

常规的kubectl auth can-i 命令检查default SA 是否可以检索default 命名空间中的Pod 数据:

kubectl auth can-i get pod --as system:serviceaccount:default:default

在 Bearer Token 身份验证中使用 JSON 类型的内容通过 HTTP 调用 k8s REST API 的等效方法:

curl -k \
    -X POST \
    -d @- \
    -H "Authorization: Bearer $MY_TOKEN" \
    -H 'Accept: application/json' \
    -H "Impersonate-User: system:serviceaccount:default:default" \
    -H 'Content-Type: application/json' \
    https://<API-Server>/apis/authorization.k8s.io/v1/selfsubjectacces-s-reviews <<'EOF'

  "kind": "SelfSubjectAccessReview",
  "apiVersion": "authorization.k8s.io/v1",
  "spec":"resourceAttributes":"namespace":"default","verb":"get","resource":"pods"

EOF

输出:

....“状态”: “允许”:是的, "reason": "RBAC: RoleBinding 允许 ....

【讨论】:

以上是关于代理 K8S 应用程序委托对来自其他 pod 的请求进行身份验证的主要内容,如果未能解决你的问题,请参考以下文章

k8s 四层代理 Service

k8s基本对象概念

k8s学习-Service(概念模板创建外部代理删除等)

k8s实战读书笔记

k8s之ingress方向代理pod

K8s网络模型