Skip to content

Kubernetes

The Helm chart runs a headless kabactl node as a Deployment with a persistent volume. A chart is published to the Forgejo helm registry for every release.

Terminal window
helm repo add kaba https://git.djcas9.com/api/packages/kaba-labs/helm
helm repo update
helm upgrade --install kabactl kaba/kabactl \
--namespace kaba --create-namespace \
--version 0.87.5

Adding the repo with credentials, pinning versions, upgrading and uninstalling are covered under install & quick start. To install from a checkout instead, use the chart at deploy/helm/kabactl.

The image reference is assembled as <registry>/<repository>/<name>:<tag>, by default git.djcas9.com/kaba-labs/kabactl/kabactl; image.tag defaults to the chart’s app version.

Reach it from your machine:

Terminal window
kubectl -n kaba port-forward svc/kabactl 28832:28832
curl -k https://localhost:28832/health
kubectl -n kaba logs -l app.kubernetes.io/instance=kabactl -f
ResourceNotes
DeploymentOne replica, Recreate strategy.
PersistentVolumeClaim20 Gi, ReadWriteOnce, mounted at /home/kaba/.config.
ServiceClusterIP on port 28832.
ServiceAccount
ConfigMapOnly when config is set.
SecretOnly when jwtSecret is set.
CertificateOnly with cert-manager enabled.
Ingress, HorizontalPodAutoscalerOff by default.

The pod runs as UID and GID 10001, non-root, with all capabilities dropped, no privilege escalation and the runtime’s default seccomp profile.

ValueDefaultDescription
image.registry, image.repository, image.name, image.tagImage reference.
image.pullPolicyIfNotPresent
imagePullSecrets[]For a private registry.
args[]Overrides the container’s default server command arguments.
env, envFrom[]Extra environment.
config""Inline config.toml. See below.
service.type, service.portClusterIP, 28832
service.proxyEnabled, service.proxyPortfalse, 28833Also expose the SOCKS5 proxy.
ingress.*disabledStandard ingress settings.
persistence.enabledtruefalse uses an emptyDir and loses all data on restart.
persistence.size, storageClass, accessModes, existingClaim20Gi
resources200m / 512Mi requests, 2 CPU / 4Gi limitsRaise the memory limit for inference.
certs.*See certificates.
livenessProbe, readinessProbe, startupProbeTCP on the API portThe startup probe allows 5 minutes.
nodeSelector, tolerations, affinity, priorityClassNameScheduling.
terminationGracePeriodSeconds30

Set config to supply a whole config.toml:

config: |
jwt_exp_time = 28800
jwt_secret = "change-me"
cert_path = "/home/kaba/.config/kaba/certs/kaba.cert"
key_path = "/home/kaba/.config/kaba/certs/kaba.key"
tls = true
cert_format_version = 1
[memory_options]
memory_version_limit = 100
memory_optimization_interval = 60
[adblock_options]
enabled = true
blocklist_urls = ["https://easylist.to/easylist/easylist.txt"]
[cluster_options]
relays = ["https://relay.example.com"]

The file is mounted read-only over /home/kaba/.config/kaba/config.toml, and the pod restarts when it changes. Leave config empty and kabactl writes its own defaults onto the volume. All keys are described in the config reference.

By default kabactl generates a self-signed certificate on the volume. The chart offers two alternatives.

cert-manager

certs:
create: true
useCertManager: true
issuerRef:
name: letsencrypt-prod
kind: ClusterIssuer
commonName: kabactl.example.com
dnsNames:
- kabactl.example.com

This creates a Certificate, and mounts the resulting tls.crt and tls.key at the paths kabactl expects.

An existing Secret

certs:
existingSecret: my-kabactl-tls
fileNames:
cert: kaba.cert
key: kaba.key
trustBundle: trust-bundle.pem

The Secret must contain all three named keys. The trust bundle is a file the desktop client builds for its own use; kabactl does not need it, so it can be a copy of the certificate.

See certs for the format and for cert_format_version.

kabactl serves HTTPS, so an ingress in front of it must speak HTTPS to the back end. With ingress-nginx:

ingress:
enabled: true
className: nginx
annotations:
nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
hosts:
- host: kabactl.example.com
paths:
- path: /
pathType: Prefix

Exposing the API publicly is rarely necessary. Other devices reach this node through the mesh, not through the ingress.

Terminal window
kubectl -n kaba exec deploy/kabactl -- kabactl cluster join kaba_invite_…
kubectl -n kaba rollout restart deploy/kabactl

Or create an invite on this node for other devices to use:

Terminal window
kubectl -n kaba exec deploy/kabactl -- kabactl cluster invite --name laptop

Request the GPU resource and schedule onto GPU nodes with the usual Kubernetes mechanisms, and use an image built with the matching back end:

resources:
limits:
nvidia.com/gpu: 1
memory: 16Gi
nodeSelector:
nvidia.com/gpu.present: "true"

From the kabactl repository:

Terminal window
make helm-lint
make helm-template
make helm-package # stamps the chart with the current version
make helm-push # pushes the chart to the registry