k8s:RBAC

RBAC

RBAC - 基于角色的访问控制。
RBAC使用rbac.authorization.k8s.io API Group 来实现授权决策,允许管理员通过 Kubernetes API 动态配置策略,要启用RBAC,需要在apiserver 中添加参数–authorization-mode=RBAC ,如果使用的kubeadm安装的集群,1.6 版本以上的都默认开启了RBAC,可以通过查看 Master节点上 apiserver 的静态Pod 定义文件:

cat /etc/kubernetes/manifests/kube-apiserver.yaml
...
 1. --authorization-mode=Node,RBAC
...
如果是二进制安装则需重启

RBAC API 对象

Kubernetes 有一个很基本的特性就是它的所有资源对象都是模型化的 API
对象
,允许执行 CRUD(Create、Read、Update、Delete)操作(增、删、
改、查),比如下面的这些资源:
2. Pods
3. ConfigMaps
4. Deployments
5. Nodes
6. Secrets
7. Namespaces

上面这些资源对象的可能存在的操作有:

  1. create
  2. get
  3. delete
  4. list
  5. update
  6. edit
  7. watch
  8. exec

在更上层,这些资源和 API Group 进行关联,比如Pods属于 Core APIGroup,而Deployements 属于 apps API Group,要在Kubernetes 中进行RBAC的管理,除了上面的这些资源和操作以外,还需要另外的一些对象:

  1. Rule:规则,规则是一组属于不同 API Group 资源上的一组操作的集合
  2. Role 和 ClusterRole:角色和集群角色,这两个对象都包含上面的Rules 元素,二者的区别在于,在 Role 中,定义的规则只适用于单个命名空间,也就是和 namespace 关联的,而 ClusterRole 是集群范围内的,因此定义的规则不受命名空间的约束。另外 Role 和 ClusterRole在Kubernetes 中都被定义为集群内部的 API 资源,和我们前面学习过的 Pod、ConfigMap 这些类似,都是我们集群的资源对象,所以同样的可以使用我们前面的kubectl相关的命令来进行操作
  3. Subject:主题,对应在集群中尝试操作的对象,集群中定义了3种类型的主题资源:
1.User Account:用户,这是有外部独立服务进行管理的,管理员进行私钥的分配,用户可以使用 KeyStone或者 Goolge 帐号,甚至一个用户名和密码的文件列表也可以。对于用户的管理集群内部没有一个关联的资源对象,所以用户不能通过集群内部的 API 来进行管理
2.Group:组,这是用来关联多个账户的,集群中有一些默认创建的组,比如cluster-admin
3.Service Account:服务帐号,通过Kubernetes API 来管理的一些用户帐号,和 namespace 进行关联的,适用于集群内部运行的应用程序,需要通过 API 来完成权限认证,所以在集群内部进行权限操作,我们都需要使用到 ServiceAccount,
  1. RoleBinding 和 ClusterRoleBinding:角色绑定和集群角色绑定,简单 来说就是把声明的 Subject和我们的 Role 进行绑定的过程(给某个用户 绑定上操作的权限),二者的区别也是作用范围的区别:RoleBinding 只会影响到当前 namespace 下面的资源操作权限,而 ClusterRoleBinding 会影响到所有的 namespace。

创建一个只能访问某个 namespace 的用户

我们来创建一个 User Account,只能访问 kube-system 这个命名空间:

  1. username: abc
  2. group: aaa

第1步:创建用户凭证

Kubernetes 没有 User Account 的 API 对象,不过要创建一个用户帐号的话也是挺简单的,利用管理员分配给你的一个私钥就可以创建了,这个我们可以参考官方文档中的方法,这里我们来使用OpenSSL证书来创建一个 User,当然我们也可以使用更简单的cfssl工具来创建:

给用户 abc 创建一个私钥,命名成:abc.key:

openssl genrsa -out haimaxy.key 2048

