From a8cc8d84320eefb058b59af8a8d23885b46d3082 Mon Sep 17 00:00:00 2001 From: Patrick Ohly Date: Mon, 5 Nov 2018 11:37:42 +0100 Subject: [PATCH] deploy: split out RBAC definitions Splitting out the RBAC definitions into a separate file has the advantage that it can be used as-is without editing in other deployments. For example, the kubernetes-csi/docs example can use this rbac.yaml file instead of a local copy. While at it, the upstream external-provisioner RBAC file gets used, which fixes the too broad permissions for "endpoints". --- README.md | 4 +- deploy/kubernetes/README.md | 2 + .../kubernetes/rbac-external-provisioner.yaml | 90 +++++++++++++++++++ deploy/kubernetes/rbac.yaml | 84 +++++++++++++++++ deploy/kubernetes/setup-csi-snapshotter.yaml | 69 +------------- 5 files changed, 182 insertions(+), 67 deletions(-) create mode 100644 deploy/kubernetes/README.md create mode 100644 deploy/kubernetes/rbac-external-provisioner.yaml create mode 100644 deploy/kubernetes/rbac.yaml diff --git a/README.md b/README.md index 8e1a037ae..c7656736a 100644 --- a/README.md +++ b/README.md @@ -41,10 +41,10 @@ $ csi-snapshotter -kubeconfig ~/.kube/config -v 5 -csi-address /run/csi/socket ### Running in a statefulset -It is necessary to create a new service account and give it enough privileges to run the snapshotter. We provide one omnipotent yaml file that creates everything that's necessary, however it should be split into multiple files in production. +It is necessary to create a new service account and give it enough privileges to run the snapshotter. We provide .yaml files that deploy for use together with the hostpath example driver. A real production deployment must customize them: ``` -$ kubectl create -f deploy/kubernetes/statefulset.yaml +$ for i in $(find deploy/kubernetes -name '*.yaml'); do kubectl create -f $i; done ``` ## Testing diff --git a/deploy/kubernetes/README.md b/deploy/kubernetes/README.md new file mode 100644 index 000000000..8f2c44860 --- /dev/null +++ b/deploy/kubernetes/README.md @@ -0,0 +1,2 @@ +rbac-external-provisioner.yaml was copied from https://github.com/kubernetes-csi/external-provisioner/blob/master/deploy/kubernetes/rbac.yaml +and must be refreshed when updating the external-provisioner image in setup-csi-snapshotter.yaml diff --git a/deploy/kubernetes/rbac-external-provisioner.yaml b/deploy/kubernetes/rbac-external-provisioner.yaml new file mode 100644 index 000000000..65bd2e42e --- /dev/null +++ b/deploy/kubernetes/rbac-external-provisioner.yaml @@ -0,0 +1,90 @@ +# This YAML file contains all RBAC objects that are necessary to run external +# CSI provisioner. +# +# In production, each CSI driver deployment has to be customized: +# - to avoid conflicts, use non-default namespace and different names +# for non-namespaced entities like the ClusterRole +# - decide whether the deployment replicates the external CSI +# provisioner, in which case leadership election must be enabled; +# this influences the RBAC setup, see below + +apiVersion: v1 +kind: ServiceAccount +metadata: + name: csi-provisioner + # replace with non-default namespace name + namespace: default + +--- +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: external-provisioner-runner +rules: + - apiGroups: [""] + resources: ["secrets"] + verbs: ["get", "list"] + - 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: ["list", "watch", "create", "update", "patch"] + - apiGroups: ["snapshot.storage.k8s.io"] + resources: ["volumesnapshots"] + verbs: ["get", "list"] + - apiGroups: ["snapshot.storage.k8s.io"] + resources: ["volumesnapshotcontents"] + verbs: ["get", "list"] + +--- +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: csi-provisioner-role +subjects: + - kind: ServiceAccount + name: csi-provisioner + # replace with non-default namespace name + namespace: default +roleRef: + kind: ClusterRole + name: external-provisioner-runner + apiGroup: rbac.authorization.k8s.io + +--- +# Provisioner must be able to work with endpoints in current namespace +# if (and only if) leadership election is enabled +kind: Role +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + # replace with non-default namespace name + namespace: default + name: external-provisioner-cfg +rules: +- apiGroups: [""] + resources: ["endpoints"] + verbs: ["get", "watch", "list", "delete", "update", "create"] + +--- +kind: RoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: csi-provisioner-role-cfg + # replace with non-default namespace name + namespace: default +subjects: + - kind: ServiceAccount + name: csi-provisioner + # replace with non-default namespace name + namespace: default +roleRef: + kind: Role + name: external-provisioner-cfg + apiGroup: rbac.authorization.k8s.io diff --git a/deploy/kubernetes/rbac.yaml b/deploy/kubernetes/rbac.yaml new file mode 100644 index 000000000..b248fcda4 --- /dev/null +++ b/deploy/kubernetes/rbac.yaml @@ -0,0 +1,84 @@ +# Together with the RBAC file for external-provisioner, this YAML file +# contains all RBAC objects that are necessary to run external CSI +# snapshotter. +# +# In production, each CSI driver deployment has to be customized: +# - to avoid conflicts, use non-default namespace and different names +# for non-namespaced entities like the ClusterRole +# - optionally rename the non-namespaced ClusterRole if there +# are conflicts with other deployments + +apiVersion: v1 +kind: ServiceAccount +metadata: + name: csi-snapshotter + +--- +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + # rename if there are conflicts + name: external-snapshotter-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: ["list", "watch", "create", "update", "patch"] + - apiGroups: [""] + resources: ["secrets"] + verbs: ["get", "list"] + - apiGroups: ["snapshot.storage.k8s.io"] + resources: ["volumesnapshotclasses"] + verbs: ["get", "list", "watch"] + - apiGroups: ["snapshot.storage.k8s.io"] + resources: ["volumesnapshotcontents"] + verbs: ["create", "get", "list", "watch", "update", "delete"] + - apiGroups: ["snapshot.storage.k8s.io"] + resources: ["volumesnapshots"] + verbs: ["get", "list", "watch", "update"] + - apiGroups: ["apiextensions.k8s.io"] + resources: ["customresourcedefinitions"] + verbs: ["create", "list", "watch", "delete"] + +--- +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: csi-snapshotter-role +subjects: + - kind: ServiceAccount + name: csi-snapshotter + # replace with non-default namespace name + namespace: default +roleRef: + kind: ClusterRole + # change the name also here if the ClusterRole gets renamed + name: external-snapshotter-runner + apiGroup: rbac.authorization.k8s.io + +--- +# Provisioner must be able to work with endpoints in current namespace +# if (and only if) leadership election is enabled +kind: RoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: csi-snapshotter-provisioner-role + # replace with non-default namespace name + namespace: default +subjects: + - kind: ServiceAccount + name: csi-snapshotter + # replace with non-default namespace name + namespace: default +roleRef: + kind: Role + name: external-provisioner-cfg # from rbac-external-provisioner.yaml + apiGroup: rbac.authorization.k8s.io diff --git a/deploy/kubernetes/setup-csi-snapshotter.yaml b/deploy/kubernetes/setup-csi-snapshotter.yaml index c8880d2f3..435580e73 100644 --- a/deploy/kubernetes/setup-csi-snapshotter.yaml +++ b/deploy/kubernetes/setup-csi-snapshotter.yaml @@ -1,68 +1,7 @@ -# This YAML file contains all API objects that are necessary to run external -# CSI snapshotter. -# -# In production, this needs to be in separate files, e.g. service account and -# role and role binding needs to be created once, while stateful set may -# require some tuning. -# -# In addition, hostpath CSI driver is hardcoded as the CSI driver. -apiVersion: v1 -kind: ServiceAccount -metadata: - name: csi-snapshotter - ---- -kind: ClusterRole -apiVersion: rbac.authorization.k8s.io/v1 -metadata: - name: external-snapshotter-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: ["list", "watch", "create", "update", "patch"] - - apiGroups: [""] - resources: ["endpoints"] - verbs: ["list", "watch", "create", "update", "delete", "get"] - - apiGroups: [""] - resources: ["secrets"] - verbs: ["get", "list"] - - apiGroups: ["snapshot.storage.k8s.io"] - resources: ["volumesnapshotclasses"] - verbs: ["get", "list", "watch"] - - apiGroups: ["snapshot.storage.k8s.io"] - resources: ["volumesnapshotcontents"] - verbs: ["create", "get", "list", "watch", "update", "delete"] - - apiGroups: ["snapshot.storage.k8s.io"] - resources: ["volumesnapshots"] - verbs: ["get", "list", "watch", "update"] - - apiGroups: ["apiextensions.k8s.io"] - resources: ["customresourcedefinitions"] - verbs: ["create", "list", "watch", "delete"] - ---- -kind: ClusterRoleBinding -apiVersion: rbac.authorization.k8s.io/v1 -metadata: - name: csi-snapshotter-role -subjects: - - kind: ServiceAccount - name: csi-snapshotter - namespace: default -roleRef: - kind: ClusterRole - name: external-snapshotter-runner - apiGroup: rbac.authorization.k8s.io - ---- +# This YAML file shows how to deploy the CSI snapshotter together +# with the hostpath CSI driver. It depends on the RBAC rules +# from rbac.yaml. + kind: Service apiVersion: v1 metadata: