官方中文参考连接:
在K8S中,所有资源对象都是通过API进行操作,他们保存在ETCD里面,而对ETCD的操作,我们需要通过访问kube-apiserver来实现,ServiceAccount其实就是apiserver的认证过程,而授权的机制是通过RBAC,基于角色的访问控制实现。
RBAC中有四个资源对象,分别是Role、ClusterRole、RoleBinding、ClusterRoleBinding
Role是一组权限的集合,在名称空间下定义的角色,只能对名称空间下进行资源授权。如果是集群级别的资源,可以使用clusterrole进行授权。
实例:定义一个Role赋予读取
default
名称空间下所有Pod的权限:
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: rbac-pod
namespace: default # 针对default名称空间下资源进行授权
rules:
- apiGroups: ['']
resources: ["pods"] # 针对那些资源做授权,这里是Pod资源
resourceNames: [] # 上面指定Pod资源,这里表示针对那些Pod资源做授权,空表示名称空间下所有Pod
verbs: ["get", "watch", "list"] # 授予那些权限
ClusterRole是集群角色,跨名称空间,没有名称空间的限制
实例:定义一个ClusterRole赋予读取
所有的Server的权限:
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: clusterrole-svc
rules:
- apiGroups: [""]
resources: ["services"]
verbs: ["get", "watch" ,"list"]
角色绑定就是将Role角色和一个目录进行绑定,可以User、Group、Server Account
使用RoleBinding有名称空间限制,只能绑定同一个名称空间的角色,使用ClusterRoleBinding没有名称空间限制,为集群范围内授权。
实例:创建RoleBinding绑定 default
名称空间下rbac-pod
角色授予给 qinzt
用户
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: rbac-pod-qinzt
namespace: default
subjects:
- kind: User
name: qinzt
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: rbac-pod
apiGroup: rbac.authorizatioin.k8s.io
RoleBinding也可以绑定ClusterRole,对属于同个命名空间的ClusterRole定义的资源主体进行授权,具体如下:
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: rbac-pod-qinzt
namespace: default
subjects:
- kind: User
name: qinzt
apiGroup: rbac.authorization.k8s.io
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: clusterrole-svc
多数资源可以使用名称的字符串表示,也就是endpoint中的URL相对路径,比如Pod中的日志是 GET /api/v1/namaspaces/{namespace}/pods/{podname}/log
,如果需要在一个RBAC对象中授权上下级资源,就需要使用 “/” 分割资源和上下级资源。
实例如下:
第一步:创建 test
名称空间:
kubectl create namespace test
第二步:创建 logs-reader
角色 赋予查看Pod权限
cat logs-reader.yaml
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: logs-reader
namespace: test
rules:
- apiGroups: [""]
resources: ["pods","pods/log"]
verbs: ["get","list","watch"]
kubectl apply -f logs-reader.yaml
kubectl get role -n test
第三步:创建 sa-test
服务账户
kubectl create sa sa-test -n test
第四步:创建sa-test-1
RoleBinding,将服务账户和角色绑定
kubectl create RoleBinding sa-test-1 -n test --role=logs-readr --serviceaccount=test:sa-test
第五步:创建Pod并使用 sa-test
服务账户
cat rbac-pod.yaml
---
apiVersion: v1
kind: Pod
metadata:
name: rbac-pod-demo
namespace: test
labels:
app: rbac
spec:
serviceAccount: sa-test
containers:
- name: rbac-pod-demo
image: nginx
imagePullPolicy: IfNotPresent
第六步:测试权限
kubectl exec -it rbac-pod-demo -n test -- /bin/bash
cd /var/run/secrets/kubernetes.io/serviceaccount
# 访问test名称空间下rbac-pod-demo Pod日志
curl --cacert ./ca.crt -H "Authorization: Bearer $(cat ./token)" https://kubernetes.default/api/v1/namespaces/test/pods/rbac-pod-demo/log
curl --cacert ./ca.crt -H "Authorization: Bearer $(cat ./token)" https://kubrnetes.default/api/v1/namespaces/default/pods/web-nginx-785b94bb7-x298h/log
案例一:允许读取核心API组的Pod资源
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get","list","watch"]
案例二:允许读写apps API组中的deployment资源
rules:
- apiGroups: ["apps"]
resources: ["deployments"]
verbs: ["get","list","watch","create","update","patch","delete"]
案例三:允许读取Pod以及读写job信息
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get","list","watch"]
- apiGroups: [""]
resources: ["jobs"]
verbs: ["get","list","watch","create","update","patch","delete"]
案例四:允许读取名为nginx.conf
的ConfigMap
注意:必须绑定到一个RoleBinding来限制到一个Namespace下的ConfigMap
rules:
- apiGroups: [""]
resources: ["configmaps"]
resourceNames: ["nginx.conf"]
verbs: ["get"]
案例五:允许读取核心组的Node资源
注意:Node属于集群级别的资源,必须使用ClusterRole进行授权,且必须使用ClusterRoleBinding进行绑定
rules:
- apiGroups: [""]
resources: ["nodes"]
verbs: ["get","list","watch"]
案例六:允许对非资源端点 “/healthz” 及所有子路径进行GET和POST操作
注意:必须使用ClusterRole和ClusterRoleBinding
rules:
- nonResourceURLs: ["/healthz","/healthz/*"]
verbs: ["get","post"]
案例一:绑定qinzt用户
subjects:
- kind: User
name: qinzt
apiGroup: rbac.authorization.k8s.io
案例二:绑定qinzt组
subjects:
- kind: Group
name: alice
apiGroup: rbac.authorization.k8s.io
案例三:绑定SA,kube-system名称空间下默认ServiceAccount
subjects:
- kind: ServiceAccount
name: default
namespace: kube-system
案例一:创建名为 t1
的RoleBinding将view
集群角色和my-namespace
名称空间下 的my-sa
SA绑定
kubectl create RoleBinding t1 --clusterrole=view --serviceaccount=my-namespace:my-sa --namespace=my-namespace
案例二:创建名为default-view
的RoleBinding将view
集群角色和my-namespace
名称空间下的default
SA绑定
注意:创建名称空间后,都会存在一个默认的SA账户,如果该名称空间下创建的资源没有指定SA,默认使用default
SA。
kubectl create RoleBinding default-view --clusterrole=view --serviceaccount=my-namespace:default --namespace=my-namespace
案例三:创建名为sa-view
的RoleBinding将view
集群角色和my-namespace
名称空间下system:serviceaccounts
群组进行绑定
注意:如果希望在一个名称空间下的所有serviceaccount都具有一个权限,则可以针对群组授权如下:
kubectl create RoleBinding sa-view --clusterrole=view --group=system:serviceaccounts:my-namespace --namespace=my-namespace
案例四:为集群范围内所有的serviceaccount都授予一个低权限角色
kubectl create clusterRoleBinding sa-view --clusterrole=view --group=system:serviceaccounts
案例五:为所有serviceaccount赋予一个超级用户权限
kubectl create clusterRoleBinding sa-view --clusterrole=cluster-admin --group=system:serviceaccounts