【K8s ServiceAccount 机制原理与 RBAC 权限实战应用】

提示:本文原创作品,良心制作,干货为主,简洁清晰,一看就会

文章目录

  • 前言
  • [一、ServiceAccount 核心介绍](#一、ServiceAccount 核心介绍)
    • [1.1 SA是什么](#1.1 SA是什么)
    • [1.2 SA工作机制(适配K8s 1.21+ 新版机制)](#1.2 SA工作机制(适配K8s 1.21+ 新版机制))
  • 二、ServiceAccount应用
    • [2.1 pod 内置身份凭证自动挂载原理](#2.1 pod 内置身份凭证自动挂载原理)
    • [2.2 不给 SA 授权就不能查集群资源,授权后才能正常访问](#2.2 不给 SA 授权就不能查集群资源,授权后才能正常访问)

前言

在Kubernetes集群运维中,权限安全与资源访问管控至关重要。ServiceAccount作为集群内置的非人工身份体系,专为Pod内应用进程设计,负责容器与API Server的身份认证。依托它可实现应用权限精细化划分,规避默认账号权限过大的安全隐患。本文将详解ServiceAccount核心原理、配置使用及权限绑定实践

一、ServiceAccount 核心介绍

1.1 SA是什么

ServiceAccount 是 k8s 专 为Pod 内部应用进程提供的专属身份凭证 ,属于命名空间级别集群资源

区别于给运维人员使用的 User、Group 人工管理账号,ServiceAccount 专门用于集群内部容器业务进程访问 K8s API Server 时做身份认证与安全鉴权

核心作用:为 Pod 提供合法的集群访问身份,保障容器与 API Server 加密安全通信;配合 Role、ClusterRole 与 RBAC 权限体系实现权限精细化管控,严格限制业务容器仅能访问所需资源,遵循最小权限原则

1.2 SA工作机制(适配K8s 1.21+ 新版机制)

  • 每个命名空间默认自带 default 默认 ServiceAccount,创建 Pod 若未手动指定账号,会自动绑定当前命名空间默认 SA
  • 不再自动为 ServiceAccount 创建 Secret,不再通过 Secret 挂载认证凭证
  • 集群采用 Projected 投射卷动态注入机制,由 API Server 动态生成限时临时 Token,搭配集群 ConfigMap 提供 CA 根证书,自动挂载到容器内部固定目录
  • Token 默认有效期一小时,kubelet 会自动无感续期轮换,容器无需重启,Pod 业务运行不受任何影响

二、ServiceAccount应用

2.1 pod 内置身份凭证自动挂载原理

pod刚被创建出来,就拥有和api-server通信的权限、token和证书,这全是 Namespace 下默认的default ServiceAccount的功劳

ServiceAccount 采用 临时凭证 + 投射卷(Projected Volume)的全新安全机制,不再自动创建与挂载持久化 Secret

Pod 启动时,API Server 动态签发带过期时间的 Token,结合集群默认 ConfigMap 提供的 CA 证书与 downwardAPI 注入的命名空间,统一通过 projected 卷挂载到容器内,实现更安全、更轻量化的身份认证能力

yaml 复制代码
## 1. 如果创建一个命名空间,则默认自带一个名为default的sa
root@k8s-master1:~# mkdir  -p /k8s-test/sa
root@k8s-master1:~# cd /k8s-test/sa
root@k8s-master1:/k8s-test/sa# kubectl create ns testns
root@k8s-master1:/k8s-test/sa# kubectl get sa -n testns
NAME      SECRETS   AGE
default   0         25s

## 2. 创建一个pod,看看里面会自动挂载什么?
root@k8s-master1:/k8s-test/sa# kubectl get pod
NAME        READY   STATUS    RESTARTS   AGE
nginx-pod   1/1     Running   0          7s
root@k8s-master1:/k8s-test/sa# kubectl get pod nginx-pod -o yaml
yaml 复制代码
root@k8s-master1:/k8s-test/sa# kubectl exec -it nginx-pod /bin/bash  # 进入pod
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
root@nginx-pod:/# ls /var/run/secrets/kubernetes.io/serviceaccount  #查看存放路径,可以用cat继续查看里面的内容
ca.crt  namespace  token

2.2 不给 SA 授权就不能查集群资源,授权后才能正常访问

默认 default sa 会为 Pod 自动注入通信凭证,容器可正常与 API Server 建立加密通信、访问集群基础接口;但该账号未绑定任何 RBAC 授权规则,仅支持基础鉴权访问,无法查询、操作 Pod、节点、配置等集群核心资源,从而保障集群默认安全

我们新建一个 SA,绑定 RBAC 权限,让 Pod 可以正常查询集群资源

yaml 复制代码
## 1. 目前现状:默认SA无权限
root@k8s-master1:/k8s-test/sa# kubectl exec -it nginx-pod /bin/bash
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
root@nginx-pod:/# ls
bin  boot  dev  docker-entrypoint.d  docker-entrypoint.sh  etc  home  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
root@nginx-pod:/# apt update && apt -y install curl
## 访问具体资源接口403
root@k8s-master1:/k8s-test/sa# kubectl exec -it nginx-pod /bin/bash
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
# 查 default 命名空间下的所有 Pod 列表报错403
root@nginx-pod:/# curl -k https://kubernetes.default.svc/api/v1/namespaces/default/pods -H "Authorization: Bearer $(cat /var/run/secrets/kubernetes.io/serviceaccount/token)"
{
  "kind": "Status",
  "apiVersion": "v1",
  "metadata": {},
  "status": "Failure",
  "message": "pods is forbidden: User \"system:serviceaccount:default:default\" cannot list resource \"pods\" in API group \"\" in the namespace \"default\"",
  "reason": "Forbidden",
  "details": {
    "kind": "pods"
  },
  "code": 403
}root@nginx-pod:/# exit
exit
root@k8s-master1:/k8s-test/sa# 
yaml 复制代码
## 2. 创建自定义的sa
root@k8s-master1:/k8s-test/sa# cat test-sa.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  name: api-reader-sa
  namespace: default
root@k8s-master1:/k8s-test/sa# kubectl apply -f test-sa.yaml
root@k8s-master1:/k8s-test/sa# kubectl get sa
NAME            SECRETS   AGE
api-reader-sa   0         7s
default         0         16d
yaml 复制代码
## 3. 创建role,允许查询pod资源
root@k8s-master1:/k8s-test/sa# vim test-role.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: pod-reader-role
  namespace: default
rules:
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get", "list"]
root@k8s-master1:/k8s-test/sa# kubectl apply -f test-role.yaml 
yaml 复制代码
## 4. 绑定RoleBinding 给 SA 授权
root@k8s-master1:/k8s-test/sa# vim test-rolebinding.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: sa-pod-reader-rb
  namespace: default
subjects:
- kind: ServiceAccount
  name: api-reader-sa
roleRef:
  kind: Role
  name: pod-reader-role
  apiGroup: rbac.authorization.k8s.io
root@k8s-master1:/k8s-test/sa# kubectl apply -f test-rolebinding.yaml 
yaml 复制代码
## 5. 创建pod使用这个sa
root@k8s-master1:/k8s-test/sa# vim test-pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: sa-test-pod
spec:
  serviceAccountName: api-reader-sa  # 手动指定SA
  containers:
  - name: nginx
    image: nginx:1.24
root@k8s-master1:/k8s-test/sa# kubectl apply -f test-pod.yaml 
root@k8s-master1:/k8s-test/sa# kubectl get pod
NAME          READY   STATUS    RESTARTS   AGE
nginx-pod     1/1     Running   0          62m
sa-test-pod   1/1     Running   0          7s
root@k8s-master1:/k8s-test/sa# kubectl exec -it sa-test-pod /bin/bash
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
# 查 default 命名空间下的所有 Pod 列表
root@sa-test-pod:/# curl -k https://kubernetes.default.svc/api/v1/namespaces/default/pods -H "Authorization: Bearer $(cat /var/run/secrets/kubernetes.io/serviceaccount/token)"

注:

文中若有疏漏,欢迎大家指正赐教。

本文为100%原创,转载请务必标注原创作者,尊重劳动成果。

求赞、求关注、求评论!你的支持是我更新的最大动力,评论区等你~

相关推荐
SPC的存折3 分钟前
22、K8S-Helm
云原生·容器·kubernetes
nix.gnehc9 分钟前
Langfuse v3 Docker 部署
运维·人工智能·docker·容器·langfuse
行者-全栈开发10 分钟前
【前端安全】CVE-2026-44578:Next.js SSRF 漏洞深度解析与修复实战指南
websocket·云原生·next.js·安全防护·vercel·cve-2026-44578·中间件绕过
Elastic 中国社区官方博客13 分钟前
在 Kubernetes 上的 Elastic Cloud:简化的可用区感知、重启和 mTLS
大数据·数据库·搜索引擎·云原生·容器·kubernetes·全文检索
蜀道山老天师16 分钟前
Prometheus监控Hadoop集群(实操完整版,含避坑指南)
大数据·linux·运维·hadoop·云原生·prometheus
sbjdhjd23 分钟前
01| 裸机部署 K8S:从零搭建生产可用集群
运维·经验分享·云原生·kubernetes·开源·kubelet·kubeless
jran-30 分钟前
Docker 容器化技术&docker安装
运维·docker·容器
不会写DN33 分钟前
基于 Docker + Watchtower 自动化部署后端服务
docker·容器·自动化
Elastic 中国社区官方博客37 分钟前
通过项目标签和路由,在 Elasticsearch Serverless 中实现更快的跨项目搜索
大数据·elasticsearch·搜索引擎·云原生·serverless·全文检索
逆境不可逃2 小时前
一篇速通互联网架构的不断升级过程:从单机到云原生
java·elasticsearch·搜索引擎·云原生·架构