必须创建专用ServiceAccount并绑定RBAC权限才能安全访问API Server:先建命名空间和账号,再定义同命名空间的Role,最后用RoleBinding关联,Pod中指定serviceAccountName并验证Token与权限。

要让 Kubernetes 集群中的应用 Pod 安全、可控地访问 API Server(比如读取自身命名空间下的 Pod 列表、更新 ConfigMap、触发 Deployment 重建),必须显式创建 ServiceAccount 并通过 RBAC 绑定权限,不能依赖默认的 default 账号——它在多数生产集群中已被限制或禁用。
创建专用 ServiceAccount
先为应用分配独立身份,避免复用 default 账号造成权限混淆或横向越权。
执行命令创建命名空间和账号:kubectl create namespace app-prod && kubectl create serviceaccount app-sa -n app-prod
这一步生成的是纯身份标识,不含任何权限。若跳过此步直接在 Pod 中指定 serviceAccountName: app-sa,Pod 将因找不到该账号而无法启动(报错 serviceaccount "app-sa" not found)。
定义 Role 并限定作用域
Role 必须与 ServiceAccount 处于同一命名空间,否则绑定失败。下面这个 Role 允许对 app-prod 命名空间内的 Deployment 和 ConfigMap 执行增删改查操作:
新建 app-role.yaml:
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: app-prod
name: app-deploy-config-manager
rules:
- apiGroups: ["", "apps"]
resources: ["deployments", "configmaps"]
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
运行 kubectl apply -f app-role.yaml 创建 Role。
【注意:resources 字段中 "" 表示 core API 组,"apps" 是扩展 API 组;漏写任一都会导致对应资源操作被拒绝】
将 Role 绑定到 ServiceAccount
方法一:使用 RoleBinding 显式关联(推荐)
通过 Google 服务账户在代码中读取或写入用户的 Google 表格、文档、云盘或日历——无头、无需 OAuth 浏览器流程。适用于已获得服务账户凭证的情况。
新建 app-rolebinding.yaml:
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: app-sa-can-manage
namespace: app-prod
subjects:
- kind: ServiceAccount
name: app-sa
namespace: app-prod
roleRef:
kind: Role
name: app-deploy-config-manager
apiGroup: rbac.authorization.k8s.io
执行 kubectl apply -f app-rolebinding.yaml。
方法二:用命令行快速绑定(适合调试)
kubectl create rolebinding app-sa-binding --role=app-deploy-config-manager --serviceaccount=app-prod:app-sa -n app-prod
在 Pod 中使用该 ServiceAccount
第一步:确认 Pod YAML 中已设置 serviceAccountName: app-sa,且命名空间与 RoleBinding 一致。
第二步:确保 Pod 模板中未禁用自动挂载 Token(Kubernetes v1.24+ 默认不挂载长期 Token,但会挂载绑定的临时 Projected ServiceAccount Token)。
第三步:部署 Pod:kubectl apply -f app-pod.yaml。
第四步:进入容器验证 Token 是否就位:kubectl exec -it <pod-name> -n app-prod -- ls /var/run/secrets/kubernetes.io/serviceaccount/,应看到 ca.crt、namespace、token 三个文件。
第五步:在容器内调用 API 测试权限:curl -k --header "Authorization: Bearer $(cat /var/run/secrets/kubernetes.io/serviceaccount/token)" https://$KUBERNETES_SERVICE_HOST:$KUBERNETES_SERVICE_PORT/api/v1/namespaces/app-prod/configmaps。返回 200 表示授权成功;若返回 403,则检查 Role 规则是否覆盖目标资源与动词。

















