什么是RBAC?
基于角色的访问控制,广泛使用于各种计算机系统
怎么在k8s中使用RBAC?
apiserver启动时增加 --authorization-mode=RBAC参数,kubeadm创建的集群缺省添加有此参数
kube-apiserver --advertise-address=192.168.3.101 --allow-privileged=true --authorization-mode=Node,RBAC --client-ca-file=/etc/kubernetes/pki/ca.crt --enable-admission-plugins=NodeRestriction --enable-bootstrap-token-auth=true --etcd-cafile=/etc/kubernetes/pki/etcd/ca.crt --etcd-certfile=/etc/kubernetes/pki/apiserver-etcd-client.crt --etcd-keyfile=/etc/kubernetes/pki/apiserver-etcd-client.key --etcd-servers=https://192.168.3.101:2379,https://192.168.3.102:2379,https://192.168.3.103:2379 --insecure-port=0 --kubelet-client-certificate=/etc/kubernetes/pki/apiserver-kubelet-client.crt --kubelet-client-key=/etc/kubernetes/pki/apiserver-kubelet-client.key --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname --proxy-client-cert-file=/etc/kubernetes/pki/front-proxy-client.crt --proxy-client-key-file=/etc/kubernetes/pki/front-proxy-client.key --requestheader-allowed-names=front-proxy-client --requestheader-client-ca-file=/etc/kubernetes/pki/front-proxy-ca.crt --requestheader-extra-headers-prefix=X-Remote-Extra- --requestheader-group-headers=X-Remote-Group --requestheader-username-headers=X-Remote-User --secure-port=6443 --service-account-key-file=/etc/kubernetes/pki/sa.pub --service-cluster-ip-range=10.96.0.0/12 --tls-cert-file=/etc/kubernetes/pki/apiserver.crt --tls-private-key-file=/etc/kubernetes/pki/apiserver.key
Role和ClusterRole
Role是命名空间内权限的集合
ClusterRole是集群权限的集合,包含命名空间内的权限和其他集群权限
以下是一个Role的例子,Role pod-reader在namespace default中具有get/watch/list pods的权限
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: default
name: pod-reader
rules:
- apiGroups: [""] # ""表示核心api group
resources: ["pods"]
verbs: ["get", "watch", "list"]
以下是一个ClusterRole的例子,ClusterRole secret-reader在所有namespace中具有get/watch/list secrets的权限
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: secret-reader
rules:
- apiGroups: [""]
resources: ["secrets"]
verbs: ["get", "watch", "list"]
Aggregated ClusterRoles
Aggregated ClusterRoles可以将多个ClusterRoles的权限结合到一起,采用的是标签选择器的方式
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: monitoring
aggregationRule:
clusterRoleSelectors:
- matchLabels:
rbac.example.com/aggregate-to-monitoring: "true"
rules: [] # 由controller manager自动填写
权限
权限体现在api URL中针对各种资源的verbs。有一些资源拥有子资源,例如pod,拥有子资源log.
GET /api/v1/namespaces/{namespace}/pods/{name}/log
Role需要子资源的权限,也需要在resources中声明
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: default
name: pod-and-pod-logs-reader
rules:
- apiGroups: [""]
resources: ["pods", "pods/log"]
verbs: ["get", "list"]
也可以使用resourceNames限制到具体的对象,常见的verbs有“get”、“delete”、“update”和 “patch” 。当声明resourceNames,verb不能为list、watch、create和deletecollection
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: default
name: configmap-updater
rules:
- apiGroups: [""]
resources: ["configmaps"]
resourceNames: ["my-configmap"]
verbs: ["update", "get"]
RoleBinding和ClusterRoleBinding
Binding 就是 用户和角色之间的绑定关系,也分为RoleBinding 和ClusterRoleBinding
以下是一个RoleBinding的例子,用户jane与Role pod-reader绑定
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: read-pods
namespace: default
subjects:
- kind: User
name: jane # 用户名大小写敏感
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role #这里必须是Role或者ClusterRole
name: pod-reader #匹配Role或者ClusterRole
apiGroup: rbac.authorization.k8s.io
以下是另一个RoleBinding的例子,用户dave 与ClusterRole secret-reader绑定。需要注意,RoleBinding是有namespace限制的,用户只在 RoleBinding的namespace拥有ClusterRole的权限
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: read-secrets
namespace: development
subjects:
- kind: User
name: dave
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: secret-reader
apiGroup: rbac.authorization.k8s.io
以下是一个ClusterRoleBinding的例子,用户组 manager与ClusterRole secret-reader绑定
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: read-secrets-global
subjects:
- kind: Group
name: manager
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: secret-reader
apiGroup: rbac.authorization.k8s.io
RoleBinding和ClusterRoleBinding中的roleRef不能修改,想要修改只能删除重建。
Subjects
Subjects可以是用户、用户组和service account。
带有‘system:’前缀的用户和用户组保留给系统使用,其他名字都可以用
在pod中不声明spec.serviceAccountName,则pod会使用缺省的serviceaccount,一般是default
缺省Role和ClusterRole
所有缺省Role和ClusterRole都用kubernetes.io/bootstrapping=rbac标签,并使用’system:'前缀标识。
每次启动,apiserver都会使用缺省的Role和ClusterRole更新配置,可以修复意外修改造成的问题。
以heapster为例分析serviceAccount RBAC的使用
deployment heapster中使用serviceAccountName heapster
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: heapster
namespace: kube-system
spec:
replicas: 1
template:
metadata:
labels:
task: monitoring
k8s-app: heapster
spec:
serviceAccountName: heapster
containers:
- name: heapster
image: k8s.gcr.io/heapster-amd64:v1.5.4
imagePullPolicy: IfNotPresent
command:
- /heapster
- --source=kubernetes:https://kubernetes.default
- --sink=influxdb:http://monitoring-influxdb.kube-system.svc:8086
ServiceAccount heapster绑定ClusterRole system:heapster
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
annotations:
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"rbac.authorization.k8s.io/v1beta1","kind":"ClusterRoleBinding","metadata":{"annotations":{},"name":"heapster"},"roleRef":{"apiGroup":"rbac.authorization.k8s.io","kind":"ClusterRole","name":"system:heapster"},"subjects":[{"kind":"ServiceAccount","name":"heapster","namespace":"kube-system"}]}
creationTimestamp: 2019-05-15T07:17:42Z
name: heapster
resourceVersion: "2275681"
selfLink: /apis/rbac.authorization.k8s.io/v1/clusterrolebindings/heapster
uid: 87623890-76e1-11e9-bc74-52540005f38a
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: system:heapster
subjects:
- kind: ServiceAccount
name: heapster
namespace: kube-system
查看ClusterRole system:heapster的权限
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
annotations:
rbac.authorization.kubernetes.io/autoupdate: "true"
creationTimestamp: 2019-04-30T06:52:29Z
labels:
kubernetes.io/bootstrapping: rbac-defaults
name: system:heapster
resourceVersion: "138722"
selfLink: /apis/rbac.authorization.k8s.io/v1/clusterroles/system%3Aheapster
uid: 85945bd1-6b14-11e9-bc74-52540005f38a
rules:
- apiGroups:
- ""
resources:
- events
- namespaces
- nodes
- pods
verbs:
- get
- list
- watch
- apiGroups:
- extensions
resources:
- deployments
verbs:
- get
- list
- watch
以kubectl为例分析userAccount RBAC的使用
新建用户panmeng的证书
openssl genrsa -out panmeng.key 2048
openssl req -new -key panmeng.key -out panmeng.csr -subj "/CN=panmeng"
openssl x509 -req -in panmeng.csr -out panmeng.crt -sha1 -CA ca.crt -CAkey ca.key -CAcreateserial -days 3650
新建role及rolebinding,使用户panmeng 具有 list和get pod的权限
kubectl create role getpods --verb=get --verb=list --resource=pods
kubectl create rolebinding panmeng-getpods --role=getpods --user=panmeng --namespace=default
修改kubectl配置文件,并切换context
kubectl config set-credentials panmeng --client-certificate=/etc/kubernetes/pki/panmeng.crt --client-key=/etc/kubernetes/pki/panmeng.key --username=panmeng --embed-certs=true
kubectl config set-context --cluster=kubernetes --user=panmeng
kubectl config use-context context-panmeng
验证效果
# kubectl get nodes
Error from server (Forbidden): nodes is forbidden: User "panmeng" cannot list resource "nodes" in API group "" at the cluster scope
# kubectl get pods
NAME READY STATUS RESTARTS AGE
gc-test 0/2 CrashLoopBackOff 1086 47h
testpod-5wtb7 1/1 Running 0 15d
testpod-646d8 1/1 Running 0 15d
testpod-qczvt 1/1 Running 0 15d
# kubectl delete pod gc-test
Error from server (Forbidden): pods "gc-test" is forbidden: User "panmeng" cannot delete resource "pods" in API group "" in the namespace "default"
# kubectl auth can-i list pods
yes
# kubectl auth can-i get pods
yes
# kubectl auth can-i delete pods
no