基于角色的访问控制(RBAC)使用rbac.authorization.k8s.io
API组来驱动授权决策,允许管理员通过Kubernetes API动态配置策略。
从1.8开始RBAC模式是稳定的,由rbac.authorization.k8s.io/v1
API支持。
开启RBAC启动apiserver的时候通过--authorization-mode=RBAC
参数来配置。
Role和ClusterRole
在RBAC API里,角色包含一组标示权限的规则集合,权限是纯碎的加法没有否定规则。角色可以是定义给namespace的Role,也可以是集群范围的ClusterRole。一个Role只能用于对单个namespace的资源访问权限。这里是一个定义给default namespace的Role,可以用于读取访问pods:
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"]
ClusterRole可以用于授予和Role相同的权限,不过它是集群范围的,也可以用于授权访问权限:
- 集群范围资源(例如节点)
- 非资源端点(例如"/healthz")
- 所有namespace中的命名空间资源(例如pod)
下面的ClusterRole例子可用于访问特定namespace或者所有namespace的secrets(取决于它如何绑定):
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
# "namespace" omitted since ClusterRoles are not namespaced
name: secret-reader
rules:
- apiGroups: [""]
resources: ["secrets"]
verbs: ["get", "watch", "list"]
RoleBinding和ClusterRoleBinding
角色绑定将Role里面定义的权限授予一个用户或者一组用户集合。它包含(users,groups或者serviceaccount)以及被授予的角色引用。权限可以通过RoleBinding授予一个namespace,或者集群范围的ClusterRoleBinding。
RoleBinding可以在相同的namespace引用一个Role。下面的RoleBinding给用户jane在default空间中授予pod-reader角色。允许用户jane读取default空间中的pod。
# This role binding allows "jane" to read pods in the "default" namespace.
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: read-pods
namespace: default
subjects:
- kind: User
name: jane
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: pod-reader
apiGroup: rbac.authorization.k8s.io
RoleBinding还可以引用ClusterRole来授予RoleBinding命名空间中ClusterRole中定义的命名空间资源权限。这允许管理员为整个集群定义一组通用角色,然后在多个命名空间中使用它们。
例如,以下RoleBinding引用了一个ClusterRole,“dave”将在development命名空间中可以读取secrets。
# This role binding allows "dave" to read secrets in the "development" namespace.
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: read-secrets
namespace: development # This only grants permissions within the "development" namespace.
subjects:
- kind: User
name: dave
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: secret-reader
apiGroup: rbac.authorization.k8s.io
ClusterRoleBinding可以用于授予所有namespace集群级别的权限。下面的例子ClusterRoleBinding允许manager里面的所有用户都可以读取所有集群的secrets。
# This cluster role binding allows anyone in the "manager" group to read secrets in any namespace.
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
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
参考资源
大多数资源的名称由字符串表示,例如pods,就像它出现在API的端点URL中。然后一些Kubernetes API涉及一些子资源,例如pod的日志。下面的URL是pod的日志:
GET /api/v1/namespaces/{namespace}/pods/{name}/log
在这个例子中,pods是命名空间资源,log是pod的子资源。在RBAC中表示此角色,使用斜杠划分资源和子资源。允许读取pod和pod日志,可以这样写:
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
namespace: default
name: pod-and-pod-logs-reader
rules:
- apiGroups: [""]
resources: ["pods", "pods/log"]
verbs: ["get", "list"]
资源也可以通过resourceName列表中的某些请求的名称引用。当指定时,请求使用"get","delete","update"和"patch"动词可以被限制为资源的各个实例。要限制只能"get"和"update"一个单独的configmap可以这样写:
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
namespace: default
name: configmap-updater
rules:
- apiGroups: [""]
resources: ["configmaps"]
resourceNames: ["my-configmap"]
verbs: ["update", "get"]
值得注意的是,如果resourceNames被指定动词不能是list, watch, create或者deletecollection。因为资源名称不存在于list, watch, create和deletecollection的URL中。这些动词将不被resourceName设置的规则所允许,因为规则的resourceNames部分与请求不匹配。
Role例子
一下例子只显示rules部分:
允许读取pods资源在核心API组:
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list", "watch"]
允许读取和写deployment在extensions和app API组:
rules:
- apiGroups: ["extensions", "apps"]
resources: ["deployments"]
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
允许读取pods和读写jobs:
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list", "watch"]
- apiGroups: ["batch", "extensions"]
resources: ["jobs"]
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
允许读取名字为my-config的ConfigMap(必须绑定RoleBinding限制一个ConfigMap和一个namespace):
rules:
- apiGroups: [""]
resources: ["configmaps"]
resourceNames: ["my-config"]
verbs: ["get"]
允许核心组读取nodes(因为Node是一个集群范围,必须在ClusterRole和一个ClusterRoleBinding才可以生效):
rules:
- apiGroups: [""]
resources: ["nodes"]
verbs: ["get", "list", "watch"]
允许“GET”和“POST”请求到非资源端点“/ healthz”和所有子路径(必须在与ClusterRoleBinding绑定的ClusterRole中有效):
rules:
- nonResourceURLs: ["/healthz", "/healthz/*"] # '*' in a nonResourceURL is a suffix glob match
verbs: ["get", "post"]
参考主题
RoleBinding或ClusterRoleBinding将角色绑定到主题。主题可以是groups,users和serviceaccount。用户由字符串表示。这些可以是简单的用户名,如“alice”,电子邮件样式名称,如“bob@example.com”或以字符串表示的数字ID。由Kubernetes管理员配置认证模块以产生所需格式的用户名。RBAC授权系统不需要任何特定格式。然而,前缀"system:"是为Kubernetes系统使用而保留的,因此管理员应确保用户名不会意外包含此前缀。
Kubernetes的组信息目前由Authenticator模块提供。groups,users是用字符串表示,没有格式要求,除了预留的system:
。
Service Accounts的名字为system:serviceaccount
前缀,并且属于具有system:serviceaccounts
前缀的组。
Role绑定的例子
以下例子只显示了RoleBinding部分。
用户名为"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
在kube-system命名空间里的default service account:
subjects:
- kind: ServiceAccount
name: default
namespace: kube-system
qa命名空间里面的所有的service account:
subjects:
- kind: Group
name: system:serviceaccounts:qa
apiGroup: rbac.authorization.k8s.io
所有service account在任何地方:
subjects:
- kind: Group
name: system:serviceaccounts
apiGroup: rbac.authorization.k8s.io
所有的验证用户(版本:1.5+):
subjects:
- kind: Group
name: system:authenticated
apiGroup: rbac.authorization.k8s.io
所有的不需要验证用户(版本:1.5+):
subjects:
- kind: Group
name: system:unauthenticated
apiGroup: rbac.authorization.k8s.io
所有类型用户(版本1.5+):
subjects:
- kind: Group
name: system:authenticated
apiGroup: rbac.authorization.k8s.io
- kind: Group
name: system:unauthenticated
apiGroup: rbac.authorization.k8s.io