GKE元数据服务器在工作负载身份中的工作原理是什么?

17
我最近一直在使用GKE Workload Identity功能。我想更详细地了解gke-metadata-server组件的工作原理。
  1. GCP客户端代码(gcloud或其他语言SDK)会落到GCE元数据方法。
  2. 请求发送到http://metadata.google.internal/path
  3. (猜测)在我的节点池上设置GKE_METADATA_SERVER将其配置为解析为该节点上的gke-metadata-server pod。
  4. (猜测)带有--privileged和主机网络的gke-metadata-server pod 有一种方式来确定源(pod IP?),然后查找pod及其服务帐号以检查iam.gke.io/gcp-service-account注释。
  5. (猜测)代理使用设置了伪身份的pod(例如,[PROJECT_ID].svc.id.goog[[K8S_NAMESPACE]/[KSA_NAME]])调用元数据服务器,以获取在其Kubernetes服务帐号上注释的服务帐号的令牌。
  6. 如果此帐户具有令牌创建者/工作负载ID用户权限,则GCP的响应可能是成功的,并包含一个令牌,然后将其打包并设置回调用pod,以进行对其他Google API的身份验证调用。

我现在最大的疑问是验证调用pod的身份。最初,我认为这将使用TokenReview API,但现在我不确定Google客户端工具如何知道使用挂载到pod中的服务帐户令牌...

编辑后续问题:

问题1:第2步和第3步之间,请求metadata.google.internal是否通过节点池上的设置GKE_METADATA_SERVER路由到GKE元数据代理?

问题2:为什么元数据服务器Pod需要主机网络?

问题3:在此视频中:https://youtu.be/s4NYEJDFc0M?t=2243 假定Pod进行了GCP调用。 GKE元数据服务器如何识别发起调用以启动该过程的Pod?

1个回答

28

在深入细节之前,请熟悉以下组件:

OIDC提供者:运行在Google的基础设施上,提供集群特定的元数据并签署授权的JWT。

GKE元数据服务器:作为DaemonSet运行,意味着每个节点上都有一个实例,公开特定于Pod的元数据服务器(它将向旧客户端库提供向后兼容性),模拟现有的节点元数据服务器。

Google IAM:发出访问令牌,验证绑定,验证OIDC签名。

Google Cloud:接受访问令牌,几乎可以执行任何操作。

JWT:JSON Web Token

mTLS:Mutual Transport Layer Security

下面的步骤解释了GKE元数据服务器组件的工作原理:

步骤1:经授权的用户将集群绑定到命名空间。

步骤2:工作负载尝试使用客户端库访问Google Cloud服务。

步骤3:GKE元数据服务器将请求来自控制平面的OIDC签名JWT。该连接使用节点凭据进行互相TLS(mTLS)连接进行身份验证。

步骤4:然后,GKE元数据服务器将使用该OIDC签名JWT从IAM请求 [标识命名空间] / [Kubernetes服务帐户]的访问令牌。 IAM将验证标识命名空间和OIDC提供程序中存在适当的绑定。

步骤5:然后IAM验证它是由集群的正确OIDC提供者签署的。然后,它将返回 [标识命名空间] / [kubernetes服务帐户]的访问令牌。

步骤6:然后元数据服务器将刚刚获得的访问令牌发送回IAM。IAM随后会在验证适当的绑定后将其交换为短期GCP服务帐号令牌。
步骤7:然后GKE元数据服务器将GCP服务帐号令牌返回给工作负载。
步骤8:工作负载可以使用该令牌调用任何Google Cloud服务。
我还发现了一段关于工作负载标识的视频,您会发现它很有用。
编辑后的跟进问题答案:
以下是您的跟进问题的答案:
Q1:在第2步和第3步之间,metadata.google.internal的请求是否通过在节点池上设置的GKE_METADATA_SERVER路由到gke元数据代理?
您是正确的,GKE_METADATA_SERVER设置在节点池上。这将向工作负载公开与V1计算元数据API兼容的元数据API。一旦工作负载尝试访问Google Cloud服务,GKE元数据服务器会执行查找(元数据服务器检查是否存在与请求的传入IP匹配的Pod列表中的Pod),然后再请求控制平面的OIDC令牌。
请记住,只有在集群级别启用工作负载标识时,才能启用GKE_METADATA_SERVER枚举功能。

Q2: 元数据服务器pod为什么需要使用主机网络?

gke-metadata-server拦截来自pod的所有GCE元数据服务器请求,但是使用主机网络的pod不会被拦截。

Q3: GKE元数据服务器如何识别调用启动进程的pod?

使用iptables规则来识别pod。


非常感谢这个详细的解释和有帮助的视频 - 关于这个话题的细节很难找到!我还有一些未解决的问题。由于SO评论不允许换行,所以我已经把它们放在了我的问题末尾。 - Charlie Egan
这是我的荣幸。我很高兴它对你有帮助。我已经更新了我的答案,加入了你的问题的答案。 - Md Daud Walizarif
1
是的,在第三步中,GKE元数据服务器从Kubernetes API服务器请求JSON Web Token(JWT),该服务器是Kubernetes控制平面的前端组件。随后,Kubernetes API服务器会回复Kubernetes服务帐户的JWT。(有关JWT索赔的答案将在下一个评论中给出,因为我用完了字符限制。) - Md Daud Walizarif
很好,看到gke元数据服务器正在挂载到本地kubelet的kubeconfig(/var/lib/kubelet/kubeconfig),所以我猜这就是它能够检索所述secrets/JWTs的方式。 - dippynark
最后,我看到元数据服务正在使用容器运行时接口(挂载在/var/run/中)- 你知道它被用来做什么吗?我猜它被用来拦截Pod流量,当它试图使用客户端库对某些Google API进行身份验证时,但具体是做什么的呢? - dippynark
显示剩余7条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接