Handleiding

Installeren met Helm

Draai Penweir op Kubernetes met de Helm-chart: secrets, values, installeren, eerste admin, upgrades en rollbacks.

De chart draait dezelfde image als de Docker-route, met dezelfde hardening: non-root (65532), read-only root-bestandssysteem, alle capabilities weg, RuntimeDefault-seccomp en geen service account token. Er draait één replica. High availability is een Enterprise-functie.

Je hebt Kubernetes 1.27 of nieuwer en Helm 3 nodig.

1. Haal de chart op

Download penweir-1.3.0.tgz van de downloadpagina. De chartversie komt overeen met de imageversie.

2. Maak de secrets

De chart maakt zelf nooit secrets aan, zodat er geen geheime waarde in de releasegeschiedenis van Helm belandt. Maak de namespace aan, met Pod Security-niveau restricted, en twee Secrets:

kubectl create namespace penweir
kubectl label namespace penweir pod-security.kubernetes.io/enforce=restricted
kubectl -n penweir create secret generic penweir-master \
  --from-literal=master-key="$(docker run --rm ghcr.io/robinhana04/penweir-app:1.3.0 keygen master)"
kubectl -n penweir create secret generic penweir-providers \
  --from-literal=openai="$OPENAI_API_KEY"

De master key versleutelt opgeslagen provider-keys en two-factor-seeds. Bewaar een kopie in je secret manager: een back-up van de database is nutteloos zonder deze sleutel.

3. Schrijf een values-bestand

Sla dit op als values.yaml. Het wijst de chart naar je Secrets en bevat de Penweir-configuratie:

image:
  tag: "1.3.0"
masterKey:
  existingSecret: penweir-master
secretEnv:
  - {name: OPENAI_API_KEY, secretName: penweir-providers, key: openai}
config:
  version: 1
  providers:
    - name: openai
      type: openai_compatible
      base_url: https://api.openai.com/v1
      api_key: {env: OPENAI_API_KEY}
  models:
    - {name: cloud/default, targets: {openai: gpt-4.1-mini}}
  pipelines:
    - name: default
      default: true
      routing: {allow: [openai]}
      request_steps:
        - {detector: iban, action: tokenize}
        - {detector: email, action: tokenize}
        - {detector: bsn, action: block}

Op Kubernetes is de ConfigMap de bron van waarheid, dus het dashboard toont de configuratie read-only. Pas config in je values aan en draai helm upgrade. De pod herstart met de nieuwe configuratie. Wil je de configuratie in een ConfigMap houden die je zelf beheert, zet dan existingConfigMap.

Alles wat in de database staat werkt nog gewoon vanuit het dashboard: applicaties, keys, admins, opgeslagen secrets en het auditlog.

4. Installeer en maak de eerste admin

helm install penweir ./penweir-1.3.0.tgz -n penweir -f values.yaml --wait
helm test penweir -n penweir
kubectl -n penweir exec -it deploy/penweir -- penweir admin create <je-naam>

Er is geen standaardaccount. Het commando vraagt om een wachtwoord van minimaal 12 tekens.

Open het dashboard via een port-forward:

kubectl -n penweir port-forward svc/penweir-admin 8081:8081

Ga dan naar http://127.0.0.1:8081 en stuur je eerste verzoek. De gateway is svc/penweir op poort 8080.

Values

Value Standaard Betekenis
image.repository, image.tag de appVersion van de chart De image die draait. Pin in productie een digest.
config {version: 1} De inhoud van penweir.yaml.
existingConfigMap leeg Gebruik deze ConfigMap (key penweir.yaml) in plaats van config.
masterKey.existingSecret, .key leeg, master-key De master key voor opgeslagen secrets en TOTP.
secretEnv [] Omgevingsvariabelen uit Secrets, voor api_key: {env: ...}.
database.existingSecret, .key leeg, url Een Secret met een Postgres-URL. Anders SQLite op het volume.
license.existingSecret, .key leeg, license.json Het licentiebestand.
persistence.* aan, 1Gi, ReadWriteOnce Het datavolume. Houd het ook bij Postgres: het bevat de hash key.
ingress.*, adminIngress.* uit Ingresses. Zet daar je TLS op.
networkPolicy.* uit Zie hieronder.
resources 100m / 256Mi request, 1Gi limit Containerresources.
logLevel, auditRetentionDays info, 90 Logniveau en hoelang auditrecords bewaard blijven.

Bereikbaar maken

Maak alleen de gatewaypoort bereikbaar voor applicaties. Houd de adminpoort intern: gebruik kubectl port-forward, of een adminIngress die beperkt is tot je VPN. Zet TLS op de Ingress en stuur Strict-Transport-Security daarvandaan.

Network policy

Met networkPolicy.enabled: true accepteert de pod gatewayverkeer alleen van de peers in ingressFrom (van overal als die leeg is). De adminpoort is dicht, behalve voor de peers in adminIngressFrom; kubectl port-forward blijft werken. De pod verstuurt alleen verkeer naar DNS en naar de regels in egress. Zet je providers daarin om het op clusterniveau af te dwingen:

networkPolicy:
  enabled: true
  ingressFrom:
    - namespaceSelector: {matchLabels: {kubernetes.io/metadata.name: apps}}
  egress:
    - to: [{ipBlock: {cidr: 10.20.0.0/16}}]   # vLLM in het cluster
      ports: [{port: 8000}]

Je CNI moet NetworkPolicy ondersteunen, anders doet het niets. Als ingressFrom gezet is, sta dan ook de testpod van de release toe (app.kubernetes.io/name: penweir-test), anders kan helm test Penweir niet bereiken.

Postgres

kubectl -n penweir create secret generic penweir-db \
  --from-literal=url='postgresql+asyncpg://penweir:<wachtwoord>@postgres:5432/penweir'

Zet database.existingSecret: penweir-db. Penweir migreert het schema bij het starten. De database bevat alleen metadata en configuratie.

Upgraden

  1. Maak een back-up van het datavolume, en van de database als je Postgres gebruikt.
  2. Lees de releasenotes voor wijzigingen in de values.
  3. Draai helm upgrade penweir ./penweir-<nieuwe-versie>.tgz -n penweir -f values.yaml --wait. De Recreate-strategie stopt de oude pod voordat de nieuwe start, zodat twee versies nooit dezelfde database delen. Migraties draaien bij het starten.
  4. Draai helm test penweir -n penweir.

Terugdraaien kan met helm rollback penweir -n penweir. Een migratie die al gedraaid heeft wordt door een rollback niet teruggedraaid. Herstel de back-up als de oude versie het nieuwe schema niet kan lezen.

Verwijderen

helm uninstall penweir -n penweir verwijdert de release. Het datavolume blijft standaard bestaan; verwijder de PersistentVolumeClaim zelf om de data te wissen.