k8s RBAC 授权理论实践
当客户端发起API Server调用时,API Server内部要先进行用户认证,然后执行用户授权流程,即通过授权策略来决定一个API调用是否合法。对合法用户进行授权并且随后在用户访问时进行鉴权,是权限与安全系统的重要一环。简单地说,授权就是授予不同的用户不同的访问权限。API Server目前支持以下几种授权策略(通过API Server的启动参数“--authorization-mode”设置)。
◎ AlwaysDeny:表示拒绝所有请求,一般用于测试。
◎ AlwaysAllow:允许接收所有请求,如果集群不需要授权流程,则可以采用该策略,这也是Kubernetes的默认配置。
◎ ABAC(Attribute-Based Access Control):基于属性的访问控制,表示使用用户配置的授权规则对用户请求进行匹配和控制。
◎ Webhook:通过调用外部REST服务对用户进行授权。
◎ RBAC:Role-Based Access Control,基于角色的访问控制。
◎ Node:是一种专用模式,用于对kubelet发出的请求进行访问控制。
API Server在接收到请求后,会读取该请求中的数据,生成一个访问策略对象,如果在该请求中不带某些属性(如Namespace),则这些属性的值将根据属性类型的不同,设置不同的默认值(例如,为字符串类型的属性设置一个空字符串;为布尔类型的属性设置false;为数值类型的属性设置0)。然后将这个访问策略对象和授权策略文件中的所有访问策略对象逐条匹配,如果至少有一个策略对象被匹配,则该请求被鉴权通过,否则终止API调用流程,并返回客户端的错误调用码。
要使用RBAC授权模式,需要在API Server的启动参数中加上--authorization-mode=RBAC。
1. 用户授权
使用kubeconfig (https证书认证授权)1.1 管理员授权
创建证书请求文件
cat > kubectl-admin-csr.json <<EOF { "CN": "admin", # 用户名 "hosts": [], "key": { "algo": "rsa", "size": 2048 }, "names": [ { "C": "CN", "L": "ShangHai", "ST": "ShangHai", "O": "system:masters", # 所属组 "OU": "System" } ] } EOF
字段解释:
1. CN
(Common Name):通常表示证书的主体或用户标识。在 Kubernetes 中,这里用来标识用户的名称,即 admin
。
2. hosts:证书可用于的主机名或 IP 地址。为空时,表示证书不会绑定到特定主机名或 IP 地址。
key
-
描述:用于指定证书的密钥算法和密钥大小。
-
algo
- 值:
rsa
- 描述:密钥算法,选择使用 RSA 算法。
- 值:
-
size
- 值:
2048
- 描述:密钥的长度(位数)。2048 位是一个常见且安全的密钥长度。
- 值:
4.
names
-
描述:定义证书的附加信息,用于标识证书主体的各种属性。
-
子字段:
-
C
(Country)- 值:
CN
- 描述:国家代码,用于标识证书主体所属国家。
- 值:
-
L
(Locality)- 值:
ShangHai
- 描述:证书主体的所在地城市。
- 值:
-
ST
(State)- 值:
ShangHai
- 描述:证书主体所在的州或省份。
- 值:
-
O
(Organization)- 值:
system:masters
- 描述:组织名称。在 Kubernetes 中,
system:masters
是一个内置组,具有集群管理员权限。
- 值:
-
OU
(Organizational Unit)- 值:
System
- 描述:组织单位名称。该值通常不影响证书的功能,可自由定义。
- 值:
-
总结:当O字段为system:masters时,不需要给用户创建RBAC权限绑定,因为他已经被绑定到集群内置管理组。
如何论证system:master是k8s的管理员用户组呢?
[root@master-1 .kube]# kubectl get clusterrolebinding system:node-proxier ClusterRole/system:node-proxier 16d cluster-admin ClusterRole/cluster-admin 16d [root@master-1 .kube]# kubectl describe clusterrolebinding cluster-admin Name: cluster-admin Labels: kubernetes.io/bootstrapping=rbac-defaults Annotations: rbac.authorization.kubernetes.io/autoupdate: true Role: Kind: ClusterRole Name: cluster-admin Subjects: Kind Name Namespace ---- ---- --------- Group system:masters
同样,kube-proxy是绑定给了用户
{ "CN": "system:kube-proxy", "hosts": [], "key": { "algo": "rsa", "size": 2048 }, "names": [ { "C": "CN", "L": "ShangHai", "ST": "ShangHai", "O": "k8s", "OU": "System" } ] } [root@master-1 .kube]# kubectl describe clusterrolebinding system:node-proxier Name: system:node-proxier Labels: kubernetes.io/bootstrapping=rbac-defaults Annotations: rbac.authorization.kubernetes.io/autoupdate: true Role: Kind: ClusterRole Name: system:node-proxier Subjects: Kind Name Namespace ---- ---- --------- User system:kube-proxy # 查看权限 [root@master-1 .kube]# kubectl describe clusterrole system:node-proxier Name: system:node-proxier Labels: kubernetes.io/bootstrapping=rbac-defaults Annotations: rbac.authorization.kubernetes.io/autoupdate: true PolicyRule: Resources Non-Resource URLs Resource Names Verbs --------- ----------------- -------------- ----- events [] [] [create patch update] events.events.k8s.io [] [] [create patch update] nodes [] [] [get list watch] endpoints [] [] [list watch] services [] [] [list watch] endpointslices.discovery.k8s.io [] [] [list watch]
2. 普通用户授权
在 Kubernetes 中,为用户创建访问权限涉及以下几个步骤:
- 生成用户证书
{ "CN": "zhangsan", "hosts": [], "key": { "algo": "rsa", "size": 2048 }, "names": [ { "C": "CN", "L": "ShangHai", "ST": "ShangHai", "O": "dev-team", "OU": "dev" } ] }
- 2配置 Kubernetes 集群的 RBAC
[root@master-1 kubectl-rbac]# cat zhangsan-kubectl-rbac-clusterrole.yaml kind: ClusterRole apiVersion: rbac.authorization.k8s.io/v1 metadata: name: zhangsan-view-cluster rules: - apiGroups: [""] resources: ["*"] verbs: ["get", "list", "watch"] [root@master-1 kubectl-rbac]# cat zhangsan-kubectl-rbac-clusterrolebinding.yaml kind: ClusterRoleBinding apiVersion: rbac.authorization.k8s.io/v1 metadata: name: dev-team-zs-rolebinding subjects: - kind: User name: zhangsan #namespace: default #apiGroup: rbac.authorization.k8s.io roleRef: kind: ClusterRole name: zhangsan-view-cluster apiGroup: rbac.authorization.k8s.io
- 创建用户 kubeconfig 文件
KUBE_CONFIG="/root/.kube/config-zs" KUBE_APISERVER="https://192.168.43.129:6443" # 设置集群 kubectl config set-cluster kubernetes \ --certificate-authority=/opt/tls/k8s/ca.pem \ --embed-certs=true \ # 将证书导入到配置文件 --server=${KUBE_APISERVER} \ # 集群地址 --kubeconfig=${KUBE_CONFIG}
# 设置用户证书 kubectl config set-credentials zhangsan \ --client-certificate=/opt/tls/k8s/kubectl-zhangsan.pem \ --client-key=/opt/tls/k8s/kubectl-zhangsan-key.pem \ --embed-certs=true \ --kubeconfig=${KUBE_CONFIG}
# 设置集群与用户关联的上下文 kubectl config set-context zhangsan \ --cluster=kubernetes \ --user=zhangsan \ --kubeconfig=${KUBE_CONFIG} # 切换使用上下文 kubectl config use-context zhangsan --kubeconfig=${KUBE_CONFIG}
如果创建的用户属于同一个用户组
cat ../kubectl-zhangsan-csr.json { "CN": "zhangsan", "hosts": [], "key": { "algo": "rsa", "size": 2048 }, "names": [ { "C": "CN", "L": "ShangHai", "ST": "ShangHai", "O": "system:rentao", "OU": "dev" } ] }
直接创建用户的kubeconfig即可,因为之前已经对用户组进行了授权。
2. 普通组授权
2.1 创建普通用户的kubeconfig
[root@master-1 kubectl-rbac]# cat /opt/tls/k8s/kubectl-admin-csr.json { "CN": "lisi", "hosts": [], "key": { "algo": "rsa", "size": 2048 }, "names": [ { "C": "CN", "L": "ShangHai", "ST": "ShangHai", "O": "dev", "OU": "System" } ] }
2.2 创建证书及生成kubeconfig
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes lisi-csr.json | cfssljson -bare lisi KUBE_CONFIG="/root/.kube/config" KUBE_APISERVER="https://192.168.43.129:6443" kubectl config set-cluster kubernetes \ --certificate-authority=/opt/tls/k8s/ca.pem \ --embed-certs=true \ --server=${KUBE_APISERVER} \ --kubeconfig=${KUBE_CONFIG} kubectl config set-credentials lisi \ --client-certificate=/opt/tls/k8s/kubectl-admin.pem \ --client-key=/opt/tls/k8s/kubectl-admin-key.pem \ --embed-certs=true \ --kubeconfig=${KUBE_CONFIG} kubectl config set-context default \ --cluster=kubernetes \ --user=lisi \ --kubeconfig=${KUBE_CONFIG} kubectl config use-context default --kubeconfig=${KUBE_CONFIG}
2.3 创建rbac,将用户绑定到普通用户组
[root@master-1 kubectl-rbac]# cat kubectl-rbac.yaml kind: ClusterRoleBinding apiVersion: rbac.authorization.k8s.io/v1 metadata: name: dev-team-rolebinding subjects: - kind: Group # 类型为组 name: dev # 用户组名称,需要全部对应 #namespace: default #apiGroup: rbac.authorization.k8s.io roleRef: kind: ClusterRole # 权限类型为集群 name: view # 内置权限,只有全局查看权限 apiGroup: rbac.authorization.k8s.io
执行
[root@master-1 kubectl-rbac]# kubectl apply -f kubectl-rbac.yaml clusterrolebinding.rbac.authorization.k8s.io/dev-team-rolebinding created
2.4 切换到lisi用户的上下文
kubectl config use lisi
2.5 测试权限
删除pod
[root@master-1 kubectl-rbac]# kubectl delete pod busybox Error from server (Forbidden): pods "busybox" is forbidden: User "lisi" cannot delete resource "pods" in API group "" in the namespace "defau
创建rbac资源
[root@master-1 prometheus-k8s]# kubectl apply -f rbac.yaml serviceaccount/prometheus unchanged Error from server (Forbidden): error when retrieving current configuration of: Resource: "rbac.authorization.k8s.io/v1, Resource=clusterroles", GroupVersionKind: "rbac.authorization.k8s.io/v1, Kind=ClusterRole" Name: "prometheus", Namespace: "" from server for: "rbac.yaml": clusterroles.rbac.authorization.k8s.io "prometheus" is forbidden: User "lisi" cannot get resource "clusterroles" in API grou.authorization.k8s.io" at the cluster scope Error from server (Forbidden): error when retrieving current configuration of: Resource: "rbac.authorization.k8s.io/v1, Resource=clusterrolebindings", GroupVersionKind: "rbac.authorization.k8s.io/v1, Kind=ClusterRoleBinding" Name: "prometheus", Namespace: "" from server for: "rbac.yaml": clusterrolebindings.rbac.authorization.k8s.io "prometheus" is forbidden: User "lisi" cannot get resource "clusterrolebindingPI group "rbac.authorization.k8s.io" at the cluster scope
[root@master-1 prometheus-k8s]# kubectl apply -f prometheus-deployment.yaml Error from server (Forbidden): error when creating "prometheus-deployment.yaml": deployments.apps is forbidden: User "lisi" cannot create resource "deployin API group "apps" in the namespace "monitor" Error from server (Forbidden): error when creating "prometheus-deployment.yaml": services is forbidden: User "lisi" cannot create resource "services" in Ap "" in the namespace "monitor"
查看pod
[root@master-1 kubectl-rbac]# kubectl get pod -A NAMESPACE NAME READY STATUS RESTARTS AGE default busybox 1/1 Running 0 89s default ingressclass-ingress-nginx-controller-p22gm 1/1 Running 17 14d default ingressclass-ingress-nginx-controller-t5wz9 1/1 Running 17 14d default ingressclass-ingress-nginx-controller-tt7wg 1/1 Running 18 14d default nfs-client-provisioner-7d4f48bb8f-zbhfd 1/1 Running 18 14d kube-system calico-kube-controllers-7775799c8c-6x766 1/1 Running 18 14d kube-system calico-kube-controllers-7775799c8c-75bsz 1/1 Running 18 14d kube-system calico-kube-controllers-7775799c8c-gss8z 1/1 Running 19 14d kube-system calico-node-cczr6 1/1 Running 18 14d kube-system calico-node-k89f9 1/1 Running 19 14d kube-system calico-node-w4xgb 1/1 Running 18 14d kube-system calico-typha-5dc577d877-ht7rq 1/1 Running 19 14d kube-system coredns-6bd54f798b-4khqv 1/1 Running 9 7d3h kube-system coredns-6bd54f798b-574qp 1/1 Running 9 7d3h kube-system metrics-server-5bbd7cb4c6-hv8kj 1/1 Running 18 14d staticpod static-web-master-1 1/1 Running 15 10d
修改权限
kind: ClusterRoleBinding apiVersion: rbac.authorization.k8s.io/v1 metadata: name: dev-team-rolebinding subjects: - kind: Group name: dev #namespace: default #apiGroup: rbac.authorization.k8s.io roleRef: kind: ClusterRole name: cluster-admin apiGroup: rbac.authorization.k8s.io
执行,报错
The ClusterRoleBinding "dev-team-rolebinding" is invalid: roleRef: Invalid value: rbac.RoleRef{APIGroup:"rbac.authorization.k8s.io", Kind:"ClusterRole", Name:"cluster-admin"}: cannot change roleRef
原因:出现错误 cannot change roleRef
是因为 Kubernetes 中的 RoleRef
字段是不可变的。一旦创建了 ClusterRoleBinding
或 RoleBinding
,其 roleRef
字段就无法被修改。如果需要更改角色绑定到的角色,必须删除原有的绑定并重新创建一个新的绑定。
2. ServiceAccount (Token认证授权)
2.1 默认secret
每个命名空间下都会有一个default的secret,当权限不满足当前需求时,可以创建一个SA,然后创建一系列的role与clusterrole,然后使用rolebinding与clusterrolebinding与S绑定,然后在创建pod时指定该SA,该SA就会挂载到容器内部的/var/run/secrets/kubernetes.io/serviceaccount/目录下。
[root@master-1 yml]# kubectl get secret -A | grep admin-user kubernetes-dashboard admin-user-token-p57w4 kubernetes.io/service-account-token 3 57s [root@master-1 yml]# kubectl describe secret -n kubernetes-dashboard admin-user-token-p57w4 Name: admin-user-token-p57w4 Namespace: kubernetes-dashboard Labels: <none> Annotations: kubernetes.io/service-account.name: admin-user kubernetes.io/service-account.uid: b20ee7cb-cc60-4750-be86-916c99b292ef Type: kubernetes.io/service-account-token Data ==== ca.crt: 1326 bytes namespace: 20 bytes token: eyJhbGciOiJSUzI1NiIsIcTc4dUEifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3N...
2.2 制作kubeconfig的两种方式
DASHBOARD_TOKEN=eyJhbGciOiJSUzI1NdF83Z3oNscTc4dUEifQ.eyJpc3MiOiJrdW... # echo $DASHBOARD_TOKEN # Token认证方式 kubectl config set-cluster kubernetes --certificate-authority=/opt/kubernetes/ssl/ca.pem --server="https://192.168.0.190:8443" --embed-certs=true --kubeconfig=/opt/kubernetes/dashboard/dashboard.config kubectl config set-credentials dashboard-admin --token=$DASHBOARD_TOKEN --kubeconfig=./dashboard.config kubectl config set-context dashboard-admin@kubernetes --cluster=kubernetes --user=dashboard-admin --kubeconfig=./dashboard.config kubectl config use-context dashboard-admin@kubernetes --kubeconfig=./dashboard.config ---------------------------------------------------------- 证书认证方式 kubectl config set-cluster kubernetes \ --certificate-authority=/opt/kubernetes/ssl/ca.pem \ --embed-certs=true \ --server=${KUBE_APISERVER} \ --kubeconfig=${KUBE_CONFIG} kubectl config set-credentials cluster-admin \ # 用户名 --client-certificate=/opt/kubernetes/ssl/kubectl-admin.pem \ --client-key=/opt/kubernetes/ssl/kubectl-admin-key.pem \ --embed-certs=true \ --kubeconfig=${KUBE_CONFIG} kubectl config set-context default \ --cluster=kubernetes \ # --namespace=xxx # 限制某个命名空间的权限 --user=cluster-admin \ --kubeconfig=${KUBE_CONFIG} kubectl config use-context default --kubeconfig=${KUBE_CONFIG}
2.3 查看容器内部挂载的SA
spec: serviceAccountName: kubernetes-dashboard containers: - name: kubernetes-dashboard image: xxx/k8s/dashboard:v2.1.0 imagePullPolicy: IfNotPresent
2.4 查看创建的SA
[root@master-1 dashboard]# kubectl get secret -n kubernetes-dashboard NAME TYPE DATA AGE default-token-mrr2s kubernetes.io/service-account-token 3 73s kubernetes-dashboard-certs Opaque 0 73s kubernetes-dashboard-csrf Opaque 1 72s kubernetes-dashboard-key-holder Opaque 2 72s kubernetes-dashboard-token-6r4nl kubernetes.io/service-account-token 3 73s
2.5 查看SA关联的secret
[root@master-1 dashboard]# kubectl describe secret -n kubernetes-dashboard kubernetes-dashboard-token-6r4nl Name: kubernetes-dashboard-token-6r4nl Namespace: kubernetes-dashboard Labels: <none> Annotations: kubernetes.io/service-account.name: kubernetes-dashboard kubernetes.io/service-account.uid: 4bd529b2-c313-4dc5-9d4d-9ab723c2e8af Type: kubernetes.io/service-account-token Data ==== ca.crt: 1326 bytes namespace: 20 bytes token: eyJhbGciOiJSUzI1NiIsImtpZCI6InBKV3FGbERnYVltWHA3XzRRQy1OSWRia1NIZW5FSE5QLXZoX0hCUjQ0NVkifQ...
这个SA挂载到pod容器内部,容器就赋予了相应的权限。
2.6 示例
2.6.1 以dashboard为例,我们查看下权限创建清单
apiVersion: v1 kind: ServiceAccount metadata: labels: k8s-app: kubernetes-dashboard name: kubernetes-dashboard namespace: kubernetes-dashboard --- kind: Role apiVersion: rbac.authorization.k8s.io/v1 metadata: labels: k8s-app: kubernetes-dashboard name: kubernetes-dashboard namespace: kubernetes-dashboard rules: - apiGroups: [""] resources: ["secrets"] resourceNames: ["kubernetes-dashboard-key-holder", "kubernetes-dashboard-certs", "kubernetes-dashboard-csrf"] verbs: ["get", "update", "delete"] - apiGroups: [""] resources: ["configmaps"] resourceNames: ["kubernetes-dashboard-settings"] verbs: ["get", "update"] - apiGroups: [""] resources: ["services"] resourceNames: ["heapster", "dashboard-metrics-scraper"] verbs: ["proxy"] - apiGroups: [""] resources: ["services/proxy"] resourceNames: ["heapster", "http:heapster:", "https:heapster:", "dashboard-metrics-scraper", "http:dashboard-metrics-scraper"] verbs: ["get"] --- kind: ClusterRole apiVersion: rbac.authorization.k8s.io/v1 metadata: labels: k8s-app: kubernetes-dashboard name: kubernetes-dashboard rules: # Allow Metrics Scraper to get metrics from the Metrics server - apiGroups: ["metrics.k8s.io"] resources: ["pods", "nodes"] verbs: ["get", "list", "watch"] --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: labels: k8s-app: kubernetes-dashboard name: kubernetes-dashboard namespace: kubernetes-dashboard roleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: kubernetes-dashboard subjects: - kind: ServiceAccount name: kubernetes-dashboard namespace: kubernetes-dashboard --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: kubernetes-dashboard roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: kubernetes-dashboard subjects: - kind: ServiceAccount name: kubernetes-dashboard namespace: kubernetes-dashboard
2.6.2 关于resourceNames: [] 解释:
resourceNames
指定了资源的具体名称,用于限制权限仅适用于某些特定资源。
resourceNames
的含义
- 资源名称限制:
resourceNames
表示权限仅适用于resources
中列出的特定资源的名称。 - 目标资源:在这个配置中,权限仅适用于以下三个
Secret
:kubernetes-dashboard-key-holder
kubernetes-dashboard-certs
kubernetes-dashboard-csrf
Secret
。
[root@master-1 dashboard]# kubectl get secret -n kubernetes-dashboard NAME TYPE DATA AGE default-token-mrr2s kubernetes.io/service-account-token 3 23h kubernetes-dashboard-certs Opaque 0 23h kubernetes-dashboard-csrf Opaque 1 23h kubernetes-dashboard-key-holder Opaque 2 23h kubernetes-dashboard-read-token-9w5r9 kubernetes.io/service-account-token 3 20h kubernetes-dashboard-token-6r4nl kubernetes.io/service-account-token 3 23h [root@master-1 dashboard]# kubectl get configmap -n kubernetes-dashboard NAME DATA AGE kube-root-ca.crt 1 23h kubernetes-dashboard-settings 0 23h [root@master-1 dashboard]# kubectl get svc -n kubernetes-dashboard NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE dashboard-metrics-scraper ClusterIP 10.0.103.140 <none> 8000/TCP 23h kubernetes-dashboard NodePort 10.0.14.33 <none> 443:38778/TCP 23h
rules: - apiGroups: [""] resources: ["pods"] resourceNames: ["specific-pod"] verbs: ["list", "watch"] # 不支持
2.6.3 ClusterRole
配置 resourceNames示例:
下面的集群角色和角色绑定能让user-1为其他用户在user-1-namespace命名空间中授予admin、edit及view角色:
apiVersion:rbac.authorization.k8s.io/v1 kind:ClusterRole metadata: name:role-grantor rules : - apiGroups:["rbac.authorization.k8s.io"] resources:["rolebindings"] verbs:["create" ] - apiGroups: ["rbac.authorization.k8s.io"] resources:["clusterroles"] verbs:["bind"] resourceNames:["admin","edit","view"] --- kind: RoleBinding metadata: name: role-grantor-binding namespace: user-1-namecpace roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: role-grantor subjects: - apiGroup: rbac.authorization.k8s.io kind: User name: user-1
创建完成后切换到用户查看授权资源与权限
[root@master-1 .kube]# kubectl auth can-i --list -n kube-system Resources Non-Resource URLs Resource Names Verbs clusterroles.rbac.authorization.k8s.io [] [admin] [bind] clusterroles.rbac.authorization.k8s.io [] [edit] [bind] clusterroles.rbac.authorization.k8s.io [] [view] [bind] selfsubjectaccessreviews.authorization.k8s.io [] [] [create] selfsubjectrulesreviews.authorization.k8s.io [] [] [create] rolebindings.rbac.authorization.k8s.io [] [] [create] [/api/*] [] [get] [/api] [] [get] [/apis/*] [] [get] [/apis] [] [get] [/healthz] [] [get] [/healthz] [] [get] [/livez] [] [get] [/livez] [] [get] [/openapi/*] [] [get] [/openapi] [] [get] [/readyz] [] [get] [/readyz] [] [get] [/version/] [] [get] [/version/] [] [get] [/version] [] [get] [/version] [] [get]
可以看到,clusterrole 配置了resourceNames,clusterrole是集群范围的权限,不受限于namespace。
优点:
1. 通过rolebinding绑定到某一个namespace,实现权限降级
2. 只需要创建一次,而不需要在每一个namespace创建一个role与rolebinding与user/group/sa绑定。
3. 如果要使用clusterrole 创建权限,多个namespace的用户引用,一般来说需要设置一些集群类型的资源,而不是资源类型的资源,可以理解设置一下非namespace类型的资源对象。
查看集群API资源
属于namecpace的资源
[root@master-1 clash]# kubectl api-resources --namespaced=true NAME SHORTNAMES APIVERSION NAMESPACED KIND bindings v1 true Binding configmaps cm v1 true ConfigMap endpoints ep v1 true Endpoints events ev v1 true Event limitranges limits v1 true LimitRange persistentvolumeclaims pvc v1 true PersistentVolumeClaim pods po v1 true Pod podtemplates v1 true PodTemplate replicationcontrollers rc v1 true ReplicationController resourcequotas quota v1 true ResourceQuota secrets v1 true Secret serviceaccounts sa v1 true ServiceAccount services svc v1 true Service controllerrevisions apps/v1 true ControllerRevision daemonsets ds apps/v1 true DaemonSet deployments deploy apps/v1 true Deployment replicasets rs apps/v1 true ReplicaSet statefulsets sts apps/v1 true StatefulSet localsubjectaccessreviews authorization.k8s.io/v1 true LocalSubjectAccessReview horizontalpodautoscalers hpa autoscaling/v1 true HorizontalPodAutoscaler cronjobs cj batch/v1beta1 true CronJob jobs batch/v1 true Job leases coordination.k8s.io/v1 true Lease networkpolicies crd.projectcalico.org/v1 true NetworkPolicy networksets crd.projectcalico.org/v1 true NetworkSet endpointslices discovery.k8s.io/v1beta1 true EndpointSlice events ev events.k8s.io/v1 true Event ingresses ing extensions/v1beta1 true Ingress pods metrics.k8s.io/v1beta1 true PodMetrics ingresses ing networking.k8s.io/v1 true Ingress networkpolicies netpol networking.k8s.io/v1 true NetworkPolicy poddisruptionbudgets pdb policy/v1beta1 true PodDisruptionBudget rolebindings rbac.authorization.k8s.io/v1 true RoleBinding roles rbac.authorization.k8s.io/v1 true Role
集群范围的资源
[root@master-1 clash]# kubectl api-resources --namespaced=false NAME SHORTNAMES APIVERSION NAMESPACED KIND componentstatuses cs v1 false ComponentStatus namespaces ns v1 false Namespace nodes no v1 false Node persistentvolumes pv v1 false PersistentVolume mutatingwebhookconfigurations admissionregistration.k8s.io/v1 false MutatingWebhookConfiguration validatingwebhookconfigurations admissionregistration.k8s.io/v1 false ValidatingWebhookConfiguration customresourcedefinitions crd,crds apiextensions.k8s.io/v1 false CustomResourceDefinition apiservices apiregistration.k8s.io/v1 false APIService tokenreviews authentication.k8s.io/v1 false TokenReview selfsubjectaccessreviews authorization.k8s.io/v1 false SelfSubjectAccessReview selfsubjectrulesreviews authorization.k8s.io/v1 false SelfSubjectRulesReview subjectaccessreviews authorization.k8s.io/v1 false SubjectAccessReview certificatesigningrequests csr certificates.k8s.io/v1 false CertificateSigningRequest bgpconfigurations crd.projectcalico.org/v1 false BGPConfiguration bgppeers crd.projectcalico.org/v1 false BGPPeer blockaffinities crd.projectcalico.org/v1 false BlockAffinity clusterinformations crd.projectcalico.org/v1 false ClusterInformation felixconfigurations crd.projectcalico.org/v1 false FelixConfiguration globalnetworkpolicies crd.projectcalico.org/v1 false GlobalNetworkPolicy globalnetworksets crd.projectcalico.org/v1 false GlobalNetworkSet hostendpoints crd.projectcalico.org/v1 false HostEndpoint ipamblocks crd.projectcalico.org/v1 false IPAMBlock ipamconfigs crd.projectcalico.org/v1 false IPAMConfig ipamhandles crd.projectcalico.org/v1 false IPAMHandle ippools crd.projectcalico.org/v1 false IPPool kubecontrollersconfigurations crd.projectcalico.org/v1 false KubeControllersConfiguration flowschemas flowcontrol.apiserver.k8s.io/v1beta1 false FlowSchema prioritylevelconfigurations flowcontrol.apiserver.k8s.io/v1beta1 false PriorityLevelConfiguration nodes metrics.k8s.io/v1beta1 false NodeMetrics ingressclasses networking.k8s.io/v1 false IngressClass runtimeclasses node.k8s.io/v1 false RuntimeClass podsecuritypolicies psp policy/v1beta1 false PodSecurityPolicy clusterrolebindings rbac.authorization.k8s.io/v1 false ClusterRoleBinding clusterroles rbac.authorization.k8s.io/v1 false ClusterRole priorityclasses pc scheduling.k8s.io/v1 false PriorityClass csidrivers storage.k8s.io/v1 false CSIDriver csinodes storage.k8s.io/v1 false CSINode storageclasses sc storage.k8s.io/v1 false StorageClass volumeattachments storage.k8s.io/v1 false VolumeAttachment
2.7 权限降级
RoleBinding也可以引用ClusterRole,对属于同一命名空间内ClusterRole定义的资源主体进行授权。一种常见的做法是集群管理员为集群范围预先定义好一组ClusterRole,然后在多个命名空间中重复使用这些ClusterRole。
2.7.1 绑定用户
例如,在下面的例子中,虽然read-only-cluster-role是一个集群角色,但是因为使用了RoleBinding,所以zhangsan只能读取kubernetes-dashboard命名空间中的资源:
apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: read-only-cluster-role rules: - apiGroups: [""] resources: ["*"] verbs: ["get", "list", "watch", "create", "update", "patch"] - apiGroups: ["apps", "batch", "extensions", "networking.k8s.io", "policy", "rbac.authorization.k8s.io", "storage.k8s.io", "autoscaling"] resources: ["*"] verbs: ["get", "list", "watch", "create", "update", "patch"] --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: dashboard-test-rolebinding namespace: kubernetes-dashboard roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: read-only-cluster-role subjects: - kind: User name: zhangsan apiGroup: rbac.authorization.k8s.io
注意:如果rolebinding的metadata.namecpace未指定,则默认授权的是default命名空间。
测试权限
切换到张三的kubeconfig
mv config config-a
mv config-zs config
获取资源
[root@master-1 .kube]# kubectl get svc,secret Error from server (Forbidden): services is forbidden: User "zhangsan" cannot list resource "services" in API group "" in the namespace "default" Error from server (Forbidden): secrets is forbidden: User "zhangsan" cannot list resource "secrets" in API group "" in the namespace "default"
获取授权的命名空间资源
[root@master-1 .kube]# kubectl get svc -n kubernetes-dashboard NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE dashboard-metrics-scraper ClusterIP 10.0.103.140 <none> 8000/TCP 28h kubernetes-dashboard NodePort 10.0.14.33 <none> 443:38778/TCP 28h [root@master-1 .kube]# [root@master-1 .kube]# kubectl get svc,pod,cm,deploy,secret -n kubernetes-dashboard NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/dashboard-metrics-scraper ClusterIP 10.0.103.140 <none> 8000/TCP 28h service/kubernetes-dashboard NodePort 10.0.14.33 <none> 443:38778/TCP 28h NAME READY STATUS RESTARTS AGE pod/dashboard-metrics-scraper-6c68887d4f-zgljm 1/1 Running 3 28h pod/kubernetes-dashboard-6fb98955f6-swdf4 1/1 Running 3 28h NAME DATA AGE configmap/kube-root-ca.crt 1 28h configmap/kubernetes-dashboard-settings 0 28h NAME READY UP-TO-DATE AVAILABLE AGE deployment.apps/dashboard-metrics-scraper 1/1 1 1 28h deployment.apps/kubernetes-dashboard 1/1 1 1 28h NAME TYPE DATA AGE secret/dashboard-test-sa-token-x4bzx kubernetes.io/service-account-token 3 6m14s secret/default-token-mrr2s kubernetes.io/service-account-token 3 28h secret/kubernetes-dashboard-certs Opaque 0 28h secret/kubernetes-dashboard-csrf Opaque 1 28h secret/kubernetes-dashboard-key-holder Opaque 2 28h secret/kubernetes-dashboard-read-token-9w5r9 kubernetes.io/service-account-token 3 25h secret/kubernetes-dashboard-token-6r4nl kubernetes.io/service-account-token 3 28h
2.7.2 绑定SA
apiVersion: v1 kind: ServiceAccount metadata: name: test-read namespace: kube-system --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: read-only-cluster-role rules: - apiGroups: [""] resources: ["*"] verbs: ["get", "list", "watch", "create", "update", "patch"] - apiGroups: ["apps", "batch", "extensions", "networking.k8s.io", "policy", "rbac.authorization.k8s.io", "storage.k8s.io", "autoscaling"] resources: ["*"] verbs: ["get", "list", "watch", "create", "update", "patch"] --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: read-only-rolebinding namespace: kube-system roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: read-only-cluster-role subjects: - kind: ServiceAccount name: test-read namespace: kube-system
创建sa的上下文
[root@master-1 dashboard]# kubectl describe secret test-read-token-fcmbb -n kube-system Name: test-read-token-fcmbb Namespace: kube-system Labels: <none> Annotations: kubernetes.io/service-account.name: test-read kubernetes.io/service-account.uid: 16787adf-6811-4df8-8c62-85d5a19d6958 Type: kubernetes.io/service-account-token Data ==== namespace: 11 bytes token: eyJhbGciOiJSUzI1NiIs7JZg_O3nI68o55OfYvK_urzFEPzIeQzCKzHjXn9Ssfw5gQ1R9CuQXNGH0PCPKkCsLCRJBVb7bHIsdxkzL9A ca.crt: 1326 bytes [root@master-1 dashboard]# READ_TOKEN=eyJhbGciOiJSUzI1NiIsImtpZCIRia1NIZW56HWRKe3Mw5gQ1R9CuQXNGH0PCPKkCsLCRXz7dskL9A [root@master-1 dashboard]# echo $READ_TOKEN eyJhbGciOiJSUzI1NiIsImtpZCI6InBKV3FGbERnYVltWHA3XzRRQy1OSWRia1NIZW5FSE5lcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRl
kubectl config set-cluster kubernetes --certificate-authority=/opt/tls/k8s/ca.pem --server="https://192.168.43.129:6443" kubectl config set-credentials system-read --token=$READ_TOKEN kubectl config set-context system-read-context --cluster=kubernetes --user=system-read kubectl config use-context system-read-context
查看权限
]# kubectl get pod Error from server (Forbidden): pods is forbidden: User "system:serviceaccount:kube-system:test-read" cannot list resource "pods" in API group "" in the namespace "default" ]# kubectl get pod -n kube-system NAME READY STATUS RESTARTS AGE calico-kube-controllers-7775799c8c-2xjvh 1/1 Running 16 9d calico-kube-controllers-7775799c8c-48w8h 1/1 Running 15 9d calico-kube-controllers-7775799c8c-gss8z 1/1 Running 70 39d calico-node-cczr6 1/1 Running 60 39d calico-node-k89f9 1/1 Running 60 39d calico-node-nk8qv 1/1 Running 2 3d19h calico-node-w4xgb 1/1 Running 62 39d calico-typha-5dc577d877-ht7rq 1/1 Running 60 39d coredns-6bd54f798b-7fl28 1/1 Running 15 9d coredns-6bd54f798b-r5gkr 1/1 Running 16 9d metrics-server-5bbd7cb4c6-kkdct 1/1 Running 15 9d ]# kubectl auth can-i --list -n kube-system Resources Non-Resource URLs Resource Names Verbs selfsubjectaccessreviews.authorization.k8s.io [] [] [create] selfsubjectrulesreviews.authorization.k8s.io [] [] [create] * [] [] [get list watch create update patch] *.apps [] [] [get list watch create update patch] *.autoscaling [] [] [get list watch create update patch] *.batch [] [] [get list watch create update patch] *.extensions [] [] [get list watch create update patch] *.networking.k8s.io [] [] [get list watch create update patch] *.policy [] [] [get list watch create update patch] *.rbac.authorization.k8s.io [] [] [get list watch create update patch] *.storage.k8s.io [] [] [get list watch create update patch] [/.well-known/openid-configuration] [] [get] [/api/*] [] [get] [/api] [] [get] [/apis/*] [] [get] [/apis] [] [get] [/healthz] [] [get] [/healthz] [] [get] [/livez] [] [get] [/livez] [] [get] [/openapi/*] [] [get] [/openapi] [] [get] [/openid/v1/jwks] [] [get] [/readyz] [] [get] [/readyz] [] [get] [/version/] [] [get] [/version/] [] [get] [/version] [] [get] [/version] [] [get]
对某个命名空间下所有的sa授权
所有Service Account