Helm Charts / Detect changed charts (pull_request) Successful in 21s
Helm Charts / Library charts tool (pull_request) Skipped
Helm Charts / Application charts alloy (pull_request) Skipped
Helm Charts / Application charts chart (pull_request) Skipped
Helm Charts / Application charts grafana (pull_request) Skipped
Helm Charts / Application charts hashicorp-vault (pull_request) Skipped
Helm Charts / Application charts loki (pull_request) Skipped
Helm Charts / Application charts minio (pull_request) Skipped
Helm Charts / Application charts pgbouncer (pull_request) Skipped
Helm Charts / Application charts pgcat (pull_request) Skipped
Helm Charts / Application charts prometheus (pull_request) Skipped
Helm Charts / Application charts redis (pull_request) Skipped
Helm Charts / Application charts crowdsec (pull_request) Successful in 50s
#56 fixait le nom de machine de la LAPI avec un simple `value: crowdsec-lapi` dans `lapi.env`. Ça rendait correctement, et au runtime Kubernetes retient bien la dernière des deux définitions — un pod de test le confirmait. Mais ce n'est pas le runtime qui décide : c'est l'apply, et là ça cassait. `env` est une liste à clé de fusion (`name`). Le strategic merge patch fusionne donc les deux entrées CUSTOM_HOSTNAME en UNE, qui porte alors le `valueFrom` du chart ET notre `value`. L'API refuse : Deployment.apps "crowdsec-lapi" is invalid: spec.template.spec.containers[0].env[5].valueFrom: Invalid value: "": may not be specified when `value` is not empty ArgoCD a réessayé cinq fois puis s'est arrêté en SyncError. Le Deployment est resté INCHANGÉ — CrowdSec n'a pas été interrompu, mais le correctif n'était pas appliqué et l'application restait OutOfSync. Correctif : un `valueFrom` des deux côtés. La fusion écrase alors proprement le fieldPath et laisse une seule entrée valide. Comme un fieldRef ne sait lire qu'un champ du pod, et que tous ceux qu'expose le chart varient (le nom) ou disent autre chose (`k8s-app`, `type`), on pose un label dédié `machine-name` via `lapi.podLabels` et on pointe dessus. Vérifié cette fois sur le chemin qui compte : kubectl apply --dry-run=server -o json → une SEULE occurrence de CUSTOM_HOSTNAME, pointant sur metadata.labels['machine-name'], label valant `crowdsec-lapi`. La leçon est dans le commentaire du values : `helm template` ne voit rien de tout ça, le rendu est valide des deux côtés. Seule la fusion avec l'objet vivant distingue les deux formes. Co-Authored-By: Claude Opus 5 <[email protected]>
168 lines
7.0 KiB
YAML
168 lines
7.0 KiB
YAML
crowdsec: &crowdsec_config
|
|
# for raw logs format: json or cri (docker|containerd)
|
|
container_runtime: docker
|
|
agent:
|
|
affinity:
|
|
nodeAffinity:
|
|
requiredDuringSchedulingIgnoredDuringExecution:
|
|
nodeSelectorTerms:
|
|
- matchExpressions:
|
|
- key: node-role.kubernetes.io/control-plane
|
|
operator: Exists
|
|
# Specify each pod whose logs you want to process
|
|
acquisition:
|
|
# The namespace where the pod is located
|
|
- namespace: kube-system
|
|
# The pod name
|
|
podName: traefik-*
|
|
# as in crowdsec configuration, we need to specify the program name to find a matching parser
|
|
program: traefik
|
|
env:
|
|
- name: COLLECTIONS
|
|
value: "crowdsecurity/traefik crowdsecurity/http-cve"
|
|
- name: TZ
|
|
value: Europe/Paris
|
|
lapi:
|
|
# Source stable pour le CUSTOM_HOSTNAME défini plus bas : un fieldRef ne sait
|
|
# lire qu'un champ du pod, et tous ceux que le chart expose varient (le nom)
|
|
# ou disent autre chose (`k8s-app`, `type`). Ce label n'existe que pour ça.
|
|
podLabels:
|
|
machine-name: crowdsec-lapi
|
|
strategy:
|
|
type: Recreate
|
|
env:
|
|
- name: TZ
|
|
value: Europe/Paris
|
|
# ⚠ NOM DE MACHINE STABLE — NE PAS REVENIR AU NOM DU POD.
|
|
#
|
|
# Le chart amont code en dur `CUSTOM_HOSTNAME` sur `metadata.name`
|
|
# (templates/lapi-deployment.yaml). L'entrypoint s'en sert pour
|
|
# enregistrer la LAPI en base :
|
|
# si .login du fichier d'identifiants == CUSTOM_HOSTNAME et que la
|
|
# machine existe déjà → « Local agent already registered », rien à faire ;
|
|
# sinon → cscli machines delete <CUSTOM_HOSTNAME> puis add.
|
|
# Le `delete` ne porte QUE sur le nom courant : l'enregistrement de
|
|
# l'ancien pod, lui, n'est jamais supprimé.
|
|
#
|
|
# Or le pod change de nom bien plus souvent qu'on ne le croit. Ce n'est pas
|
|
# une histoire de redémarrages — un redémarrage garde le nom. C'est le
|
|
# `rolloutRestartTargets` du VaultDynamicSecret (templates/
|
|
# vaultdynamicsecret.yaml) : à chaque rotation de l'identifiant Postgres,
|
|
# VSO force un rollout, ce qui change le pod template, donc le hash du
|
|
# ReplicaSet, donc le nom du pod.
|
|
#
|
|
# Mesuré le 2026-09-20 : 594 enregistrements `crowdsec-lapi-*` en base
|
|
# depuis le 2025-12-05, pour 571 hashes de ReplicaSet distincts — soit
|
|
# 2,05 par jour, sur 290 jours, et une seule LAPI vivante à la fois.
|
|
# Ils s'entassent dans le PostgreSQL externe de pi2, celui-là même qui a
|
|
# refusé des connexions le 2026-09-20 (SQLSTATE 53300) et fait crasher la
|
|
# LAPI 3 fois.
|
|
#
|
|
# Avec un nom fixe, le premier démarrage fait delete+add sur CE nom, et
|
|
# tous les suivants tombent sur « already registered » — plus aucune
|
|
# écriture. Le fichier d'identifiants survit d'ailleurs aux redémarrages
|
|
# (/etc/crowdsec est un lien vers le PVC crowdsec-config), donc la
|
|
# comparaison sur `.login` tient dans le temps.
|
|
#
|
|
# ⚠ POURQUOI UN fieldRef VERS UN LABEL, ET PAS UN SIMPLE `value:`.
|
|
#
|
|
# Le chart émet sa propre définition de CUSTOM_HOSTNAME AVANT d'injecter
|
|
# `.Values.lapi.env`. On se retrouve donc avec deux entrées de même nom, et
|
|
# au RUNTIME Kubernetes retient bien la dernière — un pod de test le
|
|
# confirme. Mais ce n'est pas le runtime qui décide ici : c'est l'APPLY.
|
|
#
|
|
# `env` est une liste à clé de fusion (`name`). Un strategic merge patch
|
|
# FUSIONNE donc les deux entrées en une seule. Avec un `value:` en face du
|
|
# `valueFrom:` du chart, l'objet fusionné porte les deux, et l'API refuse :
|
|
# Deployment.apps "crowdsec-lapi" is invalid:
|
|
# spec.template.spec.containers[0].env[5].valueFrom: Invalid value: "":
|
|
# may not be specified when `value` is not empty
|
|
# Mesuré le 2026-09-20 : ArgoCD a bouclé cinq fois là-dessus, sync en échec,
|
|
# Deployment inchangé. `helm template` ne voit rien de tout ça — le rendu
|
|
# est parfaitement valide, c'est la fusion avec l'objet vivant qui casse.
|
|
#
|
|
# Avec un `valueFrom` des deux côtés, la fusion écrase proprement le
|
|
# fieldPath et laisse UNE entrée valide. Vérifié par
|
|
# `kubectl apply --dry-run=server -o json` : une seule occurrence, pointant
|
|
# sur metadata.labels['machine-name'].
|
|
#
|
|
# D'où le label `machine-name` posé via lapi.podLabels juste au-dessus : le
|
|
# fieldRef a besoin d'une source stable, et un label dédié se lit mieux que
|
|
# de détourner `k8s-app` ou `type`.
|
|
#
|
|
# ⚠ Ne pas « simplifier » en `value: crowdsec-lapi`. C'est exactement ce qui
|
|
# a échoué, et ça échoue à l'apply, pas au rendu.
|
|
#
|
|
# Ne pas « corriger » non plus en supprimant le rolloutRestartTargets : les
|
|
# identifiants arrivent par secretKeyRef, qui ne se recharge pas à chaud.
|
|
# Sans rollout, la LAPI garderait des identifiants révoqués par Vault.
|
|
- name: CUSTOM_HOSTNAME
|
|
valueFrom:
|
|
fieldRef:
|
|
fieldPath: metadata.labels['machine-name']
|
|
# To enroll the Security Engine to the console
|
|
- name: ENROLL_KEY
|
|
value: "cmieq72i3000802jr1wx8kply"
|
|
- name: ENROLL_INSTANCE_NAME
|
|
value: "homelab"
|
|
- name: ENROLL_TAGS
|
|
value: "k3s rpi test"
|
|
- name: DB_USER
|
|
valueFrom:
|
|
secretKeyRef:
|
|
name: crowdsec-db-credentials
|
|
key: username
|
|
- name: DB_PASSWORD
|
|
valueFrom:
|
|
secretKeyRef:
|
|
name: crowdsec-db-credentials
|
|
key: password
|
|
appsec:
|
|
enabled: true
|
|
acquisitions:
|
|
- appsec_config: crowdsecurity/appsec-default
|
|
labels:
|
|
type: appsec
|
|
listen_addr: 0.0.0.0:7422
|
|
path: /
|
|
source: appsec
|
|
env:
|
|
- name: TZ
|
|
value: Europe/Paris
|
|
- name: COLLECTIONS
|
|
value: "crowdsecurity/appsec-virtual-patching crowdsecurity/appsec-generic-rules"
|
|
resources:
|
|
limits:
|
|
cpu: "500m"
|
|
memory: "300Mi"
|
|
requests:
|
|
cpu: "100m"
|
|
memory: "200Mi"
|
|
config:
|
|
config.yaml.local: |
|
|
db_config:
|
|
type: postgresql
|
|
user: ${DB_USER}
|
|
password: ${DB_PASSWORD}
|
|
db_name: crowdsec
|
|
host: pgbouncer.tools
|
|
port: 5432
|
|
api:
|
|
server:
|
|
auto_registration: # Activate if not using TLS for authentication
|
|
enabled: true
|
|
token: "${REGISTRATION_TOKEN}" # /!\ do not change
|
|
allowed_ranges: # /!\ adapt to the pod IP ranges used by your cluster
|
|
- "127.0.0.1/32"
|
|
- "192.168.0.0/16"
|
|
- "10.42.0.0/16"
|
|
- "172.16.0.0/12"
|
|
|
|
tool:
|
|
# kind: 'SubChart' or 'HelmChart', if subchart then uncomment Chart.yaml dependency, else comment and use tool library with helm chart template
|
|
kind: 'SubChart'
|
|
repo: https://crowdsecurity.github.io/helm-charts
|
|
chart: crowdsec
|
|
version: 0.20.1
|
|
values: *crowdsec_config
|