dipup 사용 차트를 카탈로그에 동기화 (7개 갱신 + 5개 신규)

dipup 이 go:embed 로 직접 보관·관리하던 Helm 차트를 카탈로그로 옮기는 첫 단계다.
두 저장소가 각자 CVE/SBOM 파이프라인을 운영하는 이중화를 해소하려면, 먼저 카탈로그가
dipup 과 같은 차트·같은 이미지를 보게 만들어야 한다.

배경: CVE 파이프라인 구성 이전에 두 곳에서 같은 차트를 유지하기 어려워 dipup 이 별도로
차트를 관리해 왔고, 그 결과 버전이 갈라졌다. 겹치는 10개 중 버전까지 일치하는 것은
postgresql-ha·dnsup 2개뿐이었다.

## 버전 갱신 (7개) — 신규 버전 디렉토리 추가, 구버전은 보존

| 차트 | 기존 | 신규 | appVersion |
|---|---|---|---|
| apisix | 2.14.0 | 2.16.0 | 3.16.0 → 3.17.0 |
| argo-cd | 7.7.0 | 7.8.11 | v2.13.0 → v2.14.5 |
| cert-manager | v1.16.1 | v1.21.0 | 동일 |
| gitea | 12.4.0 | 12.6.0 | 1.24.6 → 1.26.1 |
| harbor | 1.16.2 | 1.19.1 | 2.12.2 → 2.15.1 |
| kyverno | 3.4.1 | 3.8.2 | v1.14.1 → v1.18.2 |
| rancher | 2.10.1 | 2.14.3 | v2.10.1 → v2.14.3 |

차트 본문은 dipup 이 임베딩한 .tgz 를 그대로 전개했다(네트워크 pull 이 아니라 dipup 이
실제 배포하는 바이트와 동일함을 보장하기 위함). BUILD-README/CUSTOM-README/custom-values
3개 파일은 구버전에서 승계했다.

## 신규 추가 (5개)

infisical-standalone 1.9.0, longhorn 109.3.1+up1.11.2, longhorn-crd 109.3.1+up1.11.2,
metallb 0.16.1, secrets-operator v0.10.33.

longhorn/longhorn-crd 는 업스트림이 아니라 Rancher 패키징 차트(109.x 라인, Rancher 2.14
계열과 짝)다. BUILD-README 의 `helm repo add` 라인은 chart_version_detector 가 파싱하는
계약이라 실제 업스트림 repo 를 검증해 기재했고, 감지기로 현재/최신 버전이 정상 조회되는
것을 확인했다.

## custom-values — 버전과 결합된 이미지 핀 정리

카탈로그 스캐너가 dipup 의 effective image 를 보게 하려면 이미지 핀이 맞아야 한다.

- **kyverno: 승계본이 3.8.2 에서 깨져 재작성.** 3.4.1 은 정리 훅이
  `registry: ~ / repository: bitnami/kubectl` 이라 bitnamilegacy 오버라이드가 맞았지만,
  3.8.2 는 `registry: ghcr.io / repository: kyverno/readiness-checker` 로 바뀌었다.
  그대로 옮기면 ghcr.io/bitnamilegacy/kubectl 이라는 없는 좌표가 된다. 해당 오버라이드를
  제거하고, 3.8.2 에서 삭제된 policyReportsCleanup 키도 함께 뺐다. 남는 조치는 tag 고정뿐
  (기본 tag 가 비어 latest 로 떨어짐 → v1.18.2 로 고정).
- apisix: 3.16.0-keycloak-authz → 3.17.0-keycloak-authz (차트 appVersion 과 함께 이동)
- gitea: image.tag 1.26.4 핀 추가 — 차트 기본 1.26.1 대비 CRITICAL 2→0, HIGH 44→12
- infisical: image.tag v0.162.7 핀 — 기본 v0.158.x 는 stale Debian base 로 OS 기인 CVE
  다수(fixable CRITICAL 53→5, HIGH 491→55). redis/postgresql 은 bitnamilegacy 좌표로.
- longhorn: 실측 기반 리소스 튜닝(manager request, guaranteedInstanceManagerCPU,
  systemManagedCSIComponentsResourceLimits). replica 수처럼 노드 수에 의존하는 값은
  넣지 않았다 — 소비 측에서 주입한다.

## 검증

12개 차트 전부 `helm template --kube-version 1.34.1` 렌더 성공. 렌더 결과 이미지가
dipup 배포 이미지와 일치함을 확인(paasup/apisix:3.17.0-keycloak-authz,
gitea:1.26.4-rootless, readiness-checker:v1.18.2, infisical:v0.162.7).

## 범위에서 뺀 것

- **keycloak**: 카탈로그는 codecentric(app 17.0.1-legacy), dipup 은 bitnami(app 26.2.4)로
  계보가 다르다. 이슈 #1(bitnami 대체 방안 검토)의 결론이 나온 뒤 처리한다.
- **rancher-monitoring(-crd)**: 14c05f1 에서 불필요 판단으로 제거된 차트이고
  victoria-metrics 스택으로 대체 예정이라 추가하지 않는다.
- **dip-api/dip-console**: 자체 개발 차트로 각 앱 저장소가 출처다. 대조 결과 앱 저장소와
  dipup 사본이 일치해 카탈로그가 개입할 이유가 없다.
- **postgresql-ha/dnsup**: 이미 버전이 일치해 작업 대상이 아니었다.

## 후속 과제

