Skip to content

Commit e42d887

Browse files
feat: Add the ServiceLoadbalancer Addon, with MetalLB as first provider (#592)
**What problem does this PR solve?**: Adds the `ServiceLoadbalancer` addon, and support for MetalLB as the first provider. ### TODO: - [x] API type - [x] Generic handler - [x] MetalLB handler - [x] Deploy MetalLB Helm chart - [x] Default configuration for MetalLB Helm chart - [ ] Document the ServiceLoadbalancer Addon. **Which issue(s) this PR fixes**: Fixes https://jira.nutanix.com/browse/D2IQ-100444 **How Has This Been Tested?**: <!-- Please describe the tests that you ran to verify your changes. Provide output from the tests and any manual steps needed to replicate the tests. --> **Special notes for your reviewer**: <!-- Use this to provide any additional information to the reviewers. This may include: - Best way to review the PR. - Where the author wants the most review attention on. - etc. --> --------- Co-authored-by: Jimmi Dyson <[email protected]>
1 parent 968a084 commit e42d887

File tree

19 files changed

+506
-3
lines changed

19 files changed

+506
-3
lines changed

api/v1alpha1/addon_types.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ const (
2424

2525
VirtualIPProviderKubeVIP = "KubeVIP"
2626

27+
ServiceLoadBalancerProviderMetalLB = "MetalLB"
28+
2729
AddonStrategyClusterResourceSet AddonStrategy = "ClusterResourceSet"
2830
AddonStrategyHelmAddon AddonStrategy = "HelmAddon"
2931

@@ -69,6 +71,9 @@ type Addons struct {
6971

7072
// +optional
7173
CSIProviders *CSI `json:"csi,omitempty"`
74+
75+
// +optional
76+
ServiceLoadBalancer *ServiceLoadBalancer `json:"serviceLoadBalancer,omitempty"`
7277
}
7378

7479
type AddonStrategy string
@@ -160,3 +165,10 @@ type CCM struct {
160165
// +optional
161166
Credentials *corev1.LocalObjectReference `json:"credentials,omitempty"`
162167
}
168+
169+
type ServiceLoadBalancer struct {
170+
// The LoadBalancer-type Service provider to deploy. Not required in infrastructures where
171+
// the CCM acts as the provider.
172+
// +kubebuilder:validation:Enum=MetalLB
173+
Provider string `json:"provider"`
174+
}

api/v1alpha1/constants.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,6 @@ const (
1414
AWSVariableName = "aws"
1515
// NutanixVariableName is the Nutanix config patch variable name.
1616
NutanixVariableName = "nutanix"
17+
// ServiceLoadBalancerName is the Service LoadBalancer config patch variable name.
18+
ServiceLoadBalancerVariableName = "serviceLoadBalancer"
1719
)

api/v1alpha1/crds/caren.nutanix.com_awsclusterconfigs.yaml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,18 @@ spec:
201201
required:
202202
- strategy
203203
type: object
204+
serviceLoadBalancer:
205+
properties:
206+
provider:
207+
description: |-
208+
The LoadBalancer-type Service provider to deploy. Not required in infrastructures where
209+
the CCM acts as the provider.
210+
enum:
211+
- MetalLB
212+
type: string
213+
required:
214+
- provider
215+
type: object
204216
type: object
205217
aws:
206218
description: AWS cluster configuration.

api/v1alpha1/crds/caren.nutanix.com_dockerclusterconfigs.yaml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,18 @@ spec:
202202
required:
203203
- strategy
204204
type: object
205+
serviceLoadBalancer:
206+
properties:
207+
provider:
208+
description: |-
209+
The LoadBalancer-type Service provider to deploy. Not required in infrastructures where
210+
the CCM acts as the provider.
211+
enum:
212+
- MetalLB
213+
type: string
214+
required:
215+
- provider
216+
type: object
205217
type: object
206218
controlPlane:
207219
description: DockerNodeConfigSpec defines the desired state of DockerNodeSpec.

api/v1alpha1/crds/caren.nutanix.com_nutanixclusterconfigs.yaml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,18 @@ spec:
202202
required:
203203
- strategy
204204
type: object
205+
serviceLoadBalancer:
206+
properties:
207+
provider:
208+
description: |-
209+
The LoadBalancer-type Service provider to deploy. Not required in infrastructures where
210+
the CCM acts as the provider.
211+
enum:
212+
- MetalLB
213+
type: string
214+
required:
215+
- provider
216+
type: object
205217
type: object
206218
controlPlane:
207219
description: NutanixNodeSpec defines the desired state of NutanixNodeSpec.

api/v1alpha1/zz_generated.deepcopy.go

Lines changed: 20 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

charts/cluster-api-runtime-extensions-nutanix/README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,8 @@ A Helm chart for cluster-api-runtime-extensions-nutanix
6262
| hooks.nfd.crsStrategy.defaultInstallationConfigMap.name | string | `"node-feature-discovery"` | |
6363
| hooks.nfd.helmAddonStrategy.defaultValueTemplateConfigMap.create | bool | `true` | |
6464
| hooks.nfd.helmAddonStrategy.defaultValueTemplateConfigMap.name | string | `"default-nfd-helm-values-template"` | |
65+
| hooks.serviceLoadBalancer.metalLB.defaultValueTemplateConfigMap.create | bool | `true` | |
66+
| hooks.serviceLoadBalancer.metalLB.defaultValueTemplateConfigMap.name | string | `"default-metallb-helm-values-template"` | |
6567
| hooks.virtualIP.kubeVip.defaultTemplateConfigMap.create | bool | `true` | |
6668
| hooks.virtualIP.kubeVip.defaultTemplateConfigMap.name | string | `"default-kube-vip-template"` | |
6769
| image.pullPolicy | string | `"IfNotPresent"` | |

charts/cluster-api-runtime-extensions-nutanix/templates/helm-config.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@ data:
1515
ChartName: cluster-autoscaler
1616
ChartVersion: 9.35.0
1717
RepositoryURL: https://kubernetes.github.io/autoscaler
18+
metallb: |
19+
ChartName: metallb
20+
ChartVersion: v0.14.5
21+
RepositoryURL: https://metallb.github.io/metallb
1822
nfd: |
1923
ChartName: node-feature-discovery
2024
ChartVersion: 0.15.2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# Copyright 2023 D2iQ, Inc. All rights reserved.
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
{{- if .Values.hooks.serviceLoadBalancer.metalLB.defaultValueTemplateConfigMap.create }}
5+
apiVersion: v1
6+
kind: ConfigMap
7+
metadata:
8+
name: '{{ .Values.hooks.serviceLoadBalancer.metalLB.defaultValueTemplateConfigMap.name }}'
9+
data:
10+
values.yaml: |-
11+
controller:
12+
tolerations:
13+
- key: node-role.kubernetes.io/control-plane
14+
effect: NoSchedule
15+
operator: Exists
16+
- key: CriticalAddonsOnly
17+
operator: Exists
18+
- effect: NoExecute
19+
operator: Exists
20+
tolerationSeconds: 300
21+
speaker:
22+
tolerations:
23+
- key: node-role.kubernetes.io/control-plane
24+
effect: NoSchedule
25+
operator: Exists
26+
- key: CriticalAddonsOnly
27+
operator: Exists
28+
- effect: NoExecute
29+
operator: Exists
30+
tolerationSeconds: 300
31+
{{- end -}}

charts/cluster-api-runtime-extensions-nutanix/values.yaml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,11 @@ hooks:
7171
defaultValueTemplateConfigMap:
7272
create: true
7373
name: default-cluster-autoscaler-helm-values-template
74-
74+
serviceLoadBalancer:
75+
metalLB:
76+
defaultValueTemplateConfigMap:
77+
create: true
78+
name: default-metallb-helm-values-template
7579
virtualIP:
7680
kubeVip:
7781
defaultTemplateConfigMap:
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
+++
2+
title = "Service LoadBalancer"
3+
+++
4+
5+
When an application running in a cluster needs to be exposed outside of the cluster, one option is
6+
to use an [external load balancer], by creating a Kubernetes Service of the
7+
`LoadBalancer` type.
8+
9+
The Service Load Balancer is the component that backs this Kubernetes Service, either by creating
10+
a Virtual IP, creating a machine that runs load balancer software, by delegating to APIs, such as
11+
the underlying infrastructure, or a hardware load balancer.
12+
13+
CAREN currently supports the following Service Load Balancers:
14+
15+
- [MetalLB]
16+
17+
## Example
18+
19+
To enable deployment of MetalLB on a cluster, specify the following values:
20+
21+
```yaml
22+
apiVersion: cluster.x-k8s.io/v1beta1
23+
kind: Cluster
24+
metadata:
25+
name: <NAME>
26+
spec:
27+
topology:
28+
variables:
29+
- name: clusterConfig
30+
value:
31+
addons:
32+
serviceLoadBalancer:
33+
provider: MetalLB
34+
```
35+
36+
See [MetalLB documentation] for details on configuration.
37+
38+
[external load balancer]: https://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/
39+
[MetalLB]: https://metallb.org
40+
[MetalLB documentation]: https://metallb.org/configuration/
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# Copyright 2024 D2iQ, Inc. All rights reserved.
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
# NOTE This file is used by the tool in `hack/tools/helm-cm` to add
5+
# metallb chart metadata to the "helm-addons" ConfigMap. The tool takes
6+
# a kustomization as input. We do not use this file with kustomize.
7+
8+
apiVersion: kustomize.config.k8s.io/v1beta1
9+
kind: Kustomization
10+
11+
metadata:
12+
name: metallb
13+
14+
sortOptions:
15+
order: fifo
16+
17+
helmCharts:
18+
- name: metallb
19+
repo: https://metallb.github.io/metallb
20+
releaseName: metallb
21+
version: ${METALLB_CHART_VERSION}
22+
valuesFile: helm-values.yaml
23+
includeCRDs: true
24+
skipTests: true
25+
namespace: metallb-system
26+
27+
namespace: metallb-system

make/addons.mk

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ export NUTANIX_CCM_CHART_VERSION := 0.3.3
2121

2222
export KUBE_VIP_VERSION := v0.8.0
2323

24+
export METALLB_CHART_VERSION := v0.14.5
25+
2426
.PHONY: addons.sync
2527
addons.sync: $(addprefix update-addon.,calico cilium nfd cluster-autoscaler aws-ebs-csi aws-ccm.127 aws-ccm.128 aws-ccm.129 kube-vip)
2628

pkg/handlers/aws/mutation/controlplaneloadbalancer/inject_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ var _ = Describe("Generate AWS ControlPlane LoadBalancer patches", func() {
3434
Name: "unset variable",
3535
},
3636
{
37-
Name: "ControlPlaneLoadbalancer scheme set to internet-facing",
37+
Name: "ControlPlaneLoadBalancer scheme set to internet-facing",
3838
Vars: []runtimehooksv1.Variable{
3939
capitest.VariableWithValue(
4040
clusterconfig.MetaVariableName,
@@ -55,7 +55,7 @@ var _ = Describe("Generate AWS ControlPlane LoadBalancer patches", func() {
5555
}},
5656
},
5757
{
58-
Name: "ControlPlaneLoadbalancer scheme set to internal",
58+
Name: "ControlPlaneLoadBalancer scheme set to internal",
5959
Vars: []runtimehooksv1.Variable{
6060
capitest.VariableWithValue(
6161
clusterconfig.MetaVariableName,

pkg/handlers/generic/lifecycle/config/cm.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ const (
2424
NutanixStorageCSI Component = "nutanix-storage-csi"
2525
NutanixSnapshotCSI Component = "nutanix-snapshot-csi"
2626
NutanixCCM Component = "nutanix-ccm"
27+
MetalLB Component = "metallb"
2728
)
2829

2930
type HelmChartGetter struct {

pkg/handlers/generic/lifecycle/handlers.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ import (
2121
nutanixcsi "github.com/nutanix-cloud-native/cluster-api-runtime-extensions-nutanix/pkg/handlers/generic/lifecycle/csi/nutanix-csi"
2222
"github.com/nutanix-cloud-native/cluster-api-runtime-extensions-nutanix/pkg/handlers/generic/lifecycle/nfd"
2323
"github.com/nutanix-cloud-native/cluster-api-runtime-extensions-nutanix/pkg/handlers/generic/lifecycle/servicelbgc"
24+
"github.com/nutanix-cloud-native/cluster-api-runtime-extensions-nutanix/pkg/handlers/generic/lifecycle/serviceloadbalancer"
25+
"github.com/nutanix-cloud-native/cluster-api-runtime-extensions-nutanix/pkg/handlers/generic/lifecycle/serviceloadbalancer/metallb"
2426
"github.com/nutanix-cloud-native/cluster-api-runtime-extensions-nutanix/pkg/handlers/options"
2527
)
2628

@@ -34,6 +36,7 @@ type Handlers struct {
3436
nutnaixCSIConfig *nutanixcsi.NutanixCSIConfig
3537
awsccmConfig *awsccm.AWSCCMConfig
3638
nutanixCCMConfig *nutanixccm.Config
39+
metalLBConfig *metallb.Config
3740
}
3841

3942
func New(
@@ -51,6 +54,7 @@ func New(
5154
awsccmConfig: &awsccm.AWSCCMConfig{GlobalOptions: globalOptions},
5255
nutnaixCSIConfig: &nutanixcsi.NutanixCSIConfig{GlobalOptions: globalOptions},
5356
nutanixCCMConfig: &nutanixccm.Config{GlobalOptions: globalOptions},
57+
metalLBConfig: &metallb.Config{GlobalOptions: globalOptions},
5458
}
5559
}
5660

@@ -76,6 +80,13 @@ func (h *Handlers) AllHandlers(mgr manager.Manager) []handlers.Named {
7680
helmChartInfoGetter,
7781
),
7882
}
83+
serviceLoadBalancerHandlers := map[string]serviceloadbalancer.ServiceLoadBalancerProvider{
84+
v1alpha1.ServiceLoadBalancerProviderMetalLB: metallb.New(
85+
mgr.GetClient(),
86+
h.metalLBConfig,
87+
helmChartInfoGetter,
88+
),
89+
}
7990
return []handlers.Named{
8091
calico.New(mgr.GetClient(), h.calicoCNIConfig, helmChartInfoGetter),
8192
cilium.New(mgr.GetClient(), h.ciliumCNIConfig, helmChartInfoGetter),
@@ -84,6 +95,7 @@ func (h *Handlers) AllHandlers(mgr manager.Manager) []handlers.Named {
8495
servicelbgc.New(mgr.GetClient()),
8596
csi.New(mgr.GetClient(), csiHandlers),
8697
ccm.New(mgr.GetClient(), ccmHandlers),
98+
serviceloadbalancer.New(mgr.GetClient(), serviceLoadBalancerHandlers),
8799
}
88100
}
89101

@@ -96,4 +108,5 @@ func (h *Handlers) AddFlags(flagSet *pflag.FlagSet) {
96108
h.awsccmConfig.AddFlags("awsccm", pflag.CommandLine)
97109
h.nutnaixCSIConfig.AddFlags("nutanixcsi", flagSet)
98110
h.nutanixCCMConfig.AddFlags("nutanixccm", flagSet)
111+
h.metalLBConfig.AddFlags("metallb", flagSet)
99112
}

0 commit comments

Comments
 (0)