K8s访问控制(一)
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
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: defaultname: pod-reader
rules:
- apiGroups: [""] # 空字符串表示 core groupresources: ["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: devname: 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-bindingnamespace: dev
subjects:
- kind: User # 可以是 User, Group, ServiceAccountname: alice # 用户名apiGroup: rbac.authorization.k8s.io
roleRef:kind: Rolename: dev-viewerapiGroup: rbac.authorization.k8s.io
例子 2:组权限
让 dev-team
组的所有人都能管理 deployments
。
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:namespace: devname: 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: devname: deployment-admin-binding
subjects:
- kind: Group # 对整个组赋权name: dev-teamapiGroup: rbac.authorization.k8s.io
roleRef:kind: Rolename: deployment-adminapiGroup: 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: Username: bobapiGroup: rbac.authorization.k8s.io
roleRef:kind: ClusterRolename: node-readerapiGroup: 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: defaultname: pod-reader rules: - apiGroups: [""]resources: ["pods"]verbs: ["get", "list"]
绑定角色(RoleBinding/ClusterRoleBinding)
- 将角色和用户绑定:
apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata:name: read-pods-bindingnamespace: default subjects: - kind: Username: myuser # 必须和证书 CN 对应apiGroup: rbac.authorization.k8s.io roleRef:kind: Rolename: pod-readerapiGroup: rbac.authorization.k8s.io
测试用户权限
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-sanamespace: default
创建角色(Role/ClusterRole)
例如:允许应用读取 ConfigMap:apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata:namespace: defaultname: configmap-reader rules: - apiGroups: [""]resources: ["configmaps"]verbs: ["get", "list"]
绑定角色到 ServiceAccount
apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata:name: read-configmaps-bindingnamespace: default subjects: - kind: ServiceAccountname: app-sanamespace: default roleRef:kind: Rolename: configmap-readerapiGroup: rbac.authorization.k8s.io
在 Pod 中使用该 ServiceAccount
apiVersion: v1 kind: Pod metadata:name: app-podnamespace: default spec:serviceAccountName: app-sacontainers:- name: appimage: nginx
Pod 内的容器会自动挂载该 SA 的 Token 文件到
/var/run/secrets/kubernetes.io/serviceaccount/
,应用程序就能以这个身份访问 API。
总结:
用户授权:基于证书 + kubeconfig + Role/ClusterRole + RoleBinding/ClusterRoleBinding
应用程序授权:基于 ServiceAccount + RBAC
隐藏模块:
某教材的味一下就来了...