Skip to content

Commit ea55c89

Browse files
Merge pull request #4697 from pmtk/kustomizer-bug/multus
OCPBUGS-51365: Move Multus manifests from RPM to embedded assets & run kustomizer standalone
2 parents 8782abf + 457a867 commit ea55c89

28 files changed

+264
-24
lines changed

assets/optional/multus/06-daemonset.yaml assets/components/multus/06-daemonset.yaml

+2-2
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ spec:
3232
- operator: Exists
3333
initContainers:
3434
- name: install-container-network-plugins
35-
image: containernetworking-plugins-microshift
35+
image: '{{ .ContainerNetworkingPluginsImage }}'
3636
imagePullPolicy: IfNotPresent
3737
command: [ "/bin/bash", "-ec", "--" ]
3838
args:
@@ -51,7 +51,7 @@ spec:
5151
value: "{bridge,ipvlan,macvlan,static,dhcp,host-local}"
5252
containers:
5353
- name: kube-multus
54-
image: multus-cni-microshift
54+
image: '{{ .MultusCNIImage }}'
5555
imagePullPolicy: IfNotPresent
5656
command: [ "/bin/bash", "-ec", "--" ]
5757
args:

assets/optional/multus/07-daemonset-dhcp.yaml assets/components/multus/07-daemonset-dhcp.yaml

+2-2
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ spec:
3131
- operator: Exists
3232
initContainers:
3333
- name: dhcp-daemon-initialization
34-
image: containernetworking-plugins-microshift
34+
image: '{{ .ContainerNetworkingPluginsImage }}'
3535
command: ["/bin/sh"]
3636
args: ["-c", "rm -f /host/run/cni/dhcp.sock"]
3737
terminationMessagePolicy: FallbackToLogsOnError
@@ -40,7 +40,7 @@ spec:
4040
mountPath: /host/run/cni
4141
containers:
4242
- name: dhcp-daemon
43-
image: containernetworking-plugins-microshift
43+
image: '{{ .ContainerNetworkingPluginsImage }}'
4444
imagePullPolicy: IfNotPresent
4545
command: ["/usr/src/plugins/bin/dhcp"]
4646
args:

cmd/generate-config/config/config-openapi-spec.json

