全栈工程师开发手册 (作者:栾鹏)
架构系列文章


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
...- --authorization-mode=Node,RBAC
...

如果是二进制的方式搭建的集群,添加这个参数过后,记得要重启 apiserver 服务。

RBAC API 对象

Kubernetes有一个很基本的特性就是它的所有资源对象都是模型化的 API 对象,允许执行 CRUD(Create、Read、Update、Delete)操作(也就是我们常说的增、删、改、查操作),比如下面的这下资源:

  • Pods
  • ConfigMaps
  • Deployments
  • Nodes
  • Secrets
  • Namespaces

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

  • create
  • get
  • delete
  • list
  • update
  • edit
  • watch
  • exec

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

  • Rule:规则,规则是一组属于不同 API Group 资源上的一组操作的集合

  • Role 和 ClusterRole:角色和集群角色,这两个对象都包含上面的 Rules 元素,二者的区别在于,在 Role 中,定义的规则只适用于单个命名空间,也就是和 namespace 关联的,而 ClusterRole 是集群范围内的,因此定义的规则不受命名空间的约束。另外 Role 和 ClusterRole 在Kubernetes中都被定义为集群内部的 API 资源,和我们前面学习过的 Pod、ConfigMap 这些类似,都是我们集群的资源对象,所以同样的可以使用我们前面的kubectl相关的命令来进行操作

  • Subject:主题,对应在集群中尝试操作的对象,集群中定义了3种类型的主题资源:

  • User Account:用户,这是有外部独立服务进行管理的,管理员进行私钥的分配,用户可以使用 KeyStone或者 Goolge 帐号,甚至一个用户名和密码的文件列表也可以。对于用户的管理集群内部没有一个关联的资源对象,所以用户不能通过集群内部的 API 来进行管理

  • Group:组,这是用来关联多个账户的,集群中有一些默认创建的组,比如cluster-admin

  • Service Account:服务帐号,通过Kubernetes API 来管理的一些用户帐号,和 namespace 进行关联的,适用于集群内部运行的应用程序,需要通过 API 来完成权限认证,所以在集群内部进行权限操作,我们都需要使用到 ServiceAccount,这也是我们这节课的重点

  • RoleBinding 和 ClusterRoleBinding:角色绑定和集群角色绑定,简单来说就是把声明的 Subject 和我们的 Role 进行绑定的过程(给某个用户绑定上操作的权限),二者的区别也是作用范围的区别:RoleBinding 只会影响到当前 namespace 下面的资源操作权限,而 ClusterRoleBinding 会影响到所有的 namespace。

接下来我们来通过几个示例来演示下RBAC的配置方法。

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

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

  • username: haimaxy
  • group: youdianzhishi

第1步:创建用户凭证

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

  • 给用户 haimaxy 创建一个私钥,命名成:haimaxy.key:
$ openssl genrsa -out haimaxy.key 2048
  • 使用我们刚刚创建的私钥创建一个证书签名请求文件:haimaxy.csr,要注意需要确保在-subj参数中指定用户名和组(CN表示用户名,O表示组):
$ openssl req -new -key haimaxy.key -out haimaxy.csr -subj "/CN=haimaxy/O=youdianzhis"
  • 然后找到我们的Kubernetes集群的CA,我们使用的是kubeadm安装的集群,CA相关证书位于/etc/kubernetes/pki/目录下面,如果你是二进制方式搭建的,你应该在最开始搭建集群的时候就已经指定好了CA的目录,我们会利用该目录下面的ca.crtca.key两个文件来批准上面的证书请求

  • 生成最终的证书文件,我们这里设置证书的有效期为500天:

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

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

$ ls
haimaxy.csr haimaxy.key haimaxy.crt
  • 现在我们可以使用刚刚创建的证书文件和私钥文件在集群中创建新的凭证和上下文(Context):
$ kubectl config set-credentials haimaxy --client-certificate=haimaxy.crt  --client-key=haimaxy.key

我们可以看到一个用户haimaxy创建了,然后为这个用户设置新的 Context:

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

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

$ kubectl get pods --context=haimaxy-context
Error from server (Forbidden): pods is forbidden: User "haimaxy" cannot list pods in the namespace "default"

第2步:创建角色

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

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:name: haimaxy-rolenamespace: 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属于extensions这个 API Group(我怎么知道的?点这里查文档),所以 rules 下面的 apiGroups 就综合了这几个资源的 API Group:["", “extensions”, “apps”],其中verbs就是我们上面提到的可以对这些资源对象执行的操作,我们这里需要所有的操作方法,所以我们也可以使用[’*’]来代替。

然后创建这个Role

