Skip to content

Commit 5d20793

Browse files
committed
Add Volume Group KEP
1 parent 6427a0b commit 5d20793

File tree

1 file changed

+369
-0
lines changed

1 file changed

+369
-0
lines changed
Lines changed: 369 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,369 @@
1+
Volume Group KEP
2+
3+
---
4+
title: Volume Group
5+
authors:
6+
- "@xing-yang"
7+
- "@jingxu97"
8+
owning-sig: sig-storage
9+
participating-sigs:
10+
- sig-storage
11+
reviewers:
12+
- "@msau42"
13+
- "@saad-ali"
14+
- "@thockin"
15+
approvers:
16+
- "@msau42"
17+
- "@saad-ali"
18+
- "@thockin"
19+
editor: TBD
20+
creation-date: 2020-02-12
21+
last-updated: 2020-02-12
22+
status: provisional
23+
see-also:
24+
- n/a
25+
replaces:
26+
- n/a
27+
superseded-by:
28+
- n/a
29+
---
30+
31+
# Title
32+
33+
Volume Group
34+
35+
## Table of Contents
36+
37+
<!-- toc -->
38+
- [Summary](#summary)
39+
- [Motivation](#motivation)
40+
- [Goals](#goals)
41+
- [Non-Goals](#non-goals)
42+
- [Proposal](#proposal)
43+
- [API Definitions](#api-definitions)
44+
- [Example Yaml Files](#example-yaml-files)
45+
- [Volume Group Snapshot](#volume-group-snapshot)
46+
- [Volume Placement](#volume-placement)
47+
<!-- /toc -->
48+
49+
## Summary
50+
51+
This proposal is to introduce a VolumeGroup API to manage multiple volumes together and a GroupSnapshot API to take a snapshot of a VolumeGroup.
52+
53+
## Motivation
54+
55+
While there is already a KEP (https://github.com/kubernetes/enhancements/pull/1051) that introduces APIs to do application snapshot, backup, and restore, there are other use cases not covered by that KEP.
56+
57+
Use case 1:
58+
A VolumeGroup allows users to manage multiple volumes belonging to the same application together and therefore it is very useful in general. For example, it can be used to group all volumes in the same StatefulSet together.
59+
60+
User case 2:
61+
For some storage systems, volumes are always managed in a group. For these storage systems, they will have to create a group for a single volume if they need to implement a create volume function in Kubernetes. Providing a VolumeGroup API will be very convenient for them.
62+
63+
Use case 3:
64+
Instead of taking individual snapshots one after another, VolumeGroup can be used as a source for taking a snapshot of all the volumes in the same volume group. This may be a storage level consistent group snapshot if the storage system supports it. In any case, when used together with ExecutionHook, this group snapshot can be application consistent. For this use case, we will introduce another CRD GroupSnapshot.
65+
66+
Use case 4:
67+
VolumeGroup can be used to manage group replication or consistency group replication if the storage system supports it. Note replication is out of scope for this proposal. It is mentioned here as a potential future use case.
68+
69+
Use case 5:
70+
VolumeGroup can be used to manage volume placement to either spread the volumes across storage pools or stack the volumes on the same storage pool. Related KEPs proposing the concept of storage pool for volume placement is as follows:
71+
https://github.com/kubernetes/enhancements/pull/1353
72+
https://github.com/kubernetes/enhancements/pull/1347
73+
We may not really need a VolumeGroup for this use case. A StoragePool is probably enough. This is to be determined.
74+
75+
Use case 6:
76+
VolumeGroup can also be used together with application snapshot. It can be a resource managed by the ApplicationSnapshot CRD.
77+
78+
Use case 7:
79+
Some applications may not want to use ApplicationSnapshot CRD because they don’t use Kubernetes workload APIs such as StatefulSet, Deployment, etc. Instead, they have developed their own operators. In this case it is more convenient to use VolumeGroup to manage persistent volumes used in those applications.
80+
81+
### Goals
82+
83+
* Provide an API to manage multiple volumes together in a group.
84+
* Provide an API to take a snapshot of a group of volumes.
85+
* Provide a design to facilitate volume placement using the group API (To be determined).
86+
* The group API should be generic and extensible so that it may be used to support other features in the future.
87+
88+
### Non-Goals
89+
90+
* A VolumeGroup may potentially be used to support replication group in the future, but providing design on replication group is not in the scope of this KEP. This can be discussed in the future.
91+
92+
## Proposal
93+
94+
This proposal introduces new CRDs VolumeGroup, VolumeGroupClass, and GroupSnapshot.
95+
96+
Create new group:
97+
There are two ways to create a new VolumeGroup.
98+
* Create a group with existing volumes, either with a list of PVCs or using a selector.
99+
* Create an empty group first, then create each individual volume with group_id which will add a volume to the already created group.
100+
101+
Snapshot:
102+
A GroupSnapshot can be created with a VolumeGroup as the source.
103+
104+
Restore:
105+
* In the restore case, a VolumeGroup can be created from a GroupSnapshot source.
106+
* We could also achieve this by creating a volume from a snapshot for all the snapshots in the GroupSnapshot, and then create a group with those restored volumes.
107+
108+
For the volume placement support, it assumes that storage pools exist on storage systems already. In VolumeGroupClass, there is an AllowedTopologies field that can be used to specify the accessibility of the group of volumes to storage pools and nodes. However it won’t have a field to track the capacities of the storage pools.
109+
110+
### API Definitions
111+
112+
API definitions are as follows:
113+
114+
```
115+
type VolumeGroupClass struct {
116+
metav1.TypeMeta
117+
// +optional
118+
metav1.ObjectMeta
119+
120+
// Driver is the driver expected to handle this VolumeGroupClass.
121+
// This value may not be empty.
122+
Driver string
123+
124+
// Parameters holds parameters for driver.
125+
// These values are opaque to the system and are passed directly
126+
// to the driver.
127+
// +optional
128+
Parameters map[string]string
129+
130+
// This field specifies whether group snapshot is supported.
131+
// The default is false.
132+
// +optional
133+
GroupSnapshot *bool
134+
135+
// Restrict the topologies where a group of volumes can be located.
136+
// Each driver defines its own supported topology specifications.
137+
// An empty TopologySelectorTerm list means there is no topology restriction.
138+
// This field is passed on to the drivers to handle placement of a group of
139+
// volumes on storage pools.
140+
// +optional
141+
AllowedTopologies []api.TopologySelectorTerm
142+
}
143+
144+
// VolumeGroup is a user's request for a group of volumes
145+
type VolumeGroup struct {
146+
metav1.TypeMeta
147+
// +optional
148+
metav1.ObjectMeta
149+
150+
// Spec defines the volume group requested by a user
151+
Spec VolumeGroupSpec
152+
153+
// Status represents the current information about a volume group
154+
// +optional
155+
Status *VolumeGroupStatus
156+
}
157+
158+
// VolumeGroupSpec describes the common attributes of group storage devices
159+
// and allows a Source for provider-specific attributes
160+
Type VolumeGroupSpec struct {
161+
// +optional
162+
VolumeGroupClassName *string
163+
164+
// If Source is nil, an empty volume group will be created.
165+
// Otherwise, a volume group will be created with PVCs (if PVCList or Select is set) or
166+
// with a GroupSnapshot as data source
167+
// +optional
168+
Source *VolumeGroupSource
169+
}
170+
171+
// VolumeGroupSource contains 3 options. If VolumeGroupSource is not nil,
172+
// one of the 3 options must be defined.
173+
Type VolumeGroupSource struct {
174+
// A list of existing persistent volume claims
175+
// +optional
176+
PVCList []PersistentVolumeClaim
177+
178+
// A label query over existing persistent volume claims to be added to the volume group.
179+
// +optional
180+
Selector *metav1.LabelSelector
181+
182+
// This field specifies the source of a volume group. (this is for restore)
183+
// Supported Kind is GroupSnapshot
184+
// +optional
185+
GroupDataSource *TypedLocalObjectReference
186+
}
187+
188+
type VolumeGroupStatus struct {
189+
GroupCreationTime *metav1.Time
190+
191+
// A list of persistent volume claims
192+
// +optional
193+
PVCList []PersistentVolumeClaim
194+
195+
Ready *bool
196+
197+
// Last error encountered during group creation
198+
Error *VolumeGroupError
199+
}
200+
201+
// Describes an error encountered on the group
202+
type VolumeGroupError struct {
203+
// time is the timestamp when the error was encountered.
204+
// +optional
205+
Time *metav1.Time
206+
207+
// message details the encountered error
208+
// +optional
209+
Message *string
210+
}
211+
212+
// GroupSnapshot is a user's request for taking a group snapshot.
213+
type GroupSnapshot struct {
214+
metav1.TypeMeta `json:",inline"`
215+
// Standard object's metadata.
216+
// +optional
217+
metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
218+
219+
// Spec defines the desired characteristics of a group snapshot requested by a user.
220+
Spec GroupSnapshotSpec `json:"spec" protobuf:"bytes,2,opt,name=spec"`
221+
222+
// Status represents the latest observed state of the group snapshot
223+
// +optional
224+
Status *GroupSnapshotStatus `json:"status,omitempty" protobuf:"bytes,3,opt,name=status"`
225+
}
226+
227+
// GroupSnapshotSpec describes the common attributes of a group snapshot
228+
type GroupSnapshotSpec struct {
229+
// Source has the information about where the group snapshot is created from.
230+
// Supported Kind is VolumeGroup
231+
// +optional
232+
Source *TypedLocalObjectReference `json:"source" protobuf:"bytes,1,opt,name=source"`
233+
234+
// GroupSnapshotName is the name of the group snapshot
235+
// +optional
236+
GroupSnapshotName string `json:"groupSnapshotName" protobuf:"bytes,2,opt,name=groupSnapshotName"`
237+
}
238+
239+
Type GroupSnapshotStatus struct {
240+
241+
// ReadyToUse becomes true when ReadyToUse on all individual snapshots become true
242+
// +optional
243+
ReadyToUse *bool
244+
245+
// List of volume snapshots
246+
SnapshotList []VolumeSnapshot
247+
}
248+
249+
type PersistentVolumeClaimSpec struct {
250+
......
251+
VolumeGroupId *string
252+
......
253+
}
254+
255+
256+
type VolumeSnapshotSpec struct{
257+
......
258+
GroupSnapshotId *string
259+
......
260+
}
261+
```
262+
263+
### Example Yaml Files
264+
265+
#### Volume Group Snapshot
266+
267+
Example yaml files to define a VolumeGroupClass and VolumeGroup are in the following.
268+
269+
A VolumeGroupClass that supports groupSnapshot:
270+
```
271+
apiVersion: volumegroup.storage.k8s.io/v1alpha1
272+
kind: VolumeGroupClass
273+
metadata:
274+
name: volumeGroupClass1
275+
spec:
276+
parameters:
277+
…...
278+
groupSnapshot: true
279+
```
280+
281+
A VolumeGroup belongs to this VolumeGroupClass:
282+
```
283+
apiVersion: volumegroup.storage.k8s.io/v1alpha1
284+
kind: VolumeGroup
285+
metadata:
286+
Name: volumeGroup1
287+
spec:
288+
volumeGroupClassName: volumeGroupClass1
289+
selector:
290+
matchLabels:
291+
app: my-app
292+
```
293+
294+
A GroupSnapshot taken from the VolumeGroup:
295+
```
296+
apiVersion: volumegroup.storage.k8s.io/v1alpha1
297+
kind: GroupSnapshot
298+
metadata:
299+
name: my-group-snapshot
300+
spec:
301+
sourceGroupName: volumeGroup1
302+
```
303+
304+
A PVC that belongs to the volume group which supports groupSnapshot:
305+
```
306+
apiVersion: v1
307+
kind: PersistentVolumeClaim
308+
metadata:
309+
name: pvc1
310+
annotations:
311+
spec:
312+
accessModes:
313+
- ReadWriteOnce
314+
dataSource: null
315+
resources:
316+
requests:
317+
storage: 1Gi
318+
storageClassName: storageClass1
319+
volumeMode: Filesystem
320+
volumeGroupNames: [volumeGroup1]
321+
```
322+
323+
#### Volume Placement
324+
325+
A VolumeGroupClass that supports placement:
326+
```
327+
apiVersion: volumegroup.storage.k8s.io/v1alpha1
328+
kind: VolumeGroupClass
329+
metadata:
330+
name: placementGroupClass1
331+
spec:
332+
parameters:
333+
…...
334+
allowedTopologies: [failure-domain.example.com/placement: storagePool1]
335+
```
336+
```
337+
apiVersion: volumegroup.storage.k8s.io/v1alpha1
338+
kind: VolumeGroup
339+
metadata:
340+
Name: placemenGroup1
341+
spec:
342+
volumeGroupClassName: placementGroupClass1
343+
```
344+
345+
A PVC that belongs to both the volume group with groupSnapshot support and placement.
346+
```
347+
apiVersion: v1
348+
kind: PersistentVolumeClaim
349+
metadata:
350+
name: pvc1
351+
annotations:
352+
spec:
353+
accessModes:
354+
- ReadWriteOnce
355+
dataSource: null
356+
resources:
357+
requests:
358+
storage: 1Gi
359+
storageClassName: storageClass1
360+
volumeMode: Filesystem
361+
volumeGroupNames: [volumeGroup1, placementGroup1]
362+
```
363+
364+
Note: More details on VolumeGroup and VolumeGroupClass related changes in CSI Spec will be added after we make decisions on how to proceed with the design, i.e., should we drop the placement part.
365+
366+
A new external controller will handle VolumeGroupClass and VolumeGroup resources.
367+
External provisioner will be modified to read information from volume groups (through volumeGroupNames) and pass them down to the CSI driver.
368+
369+
If both placement group and volume group with groupSnapshot support are defined, it is possible for the same volume to join both groups. For example, a volume group with groupSnapshot support may include volume members from two placement groups as they belong to the same application.

0 commit comments

Comments
 (0)