Skip to content

Commit

Permalink
Creates a DeployMigrateWaiter component to manage containerruntimes
Browse files Browse the repository at this point in the history
  • Loading branch information
plkokanov committed Aug 28, 2020
1 parent 97e2874 commit e1a8b73
Show file tree
Hide file tree
Showing 15 changed files with 1,049 additions and 232 deletions.
3 changes: 2 additions & 1 deletion pkg/api/extensions/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ func GetShootNamespacedCRsLists() []runtime.Object {
//&extensionsv1alpha1.NetworkList{},
&extensionsv1alpha1.OperatingSystemConfigList{},
&extensionsv1alpha1.WorkerList{},
&extensionsv1alpha1.ContainerRuntimeList{},
//The ContainerRuntime CR is now handled as a shoot component
//&extensionsv1alpha1.ContainerRuntimeList{},
}
}
4 changes: 2 additions & 2 deletions pkg/gardenlet/controller/shoot/shoot_control_delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -346,12 +346,12 @@ func (c *Controller) runDeleteShootFlow(o *operation.Operation) *gardencorev1bet
})
deleteContainerRuntimeResources = g.Add(flow.Task{
Name: "Deleting container runtime resources",
Fn: flow.TaskFn(botanist.DeleteAllContainerRuntimeResources).RetryUntilTimeout(defaultInterval, defaultTimeout),
Fn: flow.TaskFn(botanist.Shoot.Components.Extensions.ContainerRuntime.Destroy).RetryUntilTimeout(defaultInterval, defaultTimeout),
Dependencies: flow.NewTaskIDs(initializeShootClients, cleanKubernetesResources, cleanShootNamespaces),
})
waitUntilContainerRuntimeResourcesDeleted = g.Add(flow.Task{
Name: "Waiting until stale container runtime resources are deleted",
Fn: botanist.WaitUntilContainerRuntimeResourcesDeleted,
Fn: botanist.Shoot.Components.Extensions.ContainerRuntime.WaitCleanup,
Dependencies: flow.NewTaskIDs(deleteContainerRuntimeResources),
})

Expand Down
12 changes: 6 additions & 6 deletions pkg/gardenlet/controller/shoot/shoot_control_reconcile.go
Original file line number Diff line number Diff line change
Expand Up @@ -400,23 +400,23 @@ func (c *Controller) runReconcileShootFlow(o *operation.Operation) *gardencorev1
})
deployContainerRuntimeResources = g.Add(flow.Task{
Name: "Deploying container runtime resources",
Fn: flow.TaskFn(botanist.DeployContainerRuntimeResources).RetryUntilTimeout(defaultInterval, defaultTimeout),
Fn: flow.TaskFn(botanist.DeployContainerRuntime).RetryUntilTimeout(defaultInterval, defaultTimeout),
Dependencies: flow.NewTaskIDs(deployReferencedResources, initializeShootClients),
})
_ = g.Add(flow.Task{
Name: "Waiting until container runtime resources are ready",
Fn: flow.TaskFn(botanist.WaitUntilContainerRuntimeResourcesReady),
Fn: botanist.Shoot.Components.Extensions.ContainerRuntime.Wait,
Dependencies: flow.NewTaskIDs(deployContainerRuntimeResources),
})
deleteStaleContainerRuntimeResources = g.Add(flow.Task{
deleteStaleResources = g.Add(flow.Task{
Name: "Delete stale container runtime resources",
Fn: flow.TaskFn(botanist.DeleteStaleContainerRuntimeResources).RetryUntilTimeout(defaultInterval, defaultTimeout),
Fn: flow.TaskFn(botanist.Shoot.Components.Extensions.ContainerRuntime.DeleteStaleResources).RetryUntilTimeout(defaultInterval, defaultTimeout),
Dependencies: flow.NewTaskIDs(initializeShootClients),
})
_ = g.Add(flow.Task{
Name: "Waiting until stale container runtime resources are deleted",
Fn: flow.TaskFn(botanist.WaitUntilContainerRuntimeResourcesDeleted).SkipIf(o.Shoot.HibernationEnabled),
Dependencies: flow.NewTaskIDs(deleteStaleContainerRuntimeResources),
Fn: flow.TaskFn(botanist.Shoot.Components.Extensions.ContainerRuntime.WaitCleanup).SkipIf(o.Shoot.HibernationEnabled),
Dependencies: flow.NewTaskIDs(deleteStaleResources),
})
_ = g.Add(flow.Task{
Name: "Restart control plane pods",
Expand Down
1 change: 1 addition & 0 deletions pkg/operation/botanist/botanist.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ func New(o *operation.Operation) (*Botanist, error) {
}
o.Shoot.Components.Extensions.Infrastructure = b.DefaultInfrastructure(b.K8sSeedClient.DirectClient())
o.Shoot.Components.Extensions.Network = b.DefaultNetwork(b.K8sSeedClient.DirectClient())
o.Shoot.Components.Extensions.ContainerRuntime = b.DefaultContainerRuntime(b.K8sSeedClient.DirectClient())

// control plane components
o.Shoot.Components.ControlPlane.KubeAPIServerService = b.DefaultKubeAPIServerService()
Expand Down
153 changes: 20 additions & 133 deletions pkg/operation/botanist/containerruntime.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,146 +16,33 @@ package botanist

import (
"context"
"fmt"
"time"

v1beta1constants "github.com/gardener/gardener/pkg/apis/core/v1beta1/constants"
extensionsv1alpha1 "github.com/gardener/gardener/pkg/apis/extensions/v1alpha1"
"github.com/gardener/gardener/pkg/operation/common"
"github.com/gardener/gardener/pkg/operation/botanist/extensions/containerruntime"
"github.com/gardener/gardener/pkg/operation/shoot"
"github.com/gardener/gardener/pkg/utils/flow"

metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/util/sets"
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
"sigs.k8s.io/controller-runtime/pkg/client"
)

// DeployContainerRuntimeResources creates a `Container runtime` resource in the shoot namespace in the seed
// cluster. Deploys one resource per CRI per Worker.
// Gardener waits until an external controller has reconciled the resources successfully.
func (b *Botanist) DeployContainerRuntimeResources(ctx context.Context) error {
var fns []flow.TaskFn

for _, worker := range b.Shoot.Info.Spec.Provider.Workers {
if worker.CRI == nil {
continue
}

for _, containerRuntime := range worker.CRI.ContainerRuntimes {
cr := containerRuntime
workerName := worker.Name

toApply := extensionsv1alpha1.ContainerRuntime{
ObjectMeta: metav1.ObjectMeta{
Name: getContainerRuntimeKey(cr.Type, workerName),
Namespace: b.Shoot.SeedNamespace,
},
}

fns = append(fns, func(ctx context.Context) error {
_, err := controllerutil.CreateOrUpdate(ctx, b.K8sSeedClient.Client(), &toApply, func() error {
metav1.SetMetaDataAnnotation(&toApply.ObjectMeta, v1beta1constants.GardenerOperation, v1beta1constants.GardenerOperationReconcile)
metav1.SetMetaDataAnnotation(&toApply.ObjectMeta, v1beta1constants.GardenerTimestamp, time.Now().UTC().String())
toApply.Spec.BinaryPath = extensionsv1alpha1.ContainerDRuntimeContainersBinFolder
toApply.Spec.Type = cr.Type
toApply.Spec.ProviderConfig = cr.ProviderConfig
toApply.Spec.WorkerPool.Name = workerName
toApply.Spec.WorkerPool.Selector.MatchLabels = map[string]string{v1beta1constants.LabelWorkerPool: workerName, v1beta1constants.LabelWorkerPoolDeprecated: workerName}
return nil
})
return err
})
}
}

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

func getContainerRuntimeKey(criType, workerName string) string {
return fmt.Sprintf("%s-%s", criType, workerName)
}

// WaitUntilContainerRuntimeResourcesReady waits until all container runtime resources report `Succeeded` in their last operation state.
// The state must be reported before the passed context is cancelled or a container runtime's timeout has been reached.
// As soon as one timeout has been overstepped the function returns an error, further waits on container runtime will be aborted.
func (b *Botanist) WaitUntilContainerRuntimeResourcesReady(ctx context.Context) error {
var fns []flow.TaskFn
for _, worker := range b.Shoot.Info.Spec.Provider.Workers {
if worker.CRI == nil {
continue
}

for _, containerRuntime := range worker.CRI.ContainerRuntimes {
fns = append(fns, func(ctx context.Context) error {
return common.WaitUntilExtensionCRReady(
ctx,
b.K8sSeedClient.DirectClient(),
b.Logger,
func() runtime.Object { return &extensionsv1alpha1.ContainerRuntime{} },
"ContainerRuntime",
b.Shoot.SeedNamespace,
getContainerRuntimeKey(containerRuntime.Type, worker.Name),
DefaultInterval,
DefaultSevereThreshold,
shoot.ExtensionDefaultTimeout,
nil,
)
})
}
}

return flow.ParallelExitOnError(fns...)(ctx)
}

// DeleteStaleContainerRuntimeResources deletes unused container runtime resources from the shoot namespace in the seed.
func (b *Botanist) DeleteStaleContainerRuntimeResources(ctx context.Context) error {
wantedContainerRuntimeTypes := sets.NewString()
for _, worker := range b.Shoot.Info.Spec.Provider.Workers {
if worker.CRI != nil {
for _, containerRuntime := range worker.CRI.ContainerRuntimes {
key := getContainerRuntimeKey(containerRuntime.Type, worker.Name)
wantedContainerRuntimeTypes.Insert(key)
}
}
}
return b.deleteContainerRuntimeResources(ctx, wantedContainerRuntimeTypes)
}

// DeleteAllContainerRuntimeResources deletes all container runtime resources from the Shoot namespace in the Seed.
func (b *Botanist) DeleteAllContainerRuntimeResources(ctx context.Context) error {
return b.deleteContainerRuntimeResources(ctx, sets.NewString())
}

func (b *Botanist) deleteContainerRuntimeResources(ctx context.Context, wantedContainerRuntimeTypes sets.String) error {
return common.DeleteExtensionCRs(
ctx,
b.K8sSeedClient.Client(),
&extensionsv1alpha1.ContainerRuntimeList{},
func() extensionsv1alpha1.Object { return &extensionsv1alpha1.ContainerRuntime{} },
b.Shoot.SeedNamespace,
func(obj extensionsv1alpha1.Object) bool {
cr, ok := obj.(*extensionsv1alpha1.ContainerRuntime)
if !ok {
return false
}
return !wantedContainerRuntimeTypes.Has(getContainerRuntimeKey(cr.Spec.Type, cr.Spec.WorkerPool.Name))
// DefaultContainerRuntime creates the default deployer for the ContainerRuntime custom resource.
func (b *Botanist) DefaultContainerRuntime(seedClient client.Client) shoot.ContainerRuntime {
return containerruntime.New(
b.Logger,
seedClient,
&containerruntime.Values{
Namespace: b.Shoot.SeedNamespace,
Workers: b.Shoot.Info.Spec.Provider.Workers,
},
containerruntime.DefaultInterval,
containerruntime.DefaultSevereThreshold,
containerruntime.DefaultTimeout,
)
}

// WaitUntilContainerRuntimeResourcesDeleted waits until all container runtime resources are gone or the context is cancelled.
func (b *Botanist) WaitUntilContainerRuntimeResourcesDeleted(ctx context.Context) error {
return common.WaitUntilExtensionCRsDeleted(
ctx,
b.K8sSeedClient.DirectClient(),
b.Logger,
&extensionsv1alpha1.ContainerRuntimeList{},
func() extensionsv1alpha1.Object { return &extensionsv1alpha1.ContainerRuntime{} },
"ContainerRuntime",
b.Shoot.SeedNamespace,
DefaultInterval,
shoot.ExtensionDefaultTimeout,
nil,
)
// DeployContainerRuntime deploys the ContainerRuntime custom resources and triggers the restore operation in case
// the Shoot is in the restore phase of the control plane migration
func (b *Botanist) DeployContainerRuntime(ctx context.Context) error {
if b.isRestorePhase() {
return b.Shoot.Components.Extensions.ContainerRuntime.Restore(ctx, b.ShootState)
}
return b.Shoot.Components.Extensions.ContainerRuntime.Deploy(ctx)
}

0 comments on commit e1a8b73

Please sign in to comment.