背景

经常有碰到这种需求:

  • 给某个用户某一指定名称空间下的管理权限
  • 给用户赋予集群的只读权限

前提

  • 准备一个 Kubernetes 机群
  • 了解 Kubernetes 的认证授权流程
  • Linux 下使用 openssl 创建自签证书

一、为用户创建证书

创建证书只是实现 Kubernetes 认证用,具体拥有什么样的权限取决于 RBAC 授权。也就是 RoleClusterRole

1.1 创建私钥

1cd /etc/kubernetes/pki
2(umask 077; openssl genrsa -out reader.key 2048)

输出如下

1Generating RSA private key, 2048 bit long modulus
2............+++
3...........................+++
4e is 65537 (0x10001)

1.2 创建证书颁发请求

1openssl req -new -key reader.key -out reader.csr -subj "/CN=reader"

CN 要跟后面的 User 保持一致

1.3 使用 CA 证书签发证书

1openssl x509 -req -in reader.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out reader.crt -days 3650

输出如下

1Signature ok
2subject=/CN=reader
3Getting CA Private Key

二、创建相应的 RoleRoleBinding

这里以创建 default 名称空间下查看 pod 和日志为例

2.1 创建 Role

 1kubectl apply -f - <<EOF
 2apiVersion: rbac.authorization.k8s.io/v1
 3kind: Role
 4metadata:
 5  name: pods-reader
 6  namespace: default
 7rules:
 8- apiGroups:
 9  - ""
10  resources:
11  - pods
12  - pods/log
13  verbs:
14  - get
15  - list
16  - watch
17EOF

输出如下

1role.rbac.authorization.k8s.io/pods-reader created

2.2 创建 RoleBinding

 1kubectl apply -f - <<EOF
 2apiVersion: rbac.authorization.k8s.io/v1
 3kind: RoleBinding
 4metadata:
 5  name: default-pods-reader
 6  namespace: default
 7roleRef:
 8  apiGroup: rbac.authorization.k8s.io
 9  kind: Role
10  name: pods-reader
11subjects:
12- apiGroup: rbac.authorization.k8s.io
13  kind: User
14  name: reader
15EOF

输出如下

1rolebinding.rbac.authorization.k8s.io/default-pods-reader created

三、为普通用户创建 KUBECONFIG 配置文件

3.1 设置集群

1kubectl config set-cluster kubernetes \
2  --server=https://192.168.100.10:6443 \
3  --certificate-authority=/etc/kubernetes/pki/ca.crt \
4  --embed-certs=true \
5  --kubeconfig=/tmp/reader.config

输出如下

1Cluster "kubernetes" set.

3.2 设置凭证

1kubectl config set-credentials pods-reader \
2  --client-certificate=/etc/kubernetes/pki/reader.crt \
3  --client-key=/etc/kubernetes/pki/reader.key \
4  --embed-certs=true \
5  --kubeconfig=/tmp/reader.config

输出如下

1User "pods-reader" set.

3.3 设置上下文

1kubectl config set-context pods-reader@kubernetes \
2  --cluster kubernetes \
3  --user=pods-reader \
4  --namespace=default \
5  --kubeconfig=/tmp/reader.config

输出如下

1Context "pods-reader@kubernetes" created.

3.4 设置当前上下文

1kubectl config use-context pods-reader@kubernetes \
2  --kubeconfig=/tmp/reader.config

输出如下

1Switched to context "pods-reader@kubernetes".

四、测试

4.1 使用 kubernetes-admin 创建 pod 测试

1kubectl create deployment nginx --image=nginx:1.20.1-alpine --replicas 3
2kubectl create svc clusterip nginx --tcp=80:80

4.2 查看 podsvc

1kubectl get po

输出如下

1NAME                     READY   STATUS    RESTARTS   AGE
2nginx-779c9459b8-bhbhd   1/1     Running   0          83s
3nginx-779c9459b8-r5rqc   1/1     Running   0          83s
4nginx-779c9459b8-tp4dt   1/1     Running   0          83s
1kubectl get svc

输出如下

1NAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
2kubernetes   ClusterIP   10.96.0.1       <none>        443/TCP   27m
3nginx        ClusterIP   10.106.127.90   <none>        80/TCP    86s

4.3 切换普通用户测试

查看 pod

1KUBECONFIG=/tmp/reader.config kubectl get po

输出如下,正常

1NAME                     READY   STATUS    RESTARTS   AGE
2nginx-779c9459b8-bhbhd   1/1     Running   0          2m41s
3nginx-779c9459b8-r5rqc   1/1     Running   0          2m41s
4nginx-779c9459b8-tp4dt   1/1     Running   0          2m41s

查看 svc

1KUBECONFIG=/tmp/reader.config kubectl get svc

输出如下,无操作权限

1Error from server (Forbidden): services is forbidden: User "reader" cannot list resource "services" in API group "" in the namespace "default"

删除 pod

1KUBECONFIG=/tmp/reader.config kubectl delete po nginx-779c9459b8-bhbhd

输出如下,无操作权限

1Error from server (Forbidden): pods "nginx-779c9459b8-bhbhd" is forbidden: User "reader" cannot delete resource "pods" in API group "" in the namespace "default"

五、创建集群只读用户

该用户可以查看机群内所有资源,但是不能修改

这里证书还是复用前面创建的证书,也可以重新创建

5.1 创建 ClusterRole

 1kubectl apply -f - <<EOF
 2apiVersion: rbac.authorization.k8s.io/v1
 3kind: ClusterRole
 4metadata:
 5  name: cluster-reader
 6rules:
 7- apiGroups:
 8  - ""
 9  resources:
10  - nodes
11  - pods
12  - pods/exec
13  - pods/log
14  - services
15  - configmaps
16  - secrets
17  - serviceaccounts
18  - endpoints
19  verbs:
20  - get
21  - list
22  - watch
23- apiGroups:
24  - apps
25  resources:
26  - deployments
27  - replicasets
28  - daemonsets
29  - statefulsets
30  verbs:
31  - get
32  - list
33  - watch
34- apiGroups:
35  - batch
36  resources:
37  - jobs
38  - cronjobs
39  verbs:
40  - get
41  - list
42  - watch
43EOF

输出如下

1clusterrole.rbac.authorization.k8s.io/cluster-reader created

5.2 创建 ClusterRoleBinding

 1kubectl apply -f - <<EOF
 2apiVersion: rbac.authorization.k8s.io/v1
 3kind: ClusterRoleBinding
 4metadata:
 5  name: cluster-reader
 6roleRef:
 7  apiGroup: rbac.authorization.k8s.io
 8  kind: ClusterRole
 9  name: cluster-reader
10subjects:
11- apiGroup: rbac.authorization.k8s.io
12  kind: User
13  name: reader
14EOF

输出如下

1clusterrolebinding.rbac.authorization.k8s.io/cluster-reader created

5.3 创建 KUBECONFIG

 1kubectl config set-cluster kubernetes \
 2  --server=https://192.168.100.10:6443 \
 3  --certificate-authority=/etc/kubernetes/pki/ca.crt \
 4  --embed-certs=true \
 5  --kubeconfig=/tmp/cluster-reader.config
 6
 7kubectl config set-credentials cluster-reader \
 8  --client-certificate=/etc/kubernetes/pki/reader.crt \
 9  --client-key=/etc/kubernetes/pki/reader.key \
10  --embed-certs=true \
11  --kubeconfig=/tmp/cluster-reader.config
12
13kubectl config set-context cluster-reader@kubernetes \
14  --cluster kubernetes \
15  --user=cluster-reader \
16  --namespace=default \
17  --kubeconfig=/tmp/cluster-reader.config
18
19kubectl config use-context cluster-reader@kubernetes \
20  --kubeconfig=/tmp/cluster-reader.config

5.4 使用 KUBECONFIG

通过环境变量或者将其拷贝到 ~/.kube/config

1export KUBECONFIG=/tmp/cluster-reader.config

1cp /tmp/cluster-reader.config ~/.kube/config

这样就可以通过这个只读账号查看 Kubernetes 集群的资源了。