diff --git a/docs/op/op-index.md b/docs/op/op-index.md index ff61c56..35af2e0 100644 --- a/docs/op/op-index.md +++ b/docs/op/op-index.md @@ -8,3 +8,4 @@ - [集群删除单个节点](del_one_node.md) - [替换集群使用的网络插件](change_k8s_network.md) - [集群备份与恢复](cluster_restore.md) +- [设置只读权限 kubeconfig](readonly_kubectl.md) diff --git a/docs/op/readonly_kubectl.md b/docs/op/readonly_kubectl.md new file mode 100644 index 0000000..4182f47 --- /dev/null +++ b/docs/op/readonly_kubectl.md @@ -0,0 +1,65 @@ +# 配置 kubectl 只读访问权限 + +默认 k8s 集群安装后配置的 kubectl 客户端拥有所有的管理权限,而有时候我们需要把只读权限分发给普通开发人员,本文档将创建一个只读权限的kubectl 配置文档 kubeconfig。 + +## 创建 + +- 备份下原先 admin 权限的 kubeconfig 文件:`mv ~/.kube ~/.kubeadmin` +- 执行 `ansible-playbook /etc/ansible/roles/deploy/create-read-kubeconfig.yml`,成功后查看~/.kube/config 即为只读权限 + +## 讲解 + +对照文件`/etc/ansible/roles/deploy/create-read-kubeconfig.yml`,创建主要包括三个步骤: + +- 创建 group:read rbac 权限 +- 创建 read 用户证书和私钥 +- 创建 kubeconfig + +### read rbac 权限 + +所有权限控制魔法在`k8s`中由`rbac`实现,所谓`read`权限类似于集群自带的`clusterrole view`,具体查看: + +`kubectl get clusterrole view -o yaml` + +`read`权限配置`roles/deploy/files/read-group-rbac.yaml`是在`clusterrole view`基础上增加了若干读权限(Nodes/Persistent Volume Claims) + +### read 用户证书 + +准备 read 证书请求:`read-csr.json` + +``` bash +{ + "CN": "read", + "hosts": [], + "key": { + "algo": "rsa", + "size": 2048 + }, + "names": [ + { + "C": "CN", + "ST": "HangZhou", + "L": "XS", + "O": "group:read", + "OU": "System" + } + ] +} +``` +- 注意: O `group:read`,kube-apiserver 收到该证书后将请求的 Group 设置为`group:read`;之前步骤创建的 ClusterRoleBinding `read-clusterrole-binding`将 Group `group:read`与 ClusterRole `read-clusterrole`绑定,从而实现只读权限。 + +### read kubeconfig + +kubeconfig 为与apiserver交互使用的认证配置文件,如脚本步骤需要: + +- 设置集群参数,指定CA证书和apiserver地址 +- 设置客户端认证参数,指定使用read证书和私钥 +- 设置上下文参数,指定使用cluster集群和用户read +- 设置指定默认上下文 + +创建完成后生成默认配置文件为 `~/.kube/config` + +## 参考 + +- [Using RBAC Authorization](https://kubernetes.io/docs/reference/access-authn-authz/rbac/) +- [A Read Only Kubernetes Dashboard](https://blog.cowger.us/2018/07/03/a-read-only-kubernetes-dashboard.html) diff --git a/roles/deploy/create-read-kubeconfig.yml b/roles/deploy/create-read-kubeconfig.yml new file mode 100644 index 0000000..93d1d33 --- /dev/null +++ b/roles/deploy/create-read-kubeconfig.yml @@ -0,0 +1,41 @@ +- hosts: deploy + tasks: + - name: 在deploy 节点创建相关目录 + file: path=/opt/kube/kube-system state=directory + + - name: 下载 group:read rbac 文件 + copy: src=read-group-rbac.yaml dest=/opt/kube/kube-system/read-group-rbac.yaml + + - name: 创建group:read rbac 绑定 + shell: "{{ bin_dir }}/kubectl apply -f /opt/kube/kube-system/read-group-rbac.yaml" + + # 创建readonly kubectl kubeconfig文件: /root/.kube/config + - name: 准备kubectl使用的read 证书签名请求 + template: src=read-csr.json.j2 dest={{ ca_dir }}/read-csr.json + + - name: 创建 read证书与私钥 + shell: "cd {{ ca_dir }} && {{ bin_dir }}/cfssl gencert \ + -ca={{ ca_dir }}/ca.pem \ + -ca-key={{ ca_dir }}/ca-key.pem \ + -config={{ ca_dir }}/ca-config.json \ + -profile=kubernetes read-csr.json | {{ bin_dir }}/cfssljson -bare read" + # 设置集群参数,指定CA证书和apiserver地址 + - name: 设置集群参数 + shell: "{{ bin_dir }}/kubectl config set-cluster kubernetes \ + --certificate-authority={{ ca_dir }}/ca.pem \ + --embed-certs=true \ + --server={{ KUBE_APISERVER }}" + # 设置客户端认证参数,指定使用read证书和私钥 + - name: 设置客户端认证参数 + shell: "{{ bin_dir }}/kubectl config set-credentials read \ + --client-certificate={{ ca_dir }}/read.pem \ + --embed-certs=true \ + --client-key={{ ca_dir }}/read-key.pem" + # 设置上下文参数,说明使用cluster集群和用户read + - name: 设置上下文参数 + shell: "{{ bin_dir }}/kubectl config set-context kubernetes \ + --cluster=kubernetes --user=read" + # 选择默认上下文 + - name: 选择默认上下文 + shell: "{{ bin_dir }}/kubectl config use-context kubernetes" + diff --git a/roles/deploy/files/read-group-rbac.yaml b/roles/deploy/files/read-group-rbac.yaml new file mode 100644 index 0000000..d39d85c --- /dev/null +++ b/roles/deploy/files/read-group-rbac.yaml @@ -0,0 +1,142 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: read-clusterrole-binding +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: read-clusterrole +subjects: +- kind: Group + name: "group:read" + apiGroup: rbac.authorization.k8s.io + +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: read-clusterrole +rules: +- apiGroups: + - "" + resources: + - configmaps + - endpoints + - persistentvolumeclaims + - pods + - replicationcontrollers + - replicationcontrollers/scale + - serviceaccounts + - services + - nodes + - persistentvolumeclaims + - persistentvolumes + verbs: + - get + - list + - watch +- apiGroups: + - "" + resources: + - bindings + - events + - limitranges + - namespaces/status + - pods/log + - pods/status + - replicationcontrollers/status + - resourcequotas + - resourcequotas/status + verbs: + - get + - list + - watch +- apiGroups: + - "" + resources: + - namespaces + verbs: + - get + - list + - watch +- apiGroups: + - apps + resources: + - daemonsets + - deployments + - deployments/scale + - replicasets + - replicasets/scale + - statefulsets + verbs: + - get + - list + - watch +- apiGroups: + - autoscaling + resources: + - horizontalpodautoscalers + verbs: + - get + - list + - watch +- apiGroups: + - batch + resources: + - cronjobs + - jobs + verbs: + - get + - list + - watch +- apiGroups: + - extensions + resources: + - daemonsets + - deployments + - deployments/scale + - ingresses + - networkpolicies + - replicasets + - replicasets/scale + - replicationcontrollers/scale + verbs: + - get + - list + - watch +- apiGroups: + - policy + resources: + - poddisruptionbudgets + verbs: + - get + - list + - watch +- apiGroups: + - networking.k8s.io + resources: + - networkpolicies + verbs: + - get + - list + - watch +- apiGroups: + - storage.k8s.io + resources: + - storageclasses + - volumeattachments + verbs: + - get + - list + - watch +- apiGroups: + - rbac.authorization.k8s.io + resources: + - clusterrolebindings + - clusterroles + - roles + - rolebindings + verbs: + - get + - list + - watch diff --git a/roles/deploy/templates/read-csr.json.j2 b/roles/deploy/templates/read-csr.json.j2 new file mode 100644 index 0000000..e70221d --- /dev/null +++ b/roles/deploy/templates/read-csr.json.j2 @@ -0,0 +1,17 @@ +{ + "CN": "read", + "hosts": [], + "key": { + "algo": "rsa", + "size": 2048 + }, + "names": [ + { + "C": "CN", + "ST": "HangZhou", + "L": "XS", + "O": "group:read", + "OU": "System" + } + ] +}