Kubernetes RBAC权限控制与持久化存储
·
本笔记记录了K8s 中的 RBAC 权限控制机制与持久化存储方案,涵盖用户认证、角色授权、存储类型及 PV/PVC 架构设计。
一、K8s 用户认证与账户类型
1.1默认服务账户(Service Account)

| 特性 | 说明 |
| 定义位置 | 每个命名空间下都有一个默认的default服务账户 |
| Pod默认使用 | 在资源清单中若未指定SA,Pod默认使用default账户运作 |
| 新版本变化 | K8s新版本中,SA不再自动挂载Token秘钥 |
1.2管理账户(User Account)
| 特性 | 说明 |
| 用途 | 用于通过KUbectl等工具管理集群的用户账户 |
| 认证信息存储 | $HOME/.kube/config 文件 |
| 配置内容 | 包含集群地址、证书及用户信息 |
| 权限范围 | 当前操作者通过该配置文件中的账户身份获得集群管理权限 |

二、RBAC授权核心原理
2.1三大安全原则
| 原则 | 作用 | 示例 |
| 认证(Authentication) | 验证账户是否存在及合法性 | 用户名密码、Token、SSL证书 |
| 授权(Authorization) | 缺点已认证账户对资源的操作权限 | 创建Pod、访问特定命名空间 |
| 准入控制(Admission Control) | 在对象持久化之前拦截请求,进行验证或修改 |
强制添加标签、检查镜像来源 |
2.2RBAC模型
核心概念:
- 权限不直接赋予用户,而是先定义角色(Role),再将角色绑定到用户或服务账户
- 支持角色复用和权限层级管理
三、角色与绑定的层级分类
3.1层级对比
| 层级类型 | 资源类型 | 作用范围 | 绑定资源 |
| Namesoace-scoped | Role | 特定命名空间内 | RoleBinding |
| Cluster-scoped | ClusterRole | 整个集群或非资源型端点 | ClusterRoleBinding |
3.2命名空间级别(Nmaespace-scoped)
yaml
#Role:定义特定命名空间内的权限规则
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: pod-reader
namespace: my-namespace #限定命名空间
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get","list","watch"]
yaml
#RoleBinding:将Role绑定到该命名空间内的用户或SA
apiVersion: rba.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: read-pods-binding
namespace: my-pods-binding #限定命名空间
subjects:
- kind: User
name: lucky
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: pods-reader
apiGroup: rbac.authorization.k8s.io
3.3集群级别(Cluster-scoped)
yaml
# ClusterRole:定义整个集群范围内的权限
apiVersion: rbac.authorization.k8x.io/v1
kind: ClusterRole
metadata:
name: cluster-admin
rules:
#集群级资源
- apiGroups: [""]
resources: ["nodes"]
verbs: ["get","list","watch"]
#非资源型端点
- nonResourceURLs: ["/healthz","/version"]
#非资源型端点
- nonResourceURLs: ["/healthz","/version"]
verbs: ["get"]
yaml
#ClusterRoleBinding:适用于跨命名空间或集群级资源的管理
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: cluster-admin-binding
subjects:
- kind: User
name: lucky
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: cluter-admin
apiGroup: rbac.authorization.k8s.io
3.4设计优势

优势:适用ClusterRole可避免为多个命名空间重复定义相同权限的角色,简化管理。
四、RBAC配置详解
4.1权限规则字段(rules)
| 类型 | 说明 | 示例值 | |
| apiGroups | []string | API组名称 | [" "]表示核心API组 |
| resources | []string | 资源类型列表 | ["pods","services"] |
| verbs | []string | 操作动作列表 | ["get","list","creats"] |
| resourceNames | []string | 可选,限制特定名称的资源实例 | ["my-pod"] |
4.2verbs 操作动作说明
| Verb | 含义 | HTTP方法 |
| get | 读取单个资源 | GET |
| list | 列出资源列表 | GET |
| watch | 监听资源变化 | GET |
| create | 创建资源 | POST |
| update | 更新资源 | PUT |
| patch | 部分更新资源 | PATCH |
| delete | 删除资源 | DELETE |
| deletecollection | 删除资源集合 | DELETE |
| * | 所有权限 | - |
4.3绑定配置字段
| 字段 | 说明 |
| subjects | 指定绑定的用户、组或服务账户 |
|
roleRef |
引用具体的Role或ClusterRole,需指定kind、name和apiGroup |
4.4subjects类型示例
yaml
subjects:
# 用户
- kind: User
name: lucky
apiGroup: rbac.authorization.k8s.io
# 组
- kind: Group
name: developers
apiGroup: rbac.authorization.k8s.io
# 服务账户
- kind: ServiceAccount
name: my-sa
namespace: my-namespace
五、自定义用户账户创建于配置实战
5.1整体流程

