-
Notifications
You must be signed in to change notification settings - Fork 49
/
etcd.go
483 lines (436 loc) · 21.8 KB
/
etcd.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
// SPDX-FileCopyrightText: 2024 SAP SE or an SAP affiliate company and Gardener contributors
//
// SPDX-License-Identifier: Apache-2.0
package v1alpha1
import (
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/resource"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
const (
// GarbageCollectionPolicyExponential defines the exponential policy for garbage collecting old backups
GarbageCollectionPolicyExponential = "Exponential"
// GarbageCollectionPolicyLimitBased defines the limit based policy for garbage collecting old backups
GarbageCollectionPolicyLimitBased = "LimitBased"
// Basic is a constant for metrics level basic.
Basic MetricsLevel = "basic"
// Extensive is a constant for metrics level extensive.
Extensive MetricsLevel = "extensive"
// GzipCompression is constant for gzip compression policy.
GzipCompression CompressionPolicy = "gzip"
// LzwCompression is constant for lzw compression policy.
LzwCompression CompressionPolicy = "lzw"
// ZlibCompression is constant for zlib compression policy.
ZlibCompression CompressionPolicy = "zlib"
// DefaultCompression is constant for default compression policy(only if compression is enabled).
DefaultCompression = GzipCompression
// DefaultCompressionEnabled is constant to define whether to compress the snapshots or not.
DefaultCompressionEnabled = false
// Periodic is a constant to set auto-compaction-mode 'periodic' for duration based retention.
Periodic CompactionMode = "periodic"
// Revision is a constant to set auto-compaction-mode 'revision' for revision number based retention.
Revision CompactionMode = "revision"
)
// +genclient
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// +kubebuilder:object:root=true
// +kubebuilder:subresource:status
// +kubebuilder:subresource:scale:specpath=.spec.replicas,statuspath=.status.replicas
// +kubebuilder:printcolumn:name="Ready",type=string,JSONPath=`.status.ready`
// +kubebuilder:printcolumn:name="Quorate",type=string,JSONPath=`.status.conditions[?(@.type=="Ready")].status`
// +kubebuilder:printcolumn:name="All Members Ready",type=string,JSONPath=`.status.conditions[?(@.type=="AllMembersReady")].status`
// +kubebuilder:printcolumn:name="Backup Ready",type=string,JSONPath=`.status.conditions[?(@.type=="BackupReady")].status`
// +kubebuilder:printcolumn:name="Age",type=date,JSONPath=`.metadata.creationTimestamp`
// +kubebuilder:printcolumn:name="Cluster Size",type=integer,JSONPath=`.spec.replicas`,priority=1
// +kubebuilder:printcolumn:name="Current Replicas",type=integer,JSONPath=`.status.currentReplicas`,priority=1
// +kubebuilder:printcolumn:name="Ready Replicas",type=integer,JSONPath=`.status.readyReplicas`,priority=1
// Etcd is the Schema for the etcds API
type Etcd struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
Spec EtcdSpec `json:"spec,omitempty"`
Status EtcdStatus `json:"status,omitempty"`
}
// +genclient
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// +kubebuilder:object:root=true
// EtcdList contains a list of Etcd
type EtcdList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
Items []Etcd `json:"items"`
}
// MetricsLevel defines the level 'basic' or 'extensive'.
// +kubebuilder:validation:Enum=basic;extensive
type MetricsLevel string
// GarbageCollectionPolicy defines the type of policy for snapshot garbage collection.
// +kubebuilder:validation:Enum=Exponential;LimitBased
type GarbageCollectionPolicy string
// CompressionPolicy defines the type of policy for compression of snapshots.
// +kubebuilder:validation:Enum=gzip;lzw;zlib
type CompressionPolicy string
// CompactionMode defines the auto-compaction-mode: 'periodic' or 'revision'.
// 'periodic' for duration based retention and 'revision' for revision number based retention.
// +kubebuilder:validation:Enum=periodic;revision
type CompactionMode string
// TLSConfig hold the TLS configuration details.
type TLSConfig struct {
// +required
TLSCASecretRef SecretReference `json:"tlsCASecretRef"`
// +required
ServerTLSSecretRef corev1.SecretReference `json:"serverTLSSecretRef"`
// +optional
ClientTLSSecretRef corev1.SecretReference `json:"clientTLSSecretRef"`
}
// SecretReference defines a reference to a secret.
type SecretReference struct {
corev1.SecretReference `json:",inline"`
// DataKey is the name of the key in the data map containing the credentials.
// +optional
DataKey *string `json:"dataKey,omitempty"`
}
// CompressionSpec defines parameters related to compression of Snapshots(full as well as delta).
type CompressionSpec struct {
// +optional
Enabled *bool `json:"enabled,omitempty"`
// +optional
Policy *CompressionPolicy `json:"policy,omitempty"`
}
// LeaderElectionSpec defines parameters related to the LeaderElection configuration.
type LeaderElectionSpec struct {
// ReelectionPeriod defines the Period after which leadership status of corresponding etcd is checked.
// +optional
ReelectionPeriod *metav1.Duration `json:"reelectionPeriod,omitempty"`
// EtcdConnectionTimeout defines the timeout duration for etcd client connection during leader election.
// +optional
EtcdConnectionTimeout *metav1.Duration `json:"etcdConnectionTimeout,omitempty"`
}
// BackupSpec defines parameters associated with the full and delta snapshots of etcd.
type BackupSpec struct {
// Port define the port on which etcd-backup-restore server will be exposed.
// +optional
Port *int32 `json:"port,omitempty"`
// +optional
TLS *TLSConfig `json:"tls,omitempty"`
// Image defines the etcd container image and tag
// +optional
Image *string `json:"image,omitempty"`
// Store defines the specification of object store provider for storing backups.
// +optional
Store *StoreSpec `json:"store,omitempty"`
// Resources defines compute Resources required by backup-restore container.
// More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/
// +optional
Resources *corev1.ResourceRequirements `json:"resources,omitempty"`
// CompactionResources defines compute Resources required by compaction job.
// More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/
// +optional
CompactionResources *corev1.ResourceRequirements `json:"compactionResources,omitempty"`
// FullSnapshotSchedule defines the cron standard schedule for full snapshots.
// +optional
FullSnapshotSchedule *string `json:"fullSnapshotSchedule,omitempty"`
// GarbageCollectionPolicy defines the policy for garbage collecting old backups
// +optional
GarbageCollectionPolicy *GarbageCollectionPolicy `json:"garbageCollectionPolicy,omitempty"`
// MaxBackupsLimitBasedGC defines the maximum number of Full snapshots to retain in Limit Based GarbageCollectionPolicy
// All full snapshots beyond this limit will be garbage collected.
// +optional
MaxBackupsLimitBasedGC *int32 `json:"maxBackupsLimitBasedGC,omitempty"`
// GarbageCollectionPeriod defines the period for garbage collecting old backups
// +optional
GarbageCollectionPeriod *metav1.Duration `json:"garbageCollectionPeriod,omitempty"`
// DeltaSnapshotPeriod defines the period after which delta snapshots will be taken
// +optional
DeltaSnapshotPeriod *metav1.Duration `json:"deltaSnapshotPeriod,omitempty"`
// DeltaSnapshotMemoryLimit defines the memory limit after which delta snapshots will be taken
// +optional
DeltaSnapshotMemoryLimit *resource.Quantity `json:"deltaSnapshotMemoryLimit,omitempty"`
// DeltaSnapshotRetentionPeriod defines the duration for which delta snapshots will be retained, excluding the latest snapshot set.
// The value should be a string formatted as a duration (e.g., '1s', '2m', '3h', '4d')
// +kubebuilder:validation:Type=string
// +kubebuilder:validation:Pattern="^([0-9][0-9]*([.][0-9]+)?(s|m|h|d))+$"
// +optional
DeltaSnapshotRetentionPeriod *metav1.Duration `json:"deltaSnapshotRetentionPeriod,omitempty"`
// SnapshotCompression defines the specification for compression of Snapshots.
// +optional
SnapshotCompression *CompressionSpec `json:"compression,omitempty"`
// EnableProfiling defines if profiling should be enabled for the etcd-backup-restore-sidecar
// +optional
EnableProfiling *bool `json:"enableProfiling,omitempty"`
// EtcdSnapshotTimeout defines the timeout duration for etcd FullSnapshot operation
// +optional
EtcdSnapshotTimeout *metav1.Duration `json:"etcdSnapshotTimeout,omitempty"`
// LeaderElection defines parameters related to the LeaderElection configuration.
// +optional
LeaderElection *LeaderElectionSpec `json:"leaderElection,omitempty"`
}
// EtcdConfig defines the configuration for the etcd cluster to be deployed.
type EtcdConfig struct {
// Quota defines the etcd DB quota.
// +optional
Quota *resource.Quantity `json:"quota,omitempty"`
// DefragmentationSchedule defines the cron standard schedule for defragmentation of etcd.
// +optional
DefragmentationSchedule *string `json:"defragmentationSchedule,omitempty"`
// +optional
ServerPort *int32 `json:"serverPort,omitempty"`
// +optional
ClientPort *int32 `json:"clientPort,omitempty"`
// Image defines the etcd container image and tag
// +optional
Image *string `json:"image,omitempty"`
// +optional
AuthSecretRef *corev1.SecretReference `json:"authSecretRef,omitempty"`
// Metrics defines the level of detail for exported metrics of etcd, specify 'extensive' to include histogram metrics.
// +optional
Metrics *MetricsLevel `json:"metrics,omitempty"`
// Resources defines the compute Resources required by etcd container.
// More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/
// +optional
Resources *corev1.ResourceRequirements `json:"resources,omitempty"`
// ClientUrlTLS contains the ca, server TLS and client TLS secrets for client communication to ETCD cluster
// +optional
ClientUrlTLS *TLSConfig `json:"clientUrlTls,omitempty"`
// PeerUrlTLS contains the ca and server TLS secrets for peer communication within ETCD cluster
// Currently, PeerUrlTLS does not require client TLS secrets for gardener implementation of ETCD cluster.
// +optional
PeerUrlTLS *TLSConfig `json:"peerUrlTls,omitempty"`
// EtcdDefragTimeout defines the timeout duration for etcd defrag call
// +optional
EtcdDefragTimeout *metav1.Duration `json:"etcdDefragTimeout,omitempty"`
// HeartbeatDuration defines the duration for members to send heartbeats. The default value is 10s.
// +optional
HeartbeatDuration *metav1.Duration `json:"heartbeatDuration,omitempty"`
// ClientService defines the parameters of the client service that a user can specify
// +optional
ClientService *ClientService `json:"clientService,omitempty"`
}
// ClientService defines the parameters of the client service that a user can specify
type ClientService struct {
// Annotations specify the annotations that should be added to the client service
// +optional
Annotations map[string]string `json:"annotations,omitempty"`
// Labels specify the labels that should be added to the client service
// +optional
Labels map[string]string `json:"labels,omitempty"`
}
// SharedConfig defines parameters shared and used by Etcd as well as backup-restore sidecar.
type SharedConfig struct {
// AutoCompactionMode defines the auto-compaction-mode:'periodic' mode or 'revision' mode for etcd and embedded-etcd of backup-restore sidecar.
// +optional
AutoCompactionMode *CompactionMode `json:"autoCompactionMode,omitempty"`
// AutoCompactionRetention defines the auto-compaction-retention length for etcd as well as for embedded-etcd of backup-restore sidecar.
// +optional
AutoCompactionRetention *string `json:"autoCompactionRetention,omitempty"`
}
// SchedulingConstraints defines the different scheduling constraints that must be applied to the
// pod spec in the etcd statefulset.
// Currently supported constraints are Affinity and TopologySpreadConstraints.
type SchedulingConstraints struct {
// Affinity defines the various affinity and anti-affinity rules for a pod
// that are honoured by the kube-scheduler.
// +optional
Affinity *corev1.Affinity `json:"affinity,omitempty"`
// TopologySpreadConstraints describes how a group of pods ought to spread across topology domains,
// that are honoured by the kube-scheduler.
// +optional
TopologySpreadConstraints []corev1.TopologySpreadConstraint `json:"topologySpreadConstraints,omitempty"`
}
// EtcdSpec defines the desired state of Etcd
type EtcdSpec struct {
// selector is a label query over pods that should match the replica count.
// It must match the pod template's labels.
// More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#label-selectors
Selector *metav1.LabelSelector `json:"selector"`
// +required
Labels map[string]string `json:"labels"`
// +optional
Annotations map[string]string `json:"annotations,omitempty"`
// +required
Etcd EtcdConfig `json:"etcd"`
// +required
Backup BackupSpec `json:"backup"`
// +optional
Common SharedConfig `json:"sharedConfig,omitempty"`
// +optional
SchedulingConstraints SchedulingConstraints `json:"schedulingConstraints,omitempty"`
// +required
Replicas int32 `json:"replicas"`
// PriorityClassName is the name of a priority class that shall be used for the etcd pods.
// +optional
PriorityClassName *string `json:"priorityClassName,omitempty"`
// StorageClass defines the name of the StorageClass required by the claim.
// More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1
// +optional
StorageClass *string `json:"storageClass,omitempty"`
// StorageCapacity defines the size of persistent volume.
// +optional
StorageCapacity *resource.Quantity `json:"storageCapacity,omitempty"`
// VolumeClaimTemplate defines the volume claim template to be created
// +optional
VolumeClaimTemplate *string `json:"volumeClaimTemplate,omitempty"`
}
// CrossVersionObjectReference contains enough information to let you identify the referred resource.
type CrossVersionObjectReference struct {
// Kind of the referent
// +required
Kind string `json:"kind,omitempty"`
// Name of the referent
// +required
Name string `json:"name,omitempty"`
// API version of the referent
// +optional
APIVersion string `json:"apiVersion,omitempty"`
}
const (
// ConditionTypeReady is a constant for a condition type indicating that the etcd cluster is ready.
ConditionTypeReady ConditionType = "Ready"
// ConditionTypeAllMembersReady is a constant for a condition type indicating that all members of the etcd cluster are ready.
ConditionTypeAllMembersReady ConditionType = "AllMembersReady"
// ConditionTypeFullSnapshotBackupReady is a constant for a condition type indicating that the full snapshot backup is ready.
ConditionTypeFullSnapshotBackupReady ConditionType = "FullSnapshotBackupReady"
// ConditionTypeDeltaSnapshotBackupReady is a constant for a condition type indicating that the delta snapshot backup is ready.
ConditionTypeDeltaSnapshotBackupReady ConditionType = "DeltaSnapshotBackupReady"
// ConditionTypeDataVolumesReady is a constant for a condition type indicating that the etcd data volumes are ready.
ConditionTypeDataVolumesReady ConditionType = "DataVolumesReady"
)
// EtcdMemberConditionStatus is the status of an etcd cluster member.
type EtcdMemberConditionStatus string
const (
// EtcdMemberStatusReady indicates that the etcd member is ready.
EtcdMemberStatusReady EtcdMemberConditionStatus = "Ready"
// EtcdMemberStatusNotReady indicates that the etcd member is not ready.
EtcdMemberStatusNotReady EtcdMemberConditionStatus = "NotReady"
// EtcdMemberStatusUnknown indicates that the status of the etcd member is unknown.
EtcdMemberStatusUnknown EtcdMemberConditionStatus = "Unknown"
)
// EtcdRole is the role of an etcd cluster member.
type EtcdRole string
const (
// EtcdRoleLeader describes the etcd role `Leader`.
EtcdRoleLeader EtcdRole = "Leader"
// EtcdRoleMember describes the etcd role `Member`.
EtcdRoleMember EtcdRole = "Member"
)
// EtcdMemberStatus holds information about etcd cluster membership.
type EtcdMemberStatus struct {
// Name is the name of the etcd member. It is the name of the backing `Pod`.
Name string `json:"name"`
// ID is the ID of the etcd member.
// +optional
ID *string `json:"id,omitempty"`
// Role is the role in the etcd cluster, either `Leader` or `Member`.
// +optional
Role *EtcdRole `json:"role,omitempty"`
// Status of the condition, one of True, False, Unknown.
Status EtcdMemberConditionStatus `json:"status"`
// The reason for the condition's last transition.
Reason string `json:"reason"`
// LastTransitionTime is the last time the condition's status changed.
LastTransitionTime metav1.Time `json:"lastTransitionTime"`
}
// EtcdStatus defines the observed state of Etcd.
type EtcdStatus struct {
// ObservedGeneration is the most recent generation observed for this resource.
// +optional
ObservedGeneration *int64 `json:"observedGeneration,omitempty"`
// +optional
Etcd *CrossVersionObjectReference `json:"etcd,omitempty"`
// Conditions represents the latest available observations of an etcd's current state.
// +optional
Conditions []Condition `json:"conditions,omitempty"`
// LastError represents the last occurred error.
// Deprecated: Use LastErrors instead.
// +optional
LastError *string `json:"lastError,omitempty"`
// LastErrors captures errors that occurred during the last operation.
// +optional
LastErrors []LastError `json:"lastErrors,omitempty"`
// LastOperation indicates the last operation performed on this resource.
// +optional
LastOperation *LastOperation `json:"lastOperation,omitempty"`
// CurrentReplicas is the current replica count for the etcd cluster.
// +optional
CurrentReplicas int32 `json:"currentReplicas,omitempty"`
// Replicas is the replica count of the etcd cluster.
// +optional
Replicas int32 `json:"replicas,omitempty"`
// ReadyReplicas is the count of replicas being ready in the etcd cluster.
// +optional
ReadyReplicas int32 `json:"readyReplicas,omitempty"`
// Ready is `true` if all etcd replicas are ready.
// +optional
Ready *bool `json:"ready,omitempty"`
// Members represents the members of the etcd cluster
// +optional
Members []EtcdMemberStatus `json:"members,omitempty"`
// PeerUrlTLSEnabled captures the state of peer url TLS being enabled for the etcd member(s)
// +optional
PeerUrlTLSEnabled *bool `json:"peerUrlTLSEnabled,omitempty"`
}
// LastOperationType is a string alias representing type of the last operation.
type LastOperationType string
const (
// LastOperationTypeCreate indicates that the last operation was a creation of a new Etcd resource.
LastOperationTypeCreate LastOperationType = "Create"
// LastOperationTypeReconcile indicates that the last operation was a reconciliation of the spec of an Etcd resource.
LastOperationTypeReconcile LastOperationType = "Reconcile"
// LastOperationTypeDelete indicates that the last operation was a deletion of an existing Etcd resource.
LastOperationTypeDelete LastOperationType = "Delete"
)
// LastOperationState is a string alias representing the state of the last operation.
type LastOperationState string
const (
// LastOperationStateProcessing indicates that an operation is in progress.
LastOperationStateProcessing LastOperationState = "Processing"
// LastOperationStateSucceeded indicates that an operation has completed successfully.
LastOperationStateSucceeded LastOperationState = "Succeeded"
// LastOperationStateError indicates that an operation is completed with errors and will be retried.
LastOperationStateError LastOperationState = "Error"
)
// LastOperation holds the information on the last operation done on the Etcd resource.
type LastOperation struct {
// Type is the type of last operation.
Type LastOperationType `json:"type"`
// State is the state of the last operation.
State LastOperationState `json:"state"`
// Description describes the last operation.
Description string `json:"description"`
// RunID correlates an operation with a reconciliation run.
// Every time an Etcd resource is reconciled (barring status reconciliation which is periodic), a unique ID is
// generated which can be used to correlate all actions done as part of a single reconcile run. Capturing this
// as part of LastOperation aids in establishing this correlation. This further helps in also easily filtering
// reconcile logs as all structured logs in a reconciliation run should have the `runID` referenced.
RunID string `json:"runID"`
// LastUpdateTime is the time at which the operation was last updated.
LastUpdateTime metav1.Time `json:"lastUpdateTime"`
}
// ErrorCode is a string alias representing an error code that identifies an error.
type ErrorCode string
// LastError stores details of the most recent error encountered for a resource.
type LastError struct {
// Code is an error code that uniquely identifies an error.
Code ErrorCode `json:"code"`
// Description is a human-readable message indicating details of the error.
Description string `json:"description"`
// ObservedAt is the time the error was observed.
ObservedAt metav1.Time `json:"observedAt"`
}
// IsBackupStoreEnabled returns true if backup store has been enabled for the Etcd resource, else returns false.
func (e *Etcd) IsBackupStoreEnabled() bool {
return e.Spec.Backup.Store != nil
}
// IsReconciliationInProgress returns true if the Etcd resource is currently being reconciled, else returns false.
func (e *Etcd) IsReconciliationInProgress() bool {
return e.Status.LastOperation != nil &&
e.Status.LastOperation.Type == LastOperationTypeReconcile &&
(e.Status.LastOperation.State == LastOperationStateProcessing ||
e.Status.LastOperation.State == LastOperationStateError)
}
// IsDeletionInProgress returns true if the Etcd resource is currently being reconciled, else returns false.
func (e *Etcd) IsDeletionInProgress() bool {
return e.Status.LastOperation != nil &&
e.Status.LastOperation.Type == LastOperationTypeDelete &&
(e.Status.LastOperation.State == LastOperationStateProcessing ||
e.Status.LastOperation.State == LastOperationStateError)
}