1、知识准备
● 上一节描述了k8s的帐户管理,本文描述基于角色的访问控制
● 网上RBAC的文章很是多,具体概念大神们也解释得很详细,本文没有站在高屋建瓴的角度去描述RBAC,而是站在一个普通程序员的视角,去看待RBAC
● 我理解的基于角色的访问控制,如图:node
+------------+ +------------>|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各类各样的资源
角色绑定:资源与规则组成访问权限,将角色绑定在访问权限上,最后帐户登陆以后扮演不一样的角色nginx
2、环境准备
组件 | 版本 |
---|---|
OS | Ubuntu 18.04.1 LTS |
docker | 18.06.0-ce |
k8s | v1.10.1 |
3、建立角色
角色分为role与clusterrole,区别在于前者是namespace级别,后者是整个k8s cluster级别程序员
(1)建立role
建立一个default namespace的普通角色,权限是对pod的get、list、watchdocker
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级别的,也就是全部的namespaceapi
apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: cluster_po_r rules: - apiGroups: - "" resources: - pods verbs: - get - list - watch
4、userAccount角色绑定
(1)role绑定
先将上一节的mrvolleyball帐号绑定一个namespace级别的role,使用rolebindingui
apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: mrvolleyball roleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: po_r subjects: - apiGroup: rbac.authorization.k8s.io kind: User name: mrvolleyball
再看mrvolleyball的帐户,已经拥有了对default namespace的get pod权限spa
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的访问权限3d
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的podcode
apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: mrvolleyball roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: cluster_po_r subjects: - apiGroup: rbac.authorization.k8s.io kind: User name: mrvolleyball
这时候mrvolleyball也能够读取其余namespace的podserver
root@k8s-master:~# kubectl get pod -n kube-system NAME READY STATUS RESTARTS AGE 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/v1 kind: RoleBinding metadata: name: mrvolleyball namespace: default roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: cluster_po_r subjects: - 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
5、serviceAccount角色绑定
serviceAccount要提供给pod内访问,或者是外部服务的访问。为了验证serviceAccount,咱们来模拟pod去访问api
首先先建立一个serviceAccount
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 metadata: creationTimestamp: 2019-03-12T06:36:00Z name: helloworld namespace: default 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 yaml apiVersion: v1 data: ... token: ZXlKaGJHY2lPaUpTVXpJMU5pSXNJbXRwWkNJNklpSjkuZXlKcGMzTWlPaUpyZFdKbGNtNWxkR1Z6TDNObGNuWnBZMlZoWTJOdmRXNTBJaXdpYTNWaVpYSnVaWFJsY3k1cGJ5OXpaWEoyYVdObFlXTmpiM1Z1ZEM5dVlXMWxjM0JoWTJVaU9pSmtaV1poZFd4MElpd2lhM1ZpWlhKdVpYUmxjeTVwYnk5elpYSjJhV05sWVdOamIzVnVkQzl6WldOeVpYUXVibUZ0WlNJNkltaGxiR3h2ZDI5eWJHUXRkRzlyWlc0dGMzSTVlR0lpTENKcmRXSmxjbTVsZEdWekxtbHZMM05sY25acFkyVmhZMk52ZFc1MEwzTmxjblpwWTJVdFlXTmpiM1Z1ZEM1dVlXMWxJam9pYUdWc2JHOTNiM0pzWkNJc0ltdDFZbVZ5Ym1WMFpYTXVhVzh2YzJWeWRtbGpaV0ZqWTI5MWJuUXZjMlZ5ZG1salpTMWhZMk52ZFc1MExuVnBaQ0k2SWpFNU9EZGlOR1UyTFRRME9URXRNVEZsT1MwNU5tSmpMVFV5TlRRd01HTXpOR05tTVNJc0luTjFZaUk2SW5ONWMzUmxiVHB6WlhKMmFXTmxZV05qYjNWdWREcGtaV1poZFd4ME9taGxiR3h2ZDI5eWJHUWlmUS5zTTQ3dnBMV25nVmZ1Q2c3RGRfNWlVSGFCa0loeHNvNXY1ZHotRzh3X3ctZUNaS05pZlRyUE9xd3R3QjR4MnZnS3dPaExXX2c0UWxtRDNXS3QyejhlNHVJeFV0cHZkc0lRYkdrYjVrUUdsV1p4cnZwTUZHbTF0eVRsU1lVc3gxa25GdnViWTV0bWU5Y2JkNExOc2RQQ1IxTXBBYnBkYjlqZFh6OWRxMVAyb1Z1LVVuYmVBTkFMcE5tSGJHZjFSdVRPUEJBcUNPNlI3Zm0zUUxpZFZOSDBjRUkwX1Joa0NKR2xPUi1rUlZ5bE5GYXJOVWhvQnJGSEJpTWJyOHd6UHpRNk42Z0hpblctWUc1ekFCY2JNaUR1QUZrRDBCXzBNbDlJandHaDgtbHlrSUZBTU1sbTktUS1hTjJTUjkwSnJyelRYcUtUV3NJU0ZQWHhCTUItX3BXTTlEMEhiZTU4TURCQ1VlSlp0SUcyNno4alBiU0Y1aHRuTy1YSFJRWm1CUzJoaXFLelE2aG9TMkxEa045WUdwcFRETkJUY0dySjg2U0ZQaDlkRWtaYWw0QU9XLWlfTHdEYnY0V2luQjBDOG1Pc3c1WkhDdEVxTVNUTE90aXFyOWZ3bEYzb2lldERqV3FSSXhKeG5rY1NRYTBOTHR4cENiQjFvOGRDTjlqaE1WLVRZMDdidUVNNUpJUGhzeERBMVpqTjNJenVpc3VTVWZMRjd5NkgwZ1JxaGdITzdyMVZvdU5ubGFybjNhSmxMYmF3NUk3RnIwM1ZrQ0pqSmotX0FFRmpSWGlNVmRtenM0el9nWVRfUGR0TXR4YnFfd1p5ZXJHWXpuUk9NQ3p0b2gtRlRCWktOT2dfZjBmTEN3c29rd2NJaEtWWFh2YXMtcjN0YXFBcXZEbWtOOA== kind: Secret metadata: 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-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=$token User "helloworld" set.
配置rolebinding,po_r这个role只能对default namespace的pod有读权限
apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: helloworld-role-binding namespace: default roleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: po_r subjects: - kind: ServiceAccount name: helloworld namespace: default
尝试访问一下:
root@k8s-master:~# kubectl config use-context context@helloworld Switched to context "context@helloworld". root@k8s-master:~# kubectl get pod NAME READY STATUS RESTARTS AGE busybox 1/1 Running 187 7d
该serviceAccount也只有default namespace的访问权限
root@k8s-master:~# kubectl get pod -n kube-system Error from server (Forbidden): pods is forbidden: User "system:serviceaccount:default:helloworld" cannot list pods in the namespace "kube-system"
6、小结
● 本文介绍了k8s基于权限的访问,详细k8s当中role、clusterrole与rolebinding、clusterrolebinding
● 而且模拟了不一样类型的帐户访问kube-api时不一样的认证方式
至此,本文结束 在下才疏学浅,有撒汤漏水的,请各位不吝赐教...