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

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

相关推荐
Linux-18747 小时前
分布式链路追踪系统之docker-compose安装skywalking
云原生·docker-compose·skywalking·分布式链路追踪系统·应用程序性能监控
生活爱好者!13 小时前
我把NAS当作下载机,docker一键部署qb
运维·docker·容器
隔窗听雨眠13 小时前
Spring Boot在云原生时代的编程范式革新研究
spring boot·后端·云原生
Hui Baby14 小时前
K8S使用CRD和控制器简单应用
云原生·容器·kubernetes
阿里云云原生15 小时前
从“告警驱动”到“巡检驱动”:Agent 智能体如何实现前端体验治理的闭环?
云原生
AOwhisky16 小时前
Python 学习笔记(第十三期)——运维自动化(下·前篇):远程命令执行——paramiko基础篇
运维·python·学习·云原生·自动化·运维开发·paramiko
AOwhisky17 小时前
Python 学习笔记(第十四期)——运维自动化(下·中篇):远程文件传输——paramiko进阶篇
运维·python·学习·云原生·自动化·文件传输·paramiko
做个文艺程序员17 小时前
Linux第22篇:用Docker容器化你的Java SaaS应用:一次构建,随处运行
java·docker·容器
Zhu75819 小时前
在k8s环境部署Apache Superset最新版
容器·kubernetes·apache
小的博客19 小时前
windows下安装Docker Desptop
运维·docker·容器