k8s(RBAC) user management

1. Introduction to K8S account system

In k8s, there are two types of users, service account and user. We can create a role or clusterrole, and then bind the account to the role or clusterrole to grant permissions to the account and achieve permission control. The functions of the two types of accounts are as follows.

  • Server account: The account used by k8s processes and pods to apply for authorization. Similar to the nginx service, there will be an nginx user.
  • user: The account used by k8s administrator 2\, which is the account we use.

2. Service Account

2.1, Introduction

All access in Kubernetes, whether external or internal, will be processed through the API Server. Authentication and authorization are required before accessing Kubernetes resources.

  • In k8s, service account (sa for short) is used by processes in the cluster. When a pod or process in the cluster needs to apply for resources with the apiserver, sa will be used.
2.2 Why sa is needed

Mainly for permission control, different sa accounts correspond to different permissions, such as adding, deleting, checking, etc.

2.3 How to create sa
  • create a sa
[root@node1 user]# kubectl create serviceaccount sa-example --dry-run -o yaml -n default
W1026 11:21:22.486105 25708 helpers.go:692] --dry-run is deprecated and can be replaced with --dry-run=client.
apiVersion: v1
kind: ServiceAccount
metadata:
  creationTimestamp: null
  name: sa-example
  namespace:default

[root@node1 user]# kubectl create serviceaccount sa-example -n default
serviceaccount/sa-example created
[root@node1 user]# kubectl describe serviceaccount sa-example
Name: sa-example
Namespace: default
Labels: <none>
Annotations: <none>
Image pull secrets: <none>
Mountable secrets: <none>
Tokens: <none>
Events: <none>
  • Create a secret for sa. After version v1.25, the secret is no longer automatically created after creating sa, so it needs to be created manually. The secret will contain some authentication information, including ca certificate, etc.
[root@node1 user]# vim sa-example-secret.yaml
[root@node1 user]# cat sa-example-secret.yaml
apiVersion: v1
Kind: Secret
metadata:
  name: secret-sa-example
  annotations:
    kubernetes.io/service-account.name: "sa-example" # Fill in serviceAccountName here
type: kubernetes.io/service-account-token
[root@node1 user]# kubectl apply -f sa-example-secret.yaml
secret/secret-sa-example created
[root@node1 user]# kubectl describe secret secret-sa-example
Name: secret-sa-example
Namespace: default
Labels: <none>
Annotations: kubernetes.io/service-account.name: sa-example
              kubernetes.io/service-account.uid: 118b18b3-ef04-4d6f-9e67-22110c6b025d

Type: kubernetes.io/service-account-token

Data
====
ca.crt: 1107 bytes
namespace: 7 bytes
token: eyJhbGciOiJSUzI1NiIsImtpZCI6IkNCNE9fSlozNm02Sm1peERyM0wyUDNqVFpvcFBSdnBZbUIxTVczZS1jXzgifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZX Rlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJkZWZhdWx0Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZWNyZXQubmFtZSI6InNlY3JldC1zYS1leGFtcGxlIiwia3ViZX JuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQubmFtZSI6InNhLWV4YW1wbGUiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC51aWQiO iIxMThiMThiMy1lZjA0LTRkNmYtOWU2Ny0yMjExMGM2YjAyNWQiLCJzdWIiOiJzeXN0ZW06c2VydmljZWFjY291bnQ6ZGVmYXVsdDpzYS1leGFtcGxlIn0.Or_zxnvsjcHNfSS5P9ZGC5EUIGTiAtRO 4YddHZqgAQKfpwK3CB904eFHdOubruy1AKOOqJMRBnIZ_BU1Gx7QYiqg7Z_v3cBsOBDcSl7kuKTd74mnUHpmbgUEwp1BJUlA17gOyWrXb_ADm-43nHZhQjuFcBrA9QqMsLK2TBpu-LrLwRg C2qF-tsXGwM4O4fKNg_QtlaUEJK3KL-Y7LkWWIO49ttgD8lYFlnn7SA_n6JVw1Oba_HFedIc0NszzQSwo4ZhH3WaSYsraODtliAi5KR_zlx6zoAVTaenbAgqMqvIYgBUSLwxBNyAFLKeuNwqoeQVpF-eQI 0oe3sX5YwpcZg
2.4, Permission role setting and binding
[root@node1 user]# kubectl get clusterrole cluster-admin -o yaml
apiVersion: rbac.authorization.k8s.io/v1
kind:ClusterRole
metadata:
  annotations:
    rbac.authorization.kubernetes.io/autoupdate: "true"
  creationTimestamp: "2023-09-20T01:59:58Z"
  labels:
    kubernetes.io/bootstrapping: rbac-defaults
  name: cluster-admin
  resourceVersion: "72"
  uid: ae192e4e-e6ed-4cce-920b-2cadc940c573
rules:
- apiGroups:
  - '*'
  resources:
  - '*'
  verbs:
  - '*'
- nonResourceURLs:
  - '*'
  verbs:
  - '*'
