如何在 Kubernetes 集群的 Pod 中通过 Service Account 安全访问 API 服务

举报
汪子熙 发表于 2025/08/01 19:31:27 2025/08/01
【摘要】 Kubernetes 集群中,Pod 需要与 API 服务器进行通信以执行各种操作,例如创建资源、监控状态或进行自动化操作。为了确保安全和可控的访问,Kubernetes 提供了 Service Account 机制。这一机制为 Pod 提供了简便而又安全的访问 API 的方式。通过引入 Service Account,Kubernetes 可以保证不同的 Pod 拥有不同的权限,使得整个集...

Kubernetes 集群中,Pod 需要与 API 服务器进行通信以执行各种操作,例如创建资源、监控状态或进行自动化操作。为了确保安全和可控的访问,Kubernetes 提供了 Service Account 机制。这一机制为 Pod 提供了简便而又安全的访问 API 的方式。通过引入 Service Account,Kubernetes 可以保证不同的 Pod 拥有不同的权限,使得整个集群的管理更加精细化。

1. Kubernetes 中的 Service Account 简介

Service Account 是 Kubernetes 中的资源对象,用于标识和授权运行在 Pod 内的进程。在 Kubernetes 集群中,每个 Pod 如果需要与 API 服务器交互,通常会通过 Service Account 来认证和授权。它可以看作是 Pod 在 Kubernetes 集群中的“身份证”,保证它们在与 API 服务器通信时拥有合法的身份和适当的权限。

在默认情况下,当创建 Pod 时,如果没有明确指定 Service Account,那么 Kubernetes 会为 Pod 绑定默认的 Service Account。这种默认的 Service Account 会为 Pod 提供基础的访问权限,比如读取一些集群的公共信息。但是,在实际的生产环境中,安全性是非常关键的,所以通常我们会为不同的应用创建特定的 Service Account,并授予它们最小权限原则 (Principle of Least Privilege)。

2. Service Account 的工作原理

在 Kubernetes 中,每个 Service Account 都会关联一个 Secret,这个 Secret 包含一个用于认证的 bearer token,以及连接 Kubernetes API 服务器所需的 CA 证书。Pod 在运行时,这些凭证会被自动挂载到 Pod 的文件系统内。这个凭证通常会被挂载到 /var/run/secrets/kubernetes.io/serviceaccount 目录下,其中包括以下几个文件:

  1. token:这是用于认证的 bearer token。Pod 使用它来向 API 服务器证明自己的身份。
  2. ca.crt:这是集群的 CA 证书,Pod 使用它来验证 API 服务器的 TLS 证书,保证通信安全。
  3. namespace:记录当前 Pod 所在的命名空间。

这些信息结合在一起,使得 Pod 能够安全地与 Kubernetes API 服务器进行通信。

真实世界的应用场景

想象在一个物流企业中,有一个自动化调度应用需要与 Kubernetes API 进行通信,从而动态地调整工作节点的数量以适应当前的任务负载。这种情况下,调度应用运行在一个 Pod 中,而该 Pod 需要频繁地与 API 服务器交互,例如获取当前集群的状态、查看任务执行情况、增加或减少 Pod 数量。这时候,为了安全且有效地访问这些资源,通常为该 Pod 绑定一个特定的 Service Account。这样,调度应用可以借助该 Service Account 去访问 API 服务器,同时确保没有多余的权限可以滥用。

3. 配置 Service Account 的步骤

3.1 创建 Service Account

可以通过 kubectl 命令来创建一个新的 Service Account。例如,如果你想为一个需要特定权限的应用创建一个 Service Account,可以使用以下命令:

kubectl create serviceaccount custom-sa

上述命令创建了一个名为 custom-sa 的 Service Account。默认情况下,这个 Service Account 只具备最基础的访问权限,接下来需要为它绑定一些具体的权限。

3.2 创建 Role 和 RoleBinding

Service Account 自身并不具备任何权限,要想让它能够访问集群的资源,必须通过 Role 或 ClusterRole 与它绑定。Role 和 RoleBinding 是 Kubernetes 的 RBAC (Role-Based Access Control) 授权机制的一部分,它们可以分别用于定义在某个命名空间内的权限和跨命名空间的权限。

以下是一个为命名空间 default 中的 custom-sa 创建 RoleRoleBinding 的例子:

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: default
  name: custom-role
rules:
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get", "list", "watch"]

这个 Role 名为 custom-role,它允许在 default 命名空间中执行 getlistwatch 操作。

接下来,将该 Role 绑定到我们创建的 custom-sa Service Account 上:

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: custom-rolebinding
  namespace: default
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: custom-role
subjects:
- kind: ServiceAccount
  name: custom-sa
  namespace: default

在这个 RoleBinding 中,我们将 custom-role 绑定到了名为 custom-sa 的 Service Account 上。这意味着该 Service Account 现在可以使用 custom-role 定义的权限来访问资源。

3.3 使用 Service Account 启动 Pod

接下来,可以使用我们创建的 custom-sa Service Account 来启动一个 Pod。以下是一个使用 custom-sa 的 Pod 配置示例:

apiVersion: v1
kind: Pod
metadata:
  name: sample-pod
  namespace: default
