一, 知识准备
● 上一节描述了 k8s 的账户管理, 本文描述基于角色的访问控制
● 网上 RBAC 的文章非常多, 具体概念大神们也解释得很详细, 本文没有站在高屋建瓴的角度去描述 RBAC, 而是站在一个普通程序员的视角, 去看待 RBAC
● 我理解的基于角色的访问控制, 如图:
- +------------+
- +------------>|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 各种各样的资源
角色绑定: 资源与规则组成访问权限, 将角色绑定在访问权限上, 最后账户登录之后扮演不同的角色
二, 环境准备
组件 | 版本 |
---|---|
OS | Ubuntu 18.04.1 LTS |
docker | 18.06.0-ce |
k8s | v1.10.1 |
三, 创建角色
角色分为 role 与 clusterrole, 区别在于前者是 namespace 级别, 后者是整个 k8s cluster 级别
(1) 创建 role
创建一个 default namespace 的普通角色, 权限是对 pod 的 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/v1
- kind: ClusterRole
- metadata:
- name: cluster_po_r
- rules:
- - apiGroups:
- - ""
- resources:
- - pods
- verbs:
- - get
- - list
- - watch
四, userAccount 角色绑定
(1)role 绑定
先将上一节的 mrvolleyball 账号绑定一个 namespace 级别的 role, 使用 rolebinding
- 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 权限
- 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 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/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 的 pod
- 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
五, 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"
六, 小结
● 本文介绍了 k8s 基于权限的访问, 详细 k8s 当中 role,clusterrole 与 rolebinding,clusterrolebinding
● 并且模拟了不同类型的账户访问 kube-API 时不同的认证方式
至此, 本文结束
在下才疏学浅, 有撒汤漏水的, 请各位不吝赐教...
来源: https://www.cnblogs.com/MrVolleyball/p/10709142.html