提示:本文原创作品,良心制作,干货为主,简洁清晰,一看就会
文章目录
- 前言
- [一、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%原创,转载请务必标注原创作者,尊重劳动成果。
求赞、求关注、求评论!你的支持是我更新的最大动力,评论区等你~