Skip to content

Commit 67f52ea

Browse files
authored
Merge pull request #11884 from sbueringer/pr-test-n-3
✨ Test n-3 clusterctl upgrade
2 parents f27917c + 0a7ae63 commit 67f52ea

File tree

13 files changed

+1067
-9
lines changed

13 files changed

+1067
-9
lines changed

Makefile

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -533,7 +533,7 @@ generate-doctoc:
533533
TRACE=$(TRACE) ./hack/generate-doctoc.sh
534534

535535
.PHONY: generate-e2e-templates
536-
generate-e2e-templates: $(KUSTOMIZE) $(addprefix generate-e2e-templates-, v0.3 v0.4 v1.5 v1.6 v1.8 v1.9 main) ## Generate cluster templates for all versions
536+
generate-e2e-templates: $(KUSTOMIZE) $(addprefix generate-e2e-templates-, v0.3 v0.4 v1.5 v1.6 v1.7 v1.8 v1.9 main) ## Generate cluster templates for all versions
537537

538538
DOCKER_TEMPLATES := test/e2e/data/infrastructure-docker
539539

@@ -555,6 +555,11 @@ generate-e2e-templates-v1.6: $(KUSTOMIZE)
555555
$(KUSTOMIZE) build $(DOCKER_TEMPLATES)/v1.6/cluster-template --load-restrictor LoadRestrictionsNone > $(DOCKER_TEMPLATES)/v1.6/cluster-template.yaml
556556
$(KUSTOMIZE) build $(DOCKER_TEMPLATES)/v1.6/cluster-template-topology --load-restrictor LoadRestrictionsNone > $(DOCKER_TEMPLATES)/v1.6/cluster-template-topology.yaml
557557

558+
.PHONY: generate-e2e-templates-v1.7
559+
generate-e2e-templates-v1.7: $(KUSTOMIZE)
560+
$(KUSTOMIZE) build $(DOCKER_TEMPLATES)/v1.7/cluster-template --load-restrictor LoadRestrictionsNone > $(DOCKER_TEMPLATES)/v1.7/cluster-template.yaml
561+
$(KUSTOMIZE) build $(DOCKER_TEMPLATES)/v1.7/cluster-template-topology --load-restrictor LoadRestrictionsNone > $(DOCKER_TEMPLATES)/v1.7/cluster-template-topology.yaml
562+
558563
.PHONY: generate-e2e-templates-v1.8
559564
generate-e2e-templates-v1.8: $(KUSTOMIZE)
560565
$(KUSTOMIZE) build $(DOCKER_TEMPLATES)/v1.8/cluster-template --load-restrictor LoadRestrictionsNone > $(DOCKER_TEMPLATES)/v1.8/cluster-template.yaml

docs/book/src/clusterctl/commands/upgrade.md

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -83,12 +83,13 @@ Cluster API only tests a subset of possible clusterctl upgrade paths as otherwis
8383
Untested upgrade paths are not blocked by clusterctl and should work in general, but users
8484
intending to perform an upgrade path not tested by us should do their own validation to ensure the operation works correctly.
8585

86-
The following is an example of the tested upgrade paths for v1.7:
86+
The following is an example of the tested upgrade paths for v1.10:
8787

88-
| From | To | Note |
89-
|------|------|------------------------------|
90-
| v1.5 | v1.7 | n-2 --> n (v1.5 is v1.7 - 2) |
91-
| v1.6 | v1.7 | n-1 --> n (v1.6 is v1.7 - 1) |
88+
| From | To | Note |
89+
|------|-------|-------------------------------|
90+
| v1.7 | v1.10 | n-3 --> n (v1.7 is v1.10 - 3) |
91+
| v1.8 | v1.10 | n-2 --> n (v1.8 is v1.10 - 2) |
92+
| v1.9 | v1.10 | n-1 --> n (v1.9 is v1.10 - 1) |
9293

9394
</aside>
9495

test/e2e/clusterctl_upgrade_test.go

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,38 @@ var _ = Describe("When testing clusterctl upgrades (v0.4=>v1.6=>current)", Flake
179179
})
180180
})
181181