$ kubectl create -f haimaxy-role.yaml

注意这里我们没有使用上面的haimaxy-context这个上下文了,因为木有权限啦

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

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

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:name: haimaxy-rolebindingnamespace: kube-system
subjects:
- kind: Username: haimaxyapiGroup: ""
roleRef:kind: Rolename: haimaxy-roleapiGroup: ""

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

$ kubectl create -f haimaxy-rolebinding.yaml

第4步. 测试

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

$ kubectl get pods --context=haimaxy-context
....

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

$ kubectl --context=haimaxy-context get pods --namespace=default
Error from server (Forbidden): pods is forbidden: User "haimaxy" cannot list pods in the namespace "default"

是符合我们预期的吧?因为该用户并没有 default 这个命名空间的操作权限

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

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

$ kubectl create sa haimaxy-sa -n kube-system

当然我们也可以定义成YAML文件的形式来创建。

然后新建一个 Role 对象:(haimaxy-sa-role.yaml)

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:name: haimaxy-sa-rolenamespace: kube-system
rules:
- apiGroups: [""]resources: ["pods"]verbs: ["get", "watch", "list"]
- apiGroups: ["apps"]resources: ["deployments"]verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]

可以看到我们这里定义的角色没有创建、删除、更新 Pod 的权限,待会我们可以重点测试一下,创建该 Role 对象:

$ kubectl create -f haimaxy-sa-role.yaml

然后创建一个 RoleBinding 对象,将上面的 haimaxy-sa 和角色 haimaxy-sa-role 进行绑定:(haimaxy-sa-rolebinding.yaml)

kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:name: haimaxy-sa-rolebindingnamespace: kube-system
subjects:
- kind: ServiceAccountname: haimaxy-sanamespace: kube-system
roleRef:kind: Rolename: haimaxy-sa-roleapiGroup: rbac.authorization.k8s.io

添加这个资源对象:

$ kubectl create -f haimaxy-sa-rolebinding.yaml

然后我们怎么去验证这个 ServiceAccount 呢?我们前面的课程中是不是提到过一个 ServiceAccount 会生成一个 Secret 对象和它进行映射,这个 Secret 里面包含一个 token,我们可以利用这个 token 去登录 Dashboard,然后我们就可以在 Dashboard 中来验证我们的功能是否符合预期了:

$ kubectl get secret -n kube-system |grep haimay-sa
haimay-sa-token-nxgqx                  kubernetes.io/service-account-token   3         47m
$ kubectl get secret haimay-sa-token-nxgqx -o jsonpath={.data.token} -n kube-system |base64 -d
# 会生成一串很长的base64后的字符串

使用这里的 token 去 Dashboard 页面进行登录:

Dashboard

我们可以看到上面的提示信息,这是因为我们登录进来后默认跳转到 default 命名空间,我们切换到 kube-system 命名空间下面就可以了:

Dashboard

我们可以看到可以访问pod列表了,但是也会有一些其他额外的提示:events is forbidden: User “system:serviceaccount:kube-system:haimaxy-sa” cannot list events in the namespace “kube-system”,这是因为当前登录用只被授权了访问 pod 和 deployment 的权限,同样的,访问下deployment看看可以了吗?

同样的,你可以根据自己的需求来对访问用户的权限进行限制,可以自己通过 Role 定义更加细粒度的权限,也可以使用系统内置的一些权限……

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

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

apiVersion: v1
kind: ServiceAccount
metadata:name: haimaxy-sa2namespace: kube-system

创建:

$ kubectl create -f haimaxy-sa2.yaml

然后创建一个 ClusterRoleBinding 对象(haimaxy-clusterolebinding.yaml):

kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:name: haimaxy-sa2-clusterrolebinding
subjects:
- kind: ServiceAccountname: haimaxy-sa2namespace: kube-system
roleRef:kind: ClusterRolename: cluster-adminapiGroup: rbac.authorization.k8s.io

从上面我们可以看到我们没有为这个资源对象声明 namespace,因为这是一个 ClusterRoleBinding 资源对象,是作用于整个集群的,我们也没有单独新建一个 ClusterRole 对象,而是使用的 cluster-admin 这个对象,这是Kubernetes集群内置的 ClusterRole 对象,我们可以使用kubectl get clusterrolekubectl get clusterrolebinding查看系统内置的一些集群角色和集群角色绑定,这里我们使用的 cluster-admin 这个集群角色是拥有最高权限的集群角色,所以一般需要谨慎使用该集群角色。

创建上面集群角色绑定资源对象,创建完成后同样使用 ServiceAccount 对应的 token 去登录 Dashboard 验证下:

