【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%原创,转载请务必标注原创作者,尊重劳动成果。

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

相关推荐
尘世壹俗人2 小时前
知识点12---k8s进阶操作方式yaml资源文件
docker·容器·kubernetes
尘世壹俗人2 小时前
知识点13---k8s存储持久化
容器·kubernetes·flask
SilentSamsara2 小时前
Kubernetes 网络模型:CNI 插件与 Pod 间通信的底层实现
网络·云原生·容器·架构·kubernetes·k8s
wuxinyan1233 小时前
Java面试题50:Kubernetes 全栈知识体系之一
java·kubernetes·面试题
牛奶咖啡133 小时前
Docker容器实践——Docker常用基础镜像的解析与选择
docker·容器·docker基础镜像·docker基础镜像选择·docker基础镜像最佳实践·docker基础镜像的分类·docker基础镜像的对比
java_logo4 小时前
Docker 部署 Open WebUI + Ollama 完整教程(Windows / Linux 通用)—— 打造自己的本地OpenAI
linux·docker·容器·ollama·open-webui·open-webui部署·open-webui教程
程序员老邢4 小时前
【技术底稿 23】Ollama + Docker + Ubuntu 部署踩坑实录:网络通了,参数还在调
java·经验分享·后端·ubuntu·docker·容器·milvus
小夏子_riotous4 小时前
Docker学习路径——8、Dockerfile
linux·运维·docker·容器·系统架构·centos·运维开发
切糕师学AI4 小时前
Docker Compose 完全指南:从入门到实践
运维·docker·容器