5.2步骤详解
步骤1:生成证书
bash
#1.生成用户私钥
openssl genrsa -out lucky.key 2048
#2.创建证书签名请求(CSR)
#注意:CN(Common Name)即为 Kubernetes中的用户名
openssl req -new -key lucky.key -out lucky.csr -subj "/CN=lucky/O=developers"
#3.由Kubernetes CA 签署证书
openssl x509 -req -in lucky.csr \
-CA /etc/kubernetes/pki/ca.crt \
-CAkey /etc/kubernetes/pki/ca.key \
-out lucky.crt -days 365
步骤2:配置kubeconfig
bash
# 添加用户凭证(指定证书和私钥)
kubectl config set-credentials licky \
--clien-certificate=/path/to/luck.crt \
--client-key=/path/to/lucky.key \
--embed-certs=true
# 创建上下文,关联集群、命名空间及新用户
kubectl config set-context lucky-context \
--cluster=kubernetes \
--namespace=default \
--user=lucky
# 切换只上下文
kubectl config use-context lucky-context
步骤3:创建RBAC 授权
yaml
# 创建 Role(命名空间级权限)
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: pod-manager
namespace: default
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list", "create", "delete"]
yaml
# 创建 RoleBinding 将用户绑定到 Role
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: lucky-pod-binding
namespace: default
subjects:
- kind: User
name: lucky
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: pod-manager
apiGroup: rbac.authorization.k8s.io
步骤4:验证权限
bash
# 测试权限 - 成功场景
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-pod 1/1 Running 0 1h
# 测试权限 - 失败场景(未正确绑定时)
$ kubectl get pods
Error from server (Forbidden): pods is forbidden: User "lucky" cannot
list resource "pods" in API group "" in the namespace "default"
六、持久化循序基础概念
6.1存储类比对比
| 存储类型 | 生命周期 | 数据持久性 | 共享访问 | 使用场景 |
|
emptyDir |
Pod生命周期 |
❌️Pod删除则清空 | ❌️仅单Pod | 缓存、中间数据、临时存储 |
| hostPath | 节点生命周期 | ✅️节点存活则保留 | ❌️仅单节点 | 节点级日志、系统目录 |
| NFS | 独立于Pod/节点 | ✅️永久存储 | ✅️多Pod/节点 | 生产环境共享存储 |
6.2emptyDir

yaml
apiVersion: v1
kind: Pod
metadata:
name: cache-pod
spec:
containers:
- name: app
image: nginx
volumeMounts:
- name: cache-volume
mountPath: /tmp/cache
volumes:
- name: cache-volume
emptyDir:
sizeLimit: 100Mi
medium: Memory # 可选: 使用内存作为存储后端
6.3hostPath

yaml
apiVersion: v1
kind: Pod
metadata:
name: node-log-pod
spec:
containers:
- name: logger
image: nginx
volumeMounts:
- name: node-logs
mountPath: /var/log/app
volumes:
- name: node-logs
hostPath:
path: /data/app-logs
type: DirectoryOrCreate # 目录不存在则创建
| 风险 | 说明 |
| 节点依赖 | 依赖特定节点,节点故障导致数据不可用 |
| 调度限制 | 多Pod共享hostPath时调度复杂 |
| 安全隐患 | 肯呢个访问宿主机的敏感目录 |
6.4NFS(网络存储)

yaml
apiVersion: v1
kind: Pod
metadata:
name: nfs-pod
spec:
containers:
- name: app
image: nginx
volumeMounts:
- name: nfs-storage
mountPath: /mnt/nfs
volumes:
- name: nfs-storage
nfs:
server: nfs-server.example.com
path: /data/v1
readOnly: false
前置要求:所有工作节点需安装 nfs-utils 客户端
七、PV与PVC架构设计
7.1架构解耦思想

7.2核心概念对比
| 组件 | 级别 | 定义者 | 生命周期 | 绑定方式 |
| PV | 集群级别 | 管理员/StorageClass | 独立于Pod | 一一对应 |
| PVC | 命名空间级别 | 用户 | 跟随Pod | 匹配PV |
| Pod | Pod级别 | 用户 | Pod生命周期 |
引用PVC |
7.3绑定机制详解

匹配规则:
- 容量:PVC声明容量≤PV 容量
- 访问模式:PVC访问模式必须完全匹配PV支持的模式
- 一一对应:一旦绑定,PV无法被其他PVC使用
7.4访问模式(Access Modes)
| 模式 | 简写 | 说明 | 支持的存储 |
| ReadWriteOnce | RWO | 单节点读写 | 大多数存储 |
|
ReadOnlyMany |
ROX | 多节点读写 | NFS、cephfs |
| ReadWriteMany | RWX | 多节点读写 | NFS、cephfs |
| ReadWriteOncePod | RWOP | 单Pod独占读写 | CSI支持的存储 |
八、PV/PVC静态配置实战
8.1整体流程