dnsup 은 카탈로그·dipup 사본(1.0.1)이 원본(dip-console-api helm/dnsup 1.0.0)보다 앞서
있다. 1.0.1 에만 있는 service.LoadBalancerIP·service.annotations 지원을 원본으로 백포트한
뒤, 카탈로그에서 dnsup 을 제거하는 것이 자체 개발 차트 출처 원칙에 맞다.
This commit is contained in:
wbsong111
2026-08-06 09:42:24 +09:00
parent 9d5a10b09c
commit 16321b52c7
1262 changed files with 314285 additions and 0 deletions
@@ -0,0 +1,11 @@
MetalLB is now running in the cluster.
Now you can configure it via its CRs. Please refer to the metallb official docs
on how to use the CRs.
{{- if .Values.speaker.frr.enabled }}
WARNING: The FRR mode (speaker.frr.enabled) is DEPRECATED and will be removed
in a future release. Please migrate to the frr-k8s mode (frrk8s.enabled: true),
which is now the default BGP backend and provides the same features with
additional flexibility. See https://metallb.io/concepts/bgp/#frr-k8s-mode
{{- end }}
@@ -0,0 +1,99 @@
{{/* vim: set filetype=mustache: */}}
{{/*
Expand the name of the chart.
*/}}
{{- define "metallb.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
{{- end }}
{{/*
Create a default fully qualified app name.
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
If release name contains chart name it will be used as a full name.
*/}}
{{- define "metallb.fullname" -}}
{{- if .Values.fullnameOverride }}
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- $name := default .Chart.Name .Values.nameOverride }}
{{- if contains $name .Release.Name }}
{{- .Release.Name | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
{{- end }}
{{- end }}
{{- end }}
{{/*
Create chart name and version as used by the chart label.
*/}}
{{- define "metallb.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
{{- end }}
{{/*
Common labels
*/}}
{{- define "metallb.labels" -}}
helm.sh/chart: {{ include "metallb.chart" . }}
{{ include "metallb.selectorLabels" . }}
{{- if .Chart.AppVersion }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
{{- end }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end }}
{{/*
Selector labels
*/}}
{{- define "metallb.selectorLabels" -}}
app.kubernetes.io/name: {{ include "metallb.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end }}
{{/*
Create the name of the controller service account to use
*/}}
{{- define "metallb.controller.serviceAccountName" -}}
{{- if .Values.controller.serviceAccount.create }}
{{- default (printf "%s-controller" (include "metallb.fullname" .)) .Values.controller.serviceAccount.name }}
{{- else }}
{{- default "default" .Values.controller.serviceAccount.name }}
{{- end }}
{{- end }}
{{/*
Create the name of the speaker service account to use
*/}}
{{- define "metallb.speaker.serviceAccountName" -}}
{{- if .Values.speaker.serviceAccount.create }}
{{- default (printf "%s-speaker" (include "metallb.fullname" .)) .Values.speaker.serviceAccount.name }}
{{- else }}
{{- default "default" .Values.speaker.serviceAccount.name }}
{{- end }}
{{- end }}
{{/*
Create the name of the settings Secret to use.
*/}}
{{- define "metallb.secretName" -}}
{{ default ( printf "%s-memberlist" (include "metallb.fullname" .)) .Values.speaker.secretName | trunc 63 | trimSuffix "-" }}
{{- end -}}
{{- define "metrics.exposedportname" -}}
"metricshttps"
{{- end -}}
{{- define "metrics.exposedfrrportname" -}}
"frrmetricshttps"
{{- end }}
{{- define "metrics.exposedport" -}}
{{ .Values.prometheus.metricsPort }}
{{- end }}
{{- define "metrics.exposedfrrport" -}}
{{ .Values.speaker.frr.metricsPort }}
{{- end }}
@@ -0,0 +1,184 @@
{{- if .Values.controller.enabled }}
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ template "metallb.fullname" . }}-controller
namespace: {{ .Release.Namespace | quote }}
labels:
{{- include "metallb.labels" . | nindent 4 }}
app.kubernetes.io/component: controller
{{- range $key, $value := .Values.controller.labels }}
{{ $key }}: {{ $value | quote }}
{{- end }}
spec:
{{- if .Values.controller.strategy }}
strategy: {{- toYaml .Values.controller.strategy | nindent 4 }}
{{- end }}
selector:
matchLabels:
{{- include "metallb.selectorLabels" . | nindent 6 }}
app.kubernetes.io/component: controller
template:
metadata:
{{- if or .Values.prometheus.scrapeAnnotations .Values.controller.podAnnotations }}
annotations:
{{- if .Values.prometheus.scrapeAnnotations }}
prometheus.io/scrape: "true"
prometheus.io/scheme: "https"
prometheus.io/port: "{{ .Values.prometheus.metricsPort }}"
{{- end }}
{{- with .Values.controller.podAnnotations }}
{{- toYaml . | nindent 8 }}
{{- end }}
{{- end }}
labels:
{{- include "metallb.selectorLabels" . | nindent 8 }}
app.kubernetes.io/component: controller
{{- range $key, $value := .Values.controller.labels }}
{{ $key }}: {{ $value | quote }}
{{- end }}
spec:
{{- with .Values.controller.runtimeClassName }}
runtimeClassName: {{ . | quote }}
{{- end }}
{{- with .Values.imagePullSecrets }}
imagePullSecrets:
{{- toYaml . | nindent 8 }}
{{- end }}
serviceAccountName: {{ template "metallb.controller.serviceAccountName" . }}
terminationGracePeriodSeconds: 0
{{- if .Values.controller.securityContext }}
securityContext:
{{ toYaml .Values.controller.securityContext | indent 8 }}
{{- end }}
containers:
- name: controller
image: {{ .Values.controller.image.repository }}:{{ .Values.controller.image.tag | default .Chart.AppVersion }}
{{- if .Values.controller.image.pullPolicy }}
imagePullPolicy: {{ .Values.controller.image.pullPolicy }}
{{- end }}
{{- if .Values.controller.command }}
command:
- {{ .Values.controller.command }}
{{- end }}
args:
- --port={{ .Values.prometheus.metricsPort }}
{{- with .Values.controller.logLevel }}
- --log-level={{ . }}
{{- end }}
{{- if .Values.loadBalancerClass }}
- --lb-class={{ .Values.loadBalancerClass }}
{{- end }}
{{- if .Values.controller.webhookMode }}
- --webhook-mode={{ .Values.controller.webhookMode }}
{{- end }}
{{- if .Values.tls.cipherSuites }}
- --tls-cipher-suites={{ .Values.tls.cipherSuites }}
{{- end }}
{{- if .Values.tls.curvePreferences }}
- --tls-curve-preferences={{ .Values.tls.curvePreferences }}
{{- end }}
{{- if .Values.tls.minVersion }}
- --tls-min-version={{ .Values.tls.minVersion }}
{{- end }}
{{- if .Values.tls.controllerMetricsTLSSecret }}
- --metrics-cert-dir=/etc/metrics
{{- end }}
env:
- name: METALLB_POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
{{- if and .Values.speaker.enabled .Values.speaker.memberlist.enabled }}
- name: METALLB_ML_SECRET_NAME
value: {{ include "metallb.secretName" . }}
- name: METALLB_DEPLOYMENT
value: {{ template "metallb.fullname" . }}-controller
{{- end }}
{{- if and .Values.speaker.enabled .Values.speaker.frr.enabled }}
- name: METALLB_BGP_TYPE
value: frr
{{- end }}
{{- if or .Values.frrk8s.enabled .Values.frrk8s.external }}
- name: METALLB_BGP_TYPE
value: frr-k8s
{{- end }}
ports:
- name: metricshttps
containerPort: {{ .Values.prometheus.metricsPort }}
{{- if and .Values.controller.webhookMode (ne .Values.controller.webhookMode "disabled") }}
- containerPort: 9443
name: webhook-server
protocol: TCP
{{- end }}
volumeMounts:
- mountPath: /tmp/k8s-webhook-server/serving-certs
name: cert
readOnly: true
{{- if .Values.tls.controllerMetricsTLSSecret }}
- name: metrics-certs
mountPath: /etc/metrics
readOnly: true
{{- end }}
{{- if .Values.controller.livenessProbe.enabled }}
livenessProbe:
httpGet:
path: /healthz
port: {{ .Values.controller.livenessProbe.port }}
initialDelaySeconds: {{ .Values.controller.livenessProbe.initialDelaySeconds }}
periodSeconds: {{ .Values.controller.livenessProbe.periodSeconds }}
timeoutSeconds: {{ .Values.controller.livenessProbe.timeoutSeconds }}
successThreshold: {{ .Values.controller.livenessProbe.successThreshold }}
failureThreshold: {{ .Values.controller.livenessProbe.failureThreshold }}
{{- end }}
{{- if .Values.controller.readinessProbe.enabled }}
readinessProbe:
httpGet:
path: /readyz
port: {{ .Values.controller.readinessProbe.port }}
initialDelaySeconds: {{ .Values.controller.readinessProbe.initialDelaySeconds }}
periodSeconds: {{ .Values.controller.readinessProbe.periodSeconds }}
timeoutSeconds: {{ .Values.controller.readinessProbe.timeoutSeconds }}
successThreshold: {{ .Values.controller.readinessProbe.successThreshold }}
failureThreshold: {{ .Values.controller.readinessProbe.failureThreshold }}
{{- end }}
{{- with .Values.controller.resources }}
resources:
{{- toYaml . | nindent 10 }}
{{- end }}
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop:
- ALL
{{- if .Values.controller.extraContainers }}
{{- toYaml .Values.controller.extraContainers | nindent 6 }}
{{- end }}
nodeSelector:
"kubernetes.io/os": linux
{{- with .Values.controller.nodeSelector }}
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.controller.affinity }}
affinity:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.controller.tolerations }}
tolerations:
{{- toYaml . | nindent 6 }}
{{- end }}
{{- with .Values.controller.priorityClassName }}
priorityClassName: {{ . | quote }}
{{- end }}
volumes:
- name: cert
secret:
defaultMode: 420
secretName: metallb-webhook-cert
{{- if .Values.tls.controllerMetricsTLSSecret }}
- name: metrics-certs
secret:
secretName: {{ .Values.tls.controllerMetricsTLSSecret }}
{{- end }}
{{- end }}
@@ -0,0 +1,3 @@
{{- if .Values.configInline }}
{{- fail "Starting from v0.13.0 configInline is no longer supported. Please see https://metallb.universe.tf/#backward-compatibility" }}
{{- end }}
@@ -0,0 +1,26 @@
{{- if and .Values.speaker.enabled .Values.speaker.excludeInterfaces.enabled }}
apiVersion: v1
kind: ConfigMap
metadata:
name: metallb-excludel2
namespace: {{ .Release.Namespace | quote }}
labels:
{{- include "metallb.labels" . | nindent 4 }}
data:
excludel2.yaml: |
announcedInterfacesToExclude:
- ^docker.*
- ^cbr.*
- ^dummy.*
- ^virbr.*
- ^lxcbr.*
- ^veth.*
- ^lo$
- ^cali.*
- ^tunl.*
- ^flannel.*
- ^kube-ipvs.*
- ^cni.*
- ^nodelocaldns.*
- ^lxc.*
{{- end }}
@@ -0,0 +1,42 @@
{{- if .Values.networkpolicies.enabled }}
{{- if .Values.networkpolicies.defaultDeny }}
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny
namespace: {{ .Release.Namespace | quote }}
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
{{- end }}
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: controller
namespace: {{ .Release.Namespace | quote }}
spec:
podSelector:
matchLabels:
{{- include "metallb.selectorLabels" . | nindent 6 }}
app.kubernetes.io/component: controller
egress:
- ports:
- protocol: TCP
port: {{ .Values.networkpolicies.apiPort }}
ingress:
- ports:
- protocol: TCP
port: metricshttps
{{- if and .Values.controller.webhookMode (ne .Values.controller.webhookMode "disabled") }}
- protocol: TCP
port: webhook-server
{{- end }}
policyTypes:
- Egress
- Ingress
# speaker pods do not need network policy because they are hostnetworked
{{- end }}
@@ -0,0 +1,110 @@
{{- if .Values.prometheus.podMonitor.enabled }}
apiVersion: monitoring.coreos.com/v1
kind: PodMonitor
metadata:
name: {{ template "metallb.fullname" . }}-controller
labels:
{{- include "metallb.labels" . | nindent 4 }}
app.kubernetes.io/component: controller
{{- if .Values.prometheus.podMonitor.additionalLabels }}
{{ toYaml .Values.prometheus.podMonitor.additionalLabels | indent 4 }}
{{- end }}
{{- if .Values.prometheus.podMonitor.annotations }}
annotations:
{{ toYaml .Values.prometheus.podMonitor.annotations | indent 4 }}
{{- end }}
spec:
jobLabel: {{ .Values.prometheus.podMonitor.jobLabel | quote }}
selector:
matchLabels:
{{- include "metallb.selectorLabels" . | nindent 6 }}
app.kubernetes.io/component: controller
namespaceSelector:
matchNames:
- {{ .Release.Namespace }}
podMetricsEndpoints:
- port: monitoring
path: /metrics
scheme: https
{{- if .Values.prometheus.podMonitor.interval }}
interval: {{ .Values.prometheus.podMonitor.interval }}
{{- end }}
{{- if .Values.prometheus.podMonitor.metricRelabelings }}
metricRelabelings:
{{- toYaml .Values.prometheus.podMonitor.metricRelabelings | nindent 4 }}
{{- end }}
{{- if .Values.prometheus.podMonitor.relabelings }}
relabelings:
{{- toYaml .Values.prometheus.podMonitor.relabelings | nindent 4 }}
{{- end }}
{{- if .Values.speaker.enabled }}
---
apiVersion: monitoring.coreos.com/v1
kind: PodMonitor
metadata:
name: {{ template "metallb.fullname" . }}-speaker
labels:
{{- include "metallb.labels" . | nindent 4 }}
app.kubernetes.io/component: speaker
{{- if .Values.prometheus.podMonitor.additionalLabels }}
{{ toYaml .Values.prometheus.podMonitor.additionalLabels | indent 4 }}
{{- end }}
{{- if .Values.prometheus.podMonitor.annotations }}
annotations:
{{ toYaml .Values.prometheus.podMonitor.annotations | indent 4 }}
{{- end }}
spec:
jobLabel: {{ .Values.prometheus.podMonitor.jobLabel | quote }}
selector:
matchLabels:
{{- include "metallb.selectorLabels" . | nindent 6 }}
app.kubernetes.io/component: speaker
namespaceSelector:
matchNames:
- {{ .Release.Namespace }}
podMetricsEndpoints:
- port: monitoring
path: /metrics
scheme: https
{{- if .Values.prometheus.podMonitor.interval }}
interval: {{ .Values.prometheus.podMonitor.interval }}
{{- end }}
{{- if .Values.prometheus.podMonitor.metricRelabelings }}
metricRelabelings:
{{- toYaml .Values.prometheus.podMonitor.metricRelabelings | nindent 4 }}
{{- end }}
{{- if .Values.prometheus.podMonitor.relabelings }}
relabelings:
{{- toYaml .Values.prometheus.podMonitor.relabelings | nindent 4 }}
{{- end }}
{{- end }}
---
{{- if .Values.prometheus.rbacPrometheus }}
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: {{ template "metallb.fullname" . }}-prometheus
rules:
- apiGroups:
- ""
resources:
- pods
verbs:
- get
- list
- watch
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: {{ template "metallb.fullname" . }}-prometheus
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: {{ template "metallb.fullname" . }}-prometheus
subjects:
- kind: ServiceAccount
name: {{ required ".Values.prometheus.serviceAccount must be defined when .Values.prometheus.podMonitor.enabled == true" .Values.prometheus.serviceAccount }}
namespace: {{ required ".Values.prometheus.namespace must be defined when .Values.prometheus.podMonitor.enabled == true" .Values.prometheus.namespace }}
{{- end }}
{{- end }}
@@ -0,0 +1,86 @@
{{- if .Values.prometheus.prometheusRule.enabled }}
apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
name: {{ template "metallb.fullname" . }}
labels:
{{- include "metallb.labels" . | nindent 4 }}
{{- if .Values.prometheus.prometheusRule.additionalLabels }}
{{ toYaml .Values.prometheus.prometheusRule.additionalLabels | indent 4 }}
{{- end }}
{{- if .Values.prometheus.prometheusRule.annotations }}
annotations:
{{ toYaml .Values.prometheus.prometheusRule.annotations | indent 4 }}
{{- end }}
spec:
groups:
- name: {{ template "metallb.fullname" . }}.rules
rules:
{{- if .Values.prometheus.prometheusRule.staleConfig.enabled }}
- alert: MetalLBStaleConfig
annotations:
summary: {{`'Stale config on {{ $labels.pod }}'`}}
description: {{`'{{ $labels.job }} - MetalLB {{ $labels.container }} on {{ $labels.pod }} has a stale config for > 1 minute'`}}
expr: metallb_k8s_client_config_stale_bool{job=~"{{ template "metallb.fullname" . }}.*"} == 1
for: 1m
{{- with .Values.prometheus.prometheusRule.staleConfig.labels }}
labels:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- end }}
{{- if .Values.prometheus.prometheusRule.configNotLoaded.enabled }}
- alert: MetalLBConfigNotLoaded
annotations:
summary: {{`'Config on {{ $labels.pod }} has not been loaded'`}}
description: {{`'{{ $labels.job }} - MetalLB {{ $labels.container }} on {{ $labels.pod }} has not loaded for > 1 minute'`}}
expr: metallb_k8s_client_config_loaded_bool{job=~"{{ template "metallb.fullname" . }}.*"} == 0
for: 1m
{{- with .Values.prometheus.prometheusRule.configNotLoaded.labels }}
labels:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- end }}
{{- if .Values.prometheus.prometheusRule.addressPoolExhausted.enabled }}
{{ $exclude := .Values.prometheus.prometheusRule.addressPoolExhausted.excludePools }}
- alert: MetalLBAddressPoolExhausted
annotations:
summary: {{`'Exhausted address pool on {{ $labels.pod }}'`}}
description: {{`'{{ $labels.job }} - MetalLB {{ $labels.container }} on {{ $labels.pod }} has exhausted address pool {{ $labels.pool }} for > 1 minute'`}}
expr: metallb_allocator_addresses_in_use_total{pool!~"{{ $exclude }}"} >= on(pool) metallb_allocator_addresses_total
for: 1m
{{- with .Values.prometheus.prometheusRule.addressPoolExhausted.labels }}
labels:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- end }}
{{- if .Values.prometheus.prometheusRule.addressPoolUsage.enabled }}
{{ $exclude := .Values.prometheus.prometheusRule.addressPoolUsage.excludePools }}
{{- range .Values.prometheus.prometheusRule.addressPoolUsage.thresholds }}
- alert: MetalLBAddressPoolUsage{{ .percent }}Percent
annotations:
summary: {{`'Exhausted address pool on {{ $labels.pod }}'`}}
message: {{`'{{ $labels.job }} - MetalLB {{ $labels.container }} on {{ $labels.pod }} has address pool {{ $labels.pool }} past `}}{{ .percent }}{{`% usage for > 1 minute'`}}
expr: ( metallb_allocator_addresses_in_use_total{pool!~"{{ $exclude }}"} / on(pool) metallb_allocator_addresses_total ) * 100 > {{ .percent }}
{{- with .labels }}
labels:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- end }}
{{- end }}
{{- if .Values.prometheus.prometheusRule.bgpSessionDown.enabled }}
- alert: MetalLBBGPSessionDown
annotations:
summary: {{`'BGP session down on {{ $labels.pod }}'`}}
message: {{`'{{ $labels.job }} - MetalLB {{ $labels.container }} on {{ $labels.pod }} has BGP session {{ $labels.peer }} down for > 1 minute'`}}
expr: metallb_bgp_session_up{job=~"{{ template "metallb.fullname" . }}.*"} == 0
for: 1m
{{- with .Values.prometheus.prometheusRule.bgpSessionDown.labels }}
labels:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- end }}
{{- with .Values.prometheus.prometheusRule.extraAlerts }}
{{- toYaml . | nindent 4 }}
{{- end}}
{{- end }}
@@ -0,0 +1,226 @@
{{- if .Values.rbac.create -}}
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: {{ template "metallb.fullname" . }}:controller
labels:
{{- include "metallb.labels" . | nindent 4 }}
rules:
- apiGroups: [""]
resources: ["services", "namespaces"]
verbs: ["get", "list", "watch"]
- apiGroups: [""]
resources: ["nodes"]
verbs: ["list"]
- apiGroups: [""]
resources: ["services/status"]
verbs: ["update"]
- apiGroups: [""]
resources: ["events"]
verbs: ["create", "patch"]
- apiGroups: ["admissionregistration.k8s.io"]
resources: ["validatingwebhookconfigurations"]
resourceNames: ["metallb-webhook-configuration"]
verbs: ["create", "delete", "get", "list", "patch", "update", "watch"]
- apiGroups: ["admissionregistration.k8s.io"]
resources: ["validatingwebhookconfigurations"]
verbs: ["list", "watch"]
- apiGroups: ["apiextensions.k8s.io"]
resources: ["customresourcedefinitions"]
resourceNames: ["bfdprofiles.metallb.io","bgpadvertisements.metallb.io",
"bgppeers.metallb.io","ipaddresspools.metallb.io","l2advertisements.metallb.io","communities.metallb.io","configurationstates.metallb.io"]
verbs: ["create", "delete", "get", "list", "patch", "update", "watch"]
- apiGroups: ["apiextensions.k8s.io"]
resources: ["customresourcedefinitions"]
verbs: ["list", "watch"]
- apiGroups: ["metallb.io"]
resources: ["configurationstates"]
verbs: ["create", "delete", "get", "list", "patch", "update", "watch"]
- apiGroups: ["metallb.io"]
resources: ["configurationstates/status"]
verbs: ["get", "patch", "update"]
- apiGroups: ["authentication.k8s.io"]
resources: ["tokenreviews"]
verbs: ["create"]
- apiGroups: ["authorization.k8s.io"]
resources: ["subjectaccessreviews"]
verbs: ["create"]
{{- if .Values.speaker.enabled }}
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: {{ template "metallb.fullname" . }}:speaker
labels:
{{- include "metallb.labels" . | nindent 4 }}
rules:
- apiGroups: [""]
resources: ["services", "endpoints", "nodes", "namespaces"]
verbs: ["get", "list", "watch"]
- apiGroups: ["discovery.k8s.io"]
resources: ["endpointslices"]
verbs: ["get", "list", "watch"]
- apiGroups: [""]
resources: ["events"]
verbs: ["create", "patch"]
- apiGroups: ["metallb.io"]
resources: ["servicel2statuses","servicel2statuses/status","configurationstates","configurationstates/status"]
verbs: ["*"]
- apiGroups: ["authentication.k8s.io"]
resources: ["tokenreviews"]
verbs: ["create"]
- apiGroups: ["authorization.k8s.io"]
resources: ["subjectaccessreviews"]
verbs: ["create"]
{{- if or .Values.frrk8s.enabled .Values.frrk8s.external }}
- apiGroups: ["frrk8s.metallb.io"]
resources: ["frrconfigurations"]
verbs: ["get", "list", "watch","create","update","delete"]
{{- end }}
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: {{ include "metallb.fullname" . }}-pod-lister
namespace: {{ .Release.Namespace | quote }}
labels: {{- include "metallb.labels" . | nindent 4 }}
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["list", "get"]
- apiGroups: [""]
resources: ["secrets"]
verbs: ["get", "list", "watch"]
- apiGroups: [""]
resources: ["configmaps"]
verbs: ["get", "list", "watch"]
- apiGroups: ["metallb.io"]
resources: ["bfdprofiles"]
verbs: ["get", "list", "watch"]
- apiGroups: ["metallb.io"]
resources: ["bgppeers"]
verbs: ["get", "list", "watch"]
- apiGroups: ["metallb.io"]
resources: ["l2advertisements"]
verbs: ["get", "list", "watch"]
- apiGroups: ["metallb.io"]
resources: ["bgpadvertisements"]
verbs: ["get", "list", "watch"]
- apiGroups: ["metallb.io"]
resources: ["ipaddresspools"]
verbs: ["get", "list", "watch"]
- apiGroups: ["metallb.io"]
resources: ["communities"]
verbs: ["get", "list", "watch"]
- apiGroups: ["metallb.io"]
resources: ["servicebgpstatuses","servicebgpstatuses/status"]
verbs: ["*"]
{{- end }}
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: {{ include "metallb.fullname" . }}-controller
namespace: {{ .Release.Namespace | quote }}
labels: {{- include "metallb.labels" . | nindent 4 }}
rules:
{{- if and .Values.speaker.enabled .Values.speaker.memberlist.enabled }}
- apiGroups: [""]
resources: ["secrets"]
verbs: ["create", "get", "list", "watch"]
- apiGroups: [""]
resources: ["secrets"]
resourceNames: [{{ include "metallb.secretName" . | quote }}]
verbs: ["list"]
- apiGroups: ["apps"]
resources: ["deployments"]
resourceNames: ["{{ template "metallb.fullname" . }}-controller"]
verbs: ["get"]
{{- end }}
- apiGroups: [""]
resources: ["secrets"]
verbs: ["create", "delete", "get", "list", "patch", "update", "watch"]
- apiGroups: ["metallb.io"]
resources: ["ipaddresspools"]
verbs: ["get", "list", "watch"]
- apiGroups: ["metallb.io"]
resources: ["ipaddresspools/status"]
verbs: ["update"]
- apiGroups: ["metallb.io"]
resources: ["bgppeers"]
verbs: ["get", "list"]
- apiGroups: ["metallb.io"]
resources: ["bgpadvertisements"]
verbs: ["get", "list"]
- apiGroups: ["metallb.io"]
resources: ["l2advertisements"]
verbs: ["get", "list"]
- apiGroups: ["metallb.io"]
resources: ["communities"]
verbs: ["get", "list","watch"]
- apiGroups: ["metallb.io"]
resources: ["bfdprofiles"]
verbs: ["get", "list","watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: {{ template "metallb.fullname" . }}:controller
labels:
{{- include "metallb.labels" . | nindent 4 }}
subjects:
- kind: ServiceAccount
name: {{ template "metallb.controller.serviceAccountName" . }}
namespace: {{ .Release.Namespace }}
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: {{ template "metallb.fullname" . }}:controller
{{- if .Values.speaker.enabled }}
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: {{ template "metallb.fullname" . }}:speaker
labels:
{{- include "metallb.labels" . | nindent 4 }}
subjects:
- kind: ServiceAccount
name: {{ template "metallb.speaker.serviceAccountName" . }}
namespace: {{ .Release.Namespace }}
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: {{ template "metallb.fullname" . }}:speaker
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: {{ include "metallb.fullname" . }}-pod-lister
namespace: {{ .Release.Namespace | quote }}
labels: {{- include "metallb.labels" . | nindent 4 }}
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: {{ include "metallb.fullname" . }}-pod-lister
subjects:
- kind: ServiceAccount
name: {{ template "metallb.controller.serviceAccountName" . }}
- kind: ServiceAccount
name: {{ include "metallb.speaker.serviceAccountName" . }}
{{- end }}
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: {{ include "metallb.fullname" . }}-controller
namespace: {{ .Release.Namespace | quote }}
labels: {{- include "metallb.labels" . | nindent 4 }}
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: {{ include "metallb.fullname" . }}-controller
subjects:
- kind: ServiceAccount
name: {{ include "metallb.controller.serviceAccountName" . }}
{{- end -}}
@@ -0,0 +1,30 @@
{{- if .Values.controller.serviceAccount.create }}
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: {{ template "metallb.controller.serviceAccountName" . }}
namespace: {{ .Release.Namespace | quote }}
labels:
{{- include "metallb.labels" . | nindent 4 }}
app.kubernetes.io/component: controller
{{- with .Values.controller.serviceAccount.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
{{- end }}
{{- if and .Values.speaker.enabled .Values.speaker.serviceAccount.create }}
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: {{ template "metallb.speaker.serviceAccountName" . }}
namespace: {{ .Release.Namespace | quote }}
labels:
{{- include "metallb.labels" . | nindent 4 }}
app.kubernetes.io/component: speaker
{{- with .Values.speaker.serviceAccount.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
{{- end }}
@@ -0,0 +1,195 @@
{{- if and .Values.prometheus.serviceMonitor.enabled .Values.prometheus.podMonitor.enabled }}
{{- fail "prometheus.serviceMonitor.enabled and prometheus.podMonitor.enabled cannot both be set" }}
{{- end }}
{{- if .Values.prometheus.serviceMonitor.enabled }}
{{- if .Values.speaker.enabled }}
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: {{ template "metallb.fullname" . }}-speaker-monitor
namespace: {{ .Release.Namespace | quote }}
labels:
{{- include "metallb.labels" . | nindent 4 }}
app.kubernetes.io/component: speaker
{{- if .Values.prometheus.serviceMonitor.speaker.additionalLabels }}
{{ toYaml .Values.prometheus.serviceMonitor.speaker.additionalLabels | indent 4 }}
{{- end }}
{{- if .Values.prometheus.serviceMonitor.speaker.annotations }}
annotations:
{{ toYaml .Values.prometheus.serviceMonitor.speaker.annotations | indent 4 }}
{{- end }}
spec:
endpoints:
- port: {{ template "metrics.exposedportname" . }}
honorLabels: true
bearerTokenFile: "/var/run/secrets/kubernetes.io/serviceaccount/token"
scheme: "https"
{{- if .Values.prometheus.serviceMonitor.metricRelabelings }}
metricRelabelings:
{{- toYaml .Values.prometheus.serviceMonitor.metricRelabelings | nindent 8 }}
{{- end -}}
{{- if .Values.prometheus.serviceMonitor.relabelings }}
relabelings:
{{- toYaml .Values.prometheus.serviceMonitor.relabelings | nindent 8 }}
{{- end }}
{{- if .Values.prometheus.serviceMonitor.interval }}
interval: {{ .Values.prometheus.serviceMonitor.interval }}
{{- end }}
{{- if .Values.prometheus.serviceMonitor.speaker.tlsConfig }}
tlsConfig:
{{ toYaml .Values.prometheus.serviceMonitor.speaker.tlsConfig | indent 8 }}
{{- end }}
{{- if .Values.speaker.frr.enabled }}
- port: {{ template "metrics.exposedfrrportname" . }}
honorLabels: true
bearerTokenFile: "/var/run/secrets/kubernetes.io/serviceaccount/token"
scheme: "https"
{{- if .Values.prometheus.serviceMonitor.interval }}
interval: {{ .Values.prometheus.serviceMonitor.interval }}
{{- end }}
{{- if .Values.prometheus.serviceMonitor.speaker.tlsConfig }}
tlsConfig:
{{ toYaml .Values.prometheus.serviceMonitor.speaker.tlsConfig | indent 8 }}
{{- end }}
{{- end }}
jobLabel: {{ .Values.prometheus.serviceMonitor.jobLabel | quote }}
namespaceSelector:
matchNames:
- {{ .Release.Namespace }}
selector:
matchLabels:
name: {{ template "metallb.fullname" . }}-speaker-monitor-service
---
apiVersion: v1
kind: Service
metadata:
annotations:
prometheus.io/scrape: "true"
prometheus.io/scheme: "https"
{{- if .Values.prometheus.serviceMonitor.speaker.annotations }}
{{ toYaml .Values.prometheus.serviceMonitor.speaker.annotations | indent 4 }}
{{- end }}
labels:
name: {{ template "metallb.fullname" . }}-speaker-monitor-service
{{- include "metallb.labels" . | nindent 4 }}
name: {{ template "metallb.fullname" . }}-speaker-monitor-service
namespace: {{ .Release.Namespace | quote }}
spec:
selector:
{{- include "metallb.selectorLabels" . | nindent 4 }}
app.kubernetes.io/component: speaker
clusterIP: None
ports:
- name: {{ template "metrics.exposedportname" . }}
port: {{ template "metrics.exposedport" . }}
targetPort: {{ template "metrics.exposedport" . }}
{{- if .Values.speaker.frr.enabled }}
- name: {{ template "metrics.exposedfrrportname" . }}
port: {{ template "metrics.exposedfrrport" . }}
targetPort: {{ template "metrics.exposedfrrport" . }}
{{- end }}
sessionAffinity: None
type: ClusterIP
{{- end }}
---
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: {{ template "metallb.fullname" . }}-controller-monitor
namespace: {{ .Release.Namespace | quote }}
labels:
{{- include "metallb.labels" . | nindent 4 }}
{{- if .Values.prometheus.serviceMonitor.controller.additionalLabels }}
{{ toYaml .Values.prometheus.serviceMonitor.controller.additionalLabels | indent 4 }}
{{- end }}
{{- if .Values.prometheus.serviceMonitor.controller.annotations }}
annotations:
{{ toYaml .Values.prometheus.serviceMonitor.controller.annotations | indent 4 }}
{{- end }}
spec:
endpoints:
- port: {{ template "metrics.exposedportname" . }}
honorLabels: true
bearerTokenFile: "/var/run/secrets/kubernetes.io/serviceaccount/token"
scheme: "https"
{{- if .Values.prometheus.serviceMonitor.metricRelabelings }}
metricRelabelings:
{{- toYaml .Values.prometheus.serviceMonitor.metricRelabelings | nindent 8 }}
{{- end -}}
{{- if .Values.prometheus.serviceMonitor.relabelings }}
relabelings:
{{- toYaml .Values.prometheus.serviceMonitor.relabelings | nindent 8 }}
{{- end }}
{{- if .Values.prometheus.serviceMonitor.interval }}
interval: {{ .Values.prometheus.serviceMonitor.interval }}
{{- end }}
{{- if .Values.prometheus.serviceMonitor.controller.tlsConfig }}
tlsConfig:
{{ toYaml .Values.prometheus.serviceMonitor.controller.tlsConfig | indent 8 }}
{{- end }}
jobLabel: {{ .Values.prometheus.serviceMonitor.jobLabel | quote }}
namespaceSelector:
matchNames:
- {{ .Release.Namespace }}
selector:
matchLabels:
name: {{ template "metallb.fullname" . }}-controller-monitor-service
---
apiVersion: v1
kind: Service
metadata:
annotations:
prometheus.io/scrape: "true"
prometheus.io/scheme: "https"
{{- if .Values.prometheus.serviceMonitor.controller.annotations }}
{{ toYaml .Values.prometheus.serviceMonitor.controller.annotations | indent 4 }}
{{- end }}
labels:
name: {{ template "metallb.fullname" . }}-controller-monitor-service
name: {{ template "metallb.fullname" . }}-controller-monitor-service
spec:
selector:
{{- include "metallb.selectorLabels" . | nindent 4 }}
app.kubernetes.io/component: controller
clusterIP: None
ports:
- name: {{ template "metrics.exposedportname" . }}
port: {{ template "metrics.exposedport" . }}
targetPort: {{ template "metrics.exposedport" . }}
sessionAffinity: None
type: ClusterIP
---
{{- if .Values.prometheus.rbacPrometheus }}
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: {{ template "metallb.fullname" . }}-prometheus
namespace: {{ .Release.Namespace | quote }}
rules:
- apiGroups:
- ""
resources:
- pods
- services
- endpoints
verbs:
- get
- list
- watch
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: {{ template "metallb.fullname" . }}-prometheus
namespace: {{ .Release.Namespace | quote }}
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: {{ template "metallb.fullname" . }}-prometheus
subjects:
- kind: ServiceAccount
name: {{ required ".Values.prometheus.serviceAccount must be defined when .Values.prometheus.serviceMonitor.enabled == true" .Values.prometheus.serviceAccount }}
namespace: {{ required ".Values.prometheus.namespace must be defined when .Values.prometheus.serviceMonitor.enabled == true" .Values.prometheus.namespace }}
{{- end }}
{{- end }}
@@ -0,0 +1,564 @@
{{- if .Values.speaker.frr.enabled }}
{{- if or .Values.frrk8s.enabled .Values.frrk8s.external }}
{{- fail "speaker.frr.enabled and frrk8s.enabled / external are mutually exclusive!" }}
{{- end }}
{{- end }}
{{- if and .Values.frrk8s.enabled .Values.frrk8s.external }}
{{- fail "frrk8s.enabled frrk8s.external are mutually exclusive!" }}
{{- end }}
{{- if and (not .Values.speaker.memberlist.enabled) .Values.speaker.nodeSelector }}
{{- fail "nodeSelector must be empty when memberlist is disabled" }}
{{- end }}
{{- if .Values.speaker.frr.enabled }}
# FRR expects to have these files owned by frr:frr on startup.
# Having them in a ConfigMap allows us to modify behaviors: for example enabling more daemons on startup.
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ template "metallb.fullname" . }}-frr-startup
namespace: {{ .Release.Namespace | quote }}
labels:
{{- include "metallb.labels" . | nindent 4 }}
app.kubernetes.io/component: speaker
data:
daemons: |
# This file tells the frr package which daemons to start.
#
# Sample configurations for these daemons can be found in
# /usr/share/doc/frr/examples/.
#
# ATTENTION:
#
# When activating a daemon for the first time, a config file, even if it is
# empty, has to be present *and* be owned by the user and group "frr", else
# the daemon will not be started by /etc/init.d/frr. The permissions should
# be u=rw,g=r,o=.
# When using "vtysh" such a config file is also needed. It should be owned by
# group "frrvty" and set to ug=rw,o= though. Check /etc/pam.d/frr, too.
#
# The watchfrr and zebra daemons are always started.
#
bgpd=yes
ospfd=no
ospf6d=no
ripd=no
ripngd=no
isisd=no
pimd=no
ldpd=no
nhrpd=no
eigrpd=no
babeld=no
sharpd=no
pbrd=no
bfdd=yes
fabricd=no
vrrpd=no
#
# If this option is set the /etc/init.d/frr script automatically loads
# the config via "vtysh -b" when the servers are started.
# Check /etc/pam.d/frr if you intend to use "vtysh"!
#
vtysh_enable=yes
zebra_options=" -A 127.0.0.1 -s 90000000 --limit-fds 100000"
bgpd_options=" -A 127.0.0.1 -p 0 --limit-fds 100000"
ospfd_options=" -A 127.0.0.1"
ospf6d_options=" -A ::1"
ripd_options=" -A 127.0.0.1"
ripngd_options=" -A ::1"
isisd_options=" -A 127.0.0.1"
pimd_options=" -A 127.0.0.1"
ldpd_options=" -A 127.0.0.1"
nhrpd_options=" -A 127.0.0.1"
eigrpd_options=" -A 127.0.0.1"
babeld_options=" -A 127.0.0.1"
sharpd_options=" -A 127.0.0.1"
pbrd_options=" -A 127.0.0.1"
staticd_options="-A 127.0.0.1 --limit-fds 100000"
bfdd_options=" -A 127.0.0.1 --limit-fds 100000"
fabricd_options="-A 127.0.0.1"
vrrpd_options=" -A 127.0.0.1"
# configuration profile
#
#frr_profile="traditional"
#frr_profile="datacenter"
#
# This is the maximum number of FD's that will be available.
# Upon startup this is read by the control files and ulimit
# is called. Uncomment and use a reasonable value for your
# setup if you are expecting a large number of peers in
# say BGP.
#MAX_FDS=1024
# The list of daemons to watch is automatically generated by the init script.
#watchfrr_options=""
# for debugging purposes, you can specify a "wrap" command to start instead
# of starting the daemon directly, e.g. to use valgrind on ospfd:
# ospfd_wrap="/usr/bin/valgrind"
# or you can use "all_wrap" for all daemons, e.g. to use perf record:
# all_wrap="/usr/bin/perf record --call-graph -"
# the normal daemon command is added to this at the end.
vtysh.conf: |+
service integrated-vtysh-config
frr.conf: |+
! This file gets overriden the first time the speaker renders a config.
! So anything configured here is only temporary.
frr version 8.0
frr defaults traditional
hostname Router
line vty
log stdout informational
{{- end }}
---
{{- if .Values.speaker.enabled }}
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: {{ template "metallb.fullname" . }}-speaker
namespace: {{ .Release.Namespace | quote }}
labels:
{{- include "metallb.labels" . | nindent 4 }}
app.kubernetes.io/component: speaker
{{- range $key, $value := .Values.speaker.labels }}
{{ $key }}: {{ $value | quote }}
{{- end }}
spec:
{{- if .Values.speaker.updateStrategy }}
updateStrategy: {{- toYaml .Values.speaker.updateStrategy | nindent 4 }}
{{- end }}
selector:
matchLabels:
{{- include "metallb.selectorLabels" . | nindent 6 }}
app.kubernetes.io/component: speaker
template:
metadata:
{{- if or .Values.prometheus.scrapeAnnotations .Values.speaker.podAnnotations }}
annotations:
{{- if .Values.prometheus.scrapeAnnotations }}
prometheus.io/scrape: "true"
{{- if not .Values.speaker.frr.enabled }}
prometheus.io/scheme: "https"
prometheus.io/port: "{{ .Values.prometheus.metricsPort }}"
{{- end }}
{{- end }}
{{- with .Values.speaker.podAnnotations }}
{{- toYaml . | nindent 8 }}
{{- end }}
{{- end }}
labels:
{{- include "metallb.selectorLabels" . | nindent 8 }}
app.kubernetes.io/component: speaker
{{- range $key, $value := .Values.speaker.labels }}
{{ $key }}: {{ $value | quote }}
{{- end }}
spec:
{{- if .Values.speaker.runtimeClassName }}
runtimeClassName: {{ .Values.speaker.runtimeClassName }}
{{- end }}
{{- with .Values.imagePullSecrets }}
imagePullSecrets:
{{- toYaml . | nindent 8 }}
{{- end }}
serviceAccountName: {{ template "metallb.speaker.serviceAccountName" . }}
terminationGracePeriodSeconds: 0
hostNetwork: true
{{- if .Values.speaker.securityContext }}
securityContext:
{{- toYaml .Values.speaker.securityContext | nindent 8 }}
{{- end }}
volumes:
{{- if .Values.tls.speakerMetricsTLSSecret }}
- name: metrics-certs
secret:
secretName: {{ .Values.tls.speakerMetricsTLSSecret }}
{{- end }}
{{- if .Values.speaker.memberlist.enabled }}
- name: memberlist
secret:
secretName: {{ include "metallb.secretName" . }}
defaultMode: 420
{{- end }}
{{- if .Values.speaker.excludeInterfaces.enabled }}
- name: metallb-excludel2
configMap:
defaultMode: 256
name: metallb-excludel2
{{- end }}
- name: memberlist-config
configMap:
name: metallb-memberlist-config
optional: true
{{- if .Values.speaker.frr.enabled }}
- name: frr-sockets
emptyDir: {}
- name: frr-startup
configMap:
name: {{ template "metallb.fullname" . }}-frr-startup
- name: frr-conf
emptyDir: {}
- name: reloader
emptyDir: {}
- name: metrics
emptyDir: {}
- name: frr-tmp
emptyDir: {}
- name: frr-lib
emptyDir: {}
- name: frr-log
emptyDir: {}
initContainers:
# Copies the initial config files with the right permissions to the shared volume.
- name: cp-frr-files
image: {{ .Values.speaker.frr.image.repository }}:{{ .Values.speaker.frr.image.tag | default .Chart.AppVersion }}
securityContext:
runAsUser: 100
runAsGroup: 101
command: ["/bin/sh", "-c", "cp -rLf /tmp/frr/* /etc/frr/"]
volumeMounts:
- name: frr-startup
mountPath: /tmp/frr
- name: frr-conf
mountPath: /etc/frr
{{- with .Values.speaker.initContainers.cpFrrFiles.resources }}
resources:
{{- toYaml . | nindent 12 }}
{{- end }}
# Copies the reloader to the shared volume between the speaker and reloader.
- name: cp-reloader
image: {{ .Values.speaker.image.repository }}:{{ .Values.speaker.image.tag | default .Chart.AppVersion }}
command: ["/cp-tool","/frr-reloader.sh","/etc/frr_reloader/frr-reloader.sh"]
volumeMounts:
- name: reloader
mountPath: /etc/frr_reloader
{{- with .Values.speaker.initContainers.cpReloader.resources }}
resources:
{{- toYaml . | nindent 12 }}
{{- end }}
# Copies the metrics exporter
- name: cp-metrics
image: {{ .Values.speaker.image.repository }}:{{ .Values.speaker.image.tag | default .Chart.AppVersion }}
command: ["/cp-tool","/frr-metrics","/etc/frr_metrics/frr-metrics"]
volumeMounts:
- name: metrics
mountPath: /etc/frr_metrics
{{- with .Values.speaker.initContainers.cpMetrics.resources }}
resources:
{{- toYaml . | nindent 12 }}
{{- end }}
shareProcessNamespace: true
{{- end }}
containers:
- name: speaker
image: {{ .Values.speaker.image.repository }}:{{ .Values.speaker.image.tag | default .Chart.AppVersion }}
{{- if .Values.speaker.image.pullPolicy }}
imagePullPolicy: {{ .Values.speaker.image.pullPolicy }}
{{- end }}
{{- if .Values.speaker.command }}
command:
- {{ .Values.speaker.command }}
{{- end }}
args:
- --port={{ .Values.prometheus.metricsPort }}
{{- with .Values.speaker.logLevel }}
- --log-level={{ . }}
{{- end }}
{{- if .Values.loadBalancerClass }}
- --lb-class={{ .Values.loadBalancerClass }}
{{- end }}
{{- if .Values.speaker.wanConfig }}
- --ml-wan-config
{{- end }}
{{- if .Values.speaker.ignoreExcludeLB}}
- --ignore-exclude-lb
{{- end }}
{{- if .Values.speaker.bgpDebounceTimeout }}
- --bgp-debounce-timeout={{ .Values.speaker.bgpDebounceTimeout }}
{{- end }}
{{- if .Values.frrk8s.external }}
- --frrk8s-namespace={{ required "namespace is required when frrk8s is external" .Values.frrk8s.namespace }}
{{- end }}
{{- if .Values.tls.cipherSuites }}
- --tls-cipher-suites={{ .Values.tls.cipherSuites }}
{{- end }}
{{- if .Values.tls.curvePreferences }}
- --tls-curve-preferences={{ .Values.tls.curvePreferences }}
{{- end }}
{{- if .Values.tls.minVersion }}
- --tls-min-version={{ .Values.tls.minVersion }}
{{- end }}
{{- if .Values.tls.speakerMetricsTLSSecret }}
- --metrics-cert-dir=/etc/metrics
{{- end }}
env:
- name: METALLB_NODE_NAME
valueFrom:
fieldRef:
fieldPath: spec.nodeName
- name: METALLB_HOST
valueFrom:
fieldRef:
fieldPath: status.hostIP
{{- if .Values.speaker.memberlist.enabled }}
{{- if .Values.speaker.memberlist.mlBindAddrOverride }}
- name: METALLB_ML_BIND_ADDR
value: "{{ .Values.speaker.memberlist.mlBindAddrOverride }}"
{{ else }}
- name: METALLB_ML_BIND_ADDR
valueFrom:
fieldRef:
fieldPath: status.podIP
{{ end }}
- name: METALLB_ML_LABELS
value: "app.kubernetes.io/name={{ include "metallb.name" . }},app.kubernetes.io/component=speaker"
- name: METALLB_ML_BIND_PORT
value: "{{ .Values.speaker.memberlist.mlBindPort }}"
- name: METALLB_ML_SECRET_KEY_PATH
value: "{{ .Values.speaker.memberlist.mlSecretKeyPath }}"
{{- end }}
{{- if .Values.speaker.frr.enabled }}
- name: FRR_CONFIG_FILE
value: /etc/frr_reloader/frr.conf
- name: FRR_RELOADER_PID_FILE
value: /etc/frr_reloader/reloader.pid
- name: METALLB_BGP_TYPE
value: frr
{{- end }}
{{- if or .Values.frrk8s.enabled .Values.frrk8s.external }}
- name: METALLB_BGP_TYPE
value: frr-k8s
{{- end }}
- name: METALLB_POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
ports:
- name: metricshttps
containerPort: {{ .Values.prometheus.metricsPort }}
{{- if .Values.speaker.memberlist.enabled }}
- name: memberlist-tcp
containerPort: {{ .Values.speaker.memberlist.mlBindPort }}
protocol: TCP
- name: memberlist-udp
containerPort: {{ .Values.speaker.memberlist.mlBindPort }}
protocol: UDP
{{- end }}
{{- if .Values.speaker.livenessProbe.enabled }}
livenessProbe:
httpGet:
path: /healthz
port: {{ .Values.speaker.livenessProbe.port }}
host: 127.0.0.1
initialDelaySeconds: {{ .Values.speaker.livenessProbe.initialDelaySeconds }}
periodSeconds: {{ .Values.speaker.livenessProbe.periodSeconds }}
timeoutSeconds: {{ .Values.speaker.livenessProbe.timeoutSeconds }}
successThreshold: {{ .Values.speaker.livenessProbe.successThreshold }}
failureThreshold: {{ .Values.speaker.livenessProbe.failureThreshold }}
{{- end }}
{{- if .Values.speaker.readinessProbe.enabled }}
readinessProbe:
httpGet:
path: /readyz
port: {{ .Values.speaker.readinessProbe.port }}
host: 127.0.0.1
initialDelaySeconds: {{ .Values.speaker.readinessProbe.initialDelaySeconds }}
periodSeconds: {{ .Values.speaker.readinessProbe.periodSeconds }}
timeoutSeconds: {{ .Values.speaker.readinessProbe.timeoutSeconds }}
successThreshold: {{ .Values.speaker.readinessProbe.successThreshold }}
failureThreshold: {{ .Values.speaker.readinessProbe.failureThreshold }}
{{- end }}
{{- with .Values.speaker.resources }}
resources:
{{- toYaml . | nindent 10 }}
{{- end }}
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop:
- ALL
add:
- NET_RAW
{{- if or .Values.speaker.frr.enabled .Values.speaker.memberlist.enabled .Values.speaker.excludeInterfaces.enabled .Values.tls.speakerMetricsTLSSecret }}
volumeMounts:
- name: memberlist-config
mountPath: /etc/metallb/memberlist
readOnly: true
{{- if .Values.speaker.memberlist.enabled }}
- name: memberlist
mountPath: {{ .Values.speaker.memberlist.mlSecretKeyPath }}
{{- end }}
{{- if .Values.speaker.frr.enabled }}
- name: reloader
mountPath: /etc/frr_reloader
{{- end }}
{{- if .Values.speaker.excludeInterfaces.enabled }}
- name: metallb-excludel2
mountPath: /etc/metallb
{{- end }}
{{- if .Values.tls.speakerMetricsTLSSecret }}
- name: metrics-certs
mountPath: /etc/metrics
readOnly: true
{{- end }}
{{- end }}
{{- if .Values.speaker.frr.enabled }}
- name: frr
securityContext:
readOnlyRootFilesystem: true
allowPrivilegeEscalation: false
capabilities:
add:
- NET_ADMIN
- NET_RAW
- SYS_ADMIN
- NET_BIND_SERVICE
image: {{ .Values.speaker.frr.image.repository }}:{{ .Values.speaker.frr.image.tag | default .Chart.AppVersion }}
{{- if .Values.speaker.frr.image.pullPolicy }}
imagePullPolicy: {{ .Values.speaker.frr.image.pullPolicy }}
{{- end }}
env:
- name: TINI_SUBREAPER
value: "true"
volumeMounts:
- name: frr-sockets
mountPath: /var/run/frr
- name: frr-conf
mountPath: /etc/frr
- name: frr-tmp
mountPath: /var/tmp/frr
- name: frr-lib
mountPath: /var/lib/frr
command:
- /bin/sh
- -c
- /sbin/tini -- /usr/lib/frr/docker-start
{{- with .Values.speaker.frr.resources }}
resources:
{{- toYaml . | nindent 12 }}
{{- end }}
{{- if .Values.speaker.livenessProbe.enabled }}
livenessProbe:
httpGet:
path: /livez
port: {{ .Values.speaker.frr.metricsPort }}
scheme: HTTPS
initialDelaySeconds: {{ .Values.speaker.livenessProbe.initialDelaySeconds }}
periodSeconds: {{ .Values.speaker.livenessProbe.periodSeconds }}
timeoutSeconds: {{ .Values.speaker.livenessProbe.timeoutSeconds }}
successThreshold: {{ .Values.speaker.livenessProbe.successThreshold }}
failureThreshold: {{ .Values.speaker.livenessProbe.failureThreshold }}
{{- end }}
{{- if .Values.speaker.startupProbe.enabled }}
startupProbe:
httpGet:
path: /livez
port: {{ .Values.speaker.frr.metricsPort }}
scheme: HTTPS
failureThreshold: {{ .Values.speaker.startupProbe.failureThreshold }}
periodSeconds: {{ .Values.speaker.startupProbe.periodSeconds }}
{{- end }}
- name: reloader
image: {{ .Values.speaker.frr.image.repository }}:{{ .Values.speaker.frr.image.tag | default .Chart.AppVersion }}
{{- if .Values.speaker.frr.image.pullPolicy }}
imagePullPolicy: {{ .Values.speaker.frr.image.pullPolicy }}
{{- end }}
securityContext:
readOnlyRootFilesystem: true
allowPrivilegeEscalation: false
command: ["/etc/frr_reloader/frr-reloader.sh"]
volumeMounts:
- name: frr-sockets
mountPath: /var/run/frr
- name: frr-conf
mountPath: /etc/frr
- name: reloader
mountPath: /etc/frr_reloader
- name: frr-log
mountPath: /var/log/frr
{{- with .Values.speaker.reloader.resources }}
resources:
{{- toYaml . | nindent 12 }}
{{- end }}
- name: frr-metrics
image: {{ .Values.speaker.frr.image.repository }}:{{ .Values.speaker.frr.image.tag | default .Chart.AppVersion }}
securityContext:
readOnlyRootFilesystem: true
allowPrivilegeEscalation: false
command: ["/etc/frr_metrics/frr-metrics"]
args:
- --metrics-port={{ .Values.speaker.frr.metricsPort }}
- --metrics-bind-address=0.0.0.0
{{- if .Values.tls.speakerMetricsTLSSecret }}
- --tls-cert-file=/etc/metrics/tls.crt
- --tls-private-key-file=/etc/metrics/tls.key
{{- end }}
{{- if .Values.tls.cipherSuites }}
- --tls-cipher-suites={{ .Values.tls.cipherSuites }}
{{- end }}
{{- if .Values.tls.curvePreferences }}
- --tls-curve-preferences={{ .Values.tls.curvePreferences }}
{{- end }}
{{- if .Values.tls.minVersion }}
- --tls-min-version={{ .Values.tls.minVersion }}
{{- end }}
env:
- name: VTYSH_HISTFILE
value: /dev/null
ports:
- containerPort: {{ .Values.speaker.frr.metricsPort }}
name: frrmetricshttps
volumeMounts:
- name: frr-sockets
mountPath: /var/run/frr
- name: frr-conf
mountPath: /etc/frr
- name: metrics
mountPath: /etc/frr_metrics
{{- if .Values.tls.speakerMetricsTLSSecret }}
- name: metrics-certs
mountPath: /etc/metrics
readOnly: true
{{- end }}
{{- with .Values.speaker.frrMetrics.resources }}
resources:
{{- toYaml . | nindent 12 }}
{{- end }}
{{- end }}
{{- if .Values.speaker.extraContainers }}
{{- toYaml .Values.speaker.extraContainers | nindent 6 }}
{{- end }}
nodeSelector:
"kubernetes.io/os": linux
{{- with .Values.speaker.nodeSelector }}
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.speaker.affinity }}
affinity:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- if or .Values.speaker.tolerateMaster .Values.speaker.tolerations }}
tolerations:
{{- if .Values.speaker.tolerateMaster }}
- key: node-role.kubernetes.io/master
effect: NoSchedule
operator: Exists
- key: node-role.kubernetes.io/control-plane
effect: NoSchedule
operator: Exists
{{- end }}
{{- with .Values.speaker.tolerations }}
{{- toYaml . | nindent 6 }}
{{- end }}
{{- end }}
{{- with .Values.speaker.priorityClassName }}
priorityClassName: {{ . | quote }}
{{- end }}
{{- end }}
@@ -0,0 +1,150 @@
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingWebhookConfiguration
metadata:
name: metallb-webhook-configuration
labels:
{{- include "metallb.labels" . | nindent 4 }}
webhooks:
- admissionReviewVersions:
- v1
clientConfig:
service:
name: metallb-webhook-service
namespace: {{ .Release.Namespace }}
path: /validate-metallb-io-v1beta2-bgppeer
failurePolicy: {{ .Values.crds.validationFailurePolicy }}
name: bgppeervalidationwebhook.metallb.io
rules:
- apiGroups:
- metallb.io
apiVersions:
- v1beta2
operations:
- CREATE
- UPDATE
resources:
- bgppeers
sideEffects: None
- admissionReviewVersions:
- v1
clientConfig:
service:
name: metallb-webhook-service
namespace: {{ .Release.Namespace }}
path: /validate-metallb-io-v1beta1-ipaddresspool
failurePolicy: {{ .Values.crds.validationFailurePolicy }}
name: ipaddresspoolvalidationwebhook.metallb.io
rules:
- apiGroups:
- metallb.io
apiVersions:
- v1beta1
operations:
- CREATE
- UPDATE
resources:
- ipaddresspools
sideEffects: None
- admissionReviewVersions:
- v1
clientConfig:
service:
name: metallb-webhook-service
namespace: {{ .Release.Namespace }}
path: /validate-metallb-io-v1beta1-bgpadvertisement
failurePolicy: {{ .Values.crds.validationFailurePolicy }}
name: bgpadvertisementvalidationwebhook.metallb.io
rules:
- apiGroups:
- metallb.io
apiVersions:
- v1beta1
operations:
- CREATE
- UPDATE
resources:
- bgpadvertisements
sideEffects: None
- admissionReviewVersions:
- v1
clientConfig:
service:
name: metallb-webhook-service
namespace: {{ .Release.Namespace }}
path: /validate-metallb-io-v1beta1-community
failurePolicy: {{ .Values.crds.validationFailurePolicy }}
name: communityvalidationwebhook.metallb.io
rules:
- apiGroups:
- metallb.io
apiVersions:
- v1beta1
operations:
- CREATE
- UPDATE
resources:
- communities
sideEffects: None
- admissionReviewVersions:
- v1
clientConfig:
service:
name: metallb-webhook-service
namespace: {{ .Release.Namespace }}
path: /validate-metallb-io-v1beta1-bfdprofile
failurePolicy: {{ .Values.crds.validationFailurePolicy }}
name: bfdprofilevalidationwebhook.metallb.io
rules:
- apiGroups:
- metallb.io
apiVersions:
- v1beta1
operations:
- CREATE
- DELETE
resources:
- bfdprofiles
sideEffects: None
- admissionReviewVersions:
- v1
clientConfig:
service:
name: metallb-webhook-service
namespace: {{ .Release.Namespace }}
path: /validate-metallb-io-v1beta1-l2advertisement
failurePolicy: {{ .Values.crds.validationFailurePolicy }}
name: l2advertisementvalidationwebhook.metallb.io
rules:
- apiGroups:
- metallb.io
apiVersions:
- v1beta1
operations:
- CREATE
- UPDATE
resources:
- l2advertisements
sideEffects: None
---
apiVersion: v1
kind: Service
metadata:
name: metallb-webhook-service
namespace: {{ .Release.Namespace | quote }}
labels:
{{- include "metallb.labels" . | nindent 4 }}
spec:
ports:
- port: 443
targetPort: 9443
selector:
{{- include "metallb.selectorLabels" . | nindent 4 }}
app.kubernetes.io/component: controller
---
apiVersion: v1
kind: Secret
metadata:
name: metallb-webhook-cert
namespace: {{ .Release.Namespace | quote }}
labels:
{{- include "metallb.labels" . | nindent 4 }}