Authorization
The above authentication process only confirms that both sides of the communication confirm that the other party is trusted and can communicate with each other. Authentication is to determine which resources the requestor has. API Server currently supports the following authorization policies (set through the startup parameter "-- authorization mode" of API Server)
- AlwaysDeny: it means to reject all requests. It is generally used for testing
- AlwaysAllow: all requests are allowed to be received. If the cluster does not need authorization process, this policy can be adopted
- ABAC (attribute based access control): attribute based access control, which means to match and control user requests using user configured authorization rules
- Webhook: authorize users by calling external REST services
- RBAC (Role-Based Access Control): Role-Based Access Control, the current default rule
RBAC authorization mode
RBAC (Role-Based Access Control) Role-Based Access Control was introduced in Kubernetes 1.5, and the current version has become the default standard. Compared with other access control methods, it has the following advantages:
- It has complete coverage of resources and non resources in the cluster
- The whole RBAC is completely completed by several API objects. Like other API objects, it can be operated with kubectl or API
- It can be adjusted at runtime without restarting the API Server
1. Description of RBAC resource object
RBAC introduces four new top-level resource objects: Role, ClusterRole, RoleBinding and ClusterRoleBinding. All four object types can be operated through kubectl and API
It should be noted that kubenetes does not provide User management, so where do the users specified by User, Group and ServiceAccount come from? Kubenetes components (kubectl, Kube proxy) or other customized users need to provide a certificate request file when applying for a certificate from CA
{ "CN": "admin", "hosts": [], "key": { "algo": "rsa", "size": 2048 }, "names": [ { "C": "CN", "ST": "HangZhou", "L": "XS", "O": "system:masters", "OU": "System" } ] }
The API Server will take the 'CN' field of the client certificate as the User and name O field as Group
When kubelet uses TLS bootstrapping authentication, API Server can use Bootstrap Tokens or Token authentication file to verify = token. In either case, Kubenetes will bind a default User and Group for the token
When Pod uses ServiceAccount authentication, JWT in service account token will save User information
With user information, create a pair of role / role binding (cluster role / cluster role binding) resource objects to complete permission binding
Role and ClusterRole
In RBAC API, Role refers to a group of rule permissions, which will only be increased (cumulative permissions). There is no resource that has many permissions at the beginning, but can be reduced through RBAC; Roles can be defined in one namespace. If you want to span namespaces, you can create clusterroles
kind: Role apiVersion: rbac.authorization.k8s.io/v1beta1 metadata: namespace: default name: pod-reader rules: - apiGroups: [""] # "" indicates the core API group resources: ["pods"] verbs: ["get", "watch", "list"]
ClusterRole has the same permission Role control capability as Role. The difference is that ClusterRole is cluster level. ClusterRole can be used to:
- Cluster level resource control (such as node access rights)
- Non resource endpoints (e.g. / health access)
- All namespace resource controls (e.g. pods)
kind: ClusterRole apiVersion: rbac.authorization.k8s.io/v1beta1 metadata: # "namespace" omitted since ClusterRoles are not namespaced name: secret-reader rules: - apiGroups: [""] resources: ["secrets"] verbs: ["get", "watch", "list"]
RoleBinding and ClusterRoleBinding
RoloBinding can grant the permissions defined in the Role to users or user groups. RoleBinding contains a set of permissions list (subjects), which contains different forms of permission resource types to be granted (users, groups, or service accounts); RoloBinding also contains references to roles that are bound; RoleBinding applies to authorization within a namespace, while ClusterRoleBinding applies to authorization within a cluster
Grant the pod reader role of the default namespace to the jane user, and then the jane user will have the permission of pod reader in the default namespace
kind: RoleBinding apiVersion: rbac.authorization.k8s.io/v1beta1 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 can also reference ClusterRole to authorize users, user groups or serviceaccounts in the current namespace. This operation allows the Cluster Administrator to define some common clusterroles in the whole cluster, and then use RoleBinding to reference in different namespaces
For example, the following RoleBinding refers to a ClusterRole that has access to secrets in the whole cluster; However, its authorized user 'dave' can only access secrets in the development space (because RoleBinding is defined in the development namespace)
# This role binding allows "dave" to read secrets in the "development" namespace. kind: RoleBinding apiVersion: rbac.authorization.k8s.io/v1beta1 metadata: name: read-secrets namespace: dev # 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
Use ClusterRoleBinding to authorize the permissions of all namespace resources in the whole cluster; The following example of ClusterRoleBinding shows that all users in the manager group are authorized to access secrets in all namespaces
# This cluster role binding allows anyone in the "manager" group to read secrets in any namespace. kind: ClusterRoleBinding apiVersion: rbac.authorization.k8s.io/v1beta1 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
Resources
Some resources in the Kubernetes cluster are generally represented by their name strings, which generally appear in the URL address of the API; At the same time, some resources also contain sub resources. For example, the logs resource belongs to the sub resources of pods. The URL example in the API is as follows
GET /api/v1/namespaces/{namespace}/pods/{name}/log
If you want to control the access permissions of these sub resources in the RBAC authorization model, you can use the / separator. The following is a Role definition example that defines the access permissions of pods resource logs
kind: Role apiVersion: rbac.authorization.k8s.io/v1beta1 metadata: namespace: default name: pod-and-pod-logs-reader rules: - apiGroups: [""] resources: ["pods", "pods/log"] verbs: ["get", "list"]
to Subjects
Role binding and ClusterRoleBinding can bind roles to subjects; Subjects can be groups, users or service accounts
Users in Subjects are represented by strings, which can be a common name string, such as "alice"; It can also be an email address in email format, such as“ wangyanglinux@163.com ”; Even a set of numeric ID S in the form of strings. However, the prefix system: of users is reserved by the system. The Cluster Administrator should ensure that ordinary users will not use this prefix format
The writing format of Groups is the same as that of Users, which is a string, and there are no specific format requirements; Similarly, the system: prefix is reserved for the system
Practice: creating a user can only manage dev space
{ "CN": "devuser", "hosts": [], "key": { "algo": "rsa", "size": 2048 }, "names": [ { "C": "CN", "ST": "BeiJing", "L": "BeiJing", "O": "k8s", "OU": "System" } ] } # Download certificate generation tool wget https://pkg.cfssl.org/R1.2/cfssl_linux-amd64 mv cfssl_linux-amd64 /usr/local/bin/cfssl wget https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64 mv cfssljson_linux-amd64 /usr/local/bin/cfssljson wget https://pkg.cfssl.org/R1.2/cfssl-certinfo_linux-amd64 mv cfssl-certinfo_linux-amd64 /usr/local/bin/cfssl-certinfo cfssl gencert -ca=ca.crt -ca-key=ca.key -profile=kubernetes /root/devuser-csr.json | cfssljson -bare devuser # Set cluster parameters export KUBE_APISERVER="https://192.168.88.11:6443" kubectl config set-cluster kubernetes \ --certificate-authority=ca.crt \ --embed-certs=true \ --server=${KUBE_APISERVER} \ --kubeconfig=devuser.kubeconfig # Set client authentication parameters kubectl config set-credentials devuser \ --client-certificate=devuser.pem \ --client-key=devuser-key.pem \ --embed-certs=true \ --kubeconfig=devuser.kubeconfig # Setting context parameters kubectl config set-context kubernetes \ --cluster=kubernetes \ --user=devuser \ --namespace=dev \ --kubeconfig=devuser.kubeconfig # Set default context kubectl config use-context kubernetes --kubeconfig=devuser.kubeconfig cp -f ./devuser.kubeconfig /root/.kube/config kubectl create rolebinding devuser-admin-binding --clusterrole=admin --user=devuser --namespace=dev