+15
Original file line numberDiff line numberDiff line change
@@ -470,6 +470,7 @@
470470
"type": "object",
471471
"required": [
472472
"clusterNetwork",
473+
"multus",
473474
"serviceNetwork",
474475
"serviceNodePortRange"
475476
],
@@ -493,6 +494,20 @@
493494
"ovnk"
494495
]
495496
},
497+
"multus": {
498+
"type": "object",
499+
"properties": {
500+
"status": {
501+
"description": "Status controls the deployment of the Multus CNI.\nChanging from \"Enabled\" to \"Disabled\" will not cause Multus CNI to be deleted.\nAllowed values are: unset (disabled), \"Enabled\", or \"Disabled\"",
502+
"type": "string",
503+
"default": "Disabled",
504+
"enum": [
505+
"Enabled",
506+
"Disabled"
507+
]
508+
}
509+
}
510+
},
496511
"serviceNetwork": {
497512
"description": "IP address pool for services.\nCurrently, we only support a single entry here.\nThis field is immutable after installation.",
498513
"type": "array",

docs/user/howto_config.md

+4
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,8 @@ manifests:
7575
network:
7676
clusterNetwork: []
7777
cniPlugin: ""
78+
multus:
79+
status: ""
7880
serviceNetwork: []
7981
serviceNodePortRange: ""
8082
node:
@@ -174,6 +176,8 @@ network:
174176
clusterNetwork:
175177
- 10.42.0.0/16
176178
cniPlugin: ""
179+
multus:
180+
status: Disabled
177181
serviceNetwork:
178182
- 10.43.0.0/16
179183
serviceNodePortRange: 30000-32767

packaging/microshift/config.yaml

+5
Original file line numberDiff line numberDiff line change
@@ -521,6 +521,11 @@ network:
521521
# assumes an empty string to mean the OVN-K should be deployed.
522522
# Allowed values are: unset or one of ["", "ovnk", "none"]
523523
cniPlugin: ""
524+
multus:
525+
# Status controls the deployment of the Multus CNI.
526+
# Changing from "Enabled" to "Disabled" will not cause Multus CNI to be deleted.
527+
# Allowed values are: unset (disabled), "Enabled", or "Disabled"
528+
status: Disabled
524529
# IP address pool for services.
525530
# Currently, we only support a single entry here.
526531
# This field is immutable after installation.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
network:
2+
multus:
3+
status: Enabled

packaging/rpm/microshift.spec

+7-15
Original file line numberDiff line numberDiff line change
@@ -411,24 +411,14 @@ mkdir -p -m755 %{buildroot}%{_datadir}/microshift/release
411411
install -p -m644 assets/optional/operator-lifecycle-manager/release-olm-{x86_64,aarch64}.json %{buildroot}%{_datadir}/microshift/release/
412412

413413
# multus
414-
install -d -m755 %{buildroot}/%{_prefix}/lib/microshift/manifests.d/000-microshift-multus
415-
# Copy all the Multus manifests except the arch specific ones
416-
install -p -m644 assets/optional/multus/0* %{buildroot}/%{_prefix}/lib/microshift/manifests.d/000-microshift-multus
417-
install -p -m644 assets/optional/multus/kustomization.yaml %{buildroot}/%{_prefix}/lib/microshift/manifests.d/000-microshift-multus
414+
install -d -m755 %{buildroot}%{_sysconfdir}/microshift/config.d
415+
install -p -m644 packaging/microshift/dropins/enable-multus.yaml %{buildroot}%{_sysconfdir}/microshift/config.d/00-enable-multus.yaml
418416
install -p -m755 packaging/greenboot/microshift-running-check-multus.sh %{buildroot}%{_sysconfdir}/greenboot/check/required.d/41_microshift_running_check_multus.sh
419417
install -p -m755 packaging/crio.conf.d/12-microshift-multus.conf %{buildroot}%{_sysconfdir}/crio/crio.conf.d/12-microshift-multus.conf
420418

421-
%ifarch %{arm} aarch64
422-
cat assets/optional/multus/kustomization.aarch64.yaml >> %{buildroot}/%{_prefix}/lib/microshift/manifests.d/000-microshift-multus/kustomization.yaml
423-
%endif
424-
425-
%ifarch x86_64
426-
cat assets/optional/multus/kustomization.x86_64.yaml >> %{buildroot}/%{_prefix}/lib/microshift/manifests.d/000-microshift-multus/kustomization.yaml
427-
%endif
428-
429419
# multus-release-info
430420
mkdir -p -m755 %{buildroot}%{_datadir}/microshift/release
431-
install -p -m644 assets/optional/multus/release-multus-{x86_64,aarch64}.json %{buildroot}%{_datadir}/microshift/release/
421+
install -p -m644 assets/components/multus/release-multus-{x86_64,aarch64}.json %{buildroot}%{_datadir}/microshift/release/
432422

433423
%if %{with_flannel}
434424
# kube-proxy
@@ -698,8 +688,7 @@ fi
698688
%{_datadir}/microshift/release/release-olm-{x86_64,aarch64}.json
699689

700690
%files multus
701-
%dir %{_prefix}/lib/microshift/manifests.d/000-microshift-multus
702-
%{_prefix}/lib/microshift/manifests.d/000-microshift-multus/*
691+
%{_sysconfdir}/microshift/config.d/00-enable-multus.yaml
703692
%{_sysconfdir}/greenboot/check/required.d/41_microshift_running_check_multus.sh
704693
%{_sysconfdir}/crio/crio.conf.d/12-microshift-multus.conf
705694

@@ -758,6 +747,9 @@ fi
758747
# Use Git command to generate the log and replace the VERSION string
759748
# LANG=C git log --date="format:%a %b %d %Y" --pretty="tformat:* %cd %an <%ae> VERSION%n- %s%n" packaging/rpm/microshift.spec
760749
%changelog
750+
* Wed Apr 04 2025 Patryk Matuszak <[email protected]> 4.19.0
751+
- Replace Multus manifests with drop-in configuration
752+
761753
* Mon Mar 31 2025 Gregory Giguashvili <[email protected]> 4.19.0
762754
- Default crio runtime is crun
763755

pkg/assets/crd.go

+50
Original file line numberDiff line numberDiff line change
@@ -181,3 +181,53 @@ func ApplyCRDs(ctx context.Context, cfg *config.Config) error {
181181

182182
return nil
183183
}
184+
185+
func ApplyCRDAndWaitForEstablish(ctx context.Context, crds []string, kubeconfigPath string) error {
186+
lock.Lock()
187+
defer lock.Unlock()
188+
189+
restConfig, err := clientcmd.BuildConfigFromFlags("", kubeconfigPath)
190+
if err != nil {
191+
return err
192+
}
193+
rest.AddUserAgent(restConfig, "crd-agent")
194+
195+
client := apiextclientv1.NewForConfigOrDie(restConfig)
196+
197+
for _, crd := range crds {
198+
klog.Infof("Applying CRD %s", crd)
199+
crdBytes, err := embedded.Asset(crd)
200+
if err != nil {
201+
return fmt.Errorf("error getting asset %s: %v", crd, err)
202+
}
203+
c := readCRDOrDie(crdBytes)
204+
if err = wait.PollUntilContextTimeout(ctx, customResourceReadyInterval, customResourceReadyTimeout, true, func(ctx context.Context) (done bool, err error) {
205+
if err := applyCRD(ctx, client, c); err != nil {
206+
klog.Warningf("failed to apply CRD %s: %v", crd, err)
207+
return false, nil
208+
}
209+
klog.Infof("Applied CRD %s", crd)
210+
return true, nil
211+
}); err != nil {
212+
if err == context.DeadlineExceeded {
213+
return fmt.Errorf("%v during syncCustomResourceDefinitions", err)
214+
}
215+
return err
216+
}
217+
218+
clientSet := apiextclientv1.NewForConfigOrDie(restConfig)
219+
if err = wait.PollUntilContextTimeout(ctx, customResourceReadyInterval, customResourceReadyTimeout, true, func(ctx context.Context) (done bool, err error) {
220+
done, e := isEstablished(ctx, clientSet, c)
221+
// Intermittent errors can occur when calling the apiserver. To be on the safe side, log them, but poll until timeout
222+
if e != nil {
223+
klog.Errorf("polling for crd condition status \"established\"=\"true\": %v", e)
224+
}
225+
return done, nil
226+
}); err != nil {
227+
// This will contain only errors generated by wait.PollImmediate (i.e. a timeout error).
228+
return fmt.Errorf("waiting for default CRD: %v", err)
229+
}
230+
}
231+
232+
return nil
233+
}

pkg/cmd/run.go

+3-1
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,6 @@ func RunMicroshift(cfg *config.Config) error {
209209
util.Must(m.AddService(controllers.NewInfrastructureServices(cfg)))
210210
util.Must(m.AddService(controllers.NewClusterPolicyController(cfg)))
211211
util.Must(m.AddService(controllers.NewVersionManager(cfg)))
212-
util.Must(m.AddService(kustomize.NewKustomizer(cfg)))
213212
util.Must(m.AddService(node.NewKubeletServer(cfg)))
214213
util.Must(m.AddService(loadbalancerservice.NewLoadbalancerServiceController(cfg)))
215214
util.Must(m.AddService(controllers.NewKubeStorageVersionMigrator(cfg)))
@@ -273,6 +272,9 @@ func RunMicroshift(cfg *config.Config) error {
273272
klog.Info("service does not support sd_notify readiness messages")
274273
}
275274

275+
// After MicroShift's core becomes ready, run the kustomizer (delete and/or apply manifests).
276+
kustomize.NewKustomizer(cfg).RunStandalone(runCtx)
277+
276278
// Watch for SIGTERM to exit, now that we are ready.
277279
<-sigTerm
278280
klog.Info("Interrupt received")

pkg/components/components.go

+7
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package components
22

33
import (
44
"context"
5+
56
"github.com/openshift/microshift/pkg/config"
67
"k8s.io/klog/v2"
78
)
@@ -37,5 +38,11 @@ func StartComponents(cfg *config.Config, ctx context.Context) error {
3738
klog.Warningf("Failed to start CNI plugin: %v", err)
3839
return err
3940
}
41+
42+
if err := deployMultus(ctx, cfg, kubeAdminConfig); err != nil {
43+
klog.Warningf("Failed to deploy Multus CNI: %v", err)
44+
return err
45+
}
46+
4047
return nil
4148
}

pkg/components/networking.go

+107
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,13 @@ package components
22

33
import (
44
"context"
5+
"encoding/json"
56
"fmt"
67
"path/filepath"
8+
"runtime"
9+
"strings"
710

11+
embedded "github.com/openshift/microshift/assets"
812
"github.com/openshift/microshift/pkg/assets"
913
"github.com/openshift/microshift/pkg/config"
1014
"github.com/openshift/microshift/pkg/config/ovn"
@@ -116,3 +120,106 @@ func startCNIPlugin(ctx context.Context, cfg *config.Config, kubeconfigPath stri
116120
}
117121
return nil
118122
}
123+
124+
func deployMultus(ctx context.Context, cfg *config.Config, kubeconfigPath string) error {
125+
if !cfg.Network.Multus.IsEnabled() {
126+
klog.Warningf("Multus CNI is disabled. Uninstall is not supported if it was installed previously.")
127+
return nil
128+
}
129+
130+
var (
131+
ns = []string{
132+
"components/multus/00-namespace.yaml",
133+
}
134+
crd = []string{
135+
"components/multus/01-crd-networkattachmentdefinition.yaml",
136+
}
137+
sa = []string{
138+
"components/multus/02-service-account.yaml",
139+
}
140+
cr = []string{
141+
"components/multus/03-cluster-role.yaml",
142+
}
143+
crb = []string{
144+
"components/multus/04-cluster-role-binding.yaml",
145+
}
146+
cm = []string{
147+
"components/multus/05-configmap.yaml",
148+
}
149+
ds = []string{
150+
"components/multus/06-daemonset.yaml",
151+
"components/multus/07-daemonset-dhcp.yaml",
152+
}
153+
)
154+
155+
if err := assets.ApplyNamespaces(ctx, ns, kubeconfigPath); err != nil {
156+
klog.Warningf("Failed to apply ns %v: %v", ns, err)
157+
return err
158+
}
159+
if err := assets.ApplyCRDAndWaitForEstablish(ctx, crd, kubeconfigPath); err != nil {
160+
klog.Warningf("Failed to apply ns %v: %v", ns, err)
161+
return err
162+
}
163+
if err := assets.ApplyServiceAccounts(ctx, sa, kubeconfigPath); err != nil {
164+
klog.Warningf("Failed to apply serviceAccount %v %v", sa, err)
165+
return err
166+
}
167+
if err := assets.ApplyClusterRoles(ctx, cr, kubeconfigPath); err != nil {
168+
klog.Warningf("Failed to apply cluster role %v: %v", cr, err)
169+
return err
170+
}
171+
if err := assets.ApplyClusterRoleBindings(ctx, crb, kubeconfigPath); err != nil {
172+
klog.Warningf("Failed to apply rolebinding %v: %v", crb, err)
173+
return err
174+
}
175+
if err := assets.ApplyConfigMaps(ctx, cm, renderTemplate, nil, kubeconfigPath); err != nil {
176+
klog.Warningf("Failed to apply configMap %v %v", cm, err)
177+
return err
178+
}
179+
180+
params, err := getMultusRenderParams()
181+
if err != nil {
182+
return fmt.Errorf("error creating Multus render params: %v", err)
183+
}
184+
185+
if err := assets.ApplyDaemonSets(ctx, ds, renderTemplate, params, kubeconfigPath); err != nil {
186+
klog.Warningf("Failed to apply daemonset %v %v", ds, err)
187+
return err
188+
}
189+
190+
return nil
191+
}
192+
193+
func getMultusRenderParams() (assets.RenderParams, error) {
194+
arch := strings.NewReplacer("amd64", "x86_64", "arm64", "aarch64").Replace(runtime.GOARCH)
195+
releaseInfoPath := fmt.Sprintf("components/multus/release-multus-%s.json", arch)
196+
releaseInfo, err := embedded.Asset(releaseInfoPath)
197+
if err != nil {
198+
return nil, fmt.Errorf("error getting asset %s: %v", releaseInfoPath, err)
199+
}
200+
201+
var release map[string]any
202+
if err := json.Unmarshal(releaseInfo, &release); err != nil {
203+
return nil, fmt.Errorf("unmarshaling %s: %v", releaseInfoPath, err)
204+
}
205+
206+
images, ok := release["images"].(map[string]any)
207+
if !ok {
208+
return nil, fmt.Errorf("multus release info does not contain 'images' field")
209+
}
210+
imageMultus, ok := images["multus-cni-microshift"].(string)
211+
if !ok {
212+
return nil, fmt.Errorf("multus release info does not contain 'multus-cni-microshift' image")
213+
}
214+
imagePlugins, ok := images["containernetworking-plugins-microshift"].(string)
215+
if !ok {
216+
return nil, fmt.Errorf("multus release info does not contain 'containernetworking-plugins-microshift' image")
217+
}
218+
219+
params := assets.RenderParams{
220+
"MultusCNIImage": imageMultus,
221+
"ContainerNetworkingPluginsImage": imagePlugins,
222+
}
223+
224+
return params, nil
225+
}

pkg/config/config.go

+4
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,10 @@ func (c *Config) incorporateUserSettings(u *Config) {
215215
c.Network.DNS = u.Network.DNS
216216
}
217217

218+
if u.Network.Multus.Status != "" {
219+
c.Network.Multus.Status = u.Network.Multus.Status
220+
}
221+
218222
if u.Etcd.MemoryLimitMB != 0 {
219223
c.Etcd.MemoryLimitMB = u.Etcd.MemoryLimitMB
220224
}

0 commit comments

Comments
 (0)