Kubernetes Service Accounts and RBAC
The Kubernetes integration and the Kubernetes inventory operate on a cluster using the permissions of the credentials they are given.
The Kubernetes integration provides several protocols, each backing up or restoring a different kind of data:
k8s: Kubernetes manifests and resource state. Backup and restore.k8s+csi: PVC contents, read from a CSIVolumeSnapshot. Backup only.k8s+pvc: PVC contents, read directly from the volume. Backup and restore.k8s+vm: KubeVirt virtual machines and their disks. Backup and restore.
See Kubernetes PVC for how the PVC protocols are used in Plakar Control Plane.
The required permissions depend on the operation. This guide provides a separate Role or ClusterRole and ServiceAccount for each operation. Apply only the roles required by your deployment.
Keeping the ServiceAccounts separate limits the impact of each operation. For example, a backup ServiceAccount cannot modify the cluster, while the inventory ServiceAccount can discover PVCs without accessing their contents.
Do not grant all of these roles to the same ServiceAccount. A ServiceAccount with every role described in this guide has permissions equivalent to a cluster administrator.
Roles overview
| Operation | ServiceAccount | Scope |
|---|---|---|
| PVC backup and restore | plakar-pvc |
Namespaced |
| Port forwarding | Shared | Namespaced |
| VM backup | plakar-vm-backup |
Namespaced |
| VM restore | plakar-vm-restore |
Namespaced, write |
| Manifest backup | plakar-resources-backup |
Cluster-wide read, including Secrets |
| Manifest restore | plakar-resources-restore |
Cluster-wide write |
| Inventory | plakar-inventory |
Cluster-wide read of PVCs only |
The manifests use two placeholders:
plakar: the namespace containing the ServiceAccounts. For in-cluster deployments, this is the namespace where Plakar runs.target-namespace: the namespace containing the resources to back up or restore. Namespaced roles must be created once for each target namespace.
Create the plakar namespace first:
apiVersion: v1
kind: Namespace
metadata:
name: plakarPVC backup and restore
This role covers the k8s+csi and k8s+pvc protocols. It is the smallest role
and is the only role required when backing up volumes.
The connectors read the target PVC and start a temporary pod that serves the volume over mTLS. Plakar reads the pod log to obtain the public key used to connect to the pod.
The k8s+csi protocol also creates a VolumeSnapshot and a temporary PVC
cloned from that snapshot. If you only use k8s+pvc, remove the
volumesnapshots rule and the create and delete verbs from the
persistentvolumeclaims rule.
Read access to events is optional. It improves error messages when a pod does not become ready, for example when a PVC does not bind.
apiVersion: v1
kind: ServiceAccount
metadata:
name: plakar-pvc
namespace: plakar
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: plakar-pvc
namespace: target-namespace
rules:
- apiGroups: [""]
resources: ["persistentvolumeclaims"]
verbs: ["get", "create", "delete"]
- apiGroups: [""]
resources: ["pods"]
verbs: ["create", "get", "list", "watch", "delete"]
- apiGroups: [""]
resources: ["pods/log"]
verbs: ["get"]
- apiGroups: ["snapshot.storage.k8s.io"]
resources: ["volumesnapshots"]
verbs: ["create", "get", "list", "watch", "delete"]
- apiGroups: [""]
resources: ["events"]
verbs: ["get", "list"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: plakar-pvc
namespace: target-namespace
subjects:
- kind: ServiceAccount
name: plakar-pvc
namespace: plakar
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: plakar-pvcPort forwarding
When Plakar runs outside the cluster using a kubeconfig, it reaches the temporary pod through the API server’s port-forwarding subresource.
When Plakar runs inside the cluster, it connects to the pod directly and does not require this role.
The role is shared by the ServiceAccounts used by operations that start temporary serving pods: PVC backup and restore, and VM backup and restore. Keep only the ServiceAccounts you actually use in the RoleBinding.
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: plakar-pvc-portforward
namespace: target-namespace
rules:
- apiGroups: [""]
resources: ["pods/portforward"]
verbs: ["create"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: plakar-pvc-portforward
namespace: target-namespace
subjects:
- kind: ServiceAccount
name: plakar-pvc
namespace: plakar
- kind: ServiceAccount
name: plakar-vm-backup
namespace: plakar
- kind: ServiceAccount
name: plakar-vm-restore
namespace: plakar
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: plakar-pvc-portforwardVM backup
This role is used by the k8s+vm protocol when backing up KubeVirt virtual
machines. The cluster must support KubeVirt snapshots.
The backup creates a VirtualMachineSnapshot. The KubeVirt controller handles
the guest-side snapshot operation: it freezes the guest, creates a
VolumeSnapshot for each disk, and thaws the guest again.
Plakar then reads each disk through a temporary PVC and pod, in the same way as a PVC backup. The virtual machine itself is only read.
The VirtualMachineSnapshot and the underlying VolumeSnapshot resources are
created by KubeVirt using its own credentials. The Plakar ServiceAccount only
needs permission to create and read the VirtualMachineSnapshot, and to read
the resulting VolumeSnapshot resources.
apiVersion: v1
kind: ServiceAccount
metadata:
name: plakar-vm-backup
namespace: plakar
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: plakar-vm-backup
namespace: target-namespace
rules:
- apiGroups: ["kubevirt.io"]
resources: ["virtualmachines"]
verbs: ["get"]
- apiGroups: ["snapshot.kubevirt.io"]
resources: ["virtualmachinesnapshots"]
verbs: ["create", "get", "list", "watch", "delete"]
- apiGroups: ["snapshot.kubevirt.io"]
resources: ["virtualmachinesnapshotcontents"]
verbs: ["get"]
- apiGroups: ["snapshot.storage.k8s.io"]
resources: ["volumesnapshots"]
verbs: ["get", "list", "watch"]
- apiGroups: [""]
resources: ["persistentvolumeclaims"]
verbs: ["create", "get", "delete"]
- apiGroups: [""]
resources: ["pods"]
verbs: ["create", "get", "list", "watch", "delete"]
- apiGroups: [""]
resources: ["pods/log"]
verbs: ["get"]
- apiGroups: [""]
resources: ["events"]
verbs: ["get", "list"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: plakar-vm-backup
namespace: target-namespace
subjects:
- kind: ServiceAccount
name: plakar-vm-backup
namespace: plakar
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: plakar-vm-backupVM restore
This role is used by the k8s+vm protocol when restoring a virtual machine.
The restore recreates each disk, streams the disk contents through a temporary pod, and applies the virtual machine manifest last.
The role is namespaced and only grants access to virtual machines and PVCs, along with the temporary pods required to transfer the disk data. It still grants write access to a virtual machine and therefore to whatever runs inside that virtual machine. Keep it separate from the ServiceAccount used for backups.
A restore does not delete an existing PVC. It applies the restored configuration over the existing claim.
apiVersion: v1
kind: ServiceAccount
metadata:
name: plakar-vm-restore
namespace: plakar
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: plakar-vm-restore
namespace: target-namespace
rules:
- apiGroups: ["kubevirt.io"]
resources: ["virtualmachines"]
verbs: ["get", "create", "patch"]
- apiGroups: [""]
resources: ["persistentvolumeclaims"]
verbs: ["get", "create", "patch"]
- apiGroups: [""]
resources: ["pods"]
verbs: ["create", "get", "list", "watch", "delete"]
- apiGroups: [""]
resources: ["pods/log"]
verbs: ["get"]
- apiGroups: [""]
resources: ["events"]
verbs: ["get", "list"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: plakar-vm-restore
namespace: target-namespace
subjects:
- kind: ServiceAccount
name: plakar-vm-restore
namespace: plakar
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: plakar-vm-restoreManifest backup
Warning
A manifest backup lists every resource type the cluster exposes, including Secrets. Anyone who can run a backup using this ServiceAccount can read every Secret in the cluster. Anyone who can read the resulting snapshot can also access those Secrets.
This role is used by the k8s protocol. It grants cluster-wide read access to
Kubernetes resources.
apiVersion: v1
kind: ServiceAccount
metadata:
name: plakar-resources-backup
namespace: plakar
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: plakar-resources-backup
rules:
- apiGroups: ["*"]
resources: ["*"]
verbs: ["get", "list"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: plakar-resources-backup
subjects:
- kind: ServiceAccount
name: plakar-resources-backup
namespace: plakar
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: plakar-resources-backupManifest restore
This role is used by the k8s protocol when restoring manifests.
A restore can apply any resource kind stored in the snapshot, so the role grants cluster-wide write access. Keep it on a separate ServiceAccount from manifest backups. A scheduled backup does not require this role.
apiVersion: v1
kind: ServiceAccount
metadata:
name: plakar-resources-restore
namespace: plakar
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: plakar-resources-restore
rules:
- apiGroups: ["*"]
resources: ["*"]
verbs: ["get", "list", "create", "patch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: plakar-resources-restore
subjects:
- kind: ServiceAccount
name: plakar-resources-restore
namespace: plakar
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: plakar-resources-restoreInventory
This role is used by the Kubernetes inventory to discover PVCs across all namespaces.
It only reads PVC metadata and never accesses the contents of the volumes. It
also reads the kube-system namespace, whose UID is used to identify the
cluster.
apiVersion: v1
kind: ServiceAccount
metadata:
name: plakar-inventory
namespace: plakar
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: plakar-inventory
rules:
- apiGroups: [""]
resources: ["persistentvolumeclaims"]
verbs: ["get", "list"]
- apiGroups: [""]
resources: ["namespaces"]
resourceNames: ["kube-system"]
verbs: ["get"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: plakar-inventory
subjects:
- kind: ServiceAccount
name: plakar-inventory
namespace: plakar
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: plakar-inventory