本笔记记录了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 策略回收流程

  1. 初始状态: PV(Available) ←── PVC(使用中) ←── Pod(运行中) 
  2. Pod 删除: PV(Available) ←── PVC(保留) 
  3. 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策略+定期备份

Logo

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

更多推荐