跳到主要内容

第13章 RBAC基于角色访问控制

1.RBAC介绍

官方文档:

https://kubernetes.io/zh/docs/reference/access-authn-authz/rbac/

RBAC 基于角色的访问控制:

对集群中的资源和非资源权限均有完整的覆盖
RBAC的权限配置通过几个API对象即可完成,同其他API对象一样,可以用kubectl或API进行操作
可以在运行时进行调整,无需重新启动API Server

2.API 资源对象

官方文档:

https://kubernetes.io/zh/docs/reference/using-api/#api-versioning

2.1 API概述

REST API 是 Kubernetes 的基本结构。
所有操作和组件之间的通信及外部用户命令都是调用 API 服务器处理的 REST API。
因此,Kubernetes 平台视一切皆为 API 对象, 且它们在 API 中有相应的定义。

2.2 API版本控制

JSON 和 Protobuf 序列化模式遵循相同的模式更改原则。 以下描述涵盖了这两种格式。

API 版本控制和软件版本控制是间接相关的。 API 和发布版本控制提案 描述了 API 版本控制和软件版本控制间的关系。

不同的 API 版本代表着不同的稳定性和支持级别。 你可以在 API 变更文档 中查看到更多的不同级别的判定标准。

版本级别说明:

  • Alpha:
    • 版本名称包含 alpha(例如,v1alpha1)。
    • 软件可能会有 Bug。启用某个特性可能会暴露出 Bug。 某些特性可能默认禁用。
    • 对某个特性的支持可能会随时被删除,恕不另行通知。
    • API 可能在以后的软件版本中以不兼容的方式更改,恕不另行通知。
    • 由于缺陷风险增加和缺乏长期支持,建议该软件仅用于短期测试集群。
  • Beta:
    • 版本名称包含 beta (例如, v2beta3)。
    • 软件被很好的测试过。启用某个特性被认为是安全的。 特性默认开启。
    • 尽管一些特性会发生细节上的变化,但它们将会被长期支持。
    • 在随后的 Beta 版或稳定版中,对象的模式和(或)语义可能以不兼容的方式改变。 当这种情况发生时,将提供迁移说明。 模式更改可能需要删除、编辑和重建 API 对象。 编辑过程可能并不简单。 对于依赖此功能的应用程序,可能需要停机迁移。
    • 该版本的软件不建议生产使用。 后续发布版本可能会有不兼容的变动。 如果你有多个集群可以独立升级,可以放宽这一限制。
  • Stable:
    • 版本名称如 vX,其中 X 为整数。
    • 特性的稳定版本会出现在后续很多版本的发布软件中。

2.3 API 组

API 组 能够简化对 Kubernetes API 的扩展。 API 组信息出现在REST 路径中,也出现在序列化对象的 apiVersion 字段中。

以下是 Kubernetes 中的几个组:

  • 核心组的 REST 路径为 /api/v1。 核心组并不作为 apiVersion 字段的一部分,例如, apiVersion: v1
  • 指定的组位于 REST 路径 /apis/$GROUP_NAME/$VERSION, 并且使用 apiVersion: $GROUP_NAME/$VERSION (例如, apiVersion: batch/v1)。 你可以在 Kubernetes API 参考文档 中查看全部的 API 组。

所有API组官方说明地址:

https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.22/#-strong-api-groups-strong-

2.4 查看API组信息

我们可以使用以下kubectl命令查看API组的信息:

查看所有的API组:

kubectl get --raw /

查看指定组的信息:

#默认返回的格式是没有json格式化的
kubectl get --raw /api/v1

#可以安装jq命令来格式化返回的json数据
kubectl get --raw /api/v1|jq|grep '"name"'

#查看app组信息
kubectl get --raw /apis/apps/v1|jq|grep '"name"'

3.RBAC的API资源对象

k8s里所有的资源对象都是可以被操作的,类似操作数据库一样,我们可以对资源对象执行CRUD,也就是增删改查操作。

比如以下这些资源:

Pods
Secrets
Deployment
Replicasets
Statefulsets
Namespaces

对于上面的资源可以执行以下操作:

create
watch
list
delete
get
edit

4.RBAC的基本概念

目前我们已经知道可以对资源进行操作了,但是我们还需要再了解几个概念才能在k8s创建RBAC资源。

Rule 规则

角色就是一组权限的集合

Role和ClusterRole 角色和集群角色

Role

Role定义的规则只适用单个命名空间,也就是和namespace关联的。
在创建Role时,必须指定该Role所属的名字空间。

ClusterRole

与之相对,ClusterRole 则是一个集群作用域的资源。
这两种资源的名字不同(Role 和 ClusterRole)是因为 Kubernetes 对象要么是名字空间作用域的,要么是集群作用域的,不可两者兼具。

ClusterRole 有若干用法。你可以用它来:
1.定义对某个命名空间域对象的访问权限,并将在各个命名空间内完成授权;
2.为命名空间作用域的对象设置访问权限,并跨所有命名空间执行授权;
3.为集群作用域的资源定义访问权限。

总结:

如果你希望在名字空间内定义角色,应该使用 Role;
如果你希望定义集群范围的角色,应该使用 ClusterRole。

RoleBinding和ClusterRoleBinding 角色绑定和集群角色绑定

Subject 主题

k8s里定义了3中主题资源,分别是user,group和Service Account

User Account和Service Account

User Account:
用户账号,用户是外部独立服务管理的,不属于k8s内部的API

