一、RBAC认证授权策略

官方中文参考连接:

在K8S中,所有资源对象都是通过API进行操作,他们保存在ETCD里面,而对ETCD的操作,我们需要通过访问kube-apiserver来实现,ServiceAccount其实就是apiserver的认证过程,而授权的机制是通过RBAC,基于角色的访问控制实现。

RBAC中有四个资源对象,分别是Role、ClusterRole、RoleBinding、ClusterRoleBinding

1、Role角色

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"]  # 授予那些权限

2、ClusterRole集群角色

ClusterRole是集群角色,跨名称空间,没有名称空间的限制

实例:定义一个ClusterRole赋予读取所有的Server的权限:

---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: clusterrole-svc
rules:
- apiGroups: [""]
  resources: ["services"]
  verbs: ["get", "watch" ,"list"]

3、RoleBinding角色绑定和ClusterRoleBinding集群角色绑定

角色绑定就是将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

二、通过API接口授权访问K8S资源

多数资源可以使用名称的字符串表示,也就是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

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kfztzsjj-1689423542870)(D:\MD归档文档\IMG\image-20230714195729341.png)]

curl --cacert ./ca.crt  -H "Authorization: Bearer $(cat ./token)" https://kubrnetes.default/api/v1/namespaces/default/pods/web-nginx-785b94bb7-x298h/log

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SFzUVequ-1689423542871)(D:\MD归档文档\IMG\image-20230714201922055.png)]

三、案例:常见授权策略

1、常见的角色授权策略案例

案例一:允许读取核心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"]

2、常见的角色绑定案例

案例一:绑定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

3、常见的ServiceAccount授权绑定案例

案例一:创建名为 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名称空间下的defaultSA绑定

注意:创建名称空间后,都会存在一个默认的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
Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