Operator & the NextApp CRD
The Go operator is the single source of truth for cluster state.
knext follows one hard rule: nothing mutates the cluster out-of-band. A single Go operator
watches NextApp resources and reconciles each into a running Knative Service. The CLI only ever
applies the CR — it never touches Knative or infra manifests directly.
kn-next deploy → build · push · emit CR
NextApp CR → applied to the cluster
operator → reconciles desired state
Knative Service → scaled-to-zero, reachableThe NextApp resource
- apiVersion:
apps.kn-next.dev/v1alpha1 - kind:
NextApp
One resource describes the whole deployment. The image field is required and must be
digest-pinned.
apiVersion: apps.kn-next.dev/v1alpha1
kind: NextApp
metadata:
name: storefront
spec:
image: registry/storefront@sha256:9f1c... # required, digest-pinned
scaling:
minScale: 0
maxScale: 20
containerConcurrency: 100
cache:
enableBytecodeCache: true # mount a PVC, set NODE_COMPILE_CACHE
storage:
provider: gcs
bucket: storefront-assets
security:
networkPolicy: {} # default-on internal-only isolation
status:
url: https://storefront.apps.example.com
conditions: [] # Available / Progressing / DegradedSpec fields (selected)
| Field | Notes |
|---|---|
image | Required. Container image — must be digest-pinned (@sha256:). |
scaling | minScale, maxScale, containerConcurrency. |
resources | cpuRequest, memoryRequest, cpuLimit, memoryLimit. |
storage | provider, bucket, region, endpoint. |
cache | provider, url, enableBytecodeCache, bytecodeCacheSize, keyPrefix. |
revalidation | queue, kafkaBrokerUrl, provisionKafkaSource — async ISR revalidation (see below). |
secrets | envFrom, envMap (Kubernetes Secret refs). |
runtime | bun or node (default node). |
security | networkPolicy — pod-level L3/L4 isolation, default-on. |
traffic | revisionName, canaryPercent (rollback / canary). |
buildId | Next.js BUILD_ID, stamped as label apps.kn-next.dev/build-id (skew protection). |
Status fields
| Field | Notes |
|---|---|
url | The resolved Knative Service URL. |
conditions | Standard K8s conditions (e.g. Available, Progressing, Degraded). |
currentTraffic | Mirror of the ksvc traffic split. |
ISR revalidation & the Kafka queue
knext's ISR / data cache is Redis (cache.provider: redis). revalidateTag() and
revalidatePath() write through the Redis-backed cache handler, and because the Redis keys are
shared across every pod, an invalidation is fleet-wide — one pod's revalidateTag is seen by
all of them. This is the default path and requires no queue.
The spec.revalidation block opts into running revalidation asynchronously over a queue, so
regeneration does not block the user's request:
spec:
revalidation:
queue: kafka
kafkaBrokerUrl: kafka-cluster-kafka-bootstrap.kafka.svc:9092
provisionKafkaSource: true # explicit opt-in; default is NOT provisionedWhen queue: kafka and provisionKafkaSource: true, the operator provisions a Knative
KafkaSource that consumes the <app>-revalidation topic and routes events to an
<app>-revalidator consumer.
Honest scope. This is not a turnkey feature. By default provisionKafkaSource is unset, so
no KafkaSource is provisioned — the <app>-revalidator consumer that events would sink into
is not yet shipped by knext. Setting provisionKafkaSource: true is an assertion that you have
deployed your own external consumer for the <app>-revalidation topic. If you enable queue: kafka
without opting in, the operator records a non-fatal RevalidationDeferred status condition (Ready
stays True) and provisions nothing.
Security defaults
The operator is also the policy boundary:
- Digest pinning is enforced. A CR whose
imageis:latest, tag-only, or untagged is rejected (Degraded/ reasonInvalidImage) and never deployed. The validator accepts a ref only if it contains@sha256:. - Mutating endpoints require auth. App-level cache-invalidation routes require a signed bearer token; nothing mutating is open by default.
- Default-on NetworkPolicy.
spec.security.networkPolicyreconciles an internal-only network policy for the app. - Cluster-local backends (design-stage). The planned gRPC backend layer is
cluster-localwith no public ingress — designed, not yet shipped.
Because only the operator mutates cluster state, your Git history of NextApp resources is the
deployment history — auditable, reproducible, portable across clouds.