diff --git a/cmd/openshift-install/testdata/agent/image/configurations/control-plane-4-replicas.txt b/cmd/openshift-install/testdata/agent/image/configurations/control-plane-4-replicas.txt new file mode 100644 index 00000000000..999c900de8e --- /dev/null +++ b/cmd/openshift-install/testdata/agent/image/configurations/control-plane-4-replicas.txt @@ -0,0 +1,100 @@ +# Verify control plane with 4 replicas is allowed + +exec openshift-install agent create image --dir $WORK + +stderr 'The rendezvous host IP \(node0 IP\) is 192.168.111.20' + +exists $WORK/agent.x86_64.iso +exists $WORK/auth/kubeconfig +exists $WORK/auth/kubeadmin-password +isocmp agent.x86_64.iso /etc/systemd/system.conf.d/10-default-env.conf expected/10-default-env.conf +isocmp agent.x86_64.iso /etc/assisted/manifests/agent-cluster-install.yaml expected/agent-cluster-install.yaml + +-- install-config.yaml -- +apiVersion: v1 +baseDomain: test.metalkube.org +proxy: + httpProxy: http://192.168.111.1:8215 + httpsProxy: http://192.168.111.1:8215 + noProxy: 172.22.0.0/24,virthost.ostest.test.metalkube.org +controlPlane: + name: master + replicas: 4 +compute: +- name: worker + replicas: 0 +metadata: + namespace: cluster0 + name: ostest +networking: + clusterNetwork: + - cidr: 10.128.0.0/14 + hostPrefix: 23 + networkType: OVNKubernetes + machineNetwork: + - cidr: 192.168.111.0/24 + serviceNetwork: + - 172.30.0.0/16 +platform: + baremetal: + apiVips: + - 192.168.111.5 + ingressVips: + - 192.168.111.4 +sshKey: ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDK6UTEydcEKzuNdPaofn8Z2DwgHqdcionLZBiPf/zIRNco++etLsat7Avv7yt04DINQd5zjxIFgG8jblaUB5E5C9ClUcMwb52GO0ay2Y9v1uBv1a4WhI3peKktAzYNk0EBMQlJtXPjRMrC9ylBPh+DsBHMu+KmDnfk7PIwyN4efC8k5kSRuPWoNdme1rz2+umU8FSmaWTHIajrbspf4GQbsntA5kuKEtDbfoNCU97o2KrRnUbeg3a8hwSjfh3u6MhlnGcg5K2Ij+zivEsWGCLKYUtE1ErqwfIzwWmJ6jnV66XCQGHf4Q1iIxqF7s2a1q24cgG2Z/iDXfqXrCIfy4P7b/Ztak3bdT9jfAdVZtdO5/r7I+O5hYhF86ayFlDWzZWP/ByiSb+q4CQbfVgK3BMmiAv2MqLHdhesmD/SmIcoOWUF6rFmRKZVFFpKpt5ATNTgUJ3JRowoXrrDruVXClUGRiCS6Zabd1rZ3VmTchaPJwtzQMdfIWISXj+Ig+C4UK0= +pullSecret: '{"auths": {"quay.io": {"auth": "c3VwZXItc2VjcmV0Cg=="}}}' + +-- agent-config.yaml -- +apiVersion: v1alpha1 +metadata: + name: ostest + namespace: cluster0 +rendezvousIP: 192.168.111.20 + +-- expected/10-default-env.conf -- +[Manager] +DefaultEnvironment=HTTP_PROXY="http://192.168.111.1:8215" +DefaultEnvironment=HTTPS_PROXY="http://192.168.111.1:8215" +DefaultEnvironment=NO_PROXY="172.22.0.0/24,virthost.ostest.test.metalkube.org,192.168.111.20" +-- expected/agent-cluster-install.yaml -- +apiVersion: extensions.hive.openshift.io/v1beta1 +kind: AgentClusterInstall +metadata: + creationTimestamp: null + name: ostest + namespace: cluster0 +spec: + apiVIP: 192.168.111.5 + apiVIPs: + - 192.168.111.5 + clusterDeploymentRef: + name: ostest + imageSetRef: + name: openshift-was not built correctly + ingressVIP: 192.168.111.4 + ingressVIPs: + - 192.168.111.4 + networking: + clusterNetwork: + - cidr: 10.128.0.0/14 + hostPrefix: 23 + machineNetwork: + - cidr: 192.168.111.0/24 + networkType: OVNKubernetes + serviceNetwork: + - 172.30.0.0/16 + userManagedNetworking: false + platformType: BareMetal + provisionRequirements: + controlPlaneAgents: 4 + proxy: + httpProxy: http://192.168.111.1:8215 + httpsProxy: http://192.168.111.1:8215 + noProxy: 172.22.0.0/24,virthost.ostest.test.metalkube.org + sshPublicKey: ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDK6UTEydcEKzuNdPaofn8Z2DwgHqdcionLZBiPf/zIRNco++etLsat7Avv7yt04DINQd5zjxIFgG8jblaUB5E5C9ClUcMwb52GO0ay2Y9v1uBv1a4WhI3peKktAzYNk0EBMQlJtXPjRMrC9ylBPh+DsBHMu+KmDnfk7PIwyN4efC8k5kSRuPWoNdme1rz2+umU8FSmaWTHIajrbspf4GQbsntA5kuKEtDbfoNCU97o2KrRnUbeg3a8hwSjfh3u6MhlnGcg5K2Ij+zivEsWGCLKYUtE1ErqwfIzwWmJ6jnV66XCQGHf4Q1iIxqF7s2a1q24cgG2Z/iDXfqXrCIfy4P7b/Ztak3bdT9jfAdVZtdO5/r7I+O5hYhF86ayFlDWzZWP/ByiSb+q4CQbfVgK3BMmiAv2MqLHdhesmD/SmIcoOWUF6rFmRKZVFFpKpt5ATNTgUJ3JRowoXrrDruVXClUGRiCS6Zabd1rZ3VmTchaPJwtzQMdfIWISXj+Ig+C4UK0= +status: + debugInfo: + eventsURL: "" + logsURL: "" + progress: + totalPercentage: 0 diff --git a/cmd/openshift-install/testdata/agent/image/configurations/control-plane-5-replicas.txt b/cmd/openshift-install/testdata/agent/image/configurations/control-plane-5-replicas.txt new file mode 100644 index 00000000000..282be1f7346 --- /dev/null +++ b/cmd/openshift-install/testdata/agent/image/configurations/control-plane-5-replicas.txt @@ -0,0 +1,100 @@ +# Verify control plane with 5 replicas is allowed + +exec openshift-install agent create image --dir $WORK + +stderr 'The rendezvous host IP \(node0 IP\) is 192.168.111.20' + +exists $WORK/agent.x86_64.iso +exists $WORK/auth/kubeconfig +exists $WORK/auth/kubeadmin-password +isocmp agent.x86_64.iso /etc/systemd/system.conf.d/10-default-env.conf expected/10-default-env.conf +isocmp agent.x86_64.iso /etc/assisted/manifests/agent-cluster-install.yaml expected/agent-cluster-install.yaml + +-- install-config.yaml -- +apiVersion: v1 +baseDomain: test.metalkube.org +proxy: + httpProxy: http://192.168.111.1:8215 + httpsProxy: http://192.168.111.1:8215 + noProxy: 172.22.0.0/24,virthost.ostest.test.metalkube.org +controlPlane: + name: master + replicas: 5 +compute: +- name: worker + replicas: 0 +metadata: + namespace: cluster0 + name: ostest +networking: + clusterNetwork: + - cidr: 10.128.0.0/14 + hostPrefix: 23 + networkType: OVNKubernetes + machineNetwork: + - cidr: 192.168.111.0/24 + serviceNetwork: + - 172.30.0.0/16 +platform: + baremetal: + apiVips: + - 192.168.111.5 + ingressVips: + - 192.168.111.4 +sshKey: ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDK6UTEydcEKzuNdPaofn8Z2DwgHqdcionLZBiPf/zIRNco++etLsat7Avv7yt04DINQd5zjxIFgG8jblaUB5E5C9ClUcMwb52GO0ay2Y9v1uBv1a4WhI3peKktAzYNk0EBMQlJtXPjRMrC9ylBPh+DsBHMu+KmDnfk7PIwyN4efC8k5kSRuPWoNdme1rz2+umU8FSmaWTHIajrbspf4GQbsntA5kuKEtDbfoNCU97o2KrRnUbeg3a8hwSjfh3u6MhlnGcg5K2Ij+zivEsWGCLKYUtE1ErqwfIzwWmJ6jnV66XCQGHf4Q1iIxqF7s2a1q24cgG2Z/iDXfqXrCIfy4P7b/Ztak3bdT9jfAdVZtdO5/r7I+O5hYhF86ayFlDWzZWP/ByiSb+q4CQbfVgK3BMmiAv2MqLHdhesmD/SmIcoOWUF6rFmRKZVFFpKpt5ATNTgUJ3JRowoXrrDruVXClUGRiCS6Zabd1rZ3VmTchaPJwtzQMdfIWISXj+Ig+C4UK0= +pullSecret: '{"auths": {"quay.io": {"auth": "c3VwZXItc2VjcmV0Cg=="}}}' + +-- agent-config.yaml -- +apiVersion: v1alpha1 +metadata: + name: ostest + namespace: cluster0 +rendezvousIP: 192.168.111.20 + +-- expected/10-default-env.conf -- +[Manager] +DefaultEnvironment=HTTP_PROXY="http://192.168.111.1:8215" +DefaultEnvironment=HTTPS_PROXY="http://192.168.111.1:8215" +DefaultEnvironment=NO_PROXY="172.22.0.0/24,virthost.ostest.test.metalkube.org,192.168.111.20" +-- expected/agent-cluster-install.yaml -- +apiVersion: extensions.hive.openshift.io/v1beta1 +kind: AgentClusterInstall +metadata: + creationTimestamp: null + name: ostest + namespace: cluster0 +spec: + apiVIP: 192.168.111.5 + apiVIPs: + - 192.168.111.5 + clusterDeploymentRef: + name: ostest + imageSetRef: + name: openshift-was not built correctly + ingressVIP: 192.168.111.4 + ingressVIPs: + - 192.168.111.4 + networking: + clusterNetwork: + - cidr: 10.128.0.0/14 + hostPrefix: 23 + machineNetwork: + - cidr: 192.168.111.0/24 + networkType: OVNKubernetes + serviceNetwork: + - 172.30.0.0/16 + userManagedNetworking: false + platformType: BareMetal + provisionRequirements: + controlPlaneAgents: 5 + proxy: + httpProxy: http://192.168.111.1:8215 + httpsProxy: http://192.168.111.1:8215 + noProxy: 172.22.0.0/24,virthost.ostest.test.metalkube.org + sshPublicKey: ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDK6UTEydcEKzuNdPaofn8Z2DwgHqdcionLZBiPf/zIRNco++etLsat7Avv7yt04DINQd5zjxIFgG8jblaUB5E5C9ClUcMwb52GO0ay2Y9v1uBv1a4WhI3peKktAzYNk0EBMQlJtXPjRMrC9ylBPh+DsBHMu+KmDnfk7PIwyN4efC8k5kSRuPWoNdme1rz2+umU8FSmaWTHIajrbspf4GQbsntA5kuKEtDbfoNCU97o2KrRnUbeg3a8hwSjfh3u6MhlnGcg5K2Ij+zivEsWGCLKYUtE1ErqwfIzwWmJ6jnV66XCQGHf4Q1iIxqF7s2a1q24cgG2Z/iDXfqXrCIfy4P7b/Ztak3bdT9jfAdVZtdO5/r7I+O5hYhF86ayFlDWzZWP/ByiSb+q4CQbfVgK3BMmiAv2MqLHdhesmD/SmIcoOWUF6rFmRKZVFFpKpt5ATNTgUJ3JRowoXrrDruVXClUGRiCS6Zabd1rZ3VmTchaPJwtzQMdfIWISXj+Ig+C4UK0= +status: + debugInfo: + eventsURL: "" + logsURL: "" + progress: + totalPercentage: 0 diff --git a/cmd/openshift-install/testdata/agent/image/validations/compact_invalid_controlPlane_replicas.txt b/cmd/openshift-install/testdata/agent/image/validations/compact_invalid_controlPlane_replicas.txt index fb7dd4e2117..b67c67fc0e9 100644 --- a/cmd/openshift-install/testdata/agent/image/validations/compact_invalid_controlPlane_replicas.txt +++ b/cmd/openshift-install/testdata/agent/image/validations/compact_invalid_controlPlane_replicas.txt @@ -1,6 +1,6 @@ ! exec openshift-install agent create image --dir $WORK -stderr 'ControlPlane.Replicas can only be set to 3 or 1. Found 2' +stderr 'ControlPlane.Replicas can only be set to 5, 4, 3, or 1. Found 2' ! exists $WORK/agent.x86_64.iso ! exists $WORK/auth/kubeconfig diff --git a/docs/user/agent/control-plane-replicas.md b/docs/user/agent/control-plane-replicas.md new file mode 100644 index 00000000000..6013e9d73ad --- /dev/null +++ b/docs/user/agent/control-plane-replicas.md @@ -0,0 +1,26 @@ +# Control Plane Replicas + +The number of control plane replicas are either set in install-config.yaml or agent-cluster-install.yaml if ZTP manifests are used. + +install-config.yaml +``` +controlPlane: + name: master + replicas: 3 +``` + +agent-cluster-install.yaml +``` +spec: + provisionRequirements: + controlPlaneAgents: 3 +``` + +# 4.18 update + +Starting with 4.18, replicas of 5, 4, 3, or 1 are supported. + +# Prior to 4.18 + +Only control plane replicas of either 3 or 1 are supported. + diff --git a/pkg/asset/agent/installconfig.go b/pkg/asset/agent/installconfig.go index daef6b824af..4138f38ba98 100644 --- a/pkg/asset/agent/installconfig.go +++ b/pkg/asset/agent/installconfig.go @@ -215,9 +215,9 @@ func (a *OptionalInstallConfig) validateControlPlaneConfiguration(installConfig var fieldPath *field.Path if installConfig.ControlPlane != nil { - if *installConfig.ControlPlane.Replicas != 1 && *installConfig.ControlPlane.Replicas != 3 { + if *installConfig.ControlPlane.Replicas < 1 || *installConfig.ControlPlane.Replicas > 5 || *installConfig.ControlPlane.Replicas == 2 { fieldPath = field.NewPath("ControlPlane", "Replicas") - allErrs = append(allErrs, field.Invalid(fieldPath, installConfig.ControlPlane.Replicas, fmt.Sprintf("ControlPlane.Replicas can only be set to 3 or 1. Found %v", *installConfig.ControlPlane.Replicas))) + allErrs = append(allErrs, field.Invalid(fieldPath, installConfig.ControlPlane.Replicas, fmt.Sprintf("ControlPlane.Replicas can only be set to 5, 4, 3, or 1. Found %v", *installConfig.ControlPlane.Replicas))) } } return allErrs diff --git a/pkg/asset/agent/installconfig_test.go b/pkg/asset/agent/installconfig_test.go index f513f3ebab6..4b6a632ba95 100644 --- a/pkg/asset/agent/installconfig_test.go +++ b/pkg/asset/agent/installconfig_test.go @@ -291,7 +291,7 @@ platform: pullSecret: "{\"auths\":{\"example.com\":{\"auth\":\"authorization value\"}}}" `, expectedFound: false, - expectedError: "invalid install-config configuration: ControlPlane.Replicas: Invalid value: 2: ControlPlane.Replicas can only be set to 3 or 1. Found 2", + expectedError: "invalid install-config configuration: ControlPlane.Replicas: Invalid value: 2: ControlPlane.Replicas can only be set to 5, 4, 3, or 1. Found 2", }, { name: "invalid platform for SNO cluster", @@ -622,6 +622,140 @@ pullSecret: "{\"auths\":{\"example.com\":{\"auth\":\"c3VwZXItc2VjcmV0Cg==\"}}}" Publish: types.ExternalPublishingStrategy, }, }, + { + name: "valid configuration control plane replicas set to 5", + data: ` +apiVersion: v1 +metadata: + name: test-cluster +baseDomain: test-domain +networking: + networkType: OVNKubernetes +compute: + - architecture: amd64 + hyperthreading: Enabled + name: worker + platform: {} + replicas: 2 +controlPlane: + architecture: amd64 + hyperthreading: Enabled + name: master + platform: {} + replicas: 5 +platform: + none : {} +pullSecret: "{\"auths\":{\"example.com\":{\"auth\":\"c3VwZXItc2VjcmV0Cg==\"}}}" +`, + expectedFound: true, + expectedConfig: &types.InstallConfig{ + TypeMeta: metav1.TypeMeta{ + APIVersion: types.InstallConfigVersion, + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "test-cluster", + }, + AdditionalTrustBundlePolicy: types.PolicyProxyOnly, + BaseDomain: "test-domain", + Networking: &types.Networking{ + MachineNetwork: []types.MachineNetworkEntry{ + {CIDR: *ipnet.MustParseCIDR("10.0.0.0/16")}, + }, + NetworkType: "OVNKubernetes", + ServiceNetwork: []ipnet.IPNet{*ipnet.MustParseCIDR("172.30.0.0/16")}, + ClusterNetwork: []types.ClusterNetworkEntry{ + { + CIDR: *ipnet.MustParseCIDR("10.128.0.0/14"), + HostPrefix: 23, + }, + }, + }, + ControlPlane: &types.MachinePool{ + Name: "master", + Replicas: pointer.Int64(5), + Hyperthreading: types.HyperthreadingEnabled, + Architecture: types.ArchitectureAMD64, + }, + Compute: []types.MachinePool{ + { + Name: "worker", + Replicas: pointer.Int64(2), + Hyperthreading: types.HyperthreadingEnabled, + Architecture: types.ArchitectureAMD64, + }, + }, + Platform: types.Platform{None: &none.Platform{}}, + PullSecret: `{"auths":{"example.com":{"auth":"c3VwZXItc2VjcmV0Cg=="}}}`, + Publish: types.ExternalPublishingStrategy, + }, + }, + { + name: "valid configuration control plane replicas set to 4", + data: ` +apiVersion: v1 +metadata: + name: test-cluster +baseDomain: test-domain +networking: + networkType: OVNKubernetes +compute: + - architecture: amd64 + hyperthreading: Enabled + name: worker + platform: {} + replicas: 2 +controlPlane: + architecture: amd64 + hyperthreading: Enabled + name: master + platform: {} + replicas: 4 +platform: + none : {} +pullSecret: "{\"auths\":{\"example.com\":{\"auth\":\"c3VwZXItc2VjcmV0Cg==\"}}}" +`, + expectedFound: true, + expectedConfig: &types.InstallConfig{ + TypeMeta: metav1.TypeMeta{ + APIVersion: types.InstallConfigVersion, + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "test-cluster", + }, + AdditionalTrustBundlePolicy: types.PolicyProxyOnly, + BaseDomain: "test-domain", + Networking: &types.Networking{ + MachineNetwork: []types.MachineNetworkEntry{ + {CIDR: *ipnet.MustParseCIDR("10.0.0.0/16")}, + }, + NetworkType: "OVNKubernetes", + ServiceNetwork: []ipnet.IPNet{*ipnet.MustParseCIDR("172.30.0.0/16")}, + ClusterNetwork: []types.ClusterNetworkEntry{ + { + CIDR: *ipnet.MustParseCIDR("10.128.0.0/14"), + HostPrefix: 23, + }, + }, + }, + ControlPlane: &types.MachinePool{ + Name: "master", + Replicas: pointer.Int64(4), + Hyperthreading: types.HyperthreadingEnabled, + Architecture: types.ArchitectureAMD64, + }, + Compute: []types.MachinePool{ + { + Name: "worker", + Replicas: pointer.Int64(2), + Hyperthreading: types.HyperthreadingEnabled, + Architecture: types.ArchitectureAMD64, + }, + }, + Platform: types.Platform{None: &none.Platform{}}, + PullSecret: `{"auths":{"example.com":{"auth":"c3VwZXItc2VjcmV0Cg=="}}}`, + Publish: types.ExternalPublishingStrategy, + }, + }, { name: "valid configuration for baremetal platform for HA cluster - deprecated and unused fields", data: `