一.权限管理RBAC
一个K8S集群并不只有管理员在使用,如果是一个开发或者一个测试,就不能有太高的权限,预防出错。
此时就要通过K8S一个机制RBAC对权限经行细粒度划分,例如张三,可设置只能在namespaceA进行操作,不能在其他命名空间操作。
官网:https://kubernetes.io/zh/docs/reference/access-authn-authz/rbac/
1.4种资源
ClusterRole:可以配置一些权限,允许对整个集群做你想做的
ClusterRoleBinding:可以把ClusterRole配置的权限,授权给指定的“人”,让他可以对整个集群做他想做的
Role:只能允许对该Namespace做你想做的
RoleBinding:只能让指定的“人”对该Namespace做他想做的
Role和ClusterRole
kind: Role apiVersion: rbac.authorization.k8s.io/v1 metadata: namespace: default name: pod-reader rules: - apiGroups: [""] # "" indicates the core API group resources: ["pods"] verbs: ["get", "watch", "list"] 备注 kind:定义资源类型为Role API Version:定义该资源的API版本,建议使用v1版本,因为其它版本如beta版本在Kubernetes1.22+将被彻底启用 metadata:元数据定义 namespace:因为Role是作用单个Namespace下的,具有命名空间隔离,所以需要制定Namespace,不指定则为default name:Role的名称 rules:定义具体的权限,切片类型,可以配置多个 API Groups:包含该资源的apiGroup名称,比如extension resources:定义对哪些资源进行授权,切片类型,可以定义多个,比如pods、service等 verbs:定义可以执行的操作,切片类型,可以定义多个,比如create、delete、list、get、watch、deletecollection等
RoleBinding和ClusterRoleBinding
kind: RoleBinding apiVersion: rbac.authorization.k8s.io/v1 metadata: name: read-pods namespace: default subjects: - kind: User name: jane # Name is case sensitive apiGroup: rbac.authorization.k8s.io roleRef: kind: Role name: pod-reader apiGroup: rbac.authorization.k8s.io roleRef:绑定的类别 kind:指定权限来源,可以是Role或ClusterRole name:Role或ClusterRole的名字 apiGroup:API 组名 subjects:配置被绑定对象,可以配置多个 kind:绑定对象的类别,当前为User,还可以是Group、ServiceAccount name:绑定对象名称
2.Role和RoleBinding的使用
Role示例:
允许读取在API 组下的 “Pods”:
rules: - apiGroups: [""] # 在 HTTP 层面,用来访问 Pod 的资源的名称为 "pods" resources: ["pods"] verbs: ["get", "list", "watch"]
允许读/写在 “extensions” 和 “apps” API 组中的 Deployment(在 HTTP 层面,对应 URL 中资源部分为 “deployments”):
rules: - apiGroups: ["extensions", "apps"] resources: ["deployments"] verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
允许读取核心 API 组中的 “pods” 和读/写 “batch” 或 “extensions” API 组中的 “jobs”:
rules: - apiGroups: [""] resources: ["pods"] verbs: ["get", "list", "watch"] - apiGroups: ["batch", "extensions"] resources: ["jobs"] verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
对于名称为 alice@example.com 的用户:
subjects: - kind: User name: "alice@example.com" apiGroup: rbac.authorization.k8s.io
对于名称为 frontend-admins 的用户组:
subjects: - kind: Group name: "frontend-admins" apiGroup: rbac.authorization.k8s.io
RoleBinding 示例
对于名称为 alice@example.com 的用户:
subjects: - kind: User name: "alice@example.com" apiGroup: rbac.authorization.k8s.io
对于任何名称空间中的 “qa” 组中所有的服务账户:
subjects: - kind: Group name: system:serviceaccounts:qa apiGroup: rbac.authorization.k8s.io
对于所有已经过认证的用户:
subjects: - kind: Group name: system:authenticated apiGroup: rbac.authorization.k8s.io
对于所有用户:
subjects: - kind: Group name: system:authenticated apiGroup: rbac.authorization.k8s.io - kind: Group name: system:unauthenticated apiGroup: rbac.authorization.k8s.io
3.ClusterRole和ClusterRoleBinding的使用
默认 ClusterRole和默认 ClusterRoleBinding
一些默认的 ClusterRole 不是以前缀 system: 开头的。这些是面向用户的角色。 它们包括超级用户(Super-User)角色(cluster-admin)、 使用 ClusterRoleBinding 在集群范围内完成授权的角色(cluster-status)、 以及使用 RoleBinding 在特定名字空间中授予的角色(admin、edit、view)。
面向用户的 ClusterRole 使用 ClusterRole 聚合以允许管理员在 这些 ClusterRole 上添加用于定制资源的规则。如果想要添加规则到 admin、edit 或者 view, 可以创建带有以下一个或多个标签的 ClusterRole:
4.聚合ClusterRole
假设有2个ClusterRole,ClusterRoleA和ClusterRoleB,ClusterRoleA设置了rule并打上了标签,ClusterRoleB就可以引用A的标签,ClusterRoleB就会自动补上ClusterRoleA的rule.
kind: ClusterRole apiVersion: rbac.authorization.k8s.io/v1 metadata: name: monitoring aggregationRule: clusterRoleSelectors: - matchLabels: rbac.example.com/aggregate-to-monitoring: "true" rules: [] kind: ClusterRole apiVersion: rbac.authorization.k8s.io/v1 metadata: name: monitoring-endpoints labels: rbac.example.com/aggregate-to-monitoring: "true" #打上标签 # These rules will be added to the "monitoring" role. rules: - apiGroups: [""] resources: ["services", "endpoints", "pods"] verbs: ["get", "list", "watch"]
示例:
[root@k8s-master01 ~]# vim a-ClusterRole.yaml kind: ClusterRole apiVersion: rbac.authorization.k8s.io/v1 metadata: name: test-aggregation aggregationRule: clusterRoleSelectors: - matchLabels: rbac.example.com/aggregate-to-test-aggregation: "true" rules: [] [root@k8s-master01 ~]# kubectl create -f a-ClusterRole.yaml [root@k8s-master01 ~]# kubectl get -f a-ClusterRole.yaml -oyaml | grep rule -A 3 #创建查看a-ClusterRole,发现rule是空 f:rules: {} manager: kubectl-create operation: Update time: "2021-12-04T09:29:51Z" -- rules: null
验证:创建sa,并查看sa创建的secret,获得token
[root@k8s-master01 ~]# kubectl create sa test-aggregation serviceaccount/test-aggregation created [root@k8s-master01 ~]# kubectl get secret NAME TYPE DATA AGE default-token-c5kj5 kubernetes.io/service-account-token 3 12d test-aggregation-token-l6v25 kubernetes.io/service-account-token 3 3s [root@k8s-master01 ~]# kubectl describe secret test-aggregation-token-l6v25 #查看toekn ... Data ==== ca.crt: 1066 bytes namespace: 7 bytes token: eyJhbGciOiJSUzI1NiIsImtpZCI6IlVrWjJjSlVHM09qU1laUnJpM1ZJZEVONDF3M1hRRzVkNFRKdTFjTEZXODQifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJkZWZhdWx0Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZWNyZXQubmFtZSI6InRlc3QtYWdncmVnYXRpb24tdG9rZW4tbDZ2MjUiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC5uYW1lIjoidGVzdC1hZ2dyZWdhdGlvbiIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50LnVpZCI6ImJiMTUwYjcwLWI2NGUtNDcxYy1hMzhiLWNiYzExYWY5NjZkYyIsInN1YiI6InN5c3RlbTpzZXJ2aWNlYWNjb3VudDpkZWZhdWx0OnRlc3QtYWdncmVnYXRpb24ifQ.Yl92rD0KHkwSLg-Oq8meSAnVeXdHkcOjBprURSj1UFDRzj1KpBqaoPNO0zTao0FIFni2hAKxg-pG6lzPXdO2bCBRxB8rha41JYqmIEvU7UvgQXxXGr6my80f5lZHo4_AD9y0O5pJAqio4fwOqOgIk8jP7zG7me9VZNbn4ygt2mi2fSYkcNxmb2-Zj7_jzBndYP_VfgtFesaX0GHWmMeN_agsGtYlyf7cBNBebGhmmFBSx-VR-tWUhi_L6ArCC6dFKm1vcYFmDaVZQ3CZ2-Df21J0UYLwjG0tzJEk8oLD638PRTtvHCSExacbeatfO5ivoNf1_XRSEik7Tu5I9rOoaADf21J0UYLwjG0tzJEk8oLD638PRTtvHCSExacbeatfO5ivoNf1_XRSEik7Tu5I9rOoaA
创建一个名称叫test-aggregation的clusterrolebinding,把clusterrole:test-aggregation授权给SA:default命名空间下 的test-aggregation
[root@k8s-master01 ~]# kubectl create clusterrolebinding test-aggregation --clusterrole=test-aggregation --serviceaccount=default:test-aggregation clusterrolebinding.rbac.authorization.k8s.io/test-aggregation created
登录测试,发现并没有权限,只能登录
创建b-ClusterRole,使其聚合a-ClusterRole
[root@k8s-master01 ~]# vim b-ClusterRole.yaml kind: ClusterRole apiVersion: rbac.authorization.k8s.io/v1 metadata: name: b-aggregation labels: rbac.example.com/aggregate-to-test-aggregation: "true" #标签,使其和a-ClusterRole一直才能聚合 # These rules will be added to the "monitoring" role. rules: - apiGroups: [""] resources: ["services", "endpoints", "pods","namespaces"] #分配权限,加上命名空间svc等权限 verbs: ["get", "list", "watch"] [root@k8s-master01 ~]# kubectl create -f b-ClusterRole.yaml # clusterrole.rbac.authorization.k8s.io/b-aggregation created
再次验证,发现可以查看命名空间和svc等监控
二.RBAC的实践
问题:
1.创建一个名为deployment-clusterrole的clusterrole
a)该clusterrole只允许创建Deployment、Daemonset、Statefulset的create操作
2.在名字为app-team1的namespace下创建一个名为cicd-token的serviceAccount,并且将上一步创建clusterrole的权限绑定到该serviceAccount
实操:
创建namespace和serviceAccount
[root@k8s-master01 ~]# kubectl create ns app-team1 namespace/app-team1 created [root@k8s-master01 ~]# kubectl create sa cicd-token -n app-team1 serviceaccount/cicd-token created
创建名为deployment-clusterrole的clusterrole
[root@k8s-master01 ~]# vim dp-clusterrole.yaml apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: # "namespace" omitted since ClusterRoles are not namespaced name: deployment-clusterrole rules: - apiGroups: ["extensions", "apps"] # 1.17以前要用extensions # at the HTTP level, the name of the resource for accessing Secret # objects is "secrets" resources: ["deployments","statefulsets","daemonsets"] verbs: ["create"] # 赋予"deployments","statefulsets","daemonsets"的创建权限 [root@k8s-master01 ~]# kubectl create -f dp-clusterrole.yaml [root@k8s-master01 ~]# kubectl get clusterrole deployment-clusterrole -oyaml | grep rule -A 7 #查看 ... rules: - apiGroups: - extensions - apps resources: - deployments - statefulsets - daemonsets
绑定权限并查看
[root@k8s-master01 ~]# kubectl create rolebinding deployment-rolebinding --clusterrole=deployment-clusterrole --serviceaccount=app-team1:cicd-token -n app-team1 [root@k8s-master01 ~]# kubectl get rolebindings.rbac.authorization.k8s.io -n app-team1 -oyaml #查看
编辑一份deployment模板
[root@k8s-master01 ~]# cat deployment-cicd-token.yaml apiVersion: apps/v1 kind: Deployment metadata: name: nginx namespace: app-team1 spec: progressDeadlineSeconds: 600 replicas: 1 revisionHistoryLimit: 10 selector: matchLabels: app: nginx strategy: rollingUpdate: maxSurge: 25% maxUnavailable: 25% type: RollingUpdate template: metadata: creationTimestamp: null labels: app: nginx spec: containers: - image: nginx imagePullPolicy: Always name: nginx resources: {} terminationMessagePath: /dev/termination-log terminationMessagePolicy: File - image: redis imagePullPolicy: Always name: redis restartPolicy: Always
验证:通过sa创建的secret的token登录dashboard,选择右上+,选择app-team1参试创建yaml,发下最终有权限创建。
[root@k8s-master01 ~]# kubectl get secrets -n app-team1 #查看secrets名称 NAME TYPE DATA AGE cicd-token-token-kmtcd kubernetes.io/service-account-token 3 34m default-token-sqnjn kubernetes.io/service-account-token 3 35m [root@k8s-master01 ~]# kubectl describe secrets cicd-token-token-kmtcd -n app-team1 #查看token ... Data ==== ca.crt: 1066 bytes namespace: 9 bytes token: eyJhbGciOiJSUzI1NiIsImtpZCI6IlVrWjJjSlVHM09qU1laUnJpM1ZJZEVONDF3M1hRRzVkNFRKdTFjTEZXODQifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJhcHAtdGVhbTEiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlY3JldC5uYW1lIjoiY2ljZC10b2tlbi10b2tlbi1rbXRjZCIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50Lm5hbWUiOiJjaWNkLXRva2VuIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQudWlkIjoiOWEzMDg0MjQtZWQ2OS00MjkwLWI4MjEtY2I5YzJlODQxN2Q4Iiwic3ViIjoic3lzdGVtOnNlcnZpY2VhY2NvdW50OmFwcC10ZWFtMTpjaWNkLXRva2VuIn0.hVYAuxRu_LZkbiDCp0Fw_J8_2DpEGD2Veh9dqG9hjhHBmItEcjU2WhKfy-9iQsyD-xunBmwf4cxZEkBp3k3_r4pgoancg5Yu-rTkgnsoTqZhKB36CDwq_W1P9ZHlQ9Qj2sh3Uf2VJx9B_5CWCqKfFyONKab8AYqhdeyj7GqgZmsVU1GBULpYmGkx9GbSd5wssuCy2UG7xwV3mRdAa6QKgx5tywx7cqtKGeWn-E2IoG4VdtgMzt-MmEtUMmurgCsK4lGuaDlK3Je2nGTAAl8uHK6SUspvhQG0m4fgLrpvtIuYFXlfnWFdINZqMcY3X3mu9Y794iaUMUz4a6iKljfcdw 通过token登录dashboard 最后查看deployment,已创建 [root@k8s-master01 ~]# kubectl get deployments.apps -n app-team1 -owide NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR nginx 0/1 0 0 2m35s nginx,redis nginx,redis app=nginx
三.RBAC企业实战
企业中的权限划分:
如上三图,我们可以用RBAC进行权限控制,但是在企业中有很多需求场景。
正常授权,配置会非常多,这边可以把通用的权限单独给一个ClusterRole,然后再对每个用户授权(上图二)
我们可以建立单独的命名空间,把SA用户专门放入里面,通用权限可以通过ClusterRoleBinding给此命名空间授权,然后此命名空间所有用户就有了通用的权限,部分单独的权限给单独的用户授权。
示例需求:
1.用户dotbalo可以查看default、kube-system下Pod的日志
2.用户dukuan可以在default下的Pod中执行命令,并且可以删除Pod
解答:
1.创建管理用户的命名空间kube-users
[root@k8s-master01 ~]# kubectl create ns kube-users namespace/kube-users created
2.根据需求先创建2个用户dotbalo,dukuan(sa,通过Sa创建的secret的token管理节点)
[root@k8s-master01 ~]# kubectl create sa dotablo -n kube-users serviceaccount/dotablo created [root@k8s-master01 ~]# kubectl create sa dukuan -n kube-users serviceaccount/dukuan created
3.根据需求总共有4中权限分别是只读命名空间,删除日志,执行pod命名,查看日志,然后创建4种权限的ClusterRole
[root@k8s-master01 ~]# vim namespace-readonly.yaml #只读查看命名空间权限 apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: namespace-readonly rules: - apiGroups: - "" resources: - namespaces verbs: - get - list - watch - apiGroups: - metrics.k8s.io resources: - pods verbs: - get - list - watch [root@k8s-master01 ~]# vim delete-pod.yaml #删除pod的权限 apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: pod-delete rules: - apiGroups: - "" resources: - pods verbs: - get - list - delete [root@k8s-master01 ~]# vim exec-pod.yaml #执行Pod的权限 apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: pod-exec rules: - apiGroups: - "" resources: - pods verbs: - get - list - apiGroups: - "" resources: - pods/exec verbs: - create [root@k8s-master01 ~]# vim log-pod.yaml #查看log日志的权限 apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: pod-log rules: - apiGroups: - "" resources: - pods - pods/log verbs: - get - list - watch [root@k8s-master01 ~]# kubectl create -f namespace-readonly.yaml #创建4种ClusterRole clusterrole.rbac.authorization.k8s.io/namespace-readonly created [root@k8s-master01 ~]# kubectl create -f delete-pod.yaml clusterrole.rbac.authorization.k8s.io/pod-delete created [root@k8s-master01 ~]# kubectl create -f log-pod.yaml clusterrole.rbac.authorization.k8s.io/pod-log created [root@k8s-master01 ~]# kubectl create -f exec-pod.yaml clusterrole.rbac.authorization.k8s.io/pod-exec created
4.绑定全局命名空间查看权限(clusterrolebinding)
kubectl create clusterrolebinding namespace-readonly --clusterrole=namespace-readonly --serviceaccount=system:serviceaccounts:kube-users
5.绑定用户dotbalo两个命名空间default、kube-system的查看pod日志的权限(rolebinding)
kubectl create rolebinding dotbalo-pod-log \ --clusterrole=pod-log --serviceaccount=kube-users:dotbalo --namespace=kube-system kubectl create rolebinding dotbalo-pod-log \ --clusterrole=pod-log --serviceaccount=kube-users:dotbalo --namespace=default
6.绑定用户dukuan在deefault中执行pod命令权限和删除Pod权限
kubectl create rolebinding dukuan-pod-exec \ --clusterrole=pod-exec --serviceaccount=kube-users:dukuan --namespace=default kubectl create rolebinding dukuan-pod-delete \ --clusterrole=pod-delete --serviceaccount=kube-users:dukuan --namespace=default