[root@node1 user]# kubectl create role pod-reader --verb=list,get,watch --resource=pods --dry-run -o yaml
W1026 11:46:17.517099 33096 helpers.go:692] --dry-run is deprecated and can be replaced with --dry-run=client.
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  creationTimestamp: null
  name: pod-reader
rules:
- apiGroups:
  - ""
  resources:
  -pods
  verbs:
  - list
  - get
  - watch
[root@node1 user]# kubectl create rolebinding sunny-read-pods --user=sunny --role=pod-reader --dry-run -o yaml
W1026 11:46:53.788376 33297 helpers.go:692] --dry-run is deprecated and can be replaced with --dry-run=client.
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  creationTimestamp: null
  name: sunny-read-pods
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: pod-reader
subjects:
- apiGroup: rbac.authorization.k8s.io
  kind: User
  name: sunny

[root@node1 user]# kubectl create clusterrole clusterrole-reader-pods --verb=get,list,watch --resource=pods --dry-run -o yaml
W1026 14:11:45.892696 75953 helpers.go:692] --dry-run is deprecated and can be replaced with --dry-run=client.
apiVersion: rbac.authorization.k8s.io/v1
kind:ClusterRole
metadata:
  creationTimestamp: null
  name: clusterrole-reader-pods
rules:
- apiGroups:
  - ""
  resources:
  -pods
  verbs:
  - get
  - list
  - watch
[root@node1 user]# kubectl create clusterrolebinding cluster-reader --clusterrole=clusterrole-reader-pods --user=sunny --dry-run -o yaml
W1026 14:12:23.506608 76147 helpers.go:692] --dry-run is deprecated and can be replaced with --dry-run=client.
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  creationTimestamp: null
  name: cluster-reader
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: clusterrole-reader-pods
subjects:
- apiGroup: rbac.authorization.k8s.io
  kind: User
  name: sunny
[root@node1 user]# kubectl create rolebinding role-to-clusterrole --clusterrole=clusterrole-reader-pods --user=sunny --dry-run -o yaml
W1026 14:13:02.193910 76331 helpers.go:692] --dry-run is deprecated and can be replaced with --dry-run=client.
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  creationTimestamp: null
  name: role-to-clusterrole
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind:ClusterRole
  name: clusterrole-reader-pods
subjects:
- apiGroup: rbac.authorization.k8s.io
  kind: User
  name: sunny

3. User Account

3.1, Introduction

The service account mentioned earlier is used by pods in the k8s cluster. The User Account introduced here is for ourselves, that is, for the client.

3.2. Why user account is needed
  • The k8s cluster is the same as the Linux operating system. Our default account is: kubernetes-admin@kubernetes. The administrator account also has the greatest permissions and can be used unimpeded in the k8s cluster.

But in the enterprise, we are not the only ones using k8s clusters. There are also many R&D personnel who need to use the cluster. At this time, we need to create some accounts for them, but the permissions of these accounts should not be too large to prevent mistakes. Delete the resource. At this time we can use the user account.

3.3. Create user account

Proceed as follows

  • Create the certificate files and keys required by the user
  • Create user
  • Creating a Role
  • Bind roles to users
3.3.1. User certificate generation

For the sa account introduced earlier, the certificate will be created when the secret is created. For users, we need to create the certificate ourselves.

openssl genrsa -out pulin.key 2048

openssl req -new -key pulin.key -out pulin.csr -subj "/CN=pulin/O=devops"

[root@node1 pki]# openssl x509 -req -in pulin.csr -CA /etc/kubernetes/pki/ca.crt -CAkey /etc/kubernetes/pki/ca.key -CAcreateserial -out pulin.crt -days 3650
Signature OK
subject=/CN=pulin/O=devops
Getting CA Private Key
[root@node1 pki]# ls
apiserver.crt apiserver-kubelet-client.crt ca.srl front-proxy-client.crt pulin.key
apiserver-etcd-client.crt apiserver-kubelet-client.key etcd front-proxy-client.key sa.key
apiserver-etcd-client.key ca.crt front-proxy-ca.crt pulin.crt sa.pub
apiserver.key ca.key front-proxy-ca.key pulin.csr

3.3.2. Create user

Now we want to operate the cluster as singleless through kubectl. We need to add singleless authentication information to kubectl configuration, that is, ~/.kube/config. Add user singleless authentication information to kubectl configuration through the following command:

[root@node1 pki]# kubectl config set-credentials pulin --client-certificate=pulin.crt --client-key=pulin.key
User "pulin" set.
[root@node1 pki]# kubectl config get-contexts
CURRENT NAME CLUSTER AUTHINFO NAMESPACE
* kubernetes-admin@kubernetes kubernetes kubernetes-admin
###After the addition is completed, you can see the addition in ~/.kube/config
[root@node1 pki]# cat ~/.kube/config |tail -4
- name: pulin
  user:
    client-certificate: /etc/kubernetes/pki/pulin.crt
    client-key: /etc/kubernetes/pki/pulin.key
