Skip to content

Commit 58fbf4c

Browse files
author
Matt Pryor
committed
Add support for specifying a fixed API server IP
1 parent 75d1d40 commit 58fbf4c

File tree

5 files changed

+57
-10
lines changed

5 files changed

+57
-10
lines changed

api/v1alpha4/openstackcluster_types.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,16 @@ type OpenStackClusterSpec struct {
8383
// This field is not used if DisableAPIServerFloatingIP is set.
8484
APIServerFloatingIP string `json:"apiServerFloatingIP,omitempty"`
8585

86+
// APIServerFixedIP is the fixed IP which will be associated with the API server.
87+
// In the case where the API server has a floating IP but not a managed load balancer,
88+
// this field is not used.
89+
// If a managed load balancer is used and this field is not specified, a fixed IP will
90+
// be dynamically allocated for the load balancer.
91+
// If a managed load balancer is not used AND the API server floating IP is disabled,
92+
// this field MUST be specified and should correspond to a pre-allocated port that
93+
// holds the fixed IP to be used as a VIP.
94+
APIServerFixedIP string `json:"apiServerFixedIP,omitempty"`
95+
8696
// APIServerPort is the port on which the listener on the APIServer
8797
// will be created
8898
APIServerPort int `json:"apiServerPort,omitempty"`

config/crd/bases/infrastructure.cluster.x-k8s.io_openstackclusters.yaml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1078,6 +1078,17 @@ spec:
10781078
groups are configured so that all ingress and egress between cluster
10791079
nodes is permitted, allowing CNIs other than Calico to be used.
10801080
type: boolean
1081+
apiServerFixedIP:
1082+
description: APIServerFixedIP is the fixed IP which will be associated
1083+
with the API server. In the case where the API server has a floating
1084+
IP but not a managed load balancer, this field is not used. If a
1085+
managed load balancer is used and this field is not specified, a
1086+
fixed IP will be dynamically allocated for the load balancer. If
1087+
a managed load balancer is not used AND the API server floating
1088+
IP is disabled, this field MUST be specified and should correspond
1089+
to a pre-allocated port that holds the fixed IP to be used as a
1090+
VIP.
1091+
type: string
10811092
apiServerFloatingIP:
10821093
description: APIServerFloatingIP is the floatingIP which will be associated
10831094
with the API server. The floatingIP will be created if it does not

config/crd/bases/infrastructure.cluster.x-k8s.io_openstackclustertemplates.yaml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,18 @@ spec:
5757
and egress between cluster nodes is permitted, allowing
5858
CNIs other than Calico to be used.
5959
type: boolean
60+
apiServerFixedIP:
61+
description: APIServerFixedIP is the fixed IP which will be
62+
associated with the API server. In the case where the API
63+
server has a floating IP but not a managed load balancer,
64+
this field is not used. If a managed load balancer is used
65+
and this field is not specified, a fixed IP will be dynamically
66+
allocated for the load balancer. If a managed load balancer
67+
is not used AND the API server floating IP is disabled,
68+
this field MUST be specified and should correspond to a
69+
pre-allocated port that holds the fixed IP to be used as
70+
a VIP.
71+
type: string
6072
apiServerFloatingIP:
6173
description: APIServerFloatingIP is the floatingIP which will
6274
be associated with the API server. The floatingIP will be

controllers/openstackcluster_controller.go

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -487,13 +487,17 @@ func reconcileNetworkComponents(log logr.Logger, osProviderClient *gophercloud.P
487487
return errors.Errorf("Floating IP cannot be got or created: %v", err)
488488
}
489489
host = fp.FloatingIP
490+
case openStackCluster.Spec.APIServerFixedIP != "":
491+
// If a fixed IP was specified, assume that the user is providing the extra configuration
492+
// to use that IP as the VIP for the API server, e.g. using keepalived or kube-vip
493+
host = openStackCluster.Spec.APIServerFixedIP
490494
default:
491-
// This case is not managed for now (i.e. no load balancer + no floating IP)
492-
// We could manage a VIP port on the cluster network and set allowedAddressPairs accordingly
493-
// when creating control plane machines, but this would require us to deploy software on the
494-
// control plane hosts to manage the VIP (e.g. keepalived/kube-vip)
495-
// It is still possible for a user to deploy this case manually using existing options
496-
return errors.New("unable to determine VIP for API server - either load balancer or floating IP must be enabled")
495+
// For now, we do not provide a managed VIP without either a load balancer or a floating IP
496+
// In the future, we could manage a VIP port on the cluster network and set allowedAddressPairs
497+
// accordingly when creating control plane machines
498+
// However this would require us to deploy software on the control plane hosts to manage the
499+
// VIP (e.g. keepalived/kube-vip)
500+
return errors.New("unable to determine VIP for API server")
497501
}
498502

