Skip to content

Commit 89c88fc

Browse files
authored
Merge pull request #4276 from nilekhc/update-svm-kep
[UPDATE] KEP-4192: Move Storage Version Migrator in-tree
2 parents 97465c4 + b254fb6 commit 89c88fc

File tree

2 files changed

+108
-46
lines changed

2 files changed

+108
-46
lines changed

keps/sig-api-machinery/4192-svm-in-tree/README.md

Lines changed: 104 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,12 @@
1616
- [Design Details](#design-details)
1717
- [APIs to move](#apis-to-move)
1818
- [We will move following <a href="https://github.com/kubernetes-sigs/kube-storage-version-migrator/blob/60dee538334c2366994c2323c0db5db8ab4d2838/pkg/apis/migration/v1alpha1/types.go">APIs</a> in-tree:](#we-will-move-following-apis-in-tree)
19-
- [[Undecided] Changes while we move above APIs in-tree:](#undecided-changes-while-we-move-above-apis-in-tree)
19+
- [Changes while we move above APIs in-tree:](#changes-while-we-move-above-apis-in-tree)
2020
- [<a href="https://github.com/kubernetes-sigs/kube-storage-version-migrator/tree/60dee538334c2366994c2323c0db5db8ab4d2838/pkg/controller">Controller</a> to move](#controller-to-move)
2121
- [<a href="https://github.com/kubernetes-sigs/kube-storage-version-migrator/tree/60dee538334c2366994c2323c0db5db8ab4d2838/pkg/migrator">Migrator Controller</a>](#migrator-controller)
22+
- [Approach](#approach)
23+
- [Garbage Collection Cache](#garbage-collection-cache)
24+
- [Rejected Alternative](#rejected-alternative)
2225
- [Streaming List](#streaming-list)
2326
- [RBAC for SVM](#rbac-for-svm)
2427
- [Test Plan](#test-plan)
@@ -125,65 +128,113 @@ As an end user using encryption at rest, whenever the key change is detected we
125128
// StorageVersionMigration represents a migration of stored data to the latest
126129
// storage version.
127130
type StorageVersionMigration struct {
128-
metav1.TypeMeta `json:",inline"`
129-
// +optional
130-
metav1.ObjectMeta `json:"metadata,omitempty"`
131-
// Specification of the migration.
132-
// +optional
133-
Spec StorageVersionMigrationSpec `json:"spec,omitempty"`
134-
// Status of the migration.
135-
// +optional
136-
Status StorageVersionMigrationStatus `json:"status,omitempty"`
131+
metav1.TypeMeta `json:",inline"`
132+
// Standard object metadata.
133+
// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
134+
// +optional
135+
metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
136+
// Specification of the migration.
137+
// +optional
138+
Spec StorageVersionMigrationSpec `json:"spec,omitempty" protobuf:"bytes,2,opt,name=spec"`
139+
// Status of the migration.
140+
// +optional
141+
Status StorageVersionMigrationStatus `json:"status,omitempty" protobuf:"bytes,3,opt,name=status"`
137142
}
138143

139144
// Spec of the storage version migration.
140145
type StorageVersionMigrationSpec struct {
141-
// The resource that is being migrated from. The migrator sends requests to
142-
// the endpoint serving the resource.
143-
// Immutable.
144-
OriginResource GroupVersionResource `json:"resource"`
145-
// The token used in the list options to get the next chunk of objects
146-
// to migrate. When the .status.conditions indicates the migration is
147-
// "Running", users can use this token to check the progress of the
148-
// migration.
149-
// +optional
150-
ContinueToken string `json:"continueToken,omitempty"`
151-
// The storage version hash to avoid races.
152-
StorageVersionHash string `json:"storageVersionHash,omitempty"`
146+
// The resource that is being migrated. The migrator sends requests to
147+
// the endpoint serving the resource.
148+
// Immutable.
149+
Resource GroupVersionResource `json:"resource" protobuf:"bytes,1,opt,name=resource"`
150+
// The token used in the list options to get the next chunk of objects
151+
// to migrate. When the .status.conditions indicates the migration is
152+
// "Running", users can use this token to check the progress of the
153+
// migration.
154+
// +optional
155+
ContinueToken string `json:"continueToken,omitempty" protobuf:"bytes,2,opt,name=continueToken"`
156+
// TODO: consider recording the storage version hash when the migration
157+
// is created. It can avoid races.
153158
}
154159

155160
// The names of the group, the version, and the resource.
156161
type GroupVersionResource struct {
157-
// The name of the group.
158-
Group string `json:"group,omitempty"`
159-
// The name of the version.
160-
Version string `json:"version,omitempty"`
161-
// The name of the resource.
162-
Resource string `json:"resource,omitempty"`
162+
// The name of the group.
163+
Group string `json:"group,omitempty" protobuf:"bytes,1,opt,name=group"`
164+
// The name of the version.
165+
Version string `json:"version,omitempty" protobuf:"bytes,2,opt,name=version"`
166+
// The name of the resource.
167+
Resource string `json:"resource,omitempty" protobuf:"bytes,3,opt,name=resource"`
163168
}
164-
169+
170+
type MigrationConditionType string
171+
172+
const (
173+
// Indicates that the migration is running.
174+
MigrationRunning MigrationConditionType = "Running"
175+
// Indicates that the migration has completed successfully.
176+
MigrationSucceeded MigrationConditionType = "Succeeded"
177+
// Indicates that the migration has failed.
178+
MigrationFailed MigrationConditionType = "Failed"
179+
)
180+
181+
// Describes the state of a migration at a certain point.
182+
type MigrationCondition struct {
183+
// Type of the condition.
184+
Type MigrationConditionType `json:"type" protobuf:"bytes,1,opt,name=type,casttype=MigrationConditionType"`
185+
// Status of the condition, one of True, False, Unknown.
186+
Status corev1.ConditionStatus `json:"status" protobuf:"bytes,2,opt,name=status,casttype=k8s.io/api/core/v1.ConditionStatus"`
187+
// The last time this condition was updated.
188+
// +optional
189+
LastUpdateTime metav1.Time `json:"lastUpdateTime,omitempty" protobuf:"bytes,3,opt,name=lastUpdateTime"`
190+
// The reason for the condition's last transition.
191+
// +optional
192+
Reason string `json:"reason,omitempty" protobuf:"bytes,4,opt,name=reason"`
193+
// A human readable message indicating details about the transition.
194+
// +optional
195+
Message string `json:"message,omitempty" protobuf:"bytes,5,opt,name=message"`
196+
}
197+
165198
// Status of the storage version migration.
166199
type StorageVersionMigrationStatus struct {
167-
// The latest available observations of the migration's current state.
168-
// +optional
169-
// +patchMergeKey=type
170-
// +patchStrategy=merge
171-
Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type" protobuf:"bytes,1,rep,name=conditions"`
200+
// The latest available observations of the migration's current state.
201+
// +patchMergeKey=type
202+
// +patchStrategy=merge
203+
// +listType=map
204+
// +listMapKey=type
205+
// +optional
206+
Conditions []MigrationCondition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type" protobuf:"bytes,1,rep,name=conditions"`
207+
// ResourceVersion to compare with the GC cache for performing the migration.
208+
// This is the current resource version of given group, version and resource when
209+
// kube-controller-manager first observes this StorageVersionMigration resource.
210+
ResourceVersion string `json:"resourceVersion,omitempty" protobuf:"bytes,2,opt,name=resourceVersion"`
211+
// LastMigratedResourceNameHash is use to pick up migration from where it left off in case of failure.
212+
LastMigratedResourceNameHash string `json:"lastMigratedResourceNameHash,omitempty" protobuf:"bytes,3,opt,name=lastMigratedResourceNameHash"`
172213
}
173214

215+
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
216+
// +k8s:prerelease-lifecycle-gen:introduced=1.30
217+
174218
// StorageVersionMigrationList is a collection of storage version migrations.
175219
type StorageVersionMigrationList struct {
176-
metav1.TypeMeta `json:",inline"`
177-
// +optional
178-
metav1.ListMeta `json:"metadata,omitempty"`
179-
// Items is the list of StorageVersionMigration
180-
Items []StorageVersionMigration `json:"items"`
220+
metav1.TypeMeta `json:",inline"`
221+
222+
// Standard list metadata
223+
// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
224+
// +optional
225+
metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
226+
// Items is the list of StorageVersionMigration
227+
// +patchMergeKey=type
228+
// +patchStrategy=merge
229+
// +listType=map
230+
// +listMapKey=type
231+
Items []StorageVersionMigration `json:"items" listType:"map" listMapKey:"type" patchStrategy:"merge" patchMergeKey:"type" protobuf:"bytes,2,rep,name=items"`
181232
}
182233
```
183234

184235
- APIs in-tree will be _converted to `built-in types`_ from CRD.
185236

186-
#### [Undecided] Changes while we move above APIs in-tree:
237+
#### Changes while we move above APIs in-tree:
187238
To avoid any conflicts with the Storage Version Migrators running out of tree, we will change the _`group`_ from `migration.k8s.io` to `storagemigration.k8s.io`.
188239

189240
The final APIs that will be moved in-tree are:
@@ -195,6 +246,11 @@ Currently, the Storage Version Migrator comprises two controllers: the `Trigger`
195246

196247
When transitioning the Storage Version Migrator in-tree, we will exclusively move the Migrator controller as a component of KCM. The creation of the Migration resource will be deferred to the user, instead of being triggered automatically.
197248

249+
### Approach
250+
#### Garbage Collection Cache
251+
Kube Controller Manager's garbage collection cache contains the name and namespace for all resources, providing a suitable dataset for the migration process. This approach is detailed [here](https://docs.google.com/document/d/1lHDbrMCmNG1KXEpw6gMhDL8qWAWgeSlfW6gbCvD80uw/edit?usp=sharing). _We will use this approach for the Alpha release_.
252+
253+
### Rejected Alternative
198254
#### Streaming List
199255
Currently, the Migrator controller uses the `chunked List` method to retrieve the list of resources from the API server and subsequently perform storage migrations as needed. However, chunked lists are [resource-intensive]((https://github.com/kubernetes/enhancements/blob/master/keps/sig-api-machinery/3157-watch-list/README.md#motivation)) and can lead to a significant overload on the API server, potentially resulting in it being terminated due to out-of-memory (OOM) issues. To address this concern, we have proposed the adoption of an Alpha feature introduced in Kubernetes _v1.27_, known as [`Streaming List`](https://kubernetes.io/docs/reference/using-api/api-concepts/#streaming-lists).
200256
@@ -325,16 +381,22 @@ total:
325381
326382
- Feature implemented behind a feature flag
327383
- Initial e2e tests completed and enabled
384+
- Move apis in-tree under new group while keeping schema same as out-of-tree CRD.
385+
- Controller will use Garbage Collection Cache to carry out the migration.
386+
- Resolve potential kube-apiserver OOMs and cascading failure issues that may occur due to the use of paginated lists by using KCM's GC cache.
328387

329388
#### Beta
330389

331-
- Resolve potential kube-apiserver OOMs and cascading failure issues that may occur due to the use of paginated lists.
332390
- Feature is enabled by default
333391
- All of the above documented tests are complete
392+
- Leader election to make sure new controller can work with both CRD and in-tree APIs.
393+
- Using Garbage Collection Cache means using RV as an integer to validate the freshness of the cache. Approval from SigArch is required on this RV semantics.
334394

335395
### Upgrade / Downgrade Strategy
396+
The feature is enabled using the feature gate `StorageVersionMigrator`. During an upgrade, this gate must be set to true. During a downgrade, this gate must be set to false, and any remaining _StorageVersionMigration_ resources should be manually removed.
336397

337398
### Version Skew Strategy
399+
The feature will be enabled by the feature gate `StorageVersionMigrator` on both the _api-server_ and the _kube-controller-manager_. This gate must be set for both components during installation. Otherwise, since the kube-controller-manager is allowed to be one version lower than the api-server, it won't be able to process any StorageVersionMigration resources created by the API server.
338400
339401
## Production Readiness Review Questionnaire
340402
@@ -431,7 +493,7 @@ No.
431493
432494
###### Will enabling / using this feature result in any new API calls?
433495
434-
Yes. Creation of the Migration Request which creates `StorageVersionMigration` resource.
496+
Yes. Creation of the Migration Request which _creates_ `StorageVersionMigration` resource. Additionally, there will be `List` requests made for resource types that need to be migrated. Moreover, an `Update` request will be generated for each resource of the specified type to perform the migration.
435497
436498
###### Will enabling / using this feature result in introducing new API types?
437499

keps/sig-api-machinery/4192-svm-in-tree/kep.yaml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,12 @@ see-also:
2121
- "keps/sig-api-machinery/2343-automated-storage-version-migration-with-storage-version-hash"
2222
- "keps/sig-api-machinery/4020-unknown-version-interoperability-proxy"
2323
stage: alpha
24-
latest-milestone: "v1.29"
24+
latest-milestone: "v1.30"
2525
# The milestone at which this feature was, or is targeted to be, at each stage.
2626
milestone:
27-
alpha: "v1.29"
28-
beta: "v1.30"
29-
stable: "v1.31"
27+
alpha: "v1.30"
28+
beta: "v1.32"
29+
stable: "v1.33"
3030
feature-gates:
3131
- name: StorageVersionMigrator
3232
components:

0 commit comments

Comments
 (0)