$ kubectl create -f haimaxy-clusterolebinding.yaml
$ kubectl get secret -n kube-system |grep haimay-sa2
haimay-sa2-token-nxgqx                  kubernetes.io/service-account-token   3         47m
$ kubectl get secret haimay-sa2-token-nxgqx -o jsonpath={.data.token} -n kube-system |base64 -d
# 会生成一串很长的base64后的字符串

我们在最开始接触到RBAC认证的时候,可能不太熟悉,特别是不知道应该怎么去编写rules规则,大家可以去分析系统自带的 clusterrole、clusterrolebinding 这些资源对象的编写方法,怎么分析?还是利用 kubectl 的 get、describe、 -o yaml 这些操作,所以kubectl最基本的用户一定要掌握好。

RBAC只是Kubernetes中安全认证的一种方式,当然也是现在最重要的一种方式,后面我们再和大家一起聊一聊Kubernetes中安全设计。

pod内的用户证书

每个pod都会有一个ServiceAccount,默认为default,生成的证书在/var/run/secrets/kubernetes.io/serviceaccount/, 权限有限, 当我们为pod配置了ServiceAccount时,会 替换默认的证书和签名.

在pod内使用curl访问

#查出curl pod的全名:
# curl test$ kubectl get po |grep curl
curl-6f9755dc85-l8td4            1/1       Running   0          24m#把servile account 的 token 保存在变量中:
# curl test$ TOKEN_VALUE=$(kubectl exec curl-6f9755dc85-l8td4 -- cat /var/run/secrets/kubernetes.io/serviceaccount/token)#list所有POD:
# curl test$ kubectl exec curl-6f9755dc85-l8td4 -- curl -k --cacert /var/run/secrets/kubernetes.io/serviceaccount/ca.crt -H  "Authorization: Bearer $TOKEN_VALUE" https://kubernetes.default/api/v1/pods?resourceVersion=0#list所有service:
# curl test$ kubectl exec curl-6f9755dc85-l8td4 -- curl -k --cacert /var/run/secrets/kubernetes.io/serviceaccount/ca.crt -H  "Authorization: Bearer $TOKEN_VALUE" https://kubernetes.default/api/v1/services?resourceVersion=0#list所有namespace:
# curl test$ kubectl exec curl-6f9755dc85-l8td4 -- curl -k --cacert /var/run/secrets/kubernetes.io/serviceaccount/ca.crt -H  "Authorization: Bearer $TOKEN_VALUE" https://kubernetes.default/api/v1/namespaces?resourceVersion=0或者可以写成一个命令(替换你自己的{namespace})
curl -k --cacert /var/run/secrets/kubernetes.io/serviceaccount/ca.crt -H  "Authorization: Bearer $(cat /var/run/secrets/kubernetes.io/serviceaccount/token)" https://kubernetes.default/api/v1/namespaces/{namespace}/pods?resourceVersion=0

在集群内部访问kubernetes API,一般使用下面两个地址:

https://kubenetes/
https://10.254.0.1/                  通过kubectl get svc |grep kubernetes查询

kubernetes客户端,可以参考:https://kubernetes.io/docs/reference/
不能操作的api参数参考:https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.11/#

所以使用前要先部署

apiVersion: v1
kind: ServiceAccount
metadata:name: face-search-sanamespace: cloudai-2
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:name: face-search-clusterrole
rules:
- apiGroups: [""]resources: ["pods","services","endpoints","configmaps","nodes","deployments"]verbs: ["list","get","create","update","watch","delete"]
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:name: face-search-clusterrolebinding
subjects:
- kind: ServiceAccountname: face-search-sanamespace: cloudai-2
roleRef:kind: ClusterRolename: face-search-clusterroleapiGroup: rbac.authorization.k8s.io

python访问api server

在pod中就可以直接使用了

class K8s():def __init__(self,file=KUBECONFIG_FILE):  # kubectlconfig.yamld = path.dirname(__file__)  # 返回当前文件所在的目录if file:config.kube_config.load_kube_config(config_file=d+'/'+file)   # 使用kubeconfig文件名称获取访问权限else:config.load_incluster_config()   # 使用为pod配置的rbac访问集群self.v1 = client.CoreV1Api()self.v1.api_client.configuration.verify_ssl = False  # 只能设置 /usr/local/lib/python3.6/dist-packages/kubernetes/client/configuration.py:   self.verify_ssl= True ---> False

参考:https://www.cnblogs.com/dukuan/p/9948063.html

原文链接:Kubernetes RBAC 详解

