Access control
1 Introduction
-
Authentication (authentication)
now a total of eight kinds of authentication, you can enable one or more authentication methods, as long as there is a way through authentication, authentication is no longer otherwise. Generally, two authentication methods, X509 Client Certs and Service Accout Tokens, are enabled. -
There are two types of users in a Kubernetes cluster: Service Accounts managed by Kubernetes and ordinary accounts (Users Accounts). The concept of account in k8s is not an account that we understand, it does not really exist, it only exists in form.
-
Authorization (authorization)
must go through the authentication stage before reaching the authorization request. According to all authorization policies matching the requested resource attributes, it is decided to allow or deny the request. There are currently 6 authorization methods, AlwaysDeny, AlwaysAllow, ABAC, RBAC, Webhook, and Node. The default cluster forces RBAC to be enabled. -
Admission Control
is a method used to intercept requests. It runs after authentication and authorization. It is the last link in the authorization authentication chain, and it modifies and verifies the requested API resource object. -
Clients that access the API Server of k8s are mainly divided into two categories:
1.kubectl: The .kube/config in the user's home directory saves the key information related to the client's access to the API Server, so that when k8s is accessed by kubectl, it It will automatically read the configuration file, initiate authentication to the API Server, and complete the operation request.
2. Pod: The process in the Pod needs to access the API Server. If it is accessed by people or written scripts, the account used for this type of access is: UserAccount; and when the Pod itself connects to the API Server, the account used is: ServiceAccount , The latter is mostly used in production. -
The command that kubectl initiates to the apiserver uses the http method, which is actually the operation of adding, deleting, modifying and checking the URL.
$ kubectl proxy --port=8888 & ##Open a proxy port
$ curl http://localhost:8888/api/v1/namespaces/default
$ curl http://localhost:8888/apis/apps/v1/namespaces/ default/deployments -
The difference between the above two apis is:
api is a special link that can only be used by objects in the core v1 group.
apis It is the fixed format name of the entry for general API access.
2. UserAccount与serviceaccount(sa)
- UserAccount and serviceaccount:
User accounts are for people. The service account is for the process running in the pod.
User accounts are global. Its name is globally unique in each namespace of the cluster. Future user resources will not be namespace-isolated, and service accounts will be namespace-isolated.
Under normal circumstances, the user accounts of the cluster may be synchronized from the corporate database. Its creation requires special permissions and involves complex business processes. The purpose of service account creation is to be more lightweight, allowing cluster users to create service accounts for specific tasks (that is, the principle of minimizing permissions).
2.1 account service (s)
Adding the authentication information to the serviceAccount is much safer than specifying imagePullSecrets directly in the Pod.
[root@server2 ~]# kubectl get sa
[root@server2 ~]# kubectl get sa
NAME SECRETS AGE
default 1 10d
[root@server2 ~]# kubectl create serviceaccount admin ##创建sa
serviceaccount/admin created
[root@server2 ~]# kubectl get sa
NAME SECRETS AGE
admin 1 3s
default 1 10d
[root@server2 ~]# kubectl describe sa admin
Name: admin
Namespace: default
Labels: <none>
Annotations: <none>
Image pull secrets: <none>
Mountable secrets: admin-token-md4rv
Tokens: admin-token-md4rv
Events: <none>
[root@server2 ~]# kubectl describe sa default
Name: default
Namespace: default
Labels: <none>
Annotations: <none>
Image pull secrets: <none>
Mountable secrets: default-token-mdfz9
Tokens: default-token-mdfz9
Events: <none>
[root@server2 ~]# kubectl get secrets ##创建secret
NAME TYPE DATA AGE
myregistrykey kubernetes.io/dockerconfigjson 1 5d19h
[root@server2 ~]# kubectl patch serviceaccount admin -p '{"imagePullSecrets": [{"name": "myregistrykey"}]}' ##打补丁
[root@server2 ~]# kubectl describe sa admin
Name: admin
Namespace: default
Labels: <none>
Annotations: <none>
Image pull secrets: myregistrykey ##绑定secret章节所做的实验,拉取策略
Mountable secrets: admin-token-md4rv
Tokens: admin-token-md4rv
Events: <none>
[root@server2 ~]# cd secret/
[root@server2 secret]# vim pod3.yaml
[root@server2 secret]# cat pod3.yaml ##把serviceaccount和pod绑定起来:
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
containers:
- name: game2048
image: reg.westos.org/westos/game2048
#imagePullSecrets:
# - name: myregistrykey
serviceAccountName: admin ##指定sa,没有指定会拉取不到
[root@server2 secret]# kubectl apply -f pod3.yaml ##
[root@server2 secret]# kubectl get pod
NAME READY STATUS RESTARTS AGE
mypod 1/1 Running 0 12s
[root@server2 secret]# kubectl describe pod mypod
Volumes:
admin-token-md4rv: ##所要的sa认证信息
Type: Secret (a volume populated by a Secret)
SecretName: admin-token-md4rv
2.2 UserAccount
2.2.1 Authentication
[root@server2 pki]# pwd ##切换到指定目录
/etc/kubernetes/pki
[root@server2 pki]# openssl genrsa -out test.key 2048 ##生成指定key
[root@server2 pki]# ll test.key
[root@server2 pki]# openssl req -new -key test.key -out test.csr -subj "/CN=test" ##生成证书请求
[root@server2 pki]# openssl x509 -req -in test.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out test.crt -days 365 ##生成证书
[root@server2 pki]# openssl x509 -in test.crt -text -noout ##查看证书内容
[root@server2 pki]# kubectl config set-credentials test --client-certificate=/etc/kubernetes/pki/test.crt --client-key=/etc/kubernetes/pki/test.key --embed-certs=true ## 生成用户并设置认证
User "test" set.
[root@server2 pki]# kubectl config view ##查看配置内容
[root@server2 pki]# kubectl config set-context test@kubernetes --cluster=kubernetes --user=test ##设置账户
[root@server2 pki]# kubectl config use-context test@kubernetes ##使用账户test
[root@server2 pki]# kubectl get pod ##会出错,因为此时用户通过认证,但还没有权限操作集群资源,需要继续添加授权。
Error from server (Forbidden): pods is forbidden: User "test" cannot list resource "pods" in API group "" in the namespace "default"
2.2.2 Authorization
-
RBAC (Role Based Access Control): Role-based access control authorization.
Allows administrators to dynamically configure authorization policies through the Kubernetes API. RBAC is the association of users through roles and permissions.
RBAC only authorizes, not deny authorization, so you only need to define what the user is allowed to do.
RBAC includes four types: Role, ClusterRole, RoleBinding, ClusterRoleBinding. -
The three basic concepts of RBAC:
Subject: the affected person, it represents the three types of subjects in k8s, user, group, serviceAccount
Role: role, it is actually a set of rules, which defines a set of operation permissions for Kubernetes API objects.
RoleBinding: defines the binding relationship between "acted person" and "role". -
Role and ClusterRole
Role is a collection of a series of permissions. Role can only grant access to resources in a single namespace.
ClusterRole is similar to Role, but can be used globally in the cluster. -
RoleBinding and ClusterRoleBinding
RoleBinding is to grant permissions defined in Role to users or user groups. It contains a list of subjects (users, groups, service accounts) and references the Role.
RoleBinding is to authorize within a certain namespace, and ClusterRoleBinding is suitable for use within the cluster.
[root@server2 pki]# kubectl config use-context kubernetes-admin@kubernetes ##test用户没有授权,所以需要切回kubernetes-admin
[root@server2 ~]# mkdir rbac
[root@server2 ~]# cd rbac/
[root@server2 rbac]# vim role.yaml
[root@server2 rbac]# kubectl get role
NAME CREATED AT
myrole 2021-03-02T07:34:04Z
[root@server2 rbac]# vim role.yaml
[root@server2 rbac]# kubectl apply -f role.yaml
[root@server2 rbac]# kubectl get rolebindings.rbac.authorization.k8s.io
[root@server2 rbac]# kubectl describe rolebindings.rbac.authorization.k8s.io
[root@server2 rbac]# kubectl get clusterrole | grep myclusterrole
[root@server2 rbac]# cat role.yaml
kind: Role ##role示例
apiVersion: rbac.authorization.k8s.io/v1
metadata:
namespace: default
name: myrole
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "watch", "list", "create", "update", "patch", "delete"]
---
kind: RoleBinding # RoleBinding示例:
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: test-read-pods
namespace: default
subjects:
- kind: User
name: test
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role ##绑定的类型是role
name: myrole
apiGroup: rbac.authorization.k8s.io
---
kind: ClusterRole #ClusterRole示例:
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: myclusterrole
rules: ##通过规则可以设置控制的内容
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "watch", "list", "delete", "create", "update"]
- apiGroups: ["extensions", "apps"]
resources: ["deployments"]
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding ##RoleBinding示例
metadata:
name: rolebind-myclusterrole
namespace: default
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole ##绑定的是集群role
name: myclusterrole
subjects:
- apiGroup: rbac.authorization.k8s.io
kind: User
name: test
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding ##ClusterRoleBinding
metadata:
name: clusterrolebinding-myclusterrole
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole ##绑定的是集群,但是不需要指定namespace
name: myclusterrole
subjects:
- apiGroup: rbac.authorization.k8s.io
kind: User
name: test
##使用test用户进行测试
[root@server2 rbac]# kubectl get -n kube-system pod
[root@server2 rbac]# kubectl get deployments.apps
##删除
[root@server2 rbac]# kubectl delete sa 名称 ##删除sa
[root@server2 rbac]# kubectl get secrets ##查看对应的密钥
2.3.3 Supplement
-
Service account automation
Service account admission controller (Service account admission controller)
If the pod does not have a ServiceAccount setting, set its ServiceAccount to default.
Ensure that the ServiceAccount associated with the pod exists, otherwise reject the pod.
If the pod does not contain the ImagePullSecrets setting, then add the ImagePullSecrets information in the ServiceAccount to the pod.
Add a volume containing a token for API access to the pod.
Add the volumeSource mounted at /var/run/secrets/kubernetes.io/serviceaccount to each container under the pod. -
The Token controller
detects the creation of service accounts and creates corresponding Secrets to support API access.
Detect the deletion of the service account, and delete all corresponding service account Token Secrets.
Detect the increase of Secret to ensure that the corresponding service account exists, and if necessary, add token to Secret.
Detect the deletion of Secret and remove the reference from the corresponding service account if necessary. -
Service account controller (Service account controller) The
service account manager manages the service accounts under each namespace, and ensures that there is a service account named "default" under each active namespace -
Kubernetes also has the concept of "User Group" (Group):
ServiceAccount corresponds to the built-in "user" name is:
system:serviceaccount:<ServiceAccount name>
and the user group corresponds to the built-in name:
system:serviceaccounts:<Namespace name>
example 1: Represents all ServiceAccount
subjects in mynamespace : -
kind: Group
name: system:serviceaccounts:mynamespace
apiGroup: rbac.authorization.k8s.io
Example 2: Represents all ServiceAccount
subjects in the entire system : -
kind: Group
name: system:serviceaccounts
apiGroup: rbac.authorization.k8s.io- Kubernetes 还提供了四个预先定义好的 ClusterRole 来供用户直接使用: cluster-amdin admin edit view - 示例:(最佳实践) kind: RoleBinding apiVersion: rbac.authorization.k8s.io/v1 metadata: name: readonly-default subjects: - kind: ServiceAccount name: default namespace: default roleRef: kind: ClusterRole name: view apiGroup: rbac.authorization.k8s.io - [root@server2 rbac]# kubectl describe clusterrole cluster-admin [root@server2 rbac]# kubectl describe clusterrole view [root@server2 rbac]# kubectl describe clusterrole admin [root@server2 rbac]# kubectl describe clusterrole edit
2.3.4 Understanding the file
[root@server2 nfs-client]# cat nfs-client-provisioner.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: nfs-client-provisioner
# replace with namespace where provisioner is deployed
namespace: nfs-client-provisioner
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: nfs-client-provisioner-runner
rules:
- apiGroups: [""]
resources: ["persistentvolumes"]
verbs: ["get", "list", "watch", "create", "delete"]
- apiGroups: [""]
resources: ["persistentvolumeclaims"]
verbs: ["get", "list", "watch", "update"]
- apiGroups: ["storage.k8s.io"]
resources: ["storageclasses"]
verbs: ["get", "list", "watch"]
- apiGroups: [""]
resources: ["events"]
verbs: ["create", "update", "patch"]
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: run-nfs-client-provisioner
subjects:
- kind: ServiceAccount
name: nfs-client-provisioner
# replace with namespace where provisioner is deployed
namespace: nfs-client-provisioner
roleRef:
kind: ClusterRole
name: nfs-client-provisioner-runner
apiGroup: rbac.authorization.k8s.io
---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: leader-locking-nfs-client-provisioner
# replace with namespace where provisioner is deployed
namespace: nfs-client-provisioner
rules:
- apiGroups: [""]
resources: ["endpoints"]
verbs: ["get", "list", "watch", "create", "update", "patch"]
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: leader-locking-nfs-client-provisioner
# replace with namespace where provisioner is deployed
namespace: nfs-client-provisioner
subjects:
- kind: ServiceAccount
name: nfs-client-provisioner
# replace with namespace where provisioner is deployed
namespace: nfs-client-provisioner
roleRef:
kind: Role
name: leader-locking-nfs-client-provisioner
apiGroup: rbac.authorization.k8s.io
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nfs-client-provisioner
labels:
app: nfs-client-provisioner
# replace with namespace where provisioner is deployed
namespace: nfs-client-provisioner
spec:
replicas: 1
strategy:
type: Recreate
selector:
matchLabels:
app: nfs-client-provisioner
template:
metadata:
labels:
app: nfs-client-provisioner
spec:
serviceAccountName: nfs-client-provisioner
containers:
- name: nfs-client-provisioner
image: nfs-subdir-external-provisioner:v4.0.0
volumeMounts:
- name: nfs-client-root
mountPath: /persistentvolumes
env:
- name: PROVISIONER_NAME
value: k8s-sigs.io/nfs-subdir-external-provisioner
- name: NFS_SERVER
value: 172.25.13.1
- name: NFS_PATH
value: /nfsdata
volumes:
- name: nfs-client-root
nfs:
server: 172.25.13.1
path: /nfsdata
---
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: managed-nfs-storage
provisioner: k8s-sigs.io/nfs-subdir-external-provisioner
parameters:
archiveOnDelete: "true"