##Create context and bind users through context to achieve precise permission control. Context can be understood as the environment variables required when logging in as a user. Delete using kubectl config delete-context command
[root@k8s-master01 ~]# kubectl config get-contexts ##Query the context of the current environment
[root@node1 pki]# kubectl config set-context pulin --cluster=kubernetes --namespace=* --user=pulin
Context "pulin" created.
[root@node1 pki]# kubectl config get-contexts
CURRENT NAME CLUSTER AUTHINFO NAMESPACE
* kubernetes-admin@kubernetes kubernetes kubernetes-admin
          pulin kubernetes pulin *
3.3.3. Create roles

There are two main types of roles: role and clusterrole. Roles are relatively restrictive and only take effect on specified resources. The cluster role (clusterrole) has relatively broad permissions. After a new cluster role is created, this role will affect the entire cluster.

There are two ways to create a character:

  • Create via command line
[root@node1 pki]# kubectl create role myrole --verb=get,list,watch --resource=pod,svc --dry-run -o yaml
W1026 14:54:31.031360 88676 helpers.go:692] --dry-run is deprecated and can be replaced with --dry-run=client.
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  creationTimestamp: null
  name: myrole
rules:
- apiGroups:
  - ""
  resources:
  -pods
  - services
  verbs:
  - get
  - list
  - watch
[root@node1 pki]# kubectl create clusterrole myrole --verb=get,list,watch --resource=pod,svc --dry-run -o yaml
W1026 14:55:16.119402 88881 helpers.go:692] --dry-run is deprecated and can be replaced with --dry-run=client.
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  creationTimestamp: null
  name: myrole
rules:
- apiGroups:
  - ""
  resources:
  -pods
  - services
  verbs:
  - get
  - list
  - watch

[root@node1 pki]# kubectl create clusterrole pulin-admin --verb="*" --resource="*" --non-resource-url="*" --dry-run -o yaml
W1026 15:11:28.972822 93761 helpers.go:692] --dry-run is deprecated and can be replaced with --dry-run=client.
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  creationTimestamp: null
  name: pulin-admin
rules:
- apiGroups:
  - ""
  resources:
  - '*'
  verbs:
  - '*'
- nonResourceURLs:
  - '*'
  verbs:
  - '*'
[root@node1 pki]# kubectl create clusterrole pulin-admin --verb="*" --resource="*" --non-resource-url="*"
clusterrole.rbac.authorization.k8s.io/pulin-admin created
  • Create via yaml file
[root@k8s-master01 ~]# cat myrole2.yaml
apiVersion: rbac.authorization.k8s.io/v1
#api version, use kubectl explain + [resources to be queried, such as pod]
kind: Role
metadata:
  name: myrole2
rules: #rules
- apiGroups: [""] # The empty string "" indicates that all api versions are supported. Generally, leave it empty.
  resources: ["pods"] #resources: Resources, which resources these permissions are now effective for. What is written here is pod. If you want to write more, separate them with commas. It is actually a list.
  verbs: ["get", "watch", "list"] #Detailed permissions: These three are viewing permissions. If you need all permissions, just fill in an *
[root@k8s-master01 ~]# kubectl create -f myrole2.yaml
role.rbac.authorization.k8s.io/myrole2 created
3.3.4. Role binding user
[root@node1 pki]# kubectl create rolebinding myrole-binding --role=myrole2 --user=pulin --dry-run -o yaml
\W1026 15:00:23.884947 90400 helpers.go:692] --dry-run is deprecated and can be replaced with --dry-run=client.
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  creationTimestamp: null
  name:myrole-binding
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: myrole2
subjects:
- apiGroup: rbac.authorization.k8s.io
  kind: User
  name: pulin
[root@node1 pki]# kubectl create clusterrolebinding pulin-admin-ding --user=pulin --clusterrole=pulin-admin --dry-run -o yaml
W1026 15:14:24.283139 94613 helpers.go:692] --dry-run is deprecated and can be replaced with --dry-run=client.
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  creationTimestamp: null
  name: pulin-admin-ding
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind:ClusterRole
  name: pulin-admin
subjects:
- apiGroup: rbac.authorization.k8s.io
  kind: User
  name: pulin
[root@node1 pki]# kubectl create clusterrolebinding pulin-admin-ding --user=pulin --clusterrole=pulin-admin
clusterrolebinding.rbac.authorization.k8s.io/pulin-admin-ding created
3.4. Using account
[root@node1 pki]# kubectl config use-context pulin
Switched to context "pulin".
[root@node1 pki]# kubectl config get-contexts
CURRENT NAME CLUSTER AUTHINFO NAMESPACE
          kubernetes-admin@kubernetes kubernetes kubernetes-admin
*pulin kubernetes pulin*

Use the following command to switch the context back to the administrator user

[root@node1 pki]# kubectl config use-context kubernetes-admin@kubernetes
Switched to context “kubernetes-admin@kubernetes”.

[root@node1 pki]# kubectl config get-contexts
CURRENT NAME CLUSTER AUTHINFO NAMESPACE
* kubernetes-admin@kubernetes kubernetes kubernetes-admin
pulin kubernetes pulin *