spec:
  serviceAccountName: custom-sa
  containers:
  - name: sample-container
    image: nginx

在这个例子中,sample-pod 使用了我们之前创建的 Service Account custom-sa。通过这种方式,Pod 内运行的进程就可以使用 custom-sa 的 token 来与 Kubernetes API 服务器进行交互,并且只具备 custom-role 所定义的权限。

4. Pod 如何使用 Service Account 与 API 服务器交互

Pod 启动后,Kubernetes 会自动将关联的 Service Account 的凭证挂载到 Pod 内的文件系统中。通常这些凭证文件会被挂载到 /var/run/secrets/kubernetes.io/serviceaccount/ 目录下,Pod 内的进程可以使用这些凭证来访问 API 服务器。

例如,如果你在这个 Pod 内运行一个命令来请求 API 服务器,可以使用如下 curl 命令:

TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)
API_SERVER="https://kubernetes.default.svc"
NAMESPACE=$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace)

curl -k --header "Authorization: Bearer $TOKEN" $API_SERVER/api/v1/namespaces/$NAMESPACE/pods

在这个例子中,首先读取了 Pod 内的 token 文件,并通过 Authorization 头将 token 作为 bearer token 提供给 API 服务器。API 服务器会验证这个 token 的有效性,并根据该 token 所关联的权限决定是否允许访问请求的资源。

这种方式确保了只有拥有有效凭证的 Pod 才能与 Kubernetes API 服务器通信,从而保障了集群的安全性。

一个实际案例:监控系统的集成

在许多企业中,监控系统通常需要与 Kubernetes API 服务器交互,以收集节点和 Pod 的状态信息。假设在一个金融服务公司中,他们部署了一个监控系统用于监控集群的健康状况,并自动触发报警。监控系统通常需要在集群中运行,频繁地与 Kubernetes API 服务器交互,获取节点状态、资源使用率以及 Pod 状态等信息。

为了确保这种访问既安全又高效,可以为监控系统创建一个专属的 Service Account,并仅授予它对集群的只读权限。这样,即便监控系统所在的 Pod 遭受攻击,攻击者也无法利用监控系统的权限来破坏集群的关键资源,从而大大提高了集群的安全性。

5. 安全性考虑

尽管 Service Account 提供了访问 Kubernetes API 服务器的便捷方式,但在实际的生产环境中,必须考虑安全性。以下是一些最佳实践:

  • 最小权限原则:为每个 Service Account 授予尽可能少的权限,确保它们只能访问自己所需的资源。避免使用具有广泛权限的 ClusterRole,除非确实需要跨命名空间的权限。
  • 命名空间隔离:为不同的应用在不同的命名空间中创建 Service Account 和 Role,这样可以防止应用之间的权限相互干扰。
  • 定期轮换凭证:虽然 Kubernetes 会自动管理和更新 Service Account 的 token,但为了防止长期使用同一凭证而带来的安全隐患,建议定期检查和轮换这些凭证。
  • 监控和审计:启用 Kubernetes 的审计日志,记录所有对 API 服务器的访问行为。通过这些日志,可以监控和追踪 Service Account 的使用情况,发现异常的访问行为。

6. 真实场景中的挑战与解决方案

在实际的使用中,使用 Service Account 访问 API 服务器也可能面临一些挑战。比如,当集群的规模不断扩大时,管理不同应用的权限变得越来越复杂,特别是如何确保每个应用的 Service Account 都具备适当的权限而不过度授权。

以一家在线教育平台为例,他们的集群内运行着多个服务,包括直播、录播、作业管理等。每个服务都需要与 API 服务器通信,以动态地调配资源来应对用户的高峰需求。然而,这些服务之间的权限需求各不相同,部分服务可能只需要查询资源状态,而另一些服务则需要创建和删除 Pod。

在这种情况下,可以通过使用 Kubernetes 的 ClusterRoleRole 的组合,将常用的权限定义为 ClusterRole,然后在特定的命名空间内,通过 RoleBinding 将这些 ClusterRole 绑定到对应的 Service Account 上。这样既保证了权限的复用,也确保了在命名空间级别的细粒度控制。

例如,可以为所有需要只读权限的应用创建一个通用的 ClusterRole,然后在每个命名空间中绑定到对应的 Service Account 上。而对于那些需要更高权限的应用,则在它们专属的命名空间内创建特定的 Role 并绑定。这种方式使得权限管理更具灵活性,并减少了重复配置的工作量。

7. 省流版

Service Account 是 Kubernetes 中用于 Pod 安全访问 API 服务器的关键机制之一。它通过结合 RBAC 的授权机制,为不同的应用提供最小权限的访问能力,从而保证集群的安全性和稳定性。在实践中,通过合理地配置 Service Account、Role、以及 RoleBinding,可以实现对应用访问权限的精细化控制。

在实际部署和运维过程中,建议遵循以下几点来优化 Service Account 的使用:

  • 定期审查权限,确保没有过度授权。
  • 使用命名空间进行隔离,不同的应用运行在不同的命名空间中,避免相互影响。
  • 启用审计日志,监控 Service Account 的使用情况,以便及时发现潜在的安全问题。
【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。