Deploy on Kubernetes¶
Install a three-node Narad cluster on Kubernetes with the Helm chart, then check that it answers.
Before you start: a Kubernetes cluster with a default storage class, kubectl, Helm 3 or later, git and openssl.
Decide before you install¶
Three choices are cheap before the install and costly after it: the disk size, the Raft transport and the founding cluster size. Keep them, and the rest of your settings, in a values file. This one covers the choices most production clusters make:
replicaCount: 3
initialClusterSize: 3 # set once, at the first install
image:
tag: v3.2.2 # pin a release
persistence:
size: 50Gi # per pod; fixed once installed
narad:
defaultRetentionAgeMs: 604800000 # 7 days; the chart's default is 12 hours
config: # rendered to the --config JSON file
storage:
codec: zstd # compression is off by default
compression_level: fastest
security:
clusterTLS:
enabled: true # needs the narad-cluster-tls secret
allowPlaintextRaft: false
resources:
limits:
memory: 2Gi
extraEnv:
GOMEMLIMIT: 1800MiB # about 90% of the memory limit
Save it as narad-values.yaml in the clone you make under Install, or pass its path to -f.
persistence.sizeis the volume of each pod. The StatefulSet fixes it once installed, and ahelm upgradethat changes it fails. Size it with Capacity and disk sizing.narad.defaultRetentionAgeMsis the retention of a topic created withoutretention_ms. The chart's default is 12 hours and the binary's is 7 days. Retention deletes unacked messages too, so pick a value longer than your longest consumer outage.- Raft TLS. For production, keep
security.clusterTLS.enabled: trueandsecurity.allowPlaintextRaft: falsein the file, and create the TLS secret in Install step 2. Turning TLS on later needs a pause of topic and user changes (Enable on a running cluster). initialClusterSizeis the set of pods allowed to create a new cluster. Pods beyond it join the existing one. It is read only on an empty disk, so set it at the first install and leave it.codec: zstdturns on compression of stored messages. Measure the saving on your own payloads; already compressed payloads gain little.GOMEMLIMITgives the Go runtime a soft memory limit, so it collects garbage harder before the pod reaches its memory limit. From v3.1.0, Narad sets it to 90% of the pod's memory limit on its own when it is unset.
Every value, with its default, is in the Helm values reference.
Install¶
The chart lives in the repository, so the install starts from a clone of the release you mean to run.
narad: TLS ends at your ingress, clients reach the pods through the Service narad on 7942/tcp, and the pods reach each other directly on 7942/udp and 7943/tcp. Each pod keeps its own volume, data-narad-0 for narad-0 and so on.-
Get the chart and create a namespace:
git clone --branch v3.2.2 --depth 1 \ https://github.com/DebanganThakuria/narad cd narad kubectl create namespace narad -
Create the security secret. The chart reads a secret named
<release>-security, so for a release callednaradit isnarad-security:kubectl create secret generic narad-security -n narad \ --from-literal=cluster-secret="$(openssl rand -base64 32)" \ --from-literal=admin-password="$(openssl rand -base64 24)"cluster-secretauthenticates the nodes to each other and is required.admin-passwordbecomes the password of the root user,admin. It is optional: without it, one node generates a password and writes it to a file on its own volume (see Manage users and grants). With Raft TLS on, also create thenarad-cluster-tlssecret now (Create the certificates). -
Install the chart with your values file:
helm install narad ./charts/narad -n narad -f narad-values.yamlFor a trial, skip the file and set the few values that matter on the command line. This runs the Raft port without TLS, fenced to the Narad pods by the chart's NetworkPolicy, which is on by default:
helm install narad ./charts/narad -n narad \ --set replicaCount=3 \ --set persistence.size=50Gi \ --set image.tag=v3.2.2The policy holds only on a CNI that enforces NetworkPolicy (Fence the cluster ports). Turn it off (
networkPolicy.enabled=false) without TLS orsecurity.allowPlaintextRaft, and the v3.1.0 chart refuses to install and names the alternatives; the v3.0.1 chart has no policy, ignoresnetworkPolicy.enabledand runs the Raft port unfenced.Pin
image.tagto a release either way. The chart's default islatest, which followsmaster. -
Wait for the rollout:
kubectl rollout status statefulset/narad -n naradA pod reports ready once it has finished starting, is in contact with the Raft leader and has caught up with it. The rollout is done when all three pods are ready.
Work through the Production checklist before the cluster takes real traffic.
Verify¶
Forward the API port to your machine and keep the command running:
kubectl port-forward -n narad svc/narad 7942:7942
In a second terminal, read the admin password from the secret and call the cluster:
export NARAD=http://127.0.0.1:7942
export AUTH="admin:$(kubectl get secret narad-security -n narad \
-o jsonpath='{.data.admin-password}' | base64 -d)"
curl -s "$NARAD/readyz"
curl -s -u "$AUTH" "$NARAD/v1/topics"
{"status":"ready"}
{"next_page_token":"","topics":[]}
$NARADis the base URL of any node or of the load balancer in front of them.$AUTHisusername:passwordfor a user with the grant the request needs. Here it is the root admin.
/readyz needs no credentials, and the topic list is empty on a new cluster. Next, create a user for each service (Manage users and grants) and point clients at the cluster (Connect and authenticate).
Verify the image¶
New in v3.1.0.
Images are signed keyless with cosign and carry an SBOM and build provenance. Signing starts with the first image built after the v3.0.1 release. Images up to and including v3.0.1 carry no signature, so the command below fails for them.
IDENTITY='^https://github\.com/DebanganThakuria/narad/'
IDENTITY+='\.github/workflows/container\.yml@refs/(heads/master|tags/v.*)$'
cosign verify ghcr.io/debanganthakuria/narad:v3.2.2 \
--certificate-identity-regexp "$IDENTITY" \
--certificate-oidc-issuer https://token.actions.githubusercontent.com
The identity is pinned to one workflow file, on master or on a release tag. Matching the repository alone would accept a signature from any workflow on any branch.
Change values later¶
Edit the values file and upgrade:
helm upgrade narad ./charts/narad -n narad -f narad-values.yaml
Adding or removing narad.config as a whole changes the pods, so Helm rolls them. A change inside it only rewrites the ConfigMap, and a pod reads its config file only when it starts, so restart the pods after one:
kubectl rollout restart statefulset/narad -n narad
Next steps¶
- Production checklist: secure and size the cluster before it takes real traffic.
- Monitor and alert: scrape the metrics and set up the seven alerts.
- Helm values reference: look up every chart value and the ports and probes.