Skip to content

Commit

Permalink
[GEP-22] Drop shootstate-extensions and shootstate-secret control…
Browse files Browse the repository at this point in the history
…lers (gardener#8136)

* Drop legacy `ShootState` controllers

* Remove legacy ShootState controller finalizer from secrets

* Drop {Get,Set}ShootState methods on `Botanist`

* Drop `EnsureShootStateExists` function

Instead, we now fetch the `ShootState` object in the restore phase only (this is the only phase when we need it) and store it directly on the internal `Shoot` object.

* Delete `ShootState` after restoration

Only if the gardenlet is responsible for an unmanaged `Seed` - otherwise, its `shoot-state` reconciler wants to perform regular backups of the `ShootState`, so we shouldn't delete it even after successful restoration.

* Disable `shoot-state` reconciler locally

From gardener#8112 (comment):

> In our e2e tests the cpm test shoots are always scheduled on a non-managed seed. With this, the controller would always be active and we wouldn't verify that migration also works without periodic backups.

Since we don't need this periodic backup functionality in e2e tests, we simply disable the controller.
  • Loading branch information
rfranzke authored Jun 22, 2023
1 parent 8f1c1d3 commit 2e4617c
Show file tree
Hide file tree
Showing 67 changed files with 205 additions and 2,911 deletions.
6 changes: 0 additions & 6 deletions charts/gardener/gardenlet/templates/_helpers.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -226,12 +226,6 @@ config.yaml: |
concurrentSyncs: {{ required ".Values.config.controllers.shootState.concurrentSyncs is required" .Values.config.controllers.shootState.concurrentSyncs }}
syncPeriod: {{ required ".Values.config.controllers.shootState.syncPeriod is required" .Values.config.controllers.shootState.syncPeriod }}
{{- end }}
{{- if .Values.config.controllers.shootSecret }}
shootSecret:
concurrentSyncs: {{ required ".Values.config.controllers.shootSecret.concurrentSyncs is required" .Values.config.controllers.shootSecret.concurrentSyncs }}
{{- end }}
shootStateSync:
concurrentSyncs: {{ required ".Values.config.controllers.shootStateSync.concurrentSyncs is required" .Values.config.controllers.shootStateSync.concurrentSyncs }}
{{- if .Values.config.controllers.managedSeed }}
managedSeed:
concurrentSyncs: {{ required ".Values.config.controllers.managedSeed.concurrentSyncs is required" .Values.config.controllers.managedSeed.concurrentSyncs }}
Expand Down
4 changes: 0 additions & 4 deletions charts/gardener/gardenlet/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -116,10 +116,6 @@ config:
shootState:
concurrentSyncs: 5
syncPeriod: 6h
shootSecret:
concurrentSyncs: 5
shootStateSync:
concurrentSyncs: 5
managedSeed:
concurrentSyncs: 5
syncPeriod: 1h
Expand Down
33 changes: 33 additions & 0 deletions cmd/gardenlet/app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ import (
"github.com/gardener/gardener/pkg/utils/flow"
gardenerutils "github.com/gardener/gardener/pkg/utils/gardener"
kubernetesutils "github.com/gardener/gardener/pkg/utils/kubernetes"
secretsmanager "github.com/gardener/gardener/pkg/utils/secrets/manager"
)

// Name is a const for the name of this component.
Expand Down Expand Up @@ -350,6 +351,12 @@ func (g *garden) Start(ctx context.Context) error {
return err
}

// TODO(rfranzke): Remove this code after v1.74 has been released.
log.Info("Removing legacy ShootState controller finalizer from persistable secrets in seed cluster")
if err := removeLegacyShootStateControllerFinalizerFromSecrets(ctx, g.mgr.GetClient()); err != nil {
return err
}

log.Info("Setting up shoot client map")
shootClientMap, err := clientmapbuilder.
NewShootClientMapBuilder().
Expand Down Expand Up @@ -475,6 +482,32 @@ func (g *garden) updateProcessingShootStatusToAborted(ctx context.Context, garde
return flow.Parallel(taskFns...)(ctx)
}

func removeLegacyShootStateControllerFinalizerFromSecrets(ctx context.Context, seedClient client.Client) error {
secretList := &metav1.PartialObjectMetadataList{}
secretList.SetGroupVersionKind(corev1.SchemeGroupVersion.WithKind("SecretList"))
if err := seedClient.List(ctx, secretList, client.MatchingLabels{
secretsmanager.LabelKeyManagedBy: secretsmanager.LabelValueSecretsManager,
secretsmanager.LabelKeyPersist: secretsmanager.LabelValueTrue,
}); err != nil {
return fmt.Errorf("failed listing all secrets that must be persisted: %w", err)
}

var taskFns []flow.TaskFn

for _, s := range secretList.Items {
secret := s

taskFns = append(taskFns, func(ctx context.Context) error {
if err := controllerutils.RemoveFinalizers(ctx, seedClient, &secret, "gardenlet.gardener.cloud/secret-controller"); err != nil {
return fmt.Errorf("failed to remove legacy ShootState controller finalizer from secret %q: %w", client.ObjectKeyFromObject(&secret), err)
}
return nil
})
}

return flow.Parallel(taskFns...)(ctx)
}

func addAllFieldIndexes(ctx context.Context, i client.FieldIndexer) error {
for _, fn := range []func(context.Context, client.FieldIndexer) error{
// core API group
Expand Down
19 changes: 2 additions & 17 deletions docs/concepts/gardenlet.md
Original file line number Diff line number Diff line change
Expand Up @@ -444,24 +444,9 @@ A pod is considered stale when:

This reconciler periodically (default: every `6h`) performs backups of the state of `Shoot` clusters and persists them into `ShootState` resources into the same namespace as the `Shoot`s in the garden cluster.
It is only started in case the `gardenlet` is responsible for an unmanaged `Seed`, i.e. a `Seed` which is not backed by a `seedmanagement.gardener.cloud/v1alpha1.ManagedSeed` object.
Please refer to [GEP-22: Improved Usage of the `ShootState` API](../proposals/22-improved-usage-of-shootstate-api.md) for all information.

### [`ShootState` Controller](../../pkg/gardenlet/controller/shootstate)

The `ShootState` controller in the `gardenlet` reconciles resources containing information that has to be synced to the `ShootState`.
This information is used when a [control plane migration](../usage/control_plane_migration.md) is performed.

#### "Extensions" Reconciler
Alternatively, it can be disabled by setting the `concurrentSyncs=0` for the controller in the `gardenlet`'s component configuration.

This reconciler watches resources in the `extensions.gardener.cloud` API group in the seed cluster which contain a `Shoot`-specific state or data.
Those are `BackupEntry`s, `ContainerRuntime`s, `ControlPlane`s, `DNSRecord`s, `Extension`s, `Infrastructure`s, `Network`s, `OperatingSystemConfig`s, and `Worker`s.

When there is a change in the `.status.state` or `.status.resources[]` fields of these resources, then this information is synced into the `ShootState` resource in the garden cluster.

#### "Secret" Reconciler

This reconciler reconciles `Secret`s having labels `managed-by=secrets-manager` and `persist=true` in the shoot namespaces in the seed cluster.
It syncs them to the `ShootState` so that the secrets can be restored from there in case a shoot control plane has to be restored to another seed cluster (in case of migration).
Please refer to [GEP-22: Improved Usage of the `ShootState` API](../proposals/22-improved-usage-of-shootstate-api.md) for all information.

## Managed Seeds

Expand Down
4 changes: 0 additions & 4 deletions example/20-componentconfig-gardenlet.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -71,10 +71,6 @@ controllers:
shootState:
concurrentSyncs: 5
syncPeriod: 6h
shootSecret:
concurrentSyncs: 5
shootStateSync:
concurrentSyncs: 1
seed:
syncPeriod: 1h
# leaseResyncSeconds: 2
Expand Down
2 changes: 2 additions & 0 deletions example/gardener-local/gardenlet/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ config:
controllers:
shoot:
reconcileInMaintenanceOnly: true
shootState:
concurrentSyncs: 0 # we don't need the shootstate controller locally, and enabling it would even distort the results of CPM e2e tests
featureGates:
HVPA: true
HVPAForShootedSeed: true
Expand Down
5 changes: 5 additions & 0 deletions pkg/apis/core/v1beta1/helper/helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -1403,3 +1403,8 @@ func GetFailureToleranceType(shoot *gardencorev1beta1.Shoot) *gardencorev1beta1.
func IsTopologyAwareRoutingForShootControlPlaneEnabled(seed *gardencorev1beta1.Seed, shoot *gardencorev1beta1.Shoot) bool {
return SeedSettingTopologyAwareRoutingEnabled(seed.Spec.Settings) && IsMultiZonalShootControlPlane(shoot)
}

// ShootHasOperationType returns true when the 'type' in the last operation matches the provided type.
func ShootHasOperationType(lastOperation *gardencorev1beta1.LastOperation, lastOperationType gardencorev1beta1.LastOperationType) bool {
return lastOperation != nil && lastOperation.Type == lastOperationType
}
9 changes: 9 additions & 0 deletions pkg/apis/core/v1beta1/helper/helper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2678,6 +2678,15 @@ var _ = Describe("helper", func() {
BeTrue(),
),
)

DescribeTable("#ShootHasOperationType",
func(lastOperation *gardencorev1beta1.LastOperation, lastOperationType gardencorev1beta1.LastOperationType, matcher gomegatypes.GomegaMatcher) {
Expect(ShootHasOperationType(lastOperation, lastOperationType)).To(matcher)
},
Entry("last operation nil", nil, gardencorev1beta1.LastOperationTypeCreate, BeFalse()),
Entry("last operation type does not match", &gardencorev1beta1.LastOperation{}, gardencorev1beta1.LastOperationTypeCreate, BeFalse()),
Entry("last operation type matches", &gardencorev1beta1.LastOperation{Type: gardencorev1beta1.LastOperationTypeCreate}, gardencorev1beta1.LastOperationTypeCreate, BeTrue()),
)
})

func timePointer(t time.Time) *metav1.Time {
Expand Down
17 changes: 0 additions & 17 deletions pkg/gardenlet/apis/config/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -153,14 +153,10 @@ type GardenletControllerConfiguration struct {
ShootCare *ShootCareControllerConfiguration
// ShootState defines the configuration of the ShootState controller.
ShootState *ShootStateControllerConfiguration
// ShootStateSync defines the configuration of the ShootState controller.
ShootStateSync *ShootStateSyncControllerConfiguration
// NetworkPolicy defines the configuration of the NetworkPolicy controller.
NetworkPolicy *NetworkPolicyControllerConfiguration
// ManagedSeed defines the configuration of the ManagedSeed controller.
ManagedSeed *ManagedSeedControllerConfiguration
// ShootSecretControllerConfiguration defines the configuration of the ShootSecret controller.
ShootSecret *ShootSecretControllerConfiguration
// TokenRequestorControllerConfiguration defines the configuration of the TokenRequestor controller.
TokenRequestor *TokenRequestorControllerConfiguration
}
Expand Down Expand Up @@ -302,12 +298,6 @@ type ShootStateControllerConfiguration struct {
SyncPeriod *metav1.Duration
}

// ShootSecretControllerConfiguration defines the configuration of the ShootSecret controller.
type ShootSecretControllerConfiguration struct {
// ConcurrentSyncs is the number of workers used for the controller to work on events.
ConcurrentSyncs *int
}

// StaleExtensionHealthChecks defines the configuration of the check for stale extension health checks.
type StaleExtensionHealthChecks struct {
// Enabled specifies whether the check for stale extensions health checks is enabled.
Expand All @@ -327,13 +317,6 @@ type ConditionThreshold struct {
Duration metav1.Duration
}

// ShootStateSyncControllerConfiguration defines the configuration of the ShootState Sync controller.
type ShootStateSyncControllerConfiguration struct {
// ConcurrentSyncs is the number of workers used for the controller to work on
// events.
ConcurrentSyncs *int
}

// NetworkPolicyControllerConfiguration defines the configuration of the NetworkPolicy
// controller.
type NetworkPolicyControllerConfiguration struct {
Expand Down
23 changes: 0 additions & 23 deletions pkg/gardenlet/apis/config/v1alpha1/defaults.go
Original file line number Diff line number Diff line change
Expand Up @@ -168,12 +168,6 @@ func SetDefaults_GardenletControllerConfiguration(obj *GardenletControllerConfig
if obj.ShootState == nil {
obj.ShootState = &ShootStateControllerConfiguration{}
}
if obj.ShootSecret == nil {
obj.ShootSecret = &ShootSecretControllerConfiguration{}
}
if obj.ShootStateSync == nil {
obj.ShootStateSync = &ShootStateSyncControllerConfiguration{}
}
if obj.NetworkPolicy == nil {
obj.NetworkPolicy = &NetworkPolicyControllerConfiguration{}
}
Expand Down Expand Up @@ -380,23 +374,6 @@ func SetDefaults_ShootStateControllerConfiguration(obj *ShootStateControllerConf
}
}

// SetDefaults_ShootSecretControllerConfiguration sets defaults for the shoot secret controller.
func SetDefaults_ShootSecretControllerConfiguration(obj *ShootSecretControllerConfiguration) {
if obj.ConcurrentSyncs == nil {
obj.ConcurrentSyncs = pointer.Int(5)
}
}

// SetDefaults_ShootStateSyncControllerConfiguration sets defaults for the shoot state controller.
func SetDefaults_ShootStateSyncControllerConfiguration(obj *ShootStateSyncControllerConfiguration) {
if obj.ConcurrentSyncs == nil {
// The controller actually starts one controller per extension resource per Seed.
// For one seed that is already 1 * 10 extension resources = 10 workers.
v := 1
obj.ConcurrentSyncs = &v
}
}

// SetDefaults_NetworkPolicyControllerConfiguration sets defaults for the network policy controller.
func SetDefaults_NetworkPolicyControllerConfiguration(obj *NetworkPolicyControllerConfiguration) {
if obj.ConcurrentSyncs == nil {
Expand Down
15 changes: 0 additions & 15 deletions pkg/gardenlet/apis/config/v1alpha1/defaults_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,6 @@ var _ = Describe("Defaults", func() {
Expect(obj.Controllers.ShootCare).NotTo(BeNil())
Expect(obj.Controllers.SeedCare).NotTo(BeNil())
Expect(obj.Controllers.ShootState).NotTo(BeNil())
Expect(obj.Controllers.ShootStateSync).NotTo(BeNil())
Expect(obj.Controllers.ManagedSeed).NotTo(BeNil())
Expect(obj.LeaderElection).NotTo(BeNil())
Expect(obj.LogLevel).To(Equal(logger.InfoLevel))
Expand Down Expand Up @@ -361,20 +360,6 @@ var _ = Describe("Defaults", func() {
})
})

Describe("#SetDefaults_ShootSecretControllerConfiguration", func() {
var obj *ShootSecretControllerConfiguration

BeforeEach(func() {
obj = &ShootSecretControllerConfiguration{}
})

It("should default the configuration", func() {
SetDefaults_ShootSecretControllerConfiguration(obj)

Expect(obj.ConcurrentSyncs).To(PointTo(Equal(5)))
})
})

Describe("#SetDefaults_BackupEntryControllerConfiguration", func() {
var obj *BackupEntryControllerConfiguration

Expand Down
21 changes: 0 additions & 21 deletions pkg/gardenlet/apis/config/v1alpha1/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -189,18 +189,12 @@ type GardenletControllerConfiguration struct {
// ShootState defines the configuration of the ShootState controller.
// +optional
ShootState *ShootStateControllerConfiguration `json:"shootState,omitempty"`
// ShootStateSync defines the configuration of the ShootState controller
// +optional
ShootStateSync *ShootStateSyncControllerConfiguration `json:"shootStateSync,omitempty"`
// NetworkPolicy defines the configuration of the NetworkPolicy controller
// +optional
NetworkPolicy *NetworkPolicyControllerConfiguration `json:"networkPolicy,omitempty"`
// ManagedSeed defines the configuration of the ManagedSeed controller.
// +optional
ManagedSeed *ManagedSeedControllerConfiguration `json:"managedSeed,omitempty"`
// ShootSecretControllerConfiguration defines the configuration of the ShootSecret controller.
// +optional
ShootSecret *ShootSecretControllerConfiguration `json:"shootSecret,omitempty"`
// TokenRequestorControllerConfiguration defines the configuration of the TokenRequestor controller.
// +optional
TokenRequestor *TokenRequestorControllerConfiguration `json:"tokenRequestor,omitempty"`
Expand Down Expand Up @@ -372,13 +366,6 @@ type ShootStateControllerConfiguration struct {
SyncPeriod *metav1.Duration `json:"syncPeriod,omitempty"`
}

// ShootSecretControllerConfiguration defines the configuration of the ShootSecret controller.
type ShootSecretControllerConfiguration struct {
// ConcurrentSyncs is the number of workers used for the controller to work on events.
// +optional
ConcurrentSyncs *int `json:"concurrentSyncs,omitempty"`
}

// StaleExtensionHealthChecks defines the configuration of the check for stale extension health checks.
type StaleExtensionHealthChecks struct {
// Enabled specifies whether the check for stale extensions health checks is enabled.
Expand All @@ -399,14 +386,6 @@ type ConditionThreshold struct {
Duration metav1.Duration `json:"duration"`
}

// ShootStateSyncControllerConfiguration defines the configuration of the ShootState Sync controller.
type ShootStateSyncControllerConfiguration struct {
// ConcurrentSyncs is the number of workers used for the controller to work on
// events.
// +optional
ConcurrentSyncs *int `json:"concurrentSyncs,omitempty"`
}

// NetworkPolicyControllerConfiguration defines the configuration of the NetworkPolicy
// controller.
type NetworkPolicyControllerConfiguration struct {
Expand Down
Loading

0 comments on commit 2e4617c

Please sign in to comment.