Skip to content

Commit

Permalink
Support MetalLB (#466)
Browse files Browse the repository at this point in the history
* Add metallb chart

* make ck-loadbalancer chart work with cilium or metallb

* implement metallb feature

* moonray use metallb

---------

Co-authored-by: Angelos Kolaitis <angelos.kolaitis@canonical.com>
  • Loading branch information
eaudetcobello and neoaggelos committed Jun 25, 2024
1 parent 48be3da commit 1188bdc
Show file tree
Hide file tree
Showing 15 changed files with 315 additions and 4 deletions.
19 changes: 18 additions & 1 deletion build-scripts/hack/update-component-versions.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,11 @@
CONTOUR_HELM_REPO = "https://charts.bitnami.com/bitnami"
CONTOUR_CHART_VERSION = "17.0.4"

# MetalLB Helm repository and chart version
METALLB_REPO = "https://metallb.github.io/metallb"
METALLB_CHART_VERSION = "0.14.5"


def get_kubernetes_version() -> str:
"""Update Kubernetes version based on the specified marker file"""
LOG.info("Checking latest Kubernetes version from %s", KUBERNETES_VERSION_MARKER)
Expand All @@ -63,10 +68,16 @@ def get_cni_version() -> str:

raise Exception(f"Failed to find cni dependency in {deps_file}")


def pull_contour_chart() -> None:
LOG.info("Pulling Contour Helm chart from %s with version %s", CONTOUR_HELM_REPO, CONTOUR_CHART_VERSION)
LOG.info(
"Pulling Contour Helm chart from %s with version %s",
CONTOUR_HELM_REPO,
CONTOUR_CHART_VERSION,
)
util.helm_pull("contour", CONTOUR_HELM_REPO, CONTOUR_CHART_VERSION, CHARTS)


def get_containerd_version() -> str:
"""Update containerd version using latest tag of specified branch"""
containerd_repo = util.read_file(COMPONENTS / "containerd/repository")
Expand All @@ -93,6 +104,11 @@ def get_helm_version() -> str:
return util.parse_output(["git", "describe", "--tags", "--abbrev=0"], cwd=dir)


def pull_metallb_chart() -> None:
LOG.info("Pulling MetalLB chart @ %s", METALLB_CHART_VERSION)
util.helm_pull("metallb", METALLB_REPO, METALLB_CHART_VERSION, CHARTS)


def update_component_versions(dry_run: bool):
for component, get_version in [
("kubernetes", get_kubernetes_version),
Expand All @@ -110,6 +126,7 @@ def update_component_versions(dry_run: bool):

for component, pull_helm_chart in [
("bitnami/contour", pull_contour_chart),
("metallb", pull_metallb_chart),
]:
LOG.info("Updating chart for %s", component)
if not dry_run:
Expand Down
1 change: 1 addition & 0 deletions build-scripts/hack/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ def read_file(path: Path) -> str:
def read_url(url: str) -> str:
return urlopen(url).read().decode().strip()


def helm_pull(chart, repo_url: str, version: str, destination: Path) -> None:
parse_output(
[
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
{{- if .Values.bgp.enabled }}
{{- if (eq .Values.driver "cilium") }}
{{- if (.Values.bgp.enabled) }}

apiVersion: "cilium.io/v2alpha1"
kind: CiliumBGPPeeringPolicy
metadata:
Expand All @@ -15,4 +17,6 @@ spec:
neighbors:
{{- toYaml . | nindent 4 }}
{{- end }}

{{- end}}
{{- end}}
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
{{- if (eq .Values.driver "cilium") }}
{{- if .Values.l2.enabled }}

apiVersion: "cilium.io/v2alpha1"
kind: CiliumL2AnnouncementPolicy
metadata:
Expand All @@ -12,4 +14,6 @@ spec:
{{- end }}
externalIPs: true
loadBalancerIPs: true

{{- end }}
{{- end }}
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
{{- if (eq .Values.driver "cilium") }}
{{- if .Values.ipPool.cidrs }}

apiVersion: "cilium.io/v2alpha1"
kind: CiliumLoadBalancerIPPool
metadata:
Expand All @@ -10,4 +12,6 @@ spec:
blocks:
{{- toYaml . | nindent 4 }}
{{- end }}

{{- end }}
{{- end }}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
{{- if (eq .Values.driver "metallb") }}
{{- if .Values.bgp.enabled }}

apiVersion: "metallb.io/v1beta2"
kind: BGPPeer
metadata:
name: {{ include "ck-loadbalancer.fullname" . }}
labels:
{{- include "ck-loadbalancer.labels" . | nindent 4 }}
spec:
myASN: {{ .Values.bgp.localASN }}
{{- with (index .Values.bgp.neighbors 0) }}
peerASN: {{ .peerASN }}
peerAddress: {{ .peerAddress }}
peerPort: {{ .peerPort }}
{{- end }}

---

apiVersion: "metallb.io/v1beta1"
kind: BGPAdvertisement
metadata:
name: {{ include "ck-loadbalancer.fullname" . }}
labels:
{{- include "ck-loadbalancer.labels" . | nindent 4 }}
spec:
ipAddressPools:
- {{ include "ck-loadbalancer.fullname" . }}

{{- end }}
{{- end}}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{{- if (eq .Values.driver "metallb") -}}
{{- if .Values.l2.enabled }}

apiVersion: "metallb.io/v1beta1"
kind: L2Advertisement
metadata:
name: {{ include "ck-loadbalancer.fullname" . }}
labels:
{{- include "ck-loadbalancer.labels" . | nindent 4 }}
spec:
ipAddressPools:
- {{ include "ck-loadbalancer.fullname" . }}
{{- with .Values.l2.interfaces }}
interfaces:
{{- toYaml . | nindent 4 }}
{{- end }}

{{- end }}
{{- end }}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{{ if (eq .Values.driver "metallb") }}
{{ if .Values.ipPool.cidrs }}
apiVersion: "metallb.io/v1beta1"
kind: IPAddressPool
metadata:
name: {{ include "ck-loadbalancer.fullname" . }}
labels:
{{- include "ck-loadbalancer.labels" . | nindent 4 }}
spec:
addresses:
{{- range .Values.ipPool.cidrs }}
{{- if .cidr }}
- {{ .cidr }}
{{- else if and .start .stop }}
- {{ printf "%s-%s" .start .stop }}
{{ end }}
{{ end }}
{{ end }}
{{ end }}
1 change: 1 addition & 0 deletions k8s/manifests/charts/ck-loadbalancer/values.yaml
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
driver:

l2:
enabled: true
Expand Down
Binary file added k8s/manifests/charts/metallb-0.14.5.tgz
Binary file not shown.
1 change: 1 addition & 0 deletions src/k8s/pkg/k8sd/features/cilium/loadbalancer.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ func enableLoadBalancer(ctx context.Context, snap snap.Snap, loadbalancer types.
}

values := map[string]any{
"driver": "cilium",
"l2": map[string]any{
"enabled": loadbalancer.GetL2Mode(),
"interfaces": loadbalancer.GetL2Interfaces(),
Expand Down
4 changes: 2 additions & 2 deletions src/k8s/pkg/k8sd/features/implementation_moonray.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ package features

import (
"github.com/canonical/k8s/pkg/k8sd/features/calico"
"github.com/canonical/k8s/pkg/k8sd/features/cilium"
"github.com/canonical/k8s/pkg/k8sd/features/contour"
"github.com/canonical/k8s/pkg/k8sd/features/coredns"
"github.com/canonical/k8s/pkg/k8sd/features/localpv"
"github.com/canonical/k8s/pkg/k8sd/features/metallb"
metrics_server "github.com/canonical/k8s/pkg/k8sd/features/metrics-server"
)

Expand All @@ -16,7 +16,7 @@ import (
var Implementation Interface = &implementation{
applyDNS: coredns.ApplyDNS,
applyNetwork: calico.ApplyNetwork,
applyLoadBalancer: cilium.ApplyLoadBalancer,
applyLoadBalancer: metallb.ApplyLoadBalancer,
applyIngress: contour.ApplyIngress,
applyGateway: contour.ApplyGateway,
applyMetricsServer: metrics_server.ApplyMetricsServer,
Expand Down
41 changes: 41 additions & 0 deletions src/k8s/pkg/k8sd/features/metallb/chart.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package metallb

import (
"path"

"github.com/canonical/k8s/pkg/client/helm"
)

var (
// chartMetalLB represents manifests to deploy MetalLB speaker and controller.
chartMetalLB = helm.InstallableChart{
Name: "metallb",
Namespace: "metallb-system",
ManifestPath: path.Join("charts", "metallb-0.14.5.tgz"),
}

// chartMetalLBLoadBalancer represents manifests to deploy MetalLB L2 or BGP resources.
chartMetalLBLoadBalancer = helm.InstallableChart{
Name: "metallb-loadbalancer",
Namespace: "metallb-system",
ManifestPath: path.Join("charts", "ck-loadbalancer"),
}

// controllerImageRepo is the image to use for metallb-controller.
controllerImageRepo = "quay.io/metallb/controller"

// controllerImageTag is the tag to use for metallb-controller.
controllerImageTag = "v0.14.5"

// speakerImageRepo is the image to use for metallb-speaker.
speakerImageRepo = "quay.io/metallb/speaker"

// speakerImageTag is the tag to use for metallb-speaker.
speakerImageTag = "v0.14.5"

// frrImageRepo is the image to use for frrouting.
frrImageRepo = "quay.io/frrouting/frr"

// frrImageTag is the tag to use for frrouting.
frrImageTag = "9.0.2"
)
Loading

0 comments on commit 1188bdc

Please sign in to comment.