diff --git a/charts/loxilb/Chart.yaml b/charts/loxilb/Chart.yaml new file mode 100644 index 00000000..0a7ea231 --- /dev/null +++ b/charts/loxilb/Chart.yaml @@ -0,0 +1,18 @@ +apiVersion: v2 +name: loxilb +description: A Helm chart for LoxiLB - an open-source, eBPF-based load balancer for NGAP Layer 7 load balancing within 5G networks +type: application +version: 0.1.0 +appVersion: "1.0.0" +keywords: + - loxilb + - loadbalancer + - 5g + - ngap + - ebpf +home: https://github.com/loxilb-io/loxilb +sources: + - https://github.com/loxilb-io/loxilb +maintainers: + - name: William Lin + email: wlin.cs13@nycu.edu.tw diff --git a/charts/loxilb/README.md b/charts/loxilb/README.md new file mode 100644 index 00000000..c46d740b --- /dev/null +++ b/charts/loxilb/README.md @@ -0,0 +1,72 @@ +# LoxiLB Helm Chart + +This Helm chart deploys LoxiLB, an open-source, eBPF-based load balancer for NGAP Layer 7 load balancing within 5G networks. + +based on https://goldenrod-town-d4b.notion.site/Install-free5gc-with-LoxiLB-NGAP-load-balancing-1ad453c1718680019cdfc94709fd6f48 +## Features + +- NGAP Layer 7 load balancing +- UE distribution across stateless AMFs +- Seamless handovers across multiple AMFs +- High availability with automatic failover +- Support for free5GC integration + +## Prerequisites + +- Kubernetes 1.19+ +- Helm 3.2.0+ +- Multus CNI for multi-network interfaces + +## Installation + +```bash +# Add the chart repository (replace with your actual repository) +helm repo add loxilb-repo https://example.com/helm-charts/ + +# Update helm repositories +helm repo update + +# Install the chart with the release name 'loxilb' +helm install loxilb loxilb-repo/loxilb -n free5gc +``` + +Or to install from local directory: + +```bash +# Navigate to the chart directory +cd loxilb + +# Install the chart +helm install loxilb . -n free5gc +``` + +## Configuration + +| Parameter | Description | Default | +|-----------|-------------|---------| +| `image.repository` | LoxiLB image repository | `ghcr.io/loxilb-io/loxilb` | +| `image.tag` | LoxiLB image tag | `scp2` | +| `image.pullPolicy` | Image pull policy | `Always` | +| `network.n2network.name` | Name of N2 network | `n2network-free5gc-helm-free5gc-amf` | +| `network.n2network.interface` | Interface name for N2 network | `n2` | +| `network.n2network.ips` | IPs for N2 network | `["10.100.50.253/29"]` | +| `network.n2network.gateway` | Gateway for N2 network | `["10.100.50.254"]` | +| `kubeLoxilb.enabled` | Whether to deploy kube-loxilb | `true` | +| `kubeLoxilb.args` | Args for kube-loxilb | See values.yaml | + +For more configuration options, see the [values.yaml](values.yaml) file. + +## Use with free5GC + +LoxiLB works as a load balancer in front of multiple AMFs in a free5GC deployment to ensure high availability and seamless failover for NGAP connections from gNB. To use with free5GC: + +1. Deploy free5GC with AMF service type set to LoadBalancer +2. Add the appropriate annotations to the AMF service +3. Deploy LoxiLB using this chart +4. Configure gNB (UERANSIM) to use LoxiLB's external IP + +See the [free5GC integration guide](https://www.loxilb.io/post/ngap-load-balancing-with-loxilb) for detailed instructions. + +## License + +Apache License 2.0 diff --git a/charts/loxilb/templates/daemonset.yaml b/charts/loxilb/templates/daemonset.yaml new file mode 100644 index 00000000..1b93dd92 --- /dev/null +++ b/charts/loxilb/templates/daemonset.yaml @@ -0,0 +1,33 @@ +apiVersion: apps/v1 +kind: DaemonSet +metadata: + name: {{ .Release.Name }}-lb + namespace: {{ .Values.namespace }} +spec: + selector: + matchLabels: + app: {{ .Release.Name }}-app + template: + metadata: + name: {{ .Release.Name }}-lb + labels: + app: {{ .Release.Name }}-app + annotations: + k8s.v1.cni.cncf.io/networks: '[ { "name": "{{ .Values.network.n2network.name }}", + "interface": "{{ .Values.network.n2network.interface }}", "ips": {{ .Values.network.n2network.ips | toJson }}, "gateway": {{ .Values.network.n2network.gateway | toJson }} + }]' + spec: + dnsPolicy: ClusterFirstWithHostNet +{{- if .Values.tolerations }} + tolerations: +{{ toYaml .Values.tolerations | indent 8 }} +{{- end }} + containers: + - name: {{ .Release.Name }}-app + image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + command: {{ .Values.command | toJson }} + ports: + - containerPort: 11111 + securityContext: +{{ toYaml .Values.securityContext | indent 10 }} \ No newline at end of file diff --git a/charts/loxilb/templates/kube-loxilb.yaml b/charts/loxilb/templates/kube-loxilb.yaml new file mode 100644 index 00000000..409883aa --- /dev/null +++ b/charts/loxilb/templates/kube-loxilb.yaml @@ -0,0 +1,193 @@ +{{- if .Values.kubeLoxilb.enabled }} +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ .Release.Name }}-kube-loxilb + namespace: kube-system +--- +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: {{ .Release.Name }}-kube-loxilb +rules: + - apiGroups: + - "" + resources: + - nodes + verbs: + - get + - watch + - list + - patch + - apiGroups: + - "" + resources: + - pods + verbs: + - get + - watch + - list + - patch + - apiGroups: + - "" + resources: + - endpoints + - services + - namespaces + - services/status + verbs: + - get + - watch + - list + - patch + - update + - apiGroups: + - gateway.networking.k8s.io + resources: + - gatewayclasses + - gatewayclasses/status + - gateways + - gateways/status + - tcproutes + - udproutes + verbs: ["get", "watch", "list", "patch", "update"] + - apiGroups: + - discovery.k8s.io + resources: + - endpointslices + verbs: + - get + - watch + - list + - apiGroups: + - apiextensions.k8s.io + resources: + - customresourcedefinitions + verbs: + - get + - watch + - list + - apiGroups: + - authentication.k8s.io + resources: + - tokenreviews + verbs: + - create + - apiGroups: + - authorization.k8s.io + resources: + - subjectaccessreviews + verbs: + - create + - apiGroups: + - bgppeer.loxilb.io + resources: + - bgppeerservices + verbs: + - get + - watch + - list + - create + - update + - delete + - apiGroups: + - bgppolicydefinedsets.loxilb.io + resources: + - bgppolicydefinedsetsservices + verbs: + - get + - watch + - list + - create + - update + - delete + - apiGroups: + - bgppolicydefinition.loxilb.io + resources: + - bgppolicydefinitionservices + verbs: + - get + - watch + - list + - create + - update + - delete + - apiGroups: + - bgppolicyapply.loxilb.io + resources: + - bgppolicyapplyservices + verbs: + - get + - watch + - list + - create + - update + - delete + - apiGroups: + - loxiurl.loxilb.io + resources: + - loxiurls + verbs: + - get + - watch + - list + - create + - update + - delete + - apiGroups: + - egress.loxilb.io + resources: + - egresses + verbs: ["get", "watch", "list", "patch", "update"] +--- +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: {{ .Release.Name }}-kube-loxilb +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ .Release.Name }}-kube-loxilb +subjects: + - kind: ServiceAccount + name: {{ .Release.Name }}-kube-loxilb + namespace: kube-system +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ .Release.Name }}-kube-loxilb + namespace: kube-system + labels: + app: {{ .Release.Name }}-kube-loxilb-app +spec: + replicas: 1 + selector: + matchLabels: + app: {{ .Release.Name }}-kube-loxilb-app + template: + metadata: + labels: + app: {{ .Release.Name }}-kube-loxilb-app + spec: + dnsPolicy: ClusterFirstWithHostNet + tolerations: + # Mark the pod as a critical add-on for rescheduling. + - key: CriticalAddonsOnly + operator: Exists + priorityClassName: system-node-critical + serviceAccountName: {{ .Release.Name }}-kube-loxilb + terminationGracePeriodSeconds: 0 + containers: + - name: kube-loxilb + image: "{{ .Values.kubeLoxilb.image.repository }}:{{ .Values.kubeLoxilb.image.tag }}" + imagePullPolicy: {{ .Values.kubeLoxilb.image.pullPolicy }} + command: + - /bin/kube-loxilb + args: {{ .Values.kubeLoxilb.args | toJson }} + resources: +{{ toYaml .Values.kubeLoxilb.resources | indent 10 }} + securityContext: +{{ toYaml .Values.kubeLoxilb.securityContext | indent 10 }} +{{- end }} \ No newline at end of file diff --git a/charts/loxilb/templates/services.yaml b/charts/loxilb/templates/services.yaml new file mode 100644 index 00000000..deb957c2 --- /dev/null +++ b/charts/loxilb/templates/services.yaml @@ -0,0 +1,44 @@ +{{- if .Values.service.egress.enabled }} +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ .Values.service.egress.name }} + namespace: {{ .Values.namespace }} + annotations: +{{- range $key, $value := .Values.service.egress.annotations }} + {{ $key }}: {{ $value | quote }} +{{- end }} +spec: + type: {{ .Values.service.egress.type }} + loadBalancerClass: {{ .Values.service.egress.loadBalancerClass }} + selector: + app: {{ .Release.Name }}-app + ports: +{{- range .Values.service.egress.ports }} + - name: {{ .name }} + port: {{ .port }} + targetPort: {{ .targetPort }} + protocol: {{ .protocol }} +{{- end }} +{{- end }} + +{{- if .Values.service.lb.enabled }} +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ .Values.service.lb.name }} + namespace: {{ .Values.namespace }} +spec: + clusterIP: {{ .Values.service.lb.clusterIP }} + selector: + app: {{ .Release.Name }}-app + ports: +{{- range .Values.service.lb.ports }} + - name: {{ .name }} + port: {{ .port }} + targetPort: {{ .targetPort }} + protocol: {{ .protocol }} +{{- end }} +{{- end }} \ No newline at end of file diff --git a/charts/loxilb/values.yaml b/charts/loxilb/values.yaml new file mode 100644 index 00000000..2b3e0511 --- /dev/null +++ b/charts/loxilb/values.yaml @@ -0,0 +1,97 @@ +# LoxiLB Configuration +replicaCount: 1 + +image: + repository: ghcr.io/loxilb-io/loxilb + tag: scp2 + pullPolicy: Always + +command: + - "/root/loxilb-io/loxilb/loxilb" + - "--proxyonlymode" + +# Network Configurations +network: + n2network: + enabled: true + name: n2network-free5gc-helm-free5gc-amf + interface: "n2" + ips: ["10.100.50.253/29"] + gateway: ["10.100.50.254"] + +# Security Context +securityContext: + privileged: true + capabilities: + add: + - SYS_ADMIN + +# Service account +serviceAccount: + create: true + name: loxilb-sa + +# LoxiLB Service Configurations +service: + # Egress Service + egress: + enabled: true + name: loxilb-egress-service + type: LoadBalancer + loadBalancerClass: loxilb.io/loxilb + annotations: + loxilb.io/egress: "yes" + loxilb.io/probetype: "none" + loxilb.io/staticIP: "0.0.0.0" + ports: + - name: loxilb-egress + port: 9999 + targetPort: 9999 + protocol: TCP + + # LB Service + lb: + enabled: true + name: loxilb-lb-service + clusterIP: None + ports: + - name: loxilb-app + port: 11111 + targetPort: 11111 + protocol: TCP + +# KubeLoxiLB Configuration +kubeLoxilb: + enabled: true + image: + repository: ghcr.io/loxilb-io/kube-loxilb + tag: latest + pullPolicy: Always + + args: + - --cidrPools=defaultPool=10.100.50.253/32 + - --setRoles=0.0.0.0 + - --setLBMode=1 + + resources: + requests: + cpu: "100m" + memory: "50Mi" + limits: + cpu: "100m" + memory: "50Mi" + + securityContext: + privileged: true + capabilities: + add: ["NET_ADMIN", "NET_RAW"] + +# Namespace where LoxiLB should be deployed +namespace: free5gc + +# Tolerations for LoxiLB pods +tolerations: + - key: "node-role.kubernetes.io/master" + operator: Exists + - key: "node-role.kubernetes.io/control-plane" + operator: Exists