182+
// Note: This test should be changed during "prepare main branch", it should test n-3 => current.
183+
var _ = Describe("When testing clusterctl upgrades using ClusterClass (v1.7=>current) [ClusterClass]", Label("ClusterClass"), func() {
184+
// Get n-3 latest stable release
185+
version := "1.7"
186+
stableRelease, err := GetStableReleaseOfMinor(ctx, version)
187+
Expect(err).ToNot(HaveOccurred(), "Failed to get stable version for minor release : %s", version)
188+
ClusterctlUpgradeSpec(ctx, func() ClusterctlUpgradeSpecInput {
189+
return ClusterctlUpgradeSpecInput{
190+
E2EConfig: e2eConfig,
191+
ClusterctlConfigPath: clusterctlConfigPath,
192+
BootstrapClusterProxy: bootstrapClusterProxy,
193+
ArtifactFolder: artifactFolder,
194+
SkipCleanup: skipCleanup,
195+
InitWithBinary: fmt.Sprintf(clusterctlDownloadURL, stableRelease),
196+
// We have to pin the providers because with `InitWithProvidersContract` the test would
197+
// use the latest version for the contract (which is the next minor for v1beta1).
198+
InitWithCoreProvider: fmt.Sprintf(providerCAPIPrefix, stableRelease),
199+
InitWithBootstrapProviders: []string{fmt.Sprintf(providerKubeadmPrefix, stableRelease)},
200+
InitWithControlPlaneProviders: []string{fmt.Sprintf(providerKubeadmPrefix, stableRelease)},
201+
InitWithInfrastructureProviders: []string{fmt.Sprintf(providerDockerPrefix, stableRelease)},
202+
InitWithProvidersContract: "v1beta1",
203+
// Note: Both InitWithKubernetesVersion and WorkloadKubernetesVersion should be the highest mgmt cluster version supported by the source Cluster API version.
204+
// When picking this version, please check also the list of versions known by the source Cluster API version.
205+
InitWithKubernetesVersion: "v1.30.0",
206+
WorkloadKubernetesVersion: "v1.30.0",
207+
MgmtFlavor: "topology",
208+
WorkloadFlavor: "topology",
209+
UseKindForManagementCluster: true,
210+
}
211+
})
212+
})
213+
182214
// Note: This test should be changed during "prepare main branch", it should test n-2 => current.
183215
var _ = Describe("When testing clusterctl upgrades using ClusterClass (v1.8=>current) [ClusterClass]", Label("ClusterClass"), func() {
184216
// Get n-2 latest stable release
@@ -201,7 +233,7 @@ var _ = Describe("When testing clusterctl upgrades using ClusterClass (v1.8=>cur
201233
InitWithInfrastructureProviders: []string{fmt.Sprintf(providerDockerPrefix, stableRelease)},
202234
InitWithProvidersContract: "v1beta1",
203235
// Note: Both InitWithKubernetesVersion and WorkloadKubernetesVersion should be the highest mgmt cluster version supported by the source Cluster API version.
204-
// When picking this version, please check also the list of versions known by the source Cluster API version.
236+
// When picking this version, please check also the list of versions known by the source Cluster API version.
205237
InitWithKubernetesVersion: "v1.31.0",
206238
WorkloadKubernetesVersion: "v1.31.0",
207239
MgmtFlavor: "topology",
@@ -227,7 +259,7 @@ var _ = Describe("When testing clusterctl upgrades using ClusterClass (v1.9=>cur
227259
InitWithBinary: fmt.Sprintf(clusterctlDownloadURL, stableRelease),
228260
InitWithProvidersContract: "v1beta1",
229261
// Note: Both InitWithKubernetesVersion and WorkloadKubernetesVersion should be the highest mgmt cluster version supported by the source Cluster API version.
230-
// When picking this version, please check also the list of versions known by the source Cluster API version.
262+
// When picking this version, please check also the list of versions known by the source Cluster API version.
231263
InitWithKubernetesVersion: "v1.32.0",
232264
WorkloadKubernetesVersion: "v1.32.0",
233265
MgmtFlavor: "topology",
@@ -256,7 +288,7 @@ var _ = Describe("When testing clusterctl upgrades using ClusterClass (v1.9=>cur
256288
InitWithProvidersContract: "v1beta1",
257289
// Note: InitWithKubernetesVersion should be the latest of the next supported kubernetes version by the target Cluster API version.
258290
// Note: WorkloadKubernetesVersion should be the highest mgmt cluster version supported by the source Cluster API version.
259-
// When picking this version, please check also the list of versions known by the source Cluster API version.
291+
// When picking this version, please check also the list of versions known by the source Cluster API version.
260292
InitWithKubernetesVersion: initKubernetesVersion,
261293
WorkloadKubernetesVersion: "v1.32.0",
262294
MgmtFlavor: "topology",

test/e2e/config/docker.yaml

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,15 @@ providers:
6969
new: --metrics-addr=:8080
7070
files:
7171
- sourcePath: "../data/shared/v1.6/metadata.yaml"
72+
- name: "{go://sigs.k8s.io/cluster-api@v1.7}"
73+
value: "https://github.com/kubernetes-sigs/cluster-api/releases/download/{go://sigs.k8s.io/cluster-api@v1.7}/core-components.yaml"
74+
type: "url"
75+
contract: v1beta1
76+
replacements:
77+
- old: --metrics-addr=127.0.0.1:8080
78+
new: --metrics-addr=:8080
79+
files:
80+
- sourcePath: "../data/shared/v1.7/metadata.yaml"
7281
- name: "{go://sigs.k8s.io/cluster-api@v1.8}"
7382
value: "https://github.com/kubernetes-sigs/cluster-api/releases/download/{go://sigs.k8s.io/cluster-api@v1.8}/core-components.yaml"
7483
type: "url"
@@ -131,6 +140,15 @@ providers:
131140
new: --metrics-addr=:8080
132141
files:
133142
- sourcePath: "../data/shared/v1.6/metadata.yaml"
143+
- name: "{go://sigs.k8s.io/cluster-api@v1.7}"
144+
value: "https://github.com/kubernetes-sigs/cluster-api/releases/download/{go://sigs.k8s.io/cluster-api@v1.7}/bootstrap-components.yaml"
145+
type: "url"
146+
contract: v1beta1
147+
replacements:
148+
- old: --metrics-addr=127.0.0.1:8080
149+
new: --metrics-addr=:8080
150+
files:
151+
- sourcePath: "../data/shared/v1.7/metadata.yaml"
134152
- name: "{go://sigs.k8s.io/cluster-api@v1.8}"
135153
value: "https://github.com/kubernetes-sigs/cluster-api/releases/download/{go://sigs.k8s.io/cluster-api@v1.8}/bootstrap-components.yaml"
136154
type: "url"
@@ -193,6 +211,15 @@ providers:
193211
new: --metrics-addr=:8080
194212
files:
195213
- sourcePath: "../data/shared/v1.6/metadata.yaml"
214+
- name: "{go://sigs.k8s.io/cluster-api@v1.7}"
215+
value: "https://github.com/kubernetes-sigs/cluster-api/releases/download/{go://sigs.k8s.io/cluster-api@v1.7}/control-plane-components.yaml"
216+
type: "url"
217+
contract: v1beta1
218+
replacements:
219+
- old: --metrics-addr=127.0.0.1:8080
220+
new: --metrics-addr=:8080
221+
files:
222+
- sourcePath: "../data/shared/v1.7/metadata.yaml"
196223
- name: "{go://sigs.k8s.io/cluster-api@v1.8}"
197224
value: "https://github.com/kubernetes-sigs/cluster-api/releases/download/{go://sigs.k8s.io/cluster-api@v1.8}/control-plane-components.yaml"
198225
type: "url"
@@ -263,6 +290,18 @@ providers:
263290
- sourcePath: "../data/infrastructure-docker/v1.6/cluster-template.yaml"
264291
- sourcePath: "../data/infrastructure-docker/v1.6/cluster-template-topology.yaml"
265292
- sourcePath: "../data/infrastructure-docker/v1.6/clusterclass-quick-start.yaml"
293+
- name: "{go://sigs.k8s.io/cluster-api@v1.7}"
294+
value: "https://github.com/kubernetes-sigs/cluster-api/releases/download/{go://sigs.k8s.io/cluster-api@v1.7}/infrastructure-components-development.yaml"
295+
type: "url"
296+
contract: v1beta1
297+
replacements:
298+
- old: --metrics-addr=127.0.0.1:8080
299+
new: --metrics-addr=:8080
300+
files:
301+
- sourcePath: "../data/shared/v1.7/metadata.yaml"
302+
- sourcePath: "../data/infrastructure-docker/v1.7/cluster-template.yaml"
303+
- sourcePath: "../data/infrastructure-docker/v1.7/cluster-template-topology.yaml"
304+
- sourcePath: "../data/infrastructure-docker/v1.7/clusterclass-quick-start.yaml"
266305
- name: "{go://sigs.k8s.io/cluster-api@v1.8}"
267306
value: "https://github.com/kubernetes-sigs/cluster-api/releases/download/{go://sigs.k8s.io/cluster-api@v1.8}/infrastructure-components-development.yaml"
268307
type: "url"
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
---
2+
# DockerCluster object referenced by the Cluster object
3+
apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
4+
kind: DockerCluster
5+
metadata:
6+
name: '${CLUSTER_NAME}'
7+
spec:
8+
failureDomains:
9+
fd1:
10+
controlPlane: true
11+
fd2:
12+
controlPlane: true
13+
fd3:
14+
controlPlane: true
15+
fd4:
16+
controlPlane: false
17+
fd5:
18+
controlPlane: false
19+
fd6:
20+
controlPlane: false
21+
fd7:
22+
controlPlane: false
23+
fd8:
24+
controlPlane: false
25+
---
26+
# Cluster object with
27+
# - Reference to the KubeadmControlPlane object
28+
# - the label cni=${CLUSTER_NAME}-crs-0, so the cluster can be selected by the ClusterResourceSet.
29+
apiVersion: cluster.x-k8s.io/v1beta1
30+
kind: Cluster
31+
metadata:
32+
name: '${CLUSTER_NAME}'
33+
labels:
34+
cni: "${CLUSTER_NAME}-crs-0"
35+
spec:
36+
clusterNetwork:
37+
services:
38+
cidrBlocks: ['${DOCKER_SERVICE_CIDRS}']
39+
pods:
40+
cidrBlocks: ['${DOCKER_POD_CIDRS}']
41+
serviceDomain: '${DOCKER_SERVICE_DOMAIN}'
42+
infrastructureRef:
43+
apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
44+
kind: DockerCluster
45+
name: '${CLUSTER_NAME}'
46+
controlPlaneRef:
47+
kind: KubeadmControlPlane
48+
apiVersion: controlplane.cluster.x-k8s.io/v1beta1
49+
name: "${CLUSTER_NAME}-control-plane"
50+
---
51+
# DockerMachineTemplate object referenced by the KubeadmControlPlane object
52+
apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
53+
kind: DockerMachineTemplate
54+
metadata:
55+
name: "${CLUSTER_NAME}-control-plane"
56+
spec:
57+
template:
58+
spec:
59+
extraMounts:
60+
- containerPath: "/var/run/docker.sock"
61+
hostPath: "/var/run/docker.sock"
62+
# The DOCKER_PRELOAD_IMAGES variable gets set in self-hosted E2E tests to the list of images of the E2E configuration.
63+
preLoadImages: ${DOCKER_PRELOAD_IMAGES:-[]}
64+
---
65+
# KubeadmControlPlane referenced by the Cluster object with
66+
# - the label kcp-adoption.step2, because it should be created in the second step of the kcp-adoption test.
67+
kind: KubeadmControlPlane
68+
apiVersion: controlplane.cluster.x-k8s.io/v1beta1
69+
metadata:
70+
name: "${CLUSTER_NAME}-control-plane"
71+
labels:
72+
kcp-adoption.step2: ""
73+
spec:
74+
replicas: ${CONTROL_PLANE_MACHINE_COUNT}
75+
machineTemplate:
76+
infrastructureRef:
77+
kind: DockerMachineTemplate
78+
apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
79+
name: "${CLUSTER_NAME}-control-plane"
80+
kubeadmConfigSpec:
81+
clusterConfiguration:
82+
apiServer:
83+
# host.docker.internal is required by kubetest when running on MacOS because of the way ports are proxied.
84+
certSANs: [localhost, 127.0.0.1, 0.0.0.0, host.docker.internal]
85+
initConfiguration:
86+
nodeRegistration: {} # node registration parameters are automatically injected by CAPD according to the kindest/node image in use.
87+
joinConfiguration:
88+
nodeRegistration: {} # node registration parameters are automatically injected by CAPD according to the kindest/node image in use.
89+
version: "${KUBERNETES_VERSION}"
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
apiVersion: cluster.x-k8s.io/v1beta1
2+
kind: Cluster
3+
metadata:
4+
name: '${CLUSTER_NAME}'
5+
namespace: default
6+
labels:
7+
cni: "${CLUSTER_NAME}-crs-0"
8+
spec:
9+
clusterNetwork:
10+
services:
11+
cidrBlocks: ['${DOCKER_SERVICE_CIDRS}']
12+
pods:
13+
cidrBlocks: ['${DOCKER_POD_CIDRS}']
14+
serviceDomain: '${DOCKER_SERVICE_DOMAIN}'
15+
topology:
16+
class: "quick-start"
17+
version: "${KUBERNETES_VERSION}"
18+
controlPlane:
19+
metadata:
20+
labels:
21+
Cluster.topology.controlPlane.label: "Cluster.topology.controlPlane.labelValue"
22+
# Note: this label is propagated to Nodes.
23+
Cluster.topology.controlPlane.label.node.cluster.x-k8s.io: "Cluster.topology.controlPlane.nodeLabelValue"
24+
annotations:
25+
Cluster.topology.controlPlane.annotation: "Cluster.topology.controlPlane.annotationValue"
26+
nodeDeletionTimeout: "30s"
27+
nodeVolumeDetachTimeout: "5m"
28+
replicas: ${CONTROL_PLANE_MACHINE_COUNT}
29+
workers:
30+
machineDeployments:
31+
- class: "default-worker"
32+
name: "md-0"
33+
metadata:
34+
labels:
35+
Cluster.topology.machineDeployment.label: "Cluster.topology.machineDeployment.labelValue"
36+
# Note: this label is propagated to Nodes.
37+
Cluster.topology.machineDeployment.label.node.cluster.x-k8s.io: "Cluster.topology.machineDeployment.nodeLabelValue"
38+
annotations:
39+
Cluster.topology.machineDeployment.annotation: "Cluster.topology.machineDeployment.annotationValue"
40+
nodeDeletionTimeout: "30s"
41+
nodeVolumeDetachTimeout: "5m"
42+
minReadySeconds: 5
43+
replicas: ${WORKER_MACHINE_COUNT}
44+
failureDomain: fd4
45+
strategy:
46+
type: RollingUpdate
47+
rollingUpdate:
48+
maxSurge: "20%"
49+
maxUnavailable: 0
50+
machinePools:
51+
- class: "default-worker"
52+
name: "mp-0"
53+
metadata:
54+
labels:
55+
Cluster.topology.machinePool.label: "Cluster.topology.machinePool.labelValue"
56+
# Note: this label is propagated to Nodes.
57+
Cluster.topology.machinePool.label.node.cluster.x-k8s.io: "Cluster.topology.machinePool.nodeLabelValue"
58+
annotations:
59+
Cluster.topology.machinePool.annotation: "Cluster.topology.machinePool.annotationValue"
60+
nodeDeletionTimeout: "30s"
61+
nodeVolumeDetachTimeout: "5m"
62+
minReadySeconds: 5
63+
replicas: ${WORKER_MACHINE_COUNT}
64+
failureDomains:
65+
- fd4
66+
variables:
67+
# We set an empty value to use the default tag kubeadm init is using.
68+
- name: etcdImageTag
69+
value: ""
70+
# We set an empty value to use the default tag kubeadm init is using.
71+
- name: coreDNSImageTag
72+
value: ""
73+
- name: preLoadImages
74+
# The DOCKER_PRELOAD_IMAGES variable gets set in self-hosted E2E tests to the list of images of the E2E configuration.
75+
value: ${DOCKER_PRELOAD_IMAGES:-[]}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
---
2+
# ConfigMap object referenced by the ClusterResourceSet object and with
3+
# the CNI resource defined in the test config file
4+
apiVersion: v1
5+
kind: ConfigMap
6+
metadata:
7+
name: "cni-${CLUSTER_NAME}-crs-0"
8+
data: ${CNI_RESOURCES}
9+
binaryData:
10+
---
11+
# ClusterResourceSet object with
12+
# a selector that targets all the Cluster with label cni=${CLUSTER_NAME}-crs-0
13+
apiVersion: addons.cluster.x-k8s.io/v1beta1
14+
kind: ClusterResourceSet
15+
metadata:
16+
name: "${CLUSTER_NAME}-crs-0"
17+
spec:
18+
strategy: ApplyOnce
19+
clusterSelector:
20+
matchLabels:
21+
cni: "${CLUSTER_NAME}-crs-0"
22+
resources:
23+
- name: "cni-${CLUSTER_NAME}-crs-0"
24+
kind: ConfigMap

0 commit comments

Comments
 (0)