499503
// Set APIEndpoints so the Cluster API Cluster Controller can pull them

pkg/cloud/services/loadbalancer/loadbalancer.go

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,17 +44,26 @@ func (s *Service) ReconcileLoadBalancer(openStackCluster *infrav1.OpenStackClust
4444
loadBalancerName := getLoadBalancerName(clusterName)
4545
s.logger.Info("Reconciling load balancer", "name", loadBalancerName)
4646

47-
lb, err := s.getOrCreateLoadBalancer(openStackCluster, loadBalancerName, openStackCluster.Status.Network.Subnet.ID, clusterName)
47+
var fixedIPAddress string
48+
switch {
49+
case openStackCluster.Spec.APIServerFixedIP != "":
50+
fixedIPAddress = openStackCluster.Spec.APIServerFixedIP
51+
case openStackCluster.Spec.DisableAPIServerFloatingIP && openStackCluster.Spec.ControlPlaneEndpoint.IsValid():
52+
fixedIPAddress = openStackCluster.Spec.ControlPlaneEndpoint.Host
53+
}
54+
55+
lb, err := s.getOrCreateLoadBalancer(openStackCluster, loadBalancerName, openStackCluster.Status.Network.Subnet.ID, clusterName, fixedIPAddress)
4856
if err != nil {
4957
return err
5058
}
5159

5260
var lbFloatingIP string
5361
if !openStackCluster.Spec.DisableAPIServerFloatingIP {
5462
var floatingIPAddress string
55-
if openStackCluster.Spec.APIServerFloatingIP != "" {
63+
switch {
64+
case openStackCluster.Spec.APIServerFloatingIP != "":
5665
floatingIPAddress = openStackCluster.Spec.APIServerFloatingIP
57-
} else if openStackCluster.Spec.ControlPlaneEndpoint.IsValid() {
66+
case openStackCluster.Spec.ControlPlaneEndpoint.IsValid():
5867
floatingIPAddress = openStackCluster.Spec.ControlPlaneEndpoint.Host
5968
}
6069
fp, err := s.networkingService.GetOrCreateFloatingIP(openStackCluster, clusterName, floatingIPAddress)
@@ -95,7 +104,7 @@ func (s *Service) ReconcileLoadBalancer(openStackCluster *infrav1.OpenStackClust
95104
return nil
96105
}
97106

98-
func (s *Service) getOrCreateLoadBalancer(openStackCluster *infrav1.OpenStackCluster, loadBalancerName, subnetID, clusterName string) (*loadbalancers.LoadBalancer, error) {
107+
func (s *Service) getOrCreateLoadBalancer(openStackCluster *infrav1.OpenStackCluster, loadBalancerName, subnetID, clusterName string, vipAddress string) (*loadbalancers.LoadBalancer, error) {
99108
lb, err := s.checkIfLbExists(loadBalancerName)
100109
if err != nil {
101110
return nil, err
@@ -110,6 +119,7 @@ func (s *Service) getOrCreateLoadBalancer(openStackCluster *infrav1.OpenStackClu
110119
lbCreateOpts := loadbalancers.CreateOpts{
111120
Name: loadBalancerName,
112121
VipSubnetID: subnetID,
122+
VipAddress: vipAddress,
113123
Description: names.GetDescription(clusterName),
114124
}
115125
mc := metrics.NewMetricPrometheusContext("loadbalancer", "create")

0 commit comments

Comments
 (0)