Kubernetes中有不少种内置的编排对象,此外还能够自定义API资源类型和控制器的编写方式.那么,我能不能本身写一个编排对象呢?答案是确定的.而这,也正是Kubernetes项目最具吸引力的地方.
毕竟在互联网级别的大规模集群里,Kubernetes内置的编排对象,很难作到彻底知足全部需求,因此不少实际的容器化工做,都会要求设计一个本身的编排对象,实现本身的控制器模式.
因此,咱们能够基于插件机制来完成这些工做,而不须要修改任何一行代码.可是,若是要经过外部插件,在Kubernetes中实现新增和操做API对象,那么就必须先了解一个很是重要的知识:RBAC.
什么是RBAC呢?咱们知道,Kubernetes中全部的API对象,都保存在Etcd里,可是呢,对这些API对象的操做,却必定都是经过访问kube-apiserver来实现的.其中一个很是重要的缘由,就是你须要APIServer来帮助你作受权工做.而在Kubernetes项目中,负责完成受权(Authorization)工做的机制,就是RABC:基于角色的访问控制(Role-Based Access Control).web
Role |
Role自己就是一个Kubernetes的API对象,定义以下所示:api
kind: Role apiVersion: rbac.authorization.k8s.io/v1 metadata: namespace: mynamespace name: example-role rules: - apiGroups: [""] resources: ["pods"] verbs: ["get", "watch", "list"]
若是对这个格式比较熟悉的话,应该可以一眼看出来:首先,这个Role对象指定了它能产生做用的Namespace是:mynamespace.
Namespace是Kubernetes项目里的一个逻辑管理单位,不一样Namespace的API对象,在经过kubectl命令进行操做的时候,是互相隔离开的.这只是逻辑上的"隔离".Namespace并不会提供任何实际的隔离或者多租户能力.
Role对象的rules字段,就是它所定义的权限规则.在这里规则的意思就是:容许"被做用者",对mynamespace下面的Pod对象,进行GET,WATCH和LIST操做.
那么,这个具体的"被做用者"又是如何指定的呢?这就须要经过RoleBinding来实现了.svg
Subject与RoleBinding |
RoleBinding自己也是Kubernetes的API对象.定义以下:学习
kind: RoleBinding apiVersion: rbac.authorization.k8s.io/v1 metadata: name: example-rolebinding namespace: mynamespace subjects: - kind: User name: example-user apiGroup: rbac.authorization.k8s.io roleRef: kind: Role name: example-role apiGroup: rbac.authorization.k8s.io
由上,咱们可以看到,这个RoleBinding对象里定义了一个subjects字段,即"被做用者".它的类型是User,即Kubernetes中的用户,这个用户的名字是example-user.可是,在Kubernetes中,并无一个叫作"User"的API对象,这个User究竟是从哪儿来的呢?
实际上,Kubernetes中的"User"就是"用户",只是一个受权系统里的逻辑概念.它须要经过外部认证服务来提供,或者也能够直接给APIServer指定一个用户名,密码文件.那么Kubernetes的受权系统,就能够从这个文件里找到对应的"用户".其实在大多数私有的使用环境中,只要使用Kubernetes提供的内置"用户",就足够了.
好像有点儿扯远了.这个等下再详细说吧.spa
再往下看,可以看到roleRef字段.正是经过这个字段,RoleBinding对象就能够直接经过名字,来引用咱们前面定义的Role对象(example-role),从而定义了"被做用者(Subject)"和"角色(Role)"之间的绑定关系.
在这里须要强调一下:Role和RoleBinding对象都是Namespaced对象,它们对权限的限制规则仅在它们本身的Namespace内有效,roleRef也只能引用当前Namespace中的Role对象.
那么,对于非Namespaced(Non-namespaced)对象(好比:Node),或者某一个Role想要做用于全部的Namespace时,咱们又该怎么去作受权呢?
这时,就必需要使用ClusterRole和ClusterRoleBinding这两个组合了.这两个API对象的用法和Role与RoleBinding彻底同样,只不过它们的定义里,没有了Namespace字段.
具体以下所示:插件
kind: ClusterRole apiVersion: rbac.authorization.k8s.io/v1 metadata: name: example-clusterrole rules: - apiGroups: [""] resources: ["pods"] verbs: ["get", "watch", "list"]
kind: ClusterRoleBinding apiVersion: rbac.authorization.k8s.io/v1 metadata: name: example-clusterrolebinding subjects: - kind: User name: example-user apiGroup: rbac.authorization.k8s.io roleRef: kind: ClusterRole name: example-clusterrole apiGroup: rbac.authorization.k8s.io
上面的例子中,意味着名叫example-user用户,拥有对全部Namespace里的Pod进行GET,WATCH和LIST操做的权限.更进一步的说,在Role或者ClusterRole里面,若是要赋予用户example-user全部权限,那么就能够给它指定一个verbs字段的全集,以下所示:设计
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
固然,也能够根据本身的需求,只针对某一个具体的对象进行权限设置.好比:code
rules: - apiGroups: [""] resources: ["configmaps"] resourceNames: ["my-config"] verbs: ["get"]
这个例子就表示,这条规则的"被做用者",只对名叫"my-config"的ConfigMap对象,有进行GET操做权限.
在上面提了一下,大多数时候,咱们其实都不太使用"用户"这个功能,而是直接使用Kubernetes中的"内置用户",而这个"内置用户"就是:ServiceAccount.server
ServiceAccount分配权限的过程 |
经过一个实例,来说解一下为ServiceAccount分配权限的过程.
首先,须要定义一个ServiceAccount.它的API对象很是简单,以下所示:xml
apiVersion: v1 kind: ServiceAccount metadata: namespace: mynamespace name: example-sa
能够看到,一个最简单的ServiceAccount对象,只须要Name和Namespace这两个最基本的字段.
而后咱们经过编写RoleBinding的YAML文件,来为这个ServiceAccount分配权限:
kind: RoleBinding apiVersion: rbac.authorization.k8s.io/v1 metadata: name: example-rolebinding namespace: mynamespace subjects: - kind: ServiceAccount name: example-sa namespace: mynamespace roleRef: kind: Role name: example-role apiGroup: rbac.authorization.k8s.io
接下来,咱们用kubectl命令建立这三个对象:
$ kubectl create -f svc-account.yaml $ kubectl create -f role-binding.yaml $ kubectl create -f role.yaml
而后,来查看一下ServiceAccount的详细信息:
$ kubectl get sa -n mynamespace -o yaml - apiVersion: v1 kind: ServiceAccount metadata: creationTimestamp: 2018-09-08T12:59:17Z name: example-sa namespace: mynamespace resourceVersion: "409327" ... secrets: - name: example-sa-token-vmfg6
能够看到,Kubernetes会为一个ServiceAccount自动建立并分配一个Secret对象.这个Secret就是这个ServiceAccount对应的,用来和APIServer进行交互的受权文件,通常称它为:Token.
Token文件的内容通常是证书或者密码,它以一个Secret对象的方式,保存在Etcd当中.
此时,用户的Pod就能够声明使用这个ServiceAccount了.
对以上内容的总结 |
上面内容有些多,最后来一个总结:
所谓角色(Role),其实就是一组权限规则列表.分配这些权限的方式,就是经过建立RoleBinding对象,将被做用者(Subject)和权限列表进行绑定.
另外,与之对应的ClusterRole和ClusterRoleBinding,则是Kubernetes集群级别的Role和RoleBinding,它们的做用范围不受Namespace限制.
尽管权限的被做用者能够用不少种(好比,User,Group等),但在咱们日常的使用中,最广泛的用法仍是ServiceAccount.因此,Role+RoleBinding+ServiceAccount的权限分配方式,是最应该掌握的内容.
以上内容来自我学习<深刻剖析Kubernetes>专栏文章以后的一些看法,有偏颇之处,还望指出. 感谢您的阅读~