ServiceAccount:
也是一种账号,但他并不是给k8s集群的用户用的,而是给运行Pod里的进程用的,他为Pod里的进程提供了必要的身份证明。

https://kubernetes.io/zh-cn/docs/reference/access-authn-authz/service-accounts-admin/

1725849383267-2efba75b-a91a-4250-8fd6-58f72d3c1adf.png

RoleBinding和ClusterRoleBinding

角色绑定(Role Binding)是将角色中定义的权限赋予一个或者一组用户。
它包含若干 主体(用户、组或服务账户)的列表和对这些主体所获得的角色的引用。

RoleBinding 在指定的名字空间中执行授权,
ClusterRoleBinding 在集群范围执行授权。

RBAC关系图

1725447127633-aeb9cfd9-47ee-4ad3-9dcd-c112f2365fbb.png

5.RBAC 举例

5.1 创建 Role

创建一个位于default命名空间的Role,拥有对pods的访问权限

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: default
name: pod-reader
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "watch", "list"]

参数解释:

rules:
- apiGroups: [""] #""表示核心 API组
resources: ["pods"] #需要操作的资源对象列表
verbs: ["get", "watch", "list"] #允许对资源对象操作的方法列表

5.2 创建 RoleBinding

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: read-pods
namespace: default
subjects:
- kind: User
name: luffy
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: pod-reader
apiGroup: rbac.authorization.k8s.io

参数解释:

subjects:
- kind: User
name: luffy
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: pod-reader
apiGroup: rbac.authorization.k8s.io

5.3 创建 ClusterRole

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
# "namespace" 被忽略,因为 ClusterRoles 不受名字空间限制
name: secret-reader
rules:
- apiGroups: [""]
# 在 HTTP 层面,用来访问 Secret 对象的资源的名称为 "secrets"
resources: ["secrets"]
verbs: ["get", "watch", "list"]

5.4 创建 ClusterRoleBinding

apiVersion: rbac.authorization.k8s.io/v1

# 此集群角色绑定允许 “manager” 组中的任何人访问任何名字空间中的 secrets

kind: ClusterRoleBinding
metadata:
name: read-secrets-global
subjects:
- kind: Group
name: manager # 'name' 是区分大小写的
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: secret-reader
apiGroup: rbac.authorization.k8s.io

6.创建只能访问某个namespace的user

#第1步:创建key
openssl genrsa -out luffy.key 2048

#第2步:使用key生成证书
openssl req -new -key luffy.key -out luffy.csr -subj "/CN=luffy/O=luffy"

#第3步:使用k8s自己的ca.crt和ca.key签发我们生成luffy.crt有效期300天
openssl x509 -req -in luffy.csr -CA /etc/kubernetes/pki/ca.crt -CAkey /etc/kubernetes/pki/ca.key -CAcreateserial -out luffy.crt -days 300

#第4步:生成集群配置
kubectl config set-cluster kubernetes --server=https://10.0.0.10:6443 --certificate-authority=/etc/kubernetes/pki/ca.crt --embed-certs=true --kubeconfig=luffy.config

#第5步:生成运行环境
kubectl config set-context luffy-context --cluster=kubernetes --user=luffy --namespace=default --kubeconfig=luffy.config

#第5步:设置配置文件里的运行环境
kubectl config set current-context luffy-context --kubeconfig luffy.config

#第6步:指定用户的证书
kubectl config set-credentials luffy --client-certificate=luffy.crt --client-key=luffy.key --embed-certs=true --kubeconfig=luffy.config

#第7步:创建角色
cat > luffy-role.yaml << 'EOF'
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: luffy-role
namespace: default
rules:
- apiGroups: ["", "apps"]
resources: ["deployments", "replicasets", "pods"]
verbs: ["*"]
EOF
kubectl apply -f luffy-role.yaml

#第8步:创建角色绑定
cat > luffy-rolebinding.yml << 'EOF'
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: luffy-rolebinding
namespace: default
subjects:
- kind: User
name: luffy
apiGroup: ""
roleRef:
kind: Role
name: luffy-role
apiGroup: rbac.authorization.k8s.io
EOF
kubectl apply -f luffy-rolebinding.yml

#第9步:将config配置发送到node节点
scp luffy.config node1:/root/.kube/config

#第10步:node节点测试访问
kubectl get pods

7.创建访问某个 namespace 的 ServiceAccount

#1.创建ServiceAccount
apiVersion: v1
kind: ServiceAccount
metadata:
name: pod-sa
namespace: default

#2.编写角色
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: default
name: pod-role
rules: #权限规则
- apiGroups: [""] #核心组API,如果为空""就表示是核心组API
resources: ["pods"] #核心组API里具体的资源对象
verbs: ["get", "watch", "list"] #可操作的权限

- apiGroups: [""]
resources: ["secrets"]
verbs: ["get", "watch", "list", "delete"]

#3.编写角色绑定
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: pod-rb
namespace: default
subjects: #要绑定的账号
- kind: ServiceAccount #账号类型
name: pod-sa #账号名称
namespace: default #命名空间
roleRef:
apiGroup: rbac.authorization.k8s.io #声明一下RABC资源组
kind: Role #角色类型
name: pod-role #角色名称

#4.应用并查看
kubectl get sa
kubectl get role
kubectl get rolebindings.rbac.authorization.k8s.io
kubectl get secrets

#5.查看账户token
kubectl describe secrets pod-sa-token-rk9lc |grep token

更新: 2024-09-09 10:36:35