Kubernetes RBAC 详解相关推荐

  1. k8s、ServiceAccount权限详解、RBAC 详解(基于角色的访问控制),常用操作指令

    文章目录 Service Account应用示例 RBAC 详解(基于角色的访问控制) 创建一个角色(role)---权限 实验二 常用操作指令 Service Account应用示例 概念图权限关系 ...

  2. Kubernetes Service详解(概念、原理、流量分析、代码)

    Kubernetes Service详解(概念.原理.流量分析.代码) 作者: liukuan73 原文:https://blog.csdn.net/liukuan73/article/details ...

  3. 揭开面纱:Kubernetes架构详解

    [编者的话] 本文介绍了Kubernetes中的主要组件和各个组件的工作模式. 入门导论:Kubernetes组件和组件之间如何协同工作 本文讲的是揭开面纱:Kubernetes架构详解如果你正在实现 ...

  4. Kubernetes(k8s)权限管理RBAC详解

    文章目录 一.简介 二.用户分类 三.K8s角色&角色绑定(以ServiceAccount展开讲解) 1)授权介绍 2)角色(Role和ClusterRole) 3)角色绑定(RoleBind ...

  5. Kubernetes基础详解

    1. Kubernetes介绍 1.1 应用部署方式演变 在部署应用程序的方式上,主要经历了三个时代: 传统部署:互联网早期,会直接将应用程序部署在物理机上 优点:简单,不需要其它技术的参与 缺点:不 ...

  6. 【云原生】Kubernetes CRD 详解(Custom Resource Definition)

    文章目录 一.概述 二.定制资源 1)定制资源 和 定制控制器 2)定制控制器 3)Operator 介绍 1.Operator Framework 2.Operator 安装 3.安装 Operat ...

  7. kubernetes—Pod详解

    Pod详解 前言 Pod介绍 Pod结构 Pod定义 pod的几种基础配置 概述 基本配置(name,image) 镜像拉取(imagePullPolicy) 启动命令(command和args) 环 ...

  8. kubernetes不同的命名空间下的容器能通信吗_超长干货 | Kubernetes命名空间详解

    本文中,我们将探索Kubernetes命名空间,它是集群中组织和管理对象的一种方式. 介 绍 Kubernetes集群可以同时管理大量互不相关的工作负载,而组织通常会选择将不同团队创建的项目部署到共享 ...

  9. 超长干货 | Kubernetes命名空间详解

    K8s使用命名空间的概念帮助解决集群中在管理对象时的复杂性问题.在本文中,会讨论命名空间的工作原理,介绍常用实例,并分享如何使用命名空间来管理K8s对象.最后,介绍名为projects的Rancher ...

最新文章

  1. CCNA实验之--三层交换
  2. springclould feign客户端添加全局参数
  3. 怎么把cad做的图分享给别人_干货在线 | 这20个CAD技巧值得收藏!
  4. 24小时学通Linux内核之构建Linux内核
  5. 具有Spring Boot的Spring Integration Standalone应用程序
  6. 深入理解InnoDB(2)—页的存储结构
  7. 苹果怎么付费购买内存_【苹果手机多长时间清理一次内存,怎么清理?】
  8. 【文章】人的好运从哪里来?
  9. iOS中创建,使用动态库(dylib)
  10. 想要换壁纸,看这个网站就够了!
  11. 抖音回应视频泄露:草稿不会上传后台;苹果开卖5000元印度版iPhone XR;Jboot 2.2.5发布|极客头条...
  12. angular6、7 兼容ie9、10、11
  13. shell php的守护进程,实例详解shell编写守护进程的方法
  14. 微信发红包功能的测试用例
  15. 【易我数据恢复】超实用的数据恢复工具
  16. 图灵大会演讲 | 百度首席科学家吴华:NLP技术的演变与发展
  17. 【独行秀才】macOS Big Sur 11.5 Beta 1(20G5023d)原版镜像
  18. android实现日历
  19. 直流有刷/无刷电机的介绍
  20. 怎样计算机表格中算出平均值,怎样设置excel自动计算平均值

热门文章

  1. Vue组件化开发 - 非常详细,不要错过哦~
  2. Vue分支循环结构~非常详细哦
  3. 计算机网络重点知识总结 谢希仁版,计算机网络谢希仁版网络层知识点总结
  4. 不相交集java_不相交集类
  5. 【java笔记】函数式接口
  6. 开源视频平台:ViMP
  7. 退出所有循环_探索未知种族之osg类生物---呼吸分解之事件循环三
  8. oracle 函数 结果集,Oracle 中函数如何返回结果集
  9. 将数据追加到html 表格中,【HTML】使用Jquery实现将输入数据添加至表格中
  10. 梦幻群侠传5帮派修炼_梦幻群侠传5唯美版