K8s访问控制
描述 K8s API 访问控制
API Server 认证流程
当一个请求到达 API Server 时,会依次经过以下几个步骤:
-
认证(Authentication)
-
确认你是谁。
-
常见方式:
-
证书认证(TLS 双向认证,kubelet、kubectl 默认用证书)
-
Token 认证(ServiceAccount、OIDC 等)
-
静态用户名密码文件(一般只用于测试)
-
🔑 输出结果:用户身份(如
User: alice
、ServiceAccount: default:nginx-sa
)。 -
-
鉴权(Authorization)
-
确认你是否有权限做这件事。
-
常见方式:
-
RBAC(基于角色的访问控制) ✅ 最常用
-
ABAC(基于属性的访问控制)
-
Node(Kubelet 默认使用的权限控制器)
-
🔑 输出结果:允许/拒绝。
-
-
准入控制(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
-
/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 相关:Role、ClusterRole、RoleBinding、ClusterRoleBinding。
-
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) | 操作的对象 | pods 、deployments 、services 、configmaps |
命名空间 (namespace) | 作用范围 | 只能访问 dev 命名空间的 Pod |
API 组 (apiGroups) | 资源所属的 API | 核心资源 ("" ),apps 组 (apps/v1 ),RBAC 组 (rbac.authorization.k8s.io ) |
操作方法 (verbs) | 允许的操作 | get 、list 、watch 、create 、update 、delete |
这样组合后,你就能非常细粒度地定义权限,比如:
👉 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
好的,我来帮你系统梳理一下 K8s 面向用户授权 和 面向应用程序授权 的过程。
练习:使用RBAC进行授权
Kubernetes 的授权对象主要有两类:
-
用户(User/Group):通常代表人类用户。
-
服务账号(ServiceAccount):通常代表 Pod 内运行的应用程序。
两者最终都是通过 RBAC 规则(Role/ClusterRole + RoleBinding/ClusterRoleBinding) 来实现权限分配。
面向用户授权
授权过程
-
创建证书和用户配置
-
用户要访问集群,需要身份凭证。常见方式:
-
使用
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 是用户组。
-
-
生成 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
-
-
定义角色(Role/ClusterRole)
-
Role:命名空间级权限
-
ClusterRole:集群级权限
例:只允许
myuser
在default
命名空间获取和列出 Pod:apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: namespace: default name: pod-reader rules: - apiGroups: [""] resources: ["pods"] verbs: ["get", "list"]
-
-
绑定角色(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
- kind: User
-
-
测试用户权限
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 配合来进行授权。
授权过程
-
创建 ServiceAccount
apiVersion: v1 kind: ServiceAccount metadata: name: app-sa namespace: default
-
创建角色(Role/ClusterRole)
例如:允许应用读取 ConfigMap:
apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: namespace: default name: configmap-reader rules: - apiGroups: [""] resources: ["configmaps"] verbs: ["get", "list"]
-
绑定角色到 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
-
在 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
隐藏模块:
某教材的味一下就来了...