使用我们刚刚创建的私钥创建一个证书签名请求文件:haimaxy.csr,要注意需要确保在-subj参数中指定用户名和组(CN表示用户名,O表示组):

openssl req -new -key abc.key -out abc.csr -subj "/CN=abc/O=aaa"

然后找到我们的Kubernetes 集群的CA ,我们使用的是kubeadm安装的集群,CA 相关证书位于 /etc/kubernetes/pki/ 目录下面,如果你是二进制方式搭建的,你应该在最开始搭建集群的时候就已经指定好了CA 的目录,我们会利用该目录下面的ca.crt 和 ca.key 两个文件来批准上面的证书请求
生成最终的证书文件,我们这里设置证书的有效期为500天:

openssl x509 -req -in abc.csr -CA /etc/kubernetes/pki/ca.crt -CAkey /etc/kubernetes/pki/ca.key -CAcreateserial -out abc.crt -days 500

现在查看我们当前文件夹下面是否生成了一个证书文件:

[root@master cert]# pwd
/root/cert
[root@master cert]# ls
abc.crt  abc.csr  abc.key

现在我们可以使用刚刚创建的证书文件和私钥文件在集群中创建新的凭证:

kubectl config set-credentials abc --client-certificate=abc.crt --client-key=abc.key

然后为这个用户设置新的上下文 Context:

kubectl config set-context abc-context --cluster=kubernetes --namespace=kube-system --user=abc

到这里,我们的用户haimaxy就已经创建成功了,现在我们使用当前的这个配置文件来操作kubectl命令的时候,应该会出现错误,因为我们还没有为该用户定义任何操作的权限呢:

[root@master cert]# kubectl  get pods --context=abc-context
Error from server (Forbidden): pods is forbidden: User "abc" cannot list resource "pods" in API group "" in the namespace "kube-system"

第2步:创建角色

用户创建完成后,接下来就需要给该用户添加操作权限,我们来定义一个YAML文件,创建一个允许用户操作 Deployment、Pod、ReplicaSets 的角色,如下定义:(abc-role.yaml)

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: abc-role
  namespace: kube-system
rules:
- apiGroups: ["", "extensions", "apps"]
  resources: ["deployments", "replicasets", "pods"]
  verbs: ["get", "list", "watch", "create", "update","patch", "delete"] 
  # 也可以使用['*']

其中Pod 属于 core 这个 API Group,在YAML中用空字符就可以,而Deployment 属于 apps 这个 API Group,ReplicaSets属于属于哪个 API Group(我怎么知道的?点这里查文档),所,其中verbs就是我们上面提到的可以对这些资源对象执行的操作,我们这里需要所有的操作方法,所以我们也可以使用[’*’]来代替。

第3步:创建角色权限绑定

Role 创建完成了,但是很明显现在我们这个 Role 和我们的用户 abc还没有任何关系,需要创建一个RoleBinding对象,在 kube-system 这个命名空间下面将上面的 haimaxy-role 角色和用户 haimaxy 进行绑定:(abc-rolebinding.yaml)

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: abc-rolebinding
  namespace: kube-system
subjects:
- kind: User
  name: abc
  apiGroup: ""
roleRef:
  kind: Role
  name: abc-role
  apiGroup: ""

上面的 YAML文件中我们看到了subjects关键字,这里就是我们上面提到的用来尝试操作集群的对象,这里对应上面的 User 帐号 abc,使用kubectl创建上面的资源对象:

kubectl create -f abc-role.yaml

第4步. 测试

现在我们应该可以上面的abc-context上下文来操作集群了

kubectl get pods --context=abc-context

可以看到我们使用kubectl的使用并没有指定 namespace 了,这是因为我们已经为该用户分配了权限了,如果我们在后面加上一个-n default 试看看呢?

kubectl --context=abc-context get pods --namespace=default
Error from server (Forbidden): pods is forbidden: User "abc" cannot list resource "pods" in API group "" in the namespace "default"

因为该用户并没有 default 这个命名空间的操作权限

创建一个只能访问某个 namespace 的ServiceAccount

上面我们创建了一个只能访问某个命名空间下面资源的普通用户,我们前面也提到过 subjects 下面还有一直类型的主题资源:ServiceAccount,现在我们来创建一个集群内部的用户只能操作 kube-system 这个命名空间下面的 pods 和 deployments,首先来创建一个 ServiceAccount 对象:

apiVersion: v1
kind: ServiceAccount
metadata:
  name: sa-role
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: sa-role
  namespace: kube-system
rules:
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get","watch","list"]
- apiGroups: ["apps"]
  resources: ["deployment"]
  verbs: ["*"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: sa-rolebinding
  namespace: kube-system
subjects:
- kind: ServiceAccount
  name: sa-role
  namespace: kube-system
roleRef:
  name: sa-role
  kind: Role
  apiGroup: "rbac.authorization.k8s.io"

[root@master kubeadm.1.18.img]# kubectl  apply -f recommended.yaml
[root@master kubeadm.1.18.img]# kubectl get service -n kubernetes-dashboard 
NAME                        TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)         AGE
dashboard-metrics-scraper   ClusterIP   10.100.204.141   <none>        8000/TCP        7d9h
kubernetes-dashboard        NodePort    10.99.124.240    <none>        443:30006/TCP   7d9h

在这里插入图片描述

[root@master ~]# kubectl  get secrets sa-role-token-gz7rf -o jsonpath={.data.token} -n kube-system | base64 -d
eyJhbGciOiJSUzI1NiIsImtpZCI6Im56QTB2cmZFOUtrQTNHdG9RNjJodkNELTZfQl9nc3g1V0FIQ2paS0daS28ifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlLXN5c3RlbSIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJzYS1yb2xlLXRva2VuLWd6N3JmIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQubmFtZSI6InNhLXJvbGUiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC51aWQiOiJiM2Y5ZmQ1Yi04MGJlLTQ4NDctYjc5OC01ZjZiODgxYmExZmQiLCJzdWIiOiJzeXN0ZW06c2VydmljZWFjY291bnQ6a3ViZS1zeXN0ZW06c2Etcm9sZSJ9.BdKi4Uj19CASsYcABN0kI4cSVjzqTDfy9aIH7ddNdESfSYzB9oYufAN6sFHl7j3AlRIuTPjhfJTW-BBtL5xG8i02UqYyF_3Tssai8QtSbiZsaOD_OaiMAsNMbi72qaxYKwu8bAm_O2JAQJXghHPTqKC5Jczf2-YRWkt1rDu8e61mxjuHknB2ogmar2-IM-MGVXvKKAzuZ8lb1WODGCodQNniUpTZvRg9N-Y7kBI3DhWsYgtenJYNo31ad-kDleRZ4PTB7445NySyZFfXBVfnYPdyVt7pE-d9PCOzONv2fyqDOsbNJ-gLI7QSSlyKeZLoRfJ1Ytx5Y2mpNfrYFaYDbg

在这里插入图片描述
相应的权限只能访问相应的状态信息

创建一个可以访问所有 namespace 的ServiceAccount

如果我们现在创建一个新的 ServiceAccount,需要他操作的权限作用于所有的 namespace,这个时候我们就需要使用到 ClusterRole 和ClusterRoleBinding 这两种资源对象了。同样,首先新建一个ServiceAcount 对象:(cluster-sa.yaml)

apiVersion: v1
kind: ServiceAccount
metadata:
  name: cluster-role1
  namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
  name: clusterbinding
subjects:
- kind: ServiceAccount
  name: cluster-role1
  namespace: kube-system
roleRef:
  name: cluster-admin
  kind: ClusterRole
  apiGroup: rbac.authorization.k8s.io

在这里插入图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值