K8s访问控制(一)

发布于:2025-09-07 ⋅ 阅读:(22) ⋅ 点赞:(0)

K8s访问控制

描述 K8s API 访问控制

API Server 认证流程

当一个请求到达 API Server 时,会依次经过以下几个步骤:

  1. 认证(Authentication)

    • 确认你是谁。

    • 常见方式:

      • 证书认证(TLS 双向认证,kubelet、kubectl 默认用证书)

      • Token 认证(ServiceAccount、OIDC 等)

      • 静态用户名密码文件(一般只用于测试)

     输出结果:用户身份(如 User: aliceServiceAccount: default:nginx-sa)。

  2. 鉴权(Authorization)

    • 确认你是否有权限做这件事。

    • 常见方式:

      • RBAC(基于角色的访问控制)  最常用

      • ABAC(基于属性的访问控制)

      • Node(Kubelet 默认使用的权限控制器)

     输出结果:允许/拒绝。

  3. 准入控制(Admission Control)

    • 在通过认证+鉴权后,还会有一些插件执行进一步校验或修改请求。

    • 例如:

      • LimitRanger:限制 Pod 的 CPU/内存大小。

      • NamespaceLifecycle:禁止删除关键 namespace。

      • PodSecurity(新版本代替 PSP):控制 Pod 的安全上下文。


API组

在 K8s 里,**API 组(API Group)是对 Kubernetes API 资源的一种逻辑分类机制。


K8s 的 API 是通过 RESTful 风格设计的,路径一般长这样:

/apis/<API组>/<版本>/<资源>

比如:

  • 核心 API 组(core group,也叫 legacy group,没有名字):

    /api/v1/pods
    /api/v1/namespaces
    
  • apps 组:

    /apis/apps/v1/deployments
    /apis/apps/v1/statefulsets
    
  • rbac.authorization.k8s.io 组:

    /apis/rbac.authorization.k8s.io/v1/roles
    

 也就是说,同一个 API 组下可以包含多个资源(Pods、Deployments 等),每个资源有不同版本


常见的 API 组

  • 核心组(Core/Legacy)
    没有组名,路径就是 /api/v1/...,包含 Pods、Services、ConfigMaps、Secrets 等常用对象。

  • apps
    主要是工作负载资源:Deployment、DaemonSet、StatefulSet、ReplicaSet 等。

  • batch
    Job、CronJob。

  • rbac.authorization.k8s.io
    RBAC 相关:Role、ClusterRole、RoleBinding、ClusterRoleBinding。

  • apiextensions.k8s.io
    CRD(自定义资源定义)。

  • 其他扩展
    networking.k8s.io、policy、autoscaling、storage.k8s.io 等。


在访问控制(RBAC)里的作用

RBAC 授权规则里,权限绑定需要指定 资源对象归属的 API 组
这样可以实现更细粒度的权限控制。

举例:

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: default
  name: pod-reader
rules:
- apiGroups: [""]           # 空字符串表示 core group
  resources: ["pods"]
  verbs: ["get", "list"]
- apiGroups: ["apps"]       # apps 组
  resources: ["deployments"]
  verbs: ["get", "list"]

解释:

  • apiGroups: [""] 表示核心组(pods 就属于 core)。

  • apiGroups: ["apps"] 表示 apps 组(deployments 就属于 apps/v1)。

  • 如果写 apiGroups: ["*"],就表示所有 API 组。

描述 RBAC

Role-Based Access Control(基于角色的访问控制)。

它是一种授权机制,用于 将权限分配给角色,再将角色绑定到用户/ServiceAccount

在 K8s 中,RBAC 是通过 API 资源对象 来定义的,主要涉及:

  • Role / ClusterRole:定义一组权限。
  • RoleBinding / ClusterRoleBinding:把权限绑定到用户或 ServiceAccount。

RBAC 的多维度权限控制

RBAC 在 K8s 中就是一个 权限矩阵,你可以从多个维度组合权限:

维度 含义 示例
用户 / 组 谁来操作 用户 alice、组 dev-team、ServiceAccount nginx-sa
资源 (resources) 操作的对象 podsdeploymentsservicesconfigmaps
命名空间 (namespace) 作用范围 只能访问 dev 命名空间的 Pod
API 组 (apiGroups) 资源所属的 API 核心资源 (""),apps 组 (apps/v1),RBAC 组 (rbac.authorization.k8s.io)
操作方法 (verbs) 允许的操作 getlistwatchcreateupdatedelete

这样组合后,你就能非常细粒度地定义权限,比如:
 alice 用户在 dev 命名空间 只能查看 Pod 和 Service,不允许修改


使用 RBAC 资源对象

RBAC 主要有 四个对象

  • Role / ClusterRole:定义权限

  • RoleBinding / ClusterRoleBinding:把权限分配给用户/组/SA

例子 1:给某个用户分配 namespace 级别权限

让用户 alice 只能在 dev 命名空间查看 Pod 和 Service

# Role: 定义权限规则
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: dev
  name: dev-viewer
rules:
- apiGroups: [""]                   # "" 表示 core API group (pods, services, configmaps)
  resources: ["pods", "services"]   # 限定资源
  verbs: ["get", "list", "watch"]   # 允许的操作方法
---
# RoleBinding: 把权限赋给用户
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: dev-viewer-binding
  namespace: dev
subjects:
- kind: User                        # 可以是 User, Group, ServiceAccount
  name: alice                       # 用户名
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: Role
  name: dev-viewer
  apiGroup: rbac.authorization.k8s.io

例子 2:组权限

dev-team 组的所有人都能管理 deployments

kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  namespace: dev
  name: deployment-admin
rules:
- apiGroups: ["apps"]              # 指定 API 组 (apps/v1)
  resources: ["deployments"]
  verbs: ["*"]                     # 允许所有操作 (create, update, delete, get...)
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  namespace: dev
  name: deployment-admin-binding
subjects:
- kind: Group                      # 对整个组赋权
  name: dev-team
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: Role
  name: deployment-admin
  apiGroup: rbac.authorization.k8s.io

例子 3:集群级别权限

bob 拥有 跨命名空间的 Node 查看权限

# ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: node-reader
rules:
- apiGroups: [""]
  resources: ["nodes"]
  verbs: ["get", "list", "watch"]
---
# ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: node-reader-binding
subjects:
- kind: User
  name: bob
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: ClusterRole
  name: node-reader
  apiGroup: rbac.authorization.k8s.io

练习:使用RBAC进行授权

Kubernetes 的授权对象主要有两类:

  • 用户(User/Group):通常代表人类用户。

  • 服务账号(ServiceAccount):通常代表 Pod 内运行的应用程序。

两者最终都是通过 RBAC 规则(Role/ClusterRole + RoleBinding/ClusterRoleBinding) 来实现权限分配。


面向用户授权

授权过程
  1. 创建证书和用户配置

    • 用户要访问集群,需要身份凭证。常见方式:

      • 使用 kubeadm/cfssl 等生成 X.509 客户端证书

      • 或者直接创建一个 kubeconfig 配置文件,里面包含证书和集群 API 地址。

    示例生成证书:

    # 生成私钥
    openssl genrsa -out user.key 2048
    
    # 生成证书签名请求
    openssl req -new -key user.key -out user.csr -subj "/CN=myuser/O=mygroup"
    
    # 使用集群 CA 签发
    openssl x509 -req -in user.csr -CA ca.crt -CAkey ca.key -CAcreateserial \
    -out user.crt -days 365
    

    其中 CN=myuser 是用户名,O=mygroup 是用户组。

  2. 生成 kubeconfig 文件

    • 将证书、CA、公私钥等信息写入用户专属的 kubeconfig:
    kubectl config set-credentials myuser \
      --client-certificate=user.crt \
      --client-key=user.key
    kubectl config set-context myuser-context \
      --cluster=kubernetes \
      --namespace=default \
      --user=myuser
    kubectl config use-context myuser-context
    
  3. 定义角色(Role/ClusterRole)

    • Role:命名空间级权限

    • ClusterRole:集群级权限

    例:只允许 myuserdefault 命名空间获取和列出 Pod:

    apiVersion: rbac.authorization.k8s.io/v1
    kind: Role
    metadata:
      namespace: default
      name: pod-reader
    rules:
    - apiGroups: [""]
      resources: ["pods"]
      verbs: ["get", "list"]
    
  4. 绑定角色(RoleBinding/ClusterRoleBinding)

    • 将角色和用户绑定:
    apiVersion: rbac.authorization.k8s.io/v1
    kind: RoleBinding
    metadata:
      name: read-pods-binding
      namespace: default
    subjects:
    - kind: User
      name: myuser   # 必须和证书 CN 对应
      apiGroup: rbac.authorization.k8s.io
    roleRef:
      kind: Role
      name: pod-reader
      apiGroup: rbac.authorization.k8s.io
    
  5. 测试用户权限

    kubectl --context=myuser-context get pods   #  成功
    kubectl --context=myuser-context delete pods testpod   #  无权限
    

内置集群角色

K8s 内置了许多 ClusterRole,常用的有:

  • cluster-admin:对整个集群有最高权限

  • admin:对某个 namespace 拥有管理权限

  • edit:对某个 namespace 拥有读写权限(但不能管理 RBAC)

  • view:对某个 namespace 只有只读权限

这些可以直接用来绑定给用户/组。虽然这些是集群角色,但使用时也可以进行命名空间限制.


面向应用程序授权

应用程序(Pod)通常通过 ServiceAccount (SA) 与 RBAC 配合来进行授权。

授权过程
  1. 创建 ServiceAccount

    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: app-sa
      namespace: default
    
  2. 创建角色(Role/ClusterRole)
    例如:允许应用读取 ConfigMap:

    apiVersion: rbac.authorization.k8s.io/v1
    kind: Role
    metadata:
      namespace: default
      name: configmap-reader
    rules:
    - apiGroups: [""]
      resources: ["configmaps"]
      verbs: ["get", "list"]
    
  3. 绑定角色到 ServiceAccount

    apiVersion: rbac.authorization.k8s.io/v1
    kind: RoleBinding
    metadata:
      name: read-configmaps-binding
      namespace: default
    subjects:
    - kind: ServiceAccount
      name: app-sa
      namespace: default
    roleRef:
      kind: Role
      name: configmap-reader
      apiGroup: rbac.authorization.k8s.io
    
  4. 在 Pod 中使用该 ServiceAccount

    apiVersion: v1
    kind: Pod
    metadata:
      name: app-pod
      namespace: default
    spec:
      serviceAccountName: app-sa
      containers:
      - name: app
        image: nginx
    

    Pod 内的容器会自动挂载该 SA 的 Token 文件到 /var/run/secrets/kubernetes.io/serviceaccount/,应用程序就能以这个身份访问 API。

总结:

  • 用户授权:基于证书 + kubeconfig + Role/ClusterRole + RoleBinding/ClusterRoleBinding

  • 应用程序授权:基于 ServiceAccount + RBAC

隐藏模块:

某教材的味一下就来了...



网站公告

今日签到

点亮在社区的每一天
去签到