Both bouncers reach the LAPI and pull every 10s, and every pull gets a 400:
2a03:4000:28:f6e:...:9a29 "GET /v1/decisions/stream?..." 400 48
2a03:4000:4b:c1e:...:8f85 "GET /v1/decisions/stream?..." 400 48
The body says what it is: "Client sent an HTTP request to an HTTPS server."
Traefik was talking plaintext to a backend that serves TLS only.
serversscheme and serverstransport were on the Ingress. Under the Kubernetes
Ingress provider `traefik.ingress.kubernetes.io/service.*` are SERVICE
annotations; on an Ingress they are silently ignored. Nothing warns, and the
failure surfaces as a 400 that reads like a malformed request rather than a
scheme mismatch. They move to the chart's Service via lapi.service.annotations.
With tls.enabled the LAPI serves HTTPS on 8080 and offers no plaintext port,
so https is mandatory here rather than hardening.
Also switches the ServersTransport from rootCAsSecrets to rootCAs, which is
what Traefik has been warning about on every reconcile:
RootCAsSecrets option is deprecated, please use the RootCA option instead.
Two of my own diagnostics were wrong along the way and both were measurement
artifacts. "Traefik sees no requests" came from a Loki query whose limit was
consumed by those deprecation warnings. And the source address that justified
dropping the IPAllowList was measured on the watchdog, which curls 127.0.0.1;
the bouncer resolves the public name and arrives on the proxy's public
address, as the log lines above show.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The download moved to the controller in the previous fix and now works. The
extraction that followed it does not:
Failed to find handler for "/tmp/crowdsec-firewall-bouncer-v0.0.36.tgz".
Command "/bin/tar" detected as tar type None. GNU tar required.
The ci-ansible image ships a tar that ansible's unarchive rejects. Both host
distributions have GNU tar, and only the download ever needed to move — the
v6-only problem was reaching github.com, not opening a tarball.
So the controller now ships the archive rather than the unpacked binary, and
the host extracts it. That also keeps the artefact the checksum was verified
against intact all the way to its destination, instead of verifying an archive
and then copying something extracted from it.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
First candidate to be carried through to an end-to-end measurement. The
embedding comparison on 400 real archive documents puts bge-m3 level with the
deployed Qwen3-Embedding-0.6B where it matters and ahead everywhere else:
correspondent 74.0% vs 75.0% (ceiling 82.5%, so 90% vs 91% of achievable)
document type 70.0% vs 68.2%
time 147s vs 380s for 400 documents
peak memory 1.6 GiB vs 10.6 GiB
Same 1024 dimensions, so nothing downstream changes shape.
Note the pooling type differs — bge-m3 wants CLS where the Qwen family wants
last-token. Read from the model's own 1_Pooling/config.json rather than assumed;
across the candidates measured, three different pooling types were required, and
a wrong one produces plausible but untrained vectors with no error anywhere.
The memory limit is now measured rather than estimated. It also supersedes #745,
which raised the limit for the model being replaced: the footprint is dominated
by four slots at 4096 context plus the Vulkan working set, not by the weights —
which is why several candidates were OOMKilled at limits that looked generous
against their model size.
This is not a final answer. Every candidate has to go through the end-to-end
test (scripts/paperless-eval.sh) before the embedding choice means anything,
because nothing has yet verified that the retrieval metric predicts what
Paperless actually suggests. bge-m3 is simply the one to start with.
Changing paperless-config is also what lets that test run at all: the AI
settings from #739 have never reached the running pod, which predates the
Reloader annotation from #741. This edit gives Reloader something real to react
to, rather than forcing a restart by hand or inventing a change to trigger one.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The deploy failed on proxy-1:
Request failed: <urlopen error [Errno 101] Network is unreachable>
url: https://github.com/.../crowdsec-firewall-bouncer-linux-amd64.tgz
proxy-1 is IPv6-only, and neither github.com nor
objects.githubusercontent.com publishes an AAAA record. The host cannot reach
GitHub at all, so no retry or timeout would have helped.
Two alternatives do not work either. Mirroring into gitea.renner.uno is out:
its public records are the internal LB VIP (10.2.99.86 / fd99::86), so it is
unreachable from outside the LAN. And there is no upstream container image for
this bouncer, which is expected of something that manipulates host netfilter —
crowdsecurity publishes cloudflare, fastly, custom and others, but no firewall
bouncer.
So the controller fetches and pushes instead of the host pulling. The CI runner
has v4. The checksum is still verified, now before anything reaches a host,
which is the better place for it anyway.
The repo had told me twice that proxy-1 is the v6-only member — in
unifi_nat_hairpin.tf and in the netbird-proxy role's dhcpcd comment — and I
wrote it into the PR description myself. I never asked whether a v6-only host
can reach GitHub.
Nothing was deployed before this: the play runs serial: 1, proxy-1 went first
and failed, so proxy-2 never started.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The embedding model was picked from a recommendation and never compared. MTEB's
German retrieval results put the deployed Qwen3-Embedding-0.6B well down the
field, so a dozen candidates are being measured against the real archive with
scripts/embed-eval-real.sh — and they will not fit in 40Gi alongside the two
deployed models.
Growing the shared cache rather than using a scratch volume is deliberate: on a
slow connection the download is the long pole, and a shared cache lets the large
candidates pull in the background while the small ones are already being
measured. It also means nothing is fetched twice across runs, and a candidate
that wins is already local when it is promoted.
120Gi against 309 GiB currently free in cephfs-data0. CephFS has
allowVolumeExpansion, so this grows online without disturbing the running pods.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-02 11:10:04 +02:00
6 changed files with 94 additions and 22 deletions
# are SERVICE annotations — on an Ingress they are silently ignored, and
# Traefik then talks plaintext to a TLS-only backend. They live on the
# chart's Service instead, via lapi.service.annotations in helmrelease.yaml.
spec:
ingressClassName:traefik
rules:
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.