一、知识准备
● 上一节描述了k8s的账户管理,本文描述基于角色的访问控制 ● 网上RBAC的文章非常多,具体概念大神们也解释得很详细,本文没有站在高屋建瓴的角度去描述RBAC,而是站在一个普通程序员的视角,去看待RBAC ● 我理解的基于角色的访问控制,如图:
+------------+ +------------>|all:resource|-+ | +------------+ | +----------------+ +----+---+ | | |+------+ |role: | +------>+ namespaces ||user1 |------------>|admin | | |+------+ +--------+ +------------+ | pod | +---->|get:pod |-------->+ | | +------------+ | service | | | |+------+ +--------+ | | deployment ||user2 |------------>|role: |---+ | |+------+ |guest | .... | daemonsets | +--------+ | | | ... | +------------+ | | |list:service| +----------------+ +------------+
+------------+
+------------>|all:resource|-+
| +------------+ | +----------------+
+----+---+ | | |
+------+ |role: | +------>+ namespaces |
|user1 |------------>|admin | | |
+------+ +--------+ +------------+ | pod |
+---->|get:pod |-------->+ |
| +------------+ | service |
| | |
+------+ +--------+ | | deployment |
|user2 |------------>|role: |---+ | |
+------+ |guest | .... | daemonsets |
+--------+ | |
| ... |
+------------+ | |
|list:service| +----------------+
账户:请求kube-api必要的身份验证。身份验证之后只是被允许进入集群,但是不一定有访问资源的权限 角色:账户登录之后扮演的角色 规则:在k8s集群内允许的操作。比如get namespace、get pod等 资源:k8s各种各样的资源 角色绑定:资源与规则组成访问权限,将角色绑定在访问权限上,最后账户登录之后扮演不同的角色
二、环境准备
三、创建角色
角色分为role与clusterrole,区别在于前者是namespace级别,后者是整个k8s cluster级别
(1)创建role
创建一个default namespace的普通角色,权限是对pod的get、list、watch
apiVersion: rbac.authorization.k8s.io/v1kind: Rolemetadata: name: po_r namespace: defaultrules:- apiGroups: - "" resources: - pods verbs: - get - list - watch
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: po_r
namespace: default
rules:
- apiGroups:
- ""
resources:
- pods
verbs:
- get
- list
- watch
(2)创建clusterrole
创建一个具有pod的get、list、watch的clusterrole,这个角色是cluster级别的,也就是所有的namespace
apiVersion: rbac.authorization.k8s.io/v1kind: ClusterRolemetadata: name: cluster_po_rrules:- apiGroups: - "" resources: - pods verbs: - get - list - watch
kind: ClusterRole
name: cluster_po_r
四、userAccount角色绑定
(1)role绑定
先将上一节的mrvolleyball账号绑定一个namespace级别的role,使用rolebinding
apiVersion: rbac.authorization.k8s.io/v1kind: RoleBindingmetadata: name: mrvolleyballroleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: po_rsubjects:- apiGroup: rbac.authorization.k8s.io kind: User name: mrvolleyball
kind: RoleBinding
name: mrvolleyball
roleRef:
apiGroup: rbac.authorization.k8s.io
subjects:
- apiGroup: rbac.authorization.k8s.io
kind: User
再看mrvolleyball的账户,已经拥有了对default namespace的get pod权限
root@k8s-master:~# kubectl get podNAME READY STATUS RESTARTS AGEbusybox 1/1 Running 89 3dnginx-deployment-77d7f55978-lvfkf 1/1 Running 0 21h
root@k8s-master:~# kubectl get pod
NAME READY STATUS RESTARTS AGE
busybox 1/1 Running 89 3d
nginx-deployment-77d7f55978-lvfkf 1/1 Running 0 21h
不过他既没有service的访问权限,更没有别的namespace的访问权限
root@k8s-master:~# kubectl get svcError from server (Forbidden): services is forbidden: User "mrvolleyball" cannot list services in the namespace "default"root@k8s-master:~# kubectl get pod -n kube-systemError from server (Forbidden): pods is forbidden: User "mrvolleyball" cannot list pods in the namespace "kube-system"
root@k8s-master:~# kubectl get svc
Error from server (Forbidden): services is forbidden: User "mrvolleyball" cannot list services in the namespace "default"
root@k8s-master:~# kubectl get pod -n kube-system
Error from server (Forbidden): pods is forbidden: User "mrvolleyball" cannot list pods in the namespace "kube-system"
(2)clusterrole绑定
绑定clusterrole,让mrvollerball能够读取所有namespace的pod
apiVersion: rbac.authorization.k8s.io/v1kind: ClusterRoleBindingmetadata: name: mrvolleyballroleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: cluster_po_rsubjects:- apiGroup: rbac.authorization.k8s.io kind: User name: mrvolleyball
kind: ClusterRoleBinding
这时候mrvolleyball也可以读取其他namespace的pod
root@k8s-master:~# kubectl get pod -n kube-systemNAME READY STATUS RESTARTS AGEcalico-kube-controllers-55c94797d7-vr9k6 1/1 Running 0 15dcalico-node-86xgg 1/1 Running 0 7dcalico-node-drsl2 1/1 Running 0 7dcalico-node-l67h4 1/1 Running 0 7dcoredns-794b5f8589-vgclz 1/1 Running 4809 15dcoredns-794b5f8589-xzpxd 1/1 Running 0 130ddefault-http-backend-6cb5c56987-tcx92 1/1 Running 0 139dkubernetes-dashboard-77c46fc984-djdd4 1/1 Running 0 139dnginx-ingress-controller-6d95468cc8-ft6nn 1/1 Running 0 140d
calico-kube-controllers-55c94797d7-vr9k6 1/1 Running 0 15d
calico-node-86xgg 1/1 Running 0 7d
calico-node-drsl2 1/1 Running 0 7d
calico-node-l67h4 1/1 Running 0 7d
coredns-794b5f8589-vgclz 1/1 Running 4809 15d
coredns-794b5f8589-xzpxd 1/1 Running 0 130d
default-http-backend-6cb5c56987-tcx92 1/1 Running 0 139d
kubernetes-dashboard-77c46fc984-djdd4 1/1 Running 0 139d
nginx-ingress-controller-6d95468cc8-ft6nn 1/1 Running 0 140d
这里需要注意几种资源的绑定:
rolebinding --> role clusterrolebinding --> clusterrole rolebinding --> clusterrole
● 第一种是namespace级别的绑定,只对role所在的namespace生效 ● 第二种是cluster级别的绑定,对于集群所有的namespace都生效 ● 第三种是namespace级别的绑定,只对role所在的namespace生效
有同学要问,第一种和第三种有什么区别:
apiVersion: rbac.authorization.k8s.io/v1kind: RoleBindingmetadata: name: mrvolleyball namespace: defaultroleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: cluster_po_rsubjects:- apiGroup: rbac.authorization.k8s.io kind: User name: mrvolleyball
区别主要是为了方便管理: ● 比如有10个namespace,分配给了10个不同的团队,那每个团队都需要使用自己的userAccount操作自己所在的namespace ● 最简单的做法,就是在10个不同namespace创建10个role,然后通过rolebinding将role绑定userAccount。如果需要添加userAccount,那这个管理成本就会升高 ● 这时候创建一个clusterrole,由于他们对各自的namespace的行为都是一样的,那就只需要通过rolebinding将clusterrole绑定在userAccount,只需要创建1次clusterrole
五、serviceAccount角色绑定
serviceAccount要提供给pod内访问,或者是外部服务的访问。为了验证serviceAccount,我们来模拟pod去访问api
首先先创建一个serviceAccount
root@k8s-master:/etc/kubernetes/ssl# kubectl create serviceaccount helloworldserviceaccount "helloworld" createdroot@k8s-master:/etc/kubernetes/ssl# kubectl get sa helloworld -o yamlapiVersion: v1kind: ServiceAccountmetadata: creationTimestamp: 2019-03-12T06:36:00Z name: helloworld namespace: default resourceVersion: "24381027" selfLink: /api/v1/namespaces/default/serviceaccounts/helloworld uid: 1987b4e6-4491-11e9-96bc-525400c34cf1secrets:- name: helloworld-token-sr9xb
root@k8s-master:/etc/kubernetes/ssl# kubectl create serviceaccount helloworld
serviceaccount "helloworld" created
root@k8s-master:/etc/kubernetes/ssl# kubectl get sa helloworld -o yaml
apiVersion: v1
kind: ServiceAccount
creationTimestamp: 2019-03-12T06:36:00Z
name: helloworld
resourceVersion: "24381027"
selfLink: /api/v1/namespaces/default/serviceaccounts/helloworld
uid: 1987b4e6-4491-11e9-96bc-525400c34cf1
secrets:
- name: helloworld-token-sr9xb
serviceAccount获取默认生成一个token,该token是用于pod访问kube-api的身份验证(详情访问上一篇文章)
root@k8s-master:/etc/kubernetes/ssl# kubectl get secret helloworld-token-sr9xb -o yamlapiVersion: v1data:... token: ZXlKaGJHY2lPaUpTVXpJMU5pSXNJbXRwWkNJNklpSjkuZXlKcGMzTWlPaUpyZFdKbGNtNWxkR1Z6TDNObGNuWnBZMlZoWTJOdmRXNTBJaXdpYTNWaVpYSnVaWFJsY3k1cGJ5OXpaWEoyYVdObFlXTmpiM1Z1ZEM5dVlXMWxjM0JoWTJVaU9pSmtaV1poZFd4MElpd2lhM1ZpWlhKdVpYUmxjeTVwYnk5elpYSjJhV05sWVdOamIzVnVkQzl6WldOeVpYUXVibUZ0WlNJNkltaGxiR3h2ZDI5eWJHUXRkRzlyWlc0dGMzSTVlR0lpTENKcmRXSmxjbTVsZEdWekxtbHZMM05sY25acFkyVmhZMk52ZFc1MEwzTmxjblpwWTJVdFlXTmpiM1Z1ZEM1dVlXMWxJam9pYUdWc2JHOTNiM0pzWkNJc0ltdDFZbVZ5Ym1WMFpYTXVhVzh2YzJWeWRtbGpaV0ZqWTI5MWJuUXZjMlZ5ZG1salpTMWhZMk52ZFc1MExuVnBaQ0k2SWpFNU9EZGlOR1UyTFRRME9URXRNVEZsT1MwNU5tSmpMVFV5TlRRd01HTXpOR05tTVNJc0luTjFZaUk2SW5ONWMzUmxiVHB6WlhKMmFXTmxZV05qYjNWdWREcGtaV1poZFd4ME9taGxiR3h2ZDI5eWJHUWlmUS5zTTQ3dnBMV25nVmZ1Q2c3RGRfNWlVSGFCa0loeHNvNXY1ZHotRzh3X3ctZUNaS05pZlRyUE9xd3R3QjR4MnZnS3dPaExXX2c0UWxtRDNXS3QyejhlNHVJeFV0cHZkc0lRYkdrYjVrUUdsV1p4cnZwTUZHbTF0eVRsU1lVc3gxa25GdnViWTV0bWU5Y2JkNExOc2RQQ1IxTXBBYnBkYjlqZFh6OWRxMVAyb1Z1LVVuYmVBTkFMcE5tSGJHZjFSdVRPUEJBcUNPNlI3Zm0zUUxpZFZOSDBjRUkwX1Joa0NKR2xPUi1rUlZ5bE5GYXJOVWhvQnJGSEJpTWJyOHd6UHpRNk42Z0hpblctWUc1ekFCY2JNaUR1QUZrRDBCXzBNbDlJandHaDgtbHlrSUZBTU1sbTktUS1hTjJTUjkwSnJyelRYcUtUV3NJU0ZQWHhCTUItX3BXTTlEMEhiZTU4TURCQ1VlSlp0SUcyNno4alBiU0Y1aHRuTy1YSFJRWm1CUzJoaXFLelE2aG9TMkxEa045WUdwcFRETkJUY0dySjg2U0ZQaDlkRWtaYWw0QU9XLWlfTHdEYnY0V2luQjBDOG1Pc3c1WkhDdEVxTVNUTE90aXFyOWZ3bEYzb2lldERqV3FSSXhKeG5rY1NRYTBOTHR4cENiQjFvOGRDTjlqaE1WLVRZMDdidUVNNUpJUGhzeERBMVpqTjNJenVpc3VTVWZMRjd5NkgwZ1JxaGdITzdyMVZvdU5ubGFybjNhSmxMYmF3NUk3RnIwM1ZrQ0pqSmotX0FFRmpSWGlNVmRtenM0el9nWVRfUGR0TXR4YnFfd1p5ZXJHWXpuUk9NQ3p0b2gtRlRCWktOT2dfZjBmTEN3c29rd2NJaEtWWFh2YXMtcjN0YXFBcXZEbWtOOA==kind: Secretmetadata: annotations: kubernetes.io/service-account.name: helloworld kubernetes.io/service-account.uid: 1987b4e6-4491-11e9-96bc-525400c34cf1 creationTimestamp: 2019-03-12T06:36:00Z name: helloworld-token-sr9xb namespace: default resourceVersion: "24381026" selfLink: /api/v1/namespaces/default/secrets/helloworld-token-sr9xb uid: 198c824f-4491-11e9-96bc-525400c34cf1type: kubernetes.io/service-account-token
root@k8s-master:/etc/kubernetes/ssl# kubectl get secret helloworld-token-sr9xb -o yaml
data:
...
token: ZXlKaGJHY2lPaUpTVXpJMU5pSXNJbXRwWkNJNklpSjkuZXlKcGMzTWlPaUpyZFdKbGNtNWxkR1Z6TDNObGNuWnBZMlZoWTJOdmRXNTBJaXdpYTNWaVpYSnVaWFJsY3k1cGJ5OXpaWEoyYVdObFlXTmpiM1Z1ZEM5dVlXMWxjM0JoWTJVaU9pSmtaV1poZFd4MElpd2lhM1ZpWlhKdVpYUmxjeTVwYnk5elpYSjJhV05sWVdOamIzVnVkQzl6WldOeVpYUXVibUZ0WlNJNkltaGxiR3h2ZDI5eWJHUXRkRzlyWlc0dGMzSTVlR0lpTENKcmRXSmxjbTVsZEdWekxtbHZMM05sY25acFkyVmhZMk52ZFc1MEwzTmxjblpwWTJVdFlXTmpiM1Z1ZEM1dVlXMWxJam9pYUdWc2JHOTNiM0pzWkNJc0ltdDFZbVZ5Ym1WMFpYTXVhVzh2YzJWeWRtbGpaV0ZqWTI5MWJuUXZjMlZ5ZG1salpTMWhZMk52ZFc1MExuVnBaQ0k2SWpFNU9EZGlOR1UyTFRRME9URXRNVEZsT1MwNU5tSmpMVFV5TlRRd01HTXpOR05tTVNJc0luTjFZaUk2SW5ONWMzUmxiVHB6WlhKMmFXTmxZV05qYjNWdWREcGtaV1poZFd4ME9taGxiR3h2ZDI5eWJHUWlmUS5zTTQ3dnBMV25nVmZ1Q2c3RGRfNWlVSGFCa0loeHNvNXY1ZHotRzh3X3ctZUNaS05pZlRyUE9xd3R3QjR4MnZnS3dPaExXX2c0UWxtRDNXS3QyejhlNHVJeFV0cHZkc0lRYkdrYjVrUUdsV1p4cnZwTUZHbTF0eVRsU1lVc3gxa25GdnViWTV0bWU5Y2JkNExOc2RQQ1IxTXBBYnBkYjlqZFh6OWRxMVAyb1Z1LVVuYmVBTkFMcE5tSGJHZjFSdVRPUEJBcUNPNlI3Zm0zUUxpZFZOSDBjRUkwX1Joa0NKR2xPUi1rUlZ5bE5GYXJOVWhvQnJGSEJpTWJyOHd6UHpRNk42Z0hpblctWUc1ekFCY2JNaUR1QUZrRDBCXzBNbDlJandHaDgtbHlrSUZBTU1sbTktUS1hTjJTUjkwSnJyelRYcUtUV3NJU0ZQWHhCTUItX3BXTTlEMEhiZTU4TURCQ1VlSlp0SUcyNno4alBiU0Y1aHRuTy1YSFJRWm1CUzJoaXFLelE2aG9TMkxEa045WUdwcFRETkJUY0dySjg2U0ZQaDlkRWtaYWw0QU9XLWlfTHdEYnY0V2luQjBDOG1Pc3c1WkhDdEVxTVNUTE90aXFyOWZ3bEYzb2lldERqV3FSSXhKeG5rY1NRYTBOTHR4cENiQjFvOGRDTjlqaE1WLVRZMDdidUVNNUpJUGhzeERBMVpqTjNJenVpc3VTVWZMRjd5NkgwZ1JxaGdITzdyMVZvdU5ubGFybjNhSmxMYmF3NUk3RnIwM1ZrQ0pqSmotX0FFRmpSWGlNVmRtenM0el9nWVRfUGR0TXR4YnFfd1p5ZXJHWXpuUk9NQ3p0b2gtRlRCWktOT2dfZjBmTEN3c29rd2NJaEtWWFh2YXMtcjN0YXFBcXZEbWtOOA==
kind: Secret
annotations:
kubernetes.io/service-account.name: helloworld
kubernetes.io/service-account.uid: 1987b4e6-4491-11e9-96bc-525400c34cf1
name: helloworld-token-sr9xb
resourceVersion: "24381026"
selfLink: /api/v1/namespaces/default/secrets/helloworld-token-sr9xb
uid: 198c824f-4491-11e9-96bc-525400c34cf1
type: kubernetes.io/service-account-token
拿到该token,将其转码之后作为连接kube-api的身份验证
root@k8s-master:/etc/kubernetes/ssl# token=`kubectl get secret helloworld-token-sr9xb -o yaml | grep "token:" | awk '{print $2}' | base64 -d`root@k8s-master:/etc/kubernetes/ssl# kubectl config set-credentials helloworld --token=$tokenUser "helloworld" set.
root@k8s-master:/etc/kubernetes/ssl# token=`kubectl get secret helloworld-token-sr9xb -o yaml | grep "token:" | awk '{print $2}' | base64 -d`
root@k8s-master:/etc/kubernetes/ssl# kubectl config set-credentials helloworld --token=$token
User "helloworld" set.
配置rolebinding,po_r这个role只能对default namespace的pod有读权限
apiVersion: rbac.authorization.k8s.io/v1kind: RoleBindingmetadata: name: helloworld-role-binding namespace: defaultroleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: po_rsubjects:- kind: ServiceAccount name: helloworld namespace: default
name: helloworld-role-binding
- kind: ServiceAccount
尝试访问一下:
root@k8s-master:~# kubectl config use-context context@helloworldSwitched to context "context@helloworld".root@k8s-master:~# kubectl get podNAME READY STATUS RESTARTS AGEbusybox 1/1 Running 187 7d
root@k8s-master:~# kubectl config use-context context@helloworld
Switched to context "context@helloworld".
busybox 1/1 Running 187 7d
该serviceAccount也只有default namespace的访问权限
root@k8s-master:~# kubectl get pod -n kube-systemError from server (Forbidden): pods is forbidden: User "system:serviceaccount:default:helloworld" cannot list pods in the namespace "kube-system"
Error from server (Forbidden): pods is forbidden: User "system:serviceaccount:default:helloworld" cannot list pods in the namespace "kube-system"
六、小结
● 本文介绍了k8s基于权限的访问,详细k8s当中role、clusterrole与rolebinding、clusterrolebinding ● 并且模拟了不同类型的账户访问kube-api时不同的认证方式
至此,本文结束 在下才疏学浅,有撒汤漏水的,请各位不吝赐教...
原文链接:http://www.cnblogs.com/MrVolleyball/p/10709142.html
本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728