-
v0.1.0 Stable
released this
2026-09-29 14:37:36 +00:00 | 59 commits to main since this releaseAdded
- Deleting the
NatsReferenceGrantthat admits aNatsCluster's leaf remote to itsNatsConnectiondrops that remote from the rendered leafnodes config and its credentials from<name>-leaf-remotes, the other remotes kept, andLeafnodesConnectedreads False with the refusal naming the remote; restoring the grant renders it back. - Deleting the
NatsReferenceGrantthat admits aNatsAccountto itsNatsOperatordeletes the account's JWT from the servers and empties itsstatus.jwt, and itsNatsUsers readReadyFalse, reasonAccountNotAdmitted, and are not signed; restoring the grant signs both again. - Licensed under Apache-2.0; the chart carries
artifacthub.io/license: Apache-2.0. SECURITY.mdstates how to report a vulnerability through the repository's GitHub private vulnerability reporting, the acknowledgement time for a report, the supported versions, the trust boundaries between namespaces, and how to verify a release's signatures and provenance.- Each release's controller images and chart are signed keylessly with cosign and carry a GitHub build provenance attestation.
- The cluster controller caches only the StatefulSets, ConfigMaps, Services, PersistentVolumeClaims, PodDisruptionBudgets and NetworkPolicies labelled
cluster.nats.mikluko.io/cluster; every controller lists and watches only the metadata of Secrets and reads their data from the API server. - A controller's
/readyzpasses once it has listed and watched everything it reconciles from, on every replica, elected or not. - Every controller's OpenTelemetry resource carries its host name as
service.instance.id, unlessOTEL_RESOURCE_ATTRIBUTESsets one. - Every controller logs its release version at startup and carries it as
service.versionof its OpenTelemetry resource. - Every controller serves its Prometheus metrics over HTTPS, to a bearer token of a user allowed
geton the non-resource URL/metrics; an allow is cached for five minutes and a denial for thirty seconds. - Chart value
metrics.scraper.serviceAccount, thenamespace/nameof a ServiceAccount grantedgeton/metrics. - Chart value
metrics.prometheus.enabledserves each controller's OpenTelemetry metrics on port9464over plain HTTP, through the metrics Service and ServiceMonitor. - Chart value
metrics.tls.secretNamehas every controller serve its metrics under the certificate in that Secret, through the flag--metrics-cert-dir, and each ServiceMonitor verify it against the Secret'sca.crtormetrics.serviceMonitor.caSecret. - Chart value
metrics.serviceMonitor.authorization.credentialshas each ServiceMonitor scrape with the bearer token in a Secret key, asauthorization, in place ofbearerTokenFile. - Chart values
networkPolicy.enabledandnetworkPolicy.fromrender a NetworkPolicy over each controller's pods admitting its metrics ports8080and9464only fromnetworkPolicy.from. - Chart value
networkPolicy.egressadds egress rules to each controller's NetworkPolicy, which then admits no other egress; it requiresnetworkPolicy.enabled. helm teston the chart checks every enabled controller's/readyz.- A failed
NatsClusterreconcile readsProgressing=False, reason: ReconcileFailedand records aReconcileFailedWarning event. - The cluster controller leaves untouched any object of a name it renders that it does not control, and the
NatsClusterreadsReady=False, reason: ReconcileFailednaming each one. - Removing a
NatsClusterserver deletes its data volume claim only when the claim carries the server's labels, and its ConfigMap only when theNatsClustercontrols it; theNatsClusterreadsReady=False, reason: ReconcileFailednaming each one left. NatsClusterstatus.versionmoves only once every serverreplicasplans reports the new version; a server being removed does not count.NatsClusterstatus.removalsnames each server being removed or replaced, its phase and since when; a replaced server is recreated only once its old volume claim is gone.- CRDs for every kind at
v1beta1, underconfig/crd/, in the API groupsnats.mikluko.io,cluster.nats.mikluko.io,auth.nats.mikluko.ioandjetstream.nats.mikluko.io. - The API server refuses mutually exclusive fields set together, a
NatsClusterversion below 2.15.0 or a move of more than one minor, and changes nats-server would refuse to the immutable fields of JetStream objects. - Helm chart
charts/nats-operatorinstalling the CRDs and any subset of the three controllers, each with its own ServiceAccount and a ClusterRole holding only the verbs it uses. - The chart requires Kubernetes 1.33 or later.
- The chart refuses to render a controller with more than one replica while
leaderElection.enabledis false. - The chart sets each controller's
GOMEMLIMITto 90% of its memory limit, where one is set, unlessenvnames it, and refuses a memory limit other than an integer with an optionalk,M,G,T,Ki,Mi,GiorTisuffix. - The chart names each controller's leader election lease
<release>-<API group>. - The chart refuses an
extraArgsentry, global or per controller, setting--leader-elector--leader-election-id. - Each controller's leader election Role grants creating Leases, and getting, updating and patching only its own lease.
- The chart refuses to render a Service whose name is longer than 63 characters.
- The chart refuses a value key it does not know, checked against
values.schema.json. - Chart values
nodeSelector,annotations,podAnnotationsandaffinity, globally and per controller. - Chart values
tolerations,priorityClassName,topologySpreadConstraints,extraArgsandenv, globally and per controller. - Chart values
metrics.service.enabledandmetrics.serviceMonitor.enabled, off by default, render a metrics Service and a prometheus-operator ServiceMonitor per controller; the ServiceMonitor skips certificate verification. - Chart value
auth.systemConnection, passed to the auth controller as--system-connection. - A
NatsClusterwith a gateway withouttlsisReadyFalse, reasonGatewayWithoutTLS, and nothing is rendered for it, unless the cluster controller runs with--allow-gateway-without-tls. - Chart value
cluster.allowGatewayWithoutTLS, off by default, passes--allow-gateway-without-tlsto the cluster controller. - Every controller's
--watch-namespacesconfines it to the namespaces named; chart valuewatchNamespacespasses it and grants each controller a Role in each of those namespaces, its ClusterRole keeping onlytokenreviewsandsubjectaccessreviews. - Chart values
cluster.image.digest,auth.image.digestandjetstream.image.digestpin a controller's image by digest after its tag while that tag is the chart'sappVersion;tests.image.digestpins thehelm testimage after its tag. - Chart value
tests.image.digestdefaults to the digest ofbusybox:1.37.0. - Each release's chart sets
cluster.image.digest,auth.image.digestandjetstream.image.digestto the digests of the images released with it. NatsClusterspec.imagetakesrepositoryanddigest, andspec.exporter.imagetakesrepository,taganddigest; a digest is rendered after the tag.- A
NatsCluster's servers prefer distinct nodes, unlessspec.podTemplatesetsaffinity. - The exporter sidecar requests 10m CPU and 32Mi memory and is limited to 100m CPU and 128Mi memory;
NatsClusterspec.exporter.resourcesreplaces both. - The exporter sidecar's default image is pinned by digest.
- A controller releases its leader-election lease as it shuts down.
- Each release publishes the three controller images for linux/amd64 and linux/arm64, the chart as an OCI artifact, and a GitHub release carrying the version's changelog entry.
- Documentation site at https://mikluko.github.io/nats-operator/, of the latest release: the stories, the design and the ADRs.
- Documentation page
/docs/install/: installing the chart, its values, the controllers' flags and RBAC, upgrade and uninstall. - Documentation page
/docs/reference/api/: every kind, field and enum value of the four API groups. - Documentation page
/docs/reference/nats-permissions/: the nats-server subjects each controller requests and the presets that grant them. - Documentation page
/docs/reference/telemetry/: the controllers' OpenTelemetry configuration, instruments, spans and Kubernetes events. - The auth controller exports
nats_operator.account.jwt_expiry, when eachNatsAccount's current JWT expires. - Each controller exports OpenTelemetry metrics and traces once the SDK's environment names an exporter or endpoint.
- The 0/1 gauges
nats_operator.conditionandnats_operator.rollout.gatecarry no unit, and Prometheus reads them asnats_operator_conditionandnats_operator_rollout_gate. - The controllers record Kubernetes events for balancer moves, evacuations, rollout steps, JWT pushes and user kicks.
- The cluster controller deploys a
NatsClusteras one StatefulSet and ConfigMap per server, with Services, a PodDisruptionBudget, route TLS and aprometheus-nats-exportersidecar. NatsClusterrolls a restart-only change one server at a time, each step gated on the NATS cluster being Settled.spec.rollout.pausedholds aNatsClusterrollout, and the annotationcluster.nats.mikluko.io/force-steprestarts one waiting server at once.- Servers render
lame_duck_duration: 2mandlame_duck_grace_period: 10s. NatsClusterstatus.config.restartReasonnames what makes a spec change restart-only.- A
NatsClusterwithauthrenders its trust roots and account resolver from theNatsOperatorTrustthatauth.trustRefnames. - With
auth.systemCredentialsthe cluster controller reloads servers over$SYS; without it every config change restarts. - A self-signed route certificate is valid for one year and renewed under the same CA once a third of that remains; the CA is kept in the Secret
<name>-routes-ca. - A
NatsCluster's client Service serves only the client port; the monitoring port is on the headless Service, whichstatus.endpoints.monitornames. - A
NatsClusterrenders a NetworkPolicy admitting its route port only from its own pods, its monitoring port only from the cluster controller's namespace, and its metrics port from there and the peersspec.exporter.fromnames;monitor.networkPolicy: falserenders none. NatsClusterspec.exporter.from, the NetworkPolicy peers admitted to the metrics port.- A
NatsCluster's pods meet the restricted Pod Security Standard and mount no ServiceAccount token;podTemplatecan still escalate what the pod runs. - A change to the trusted NATS operator,
system_accountor the resolver restarts servers one at a time; a re-signed system account JWT reloads them. NatsClustertlsputs the client listener under TLS, from a Secret or cert-manager, andstatus.endpoints.clientthen readstls://.NatsClustergatewayjoins a supercluster, and status reportsGatewaysConnected.- Gateway TLS requires
ca.crtin the certificate Secret and verifies peers both ways against it. NatsClusterleafnodesaccepts leaf connections on port 7422, and is refused at apply withoutauth.NatsClusterleafRemotesdials hubs as a leaf throughNatsConnections, and status reportsLeafnodesConnected.- A renewed route, gateway or leafnode certificate reaches running servers by reload.
- The cluster controller deletes a cert-manager
Certificateit created once its listener no longer names it. - The
cluster-controlleruser preset may request$SYS.REQ.SERVER.PING.GATEWAYZand$SYS.REQ.SERVER.PING.LEAFZ. - Lowering
NatsClusterreplicasevacuates and removes servers one at a time. - A change to
jetstream.volumeClaimTemplate, or the annotationcluster.nats.mikluko.io/replace-server, replaces servers one at a time under the same name. - Deleting a
NatsClusterwaits while its NATS cluster holds JetStream data, unless annotatedcluster.nats.mikluko.io/force-delete. - The auth controller signs
NatsOperator,NatsSystemAccountandNatsAccountJWTs from adopted or generated keys. NatsAccountjwtTTL: 0ssigns a JWT that never expires.NatsAccountimports carry activation tokens for private exports, and cross namespaces only where aNatsReferenceGrantadmits them.- A
NatsAccountimport from an account under anotherNatsOperatoris left out, withReadyFalse, reasonImportsUnresolved. - The
NatsOperatorconditionRetiringKeysInUsesays when aretiringsigning key can be removed. - The auth controller signs
NatsUsers into creds Secrets, or intostatus.jwtfor a user withpublicKey. NatsUserspec.accountRefcannot change once set.- A
NatsUserwhoseNatsReferenceGrantis deleted is revoked and loses the creds Secret it owns; restoring the grant signs it under a fresh key. - Deleting a
NatsUserrevokes it and, with--system-connectionset, closes its connections before its creds Secret is removed, unless its account or the account'sNatsOperatorno longer exists. --system-connectionon the auth controller pushes account JWTs to the servers, andstatus.distributionreports how many hold the current one.- Deleting a
NatsAccountdeletes it from the servers' resolvers, also on servers that join later. NatsAccountandNatsSystemAccountstatus.revocationslist the user keys the account revokes.- An account whose status lost its JWT and revocations recovers them from the servers before it is signed again.
- The JetStream controller creates, adopts, updates and deletes the streams and consumers
NatsStreamandNatsConsumerdeclare, and corrects drift every--resync-period. NatsStreamstatus.transferreports a move to another NATS cluster while it runs.- Deleting a JetStream resource whose
NatsConnectionis gone or no longer admitted leaves its server object. - The JetStream controller manages the key-value buckets and object stores
NatsKeyValueandNatsObjectStoredeclare. NatsStream,NatsConsumer,NatsKeyValueandNatsObjectStorespec.connectionRef, andNatsConsumerspec.streamandspec.streamRef, cannot change after creation.- A
NatsObjectStorewhose streamOBJ_<bucket>exists without the object store's subjects or rollups goes Terminal, reasonNotABucket, and the stream is left untouched. - A JetStream object the servers refuse as invalid goes Terminal; one they cannot place is retried.
NatsSystemBalancerevens leaders, and optionally copies, across the servers of one NATS cluster over every account.- A
NatsSystemBalancerwithmoves.leader: falseprobes no account'sjetstream-stepdownexport and leavesstatus.capabilities.leaderunset. NatsBalancerevens leaders, and optionally copies, within pools of one account's streams.NatsClusterEvacuationmoves every JetStream object whose resource sets noplacement.clusteroff one NATS cluster to servers carrying the target tags.NatsClusterEvacuationspec.connectionRef,spec.fromandspec.tocannot change after creation.NatsClusterEvacuationstatus.remainingcounts the streams still to leave the source NATS cluster.- A
NatsStreamwhose stream matches spec but whose transfer or consumers cannot be read readsReadyFalse, reasonObserveFailed, and is retried with backoff. - The API server refuses a
NatsBalancerorNatsSystemBalancerintervalthat is not positive. - A
NatsAccountorNatsUserwhosepublicKeyanother account or user under the sameNatsOperatorholds readsReadyFalse, reasonPublicKeyInUse. - A
NatsAccountwhose key is the identity of theNatsSystemAccountitsNatsOperatorreferences, as that account's status,publicKeyor identity seed Secret gives it, readsReadyFalse, reasonPublicKeyInUse. NatsAccountandNatsSystemAccountstatus.distribution.lastPushTimeis set only by a push a server acknowledged.- Generated seed Secrets are named
<name>-<operator|systemaccount|account>-<identity|signing-1>and annotatedauth.nats.mikluko.io/generated-for; one not annotated for the object readsReadyFalse, reasonSecretConflict. - Generated seed Secrets carry no owner reference: they stay when their object is deleted, and an object of the same kind and name applied again takes the same keys.
- A generated identity Secret lost after
status.publicKeyrecorded its key readsReadyFalse, reasonSeedLost, and no new identity is minted. - A key a
NatsUserstops holding is revoked in its account and listed instatus.replacedKeysuntil the account JWT carries the revocation. - A
NatsUserwhosepublicKeychanges to a key it is refused revokes the key it held. - A
NatsAccountnoNatsReferenceGranthas yet admitted to itsNatsOperatorrecords nostatus.publicKey, and only theNatsSystemAccountaNatsOperatorreferences holds a key against its accounts. - Revocation recovery reads the servers' JWT only when every server of the roster answers.
- A server stays in the auth controller's roster until it misses three STATSZ polls in a row, counted in
status.distributionand awaited by revocation recovery and user deletion. - A
NatsAccount,NatsSystemAccountorNatsUserreadsDistributedFalse, reasonNoSystemConnection, while the auth controller runs without--system-connection. - An auth object whose reconcile fails reads
ReadyFalse, reasonReconcileError, and keepsstatus.observedGenerationat the generation last reconciled in full. NatsClusterEvacuationmakes no move while any server of its NATS system is down or the meta group has no leader, reportingReadyandProgressingFalse with reasonServersDown.- The
NatsSystemBalancerand theNatsBalancers of one NATS cluster move one at a time; while one's move is in flight the others readHolding, reasonMoveLeaseHeld. - A
NatsSystemBalancerorNatsBalancermakes no move while any member of any group in its scope is not current, any server of its NATS cluster does not answer every page of JSZ, or the meta group has no leader. - The
cluster-controller,jetstream-controllerandauth-controllerpresets subscribe only to their own inbox,_INBOX.<preset>.>; a JetStream controller account user whosepermissionsrestrict subscriptions must allow_INBOX.jetstream-controller.>. - The
readonlypreset subscribes only to its own inbox,_INBOX.readonly.>, which its client dials with.
Downloads
-
Source code (ZIP)
0 downloads
-
Source code (TAR.GZ)
0 downloads
- Deleting the