8.2步骤1:准备后端存储
bash
# 在 NFS 服务器上配置导出目录
# /etc/exports 内容:
/data/v1 *(rw,sync,no_subtree_check)
/data/v2 *(rw,sync,no_subtree_check)
/data/v3 *(rw,sync,no_subtree_check)
/data/v4 *(rw,sync,no_subtree_check)
/data/v5 *(rw,sync,no_subtree_check)
/data/v6 *(rw,sync,no_subtree_check)
/data/v7 *(rw,sync,no_subtree_check)
/data/v8 *(rw,sync,no_subtree_check)
/data/v9 *(rw,sync,no_subtree_check)
/data/v10 *(rw,sync,no_subtree_check)
# 重载 NFS 配置
exportfs -ra
8.3步骤2:创建PV
yaml
# pv-nfs-v1.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv-nfs-v1
labels:
type: nfs
capacity: 1Gi
spec:
capacity:
storage: 1Gi
accessModes:
- ReadWriteMany # 必须是 ReadWriteMany 才能被多 Pod 共享
persistentVolumeReclaimPolicy: Retain
storageClassName: nfs-storage
nfs:
server: nfs-server.example.com
path: /data/v1
---
# pv-nfs-v2.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv-nfs-v2
labels:
type: nfs
capacity: 2Gi
spec:
capacity:
storage: 2Gi
accessModes:
- ReadWriteMany
persistentVolumeReclaimPolicy: Retain
storageClassName: nfs-storage
nfs:
server: nfs-server.example.com
path: /data/v2
创建并验证:
bash
# 创建 PV
kubectl apply -f pv-nfs-v1.yaml
kubectl apply -f pv-nfs-v2.yaml
# 查看 PV 状态(初始为 Available)
kubectl get pv
# NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS AGE
# pv-nfs-v1 1Gi RWO,RWX Retain Available 10s
# pv-nfs-v2 2Gi RWO,RWX Retain Available 5s
8.4步骤3:创建PVC
yaml
# pvc-myapp.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: myapp-pvc
namespace: default
spec:
accessModes:
- ReadWriteMany # 必须与 PV 匹配
resources:
requests:
storage: 1Gi # 必须 ≤ PV 容量
storageClassName: nfs-storage
selector:
matchLabels:
type: nfs
创建并验证:
bash
# 创建 PVC
kubectl apply -f pvc-myapp.yaml
# 查看 PVC 状态
kubectl get pvc
# NAME STATUS VOLUME CAPACITY ACCESS MODES AGE
# myapp-pvc Bound pv-nfs-v1 1Gi RWO,RWX 10s
# 再次查看 PV 状态(已变为 Bound)
kubectl get pv
# NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS AGE
# pv-nfs-v1 1Gi RWO,RWX Retain Bound 2m
8.5步骤4:Pod适用PVC
yaml
# pod-with-pvc.yaml
apiVersion: v1
kind: Pod
metadata:
name: myapp-pod
spec:
containers:
- name: myapp
image: nginx
volumeMounts:
- name: myapp-storage
mountPath: /usr/share/nginx/html
volumes:
- name: myapp-storage
persistentVolumeClaim:
claimName: myapp-pvc
bash
# 创建 Pod
kubectl apply -f pod-with-pvc.yaml
# 验证 Pod 正常运行
kubectl get pod myapp-pod
# NAME READY STATUS RESTARTS AGE
# myapp-pod 1/1 Running 0 30s
# 验证挂载成功
kubectl describe pod myapp-pod | grep -A 5 "Volumes:"
# Volumes:
# myapp-storage:
# Type: NFS (a NFS volume that is mounted to the pod)
# Server: nfs-server.example.com
# Path: /data/v1
8.6失败场景分析
| 失败原因 | PVC状态 | Pod状态 | 错误信息 |
| 容量不足 | Pending | FaliedScheduling | persistentvolumeclai ms "myapp-pvc" quota 1Gi exceeded |
| 访问模式不匹配 | Pending | FaliedScheduling | no PersistentVolume available with this Request |
| StorageClisee不匹配 | Pending | FaliedScheduling | storageclass not found |
九、存储回收策略
9.1策略类型对比
| 策略 | 行为 | 数据安全 | 适用场景 |
| Retain | PVC删除后,PV释放但数据保留,需手动清理 | ✅️高安全 | 生产环境、关键数据 |
| Delete | PVC删除后,PV及后端存储数据自动删除 | ❌️有风险 | 测试环境、临时数据 |
9.2Retain策略详解

9.3Delete策略详解
Delete 策略回收流程
- 初始状态: PV(Available) ←── PVC(使用中) ←── Pod(运行中)
- Pod 删除: PV(Available) ←── PVC(保留)
- PVC 删除:
├── PV 自动删除
└── 后端存储数据自动删除 (如云盘)
9.4生产建议

9.5StorageClass动态供给(进阶)
yaml
# storageclass-nfs.yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: nfs-storage
annotations:
storageclass.kubernetes.io/is-default-class: "true"
provisioner: nfs.example.com/provisioner
parameters:
archiveOnDelete: "false" # 删除时是否保留数据副本
pathPattern: "/data/vol-${pvc.namespace}/${pvc.name}"
总结

要点:
- RBAC通过角色抽象实现权限管理,支持命名空间级和集群级
- 存储选择需要根据数据持久性和共享需求权衡
- PV/PVC解耦了存储供给与使用,简化应用配置
- 生产环境推荐NGS+Retain策略+定期备份

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐


所有评论(0)