Skip to content

Commit e601997

Browse files
committed
OKD-294: Migrate runtime from runc to crun on an upgrade for OKD
Centos stream 10 dopped the runc package. For now OKD users are following the workaround to edit the MC to point to crun before the upgrade, but this should help with the migration rather than having to intervene manually. This PR: - checks for presence of the configmap - if MCO is built for OKD, edit the MC so the runtime is crun. - deletes the configmap
1 parent a43523e commit e601997

File tree

2 files changed

+90
-7
lines changed

2 files changed

+90
-7
lines changed

pkg/controller/container-runtime-config/container_runtime_config_controller.go

Lines changed: 71 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,9 @@ const (
6060
// 5ms, 10ms, 20ms, 40ms, 80ms, 160ms, 320ms, 640ms, 1.3s, 2.6s, 5.1s, 10.2s, 20.4s, 41s, 82s
6161
maxRetries = 15
6262

63-
builtInLabelKey = "machineconfiguration.openshift.io/mco-built-in"
63+
builtInLabelKey = "machineconfiguration.openshift.io/mco-built-in"
64+
configMapName = "crio-default-container-runtime"
65+
forceSyncOnUpgrade = "force-sync-on-upgrade"
6466
)
6567

6668
var (
@@ -79,6 +81,7 @@ type Controller struct {
7981
templatesDir string
8082

8183
client mcfgclientset.Interface
84+
kubeClient clientset.Interface
8285
configClient configclientset.Interface
8386
eventRecorder record.EventRecorder
8487

@@ -148,6 +151,7 @@ func New(
148151
ctrl := &Controller{
149152
templatesDir: templatesDir,
150153
client: mcfgClient,
154+
kubeClient: kubeClient,
151155
configClient: configClient,
152156
eventRecorder: ctrlcommon.NamespacedEventRecorder(eventBroadcaster.NewRecorder(scheme.Scheme, corev1.EventSource{Component: "machineconfigcontroller-containerruntimeconfigcontroller"})),
153157
queue: workqueue.NewTypedRateLimitingQueueWithConfig(
@@ -213,6 +217,7 @@ func New(
213217

214218
ctrl.clusterVersionLister = clusterVersionInformer.Lister()
215219
ctrl.clusterVersionListerSynced = clusterVersionInformer.Informer().HasSynced
220+
ctrl.queue.Add(forceSyncOnUpgrade)
216221

217222
ctrl.fgHandler = fgHandler
218223

@@ -596,6 +601,60 @@ func (ctrl *Controller) addAnnotation(cfg *mcfgv1.ContainerRuntimeConfig, annota
596601
return annotationUpdateErr
597602
}
598603

604+
// migrateRuncToCrun performs the upgrade migration from runc to crun as the default container runtime.
605+
// This function checks for the existence of the crio-default-container-runtime ConfigMap. If it exists,
606+
// it deletes the MachineConfigs for master and worker pools, then deletes the ConfigMap to prevent
607+
// re-running the migration.
608+
func (ctrl *Controller) migrateRuncToCrun() error {
609+
// Check if the migration ConfigMap exists
610+
_, err := ctrl.kubeClient.CoreV1().ConfigMaps(ctrlcommon.MCONamespace).Get(context.TODO(), configMapName, metav1.GetOptions{})
611+
if errors.IsNotFound(err) {
612+
// ConfigMap doesn't exist, no migration needed
613+
return nil
614+
}
615+
if err != nil {
616+
return fmt.Errorf("error checking for crio-default-container-runtime configmap: %w", err)
617+
}
618+
619+
klog.Info("Found crio-default-container-runtime ConfigMap, starting migration from runc to crun")
620+
621+
// Get all MachineConfigPools
622+
pools, err := ctrl.mcpLister.List(labels.Everything())
623+
if err != nil {
624+
return fmt.Errorf("error listing MachineConfigPools: %w", err)
625+
}
626+
627+
// Only process master and worker pools for the migration
628+
for _, pool := range pools {
629+
if pool.Name != ctrlcommon.MachineConfigPoolMaster && pool.Name != ctrlcommon.MachineConfigPoolWorker {
630+
continue
631+
}
632+
633+
// Get the MachineConfig name for this pool
634+
mcName := fmt.Sprintf("00-override-%s-generated-crio-default-container-runtime", pool.Name)
635+
636+
// Delete the existing MachineConfig
637+
err := ctrl.client.MachineconfigurationV1().MachineConfigs().Delete(context.TODO(), mcName, metav1.DeleteOptions{})
638+
if errors.IsNotFound(err) {
639+
klog.Infof("MachineConfig %s not found, skipping migration for pool %s", mcName, pool.Name)
640+
continue
641+
}
642+
if err != nil {
643+
return fmt.Errorf("error deleting MachineConfig %s: %w", mcName, err)
644+
}
645+
646+
klog.Infof("Successfully deleted MachineConfig %s", mcName)
647+
}
648+
649+
// Delete the ConfigMap after successful migration
650+
if err := ctrl.kubeClient.CoreV1().ConfigMaps(ctrlcommon.MCONamespace).Delete(context.TODO(), configMapName, metav1.DeleteOptions{}); err != nil && !errors.IsNotFound(err) {
651+
return fmt.Errorf("error deleting crio-default-container-runtime configmap: %w", err)
652+
}
653+
654+
klog.Info("Successfully completed migration from runc to crun and deleted migration ConfigMap")
655+
return nil
656+
}
657+
599658
// syncContainerRuntimeConfig will sync the ContainerRuntimeconfig with the given key.
600659
// This function is not meant to be invoked concurrently with the same key.
601660
// nolint: gocyclo
@@ -606,6 +665,17 @@ func (ctrl *Controller) syncContainerRuntimeConfig(key string) error {
606665
klog.V(4).Infof("Finished syncing ContainerRuntimeconfig %q (%v)", key, time.Since(startTime))
607666
}()
608667

668+
// OKD only: Run the migration function at the start of sync
669+
if version.IsSCOS() {
670+
if err := ctrl.migrateRuncToCrun(); err != nil {
671+
return fmt.Errorf("Error during runc to crun migration: %w", err)
672+
}
673+
}
674+
675+
if key == forceSyncOnUpgrade {
676+
return nil
677+
}
678+
609679
_, name, err := cache.SplitMetaNamespaceKey(key)
610680
if err != nil {
611681
return err

pkg/controller/container-runtime-config/helpers.go

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -49,12 +49,13 @@ const (
4949
policyConfigPath = "/etc/containers/policy.json"
5050
// CRIODropInFilePathLogLevel is the path at which changes to the crio config for log-level
5151
// will be dropped in this is exported so that we can use it in the e2e-tests
52-
CRIODropInFilePathLogLevel = "/etc/crio/crio.conf.d/01-ctrcfg-logLevel"
53-
crioDropInFilePathPidsLimit = "/etc/crio/crio.conf.d/01-ctrcfg-pidsLimit"
54-
crioDropInFilePathLogSizeMax = "/etc/crio/crio.conf.d/01-ctrcfg-logSizeMax"
55-
CRIODropInFilePathDefaultRuntime = "/etc/crio/crio.conf.d/01-ctrcfg-defaultRuntime"
56-
imagepolicyType = "sigstoreSigned"
57-
sigstoreRegistriesConfigFilePath = "/etc/containers/registries.d/sigstore-registries.yaml"
52+
CRIODropInFilePathLogLevel = "/etc/crio/crio.conf.d/01-ctrcfg-logLevel"
53+
crioDropInFilePathPidsLimit = "/etc/crio/crio.conf.d/01-ctrcfg-pidsLimit"
54+
crioDropInFilePathLogSizeMax = "/etc/crio/crio.conf.d/01-ctrcfg-logSizeMax"
55+
CRIODropInFilePathDefaultRuntime = "/etc/crio/crio.conf.d/01-ctrcfg-defaultRuntime"
56+
CRIODropInFilePathDefaultContainerRuntimeCrun = "/etc/crio/crio.conf.d/01-mc-defaultContainerRuntimeCrun"
57+
imagepolicyType = "sigstoreSigned"
58+
sigstoreRegistriesConfigFilePath = "/etc/containers/registries.d/sigstore-registries.yaml"
5859
)
5960

6061
var (
@@ -1211,3 +1212,15 @@ func imagePolicyConfigFileList(namespaceJSONs map[string][]byte) []generatedConf
12111212
}
12121213
return namespacedPolicyConfigFileList
12131214
}
1215+
1216+
// createDefaultContainerRuntimeFile creates a TOML config file for crun as the default container runtime
1217+
func createDefaultContainerRuntimeFile() []generatedConfigFile {
1218+
generatedConfigFileList := make([]generatedConfigFile, 0)
1219+
tomlConf := tomlConfigCRIODefaultRuntime{}
1220+
tomlConf.Crio.Runtime.DefaultRuntime = string(mcfgv1.ContainerRuntimeDefaultRuntimeCrun)
1221+
generatedConfigFileList, err := addTOMLgeneratedConfigFile(generatedConfigFileList, CRIODropInFilePathDefaultContainerRuntimeCrun, tomlConf)
1222+
if err != nil {
1223+
klog.V(2).Infof("error setting default-container-runtime to crio.conf.d: %v", err)
1224+
}
1225+
return generatedConfigFileList
1226+
}

0 commit comments

Comments
 (0)