| name | nais-manifest |
| description | NAIS-manifest og applikasjonskonfigurasjon — nais.yaml for Application, Naisjob, ingress, resources, probes, accessPolicy, Azure AD, TokenX, Kafka eller GCP SQL. Brukes via /nais-manifest ved nye eller endrede manifester. |
NAIS-manifest
Bruk denne skillen når du skal lage eller oppdatere et komplett NAIS-manifest (CRD-ene Application og Naisjob).
Fremgangsmåte
- Les eksisterende NAIS-manifester i
.nais/ eller nais/ for å forstå hvordan applikasjonen er satt opp i dag. Bruk eksisterende namespace og labels.team — ikke anta verdier.
- Avklar om applikasjonen er backend (Kotlin) eller frontend (Node.js), siden port, health paths og observability-oppsett kan variere.
- Kartlegg hvilke ressurser applikasjonen trenger: database, Kafka, auth, ingress, scaling — eller om det er en batch-jobb (
Naisjob).
- Gjenbruk eksisterende stier for health, readiness og metrics fra nåværende manifester.
- Bruk miljøspesifikke manifester (
app-dev.yaml, app-prod.yaml) når repoet allerede følger det mønsteret.
Application-mal
apiVersion: nais.io/v1alpha1
kind: Application
metadata:
name: {app-name}
namespace: {team-namespace}
labels:
team: {team-namespace}
spec:
image: {{ image }}
port: 8080
prometheus:
enabled: true
path: /metrics
liveness:
path: /isAlive
initialDelay: 5
readiness:
path: /isReady
initialDelay: 5
resources:
requests:
cpu: 50m
memory: 256Mi
limits:
memory: 512Mi
Viktig: Sjekk alltid eksisterende manifester for korrekt port, prometheus.path, liveness.path og readiness.path.
Regel: ingen CPU-limits i Nais
Sett aldri resources.limits.cpu i Nais-manifest — bare requests.cpu.
Hvorfor: Kubernetes CFS-quota håndhever CPU-limits i 100ms-vinduer. Når en container når grensen kort, blir hele containeren throttlet i resten av vinduet — også tråder som ikke trenger CPU. Resultat: latenshaler, oppstartsproblemer (JIT, GC), og timeouts. Nais-plattformen anbefaler requests.cpu for scheduling og lar noden håndtere faktisk bruk.
Memory-limits derimot skal settes — uten limit kan en container ta ned hele noden via OOM.
Ressursstartpunkter
| Størrelse | requests.cpu | requests.memory | limits.memory |
|---|
| Liten | 15–50m | 256Mi | 512Mi |
| Middels | 100m | 512Mi | 1Gi |
| Stor | 200m | 1Gi | 2Gi |
Juster basert på faktisk forbruk (Grafana). replicas: { min: 2, max: 4, cpuThresholdPercentage: 80 } er greit startpunkt for prod.
accessPolicy — alltid eksplisitt
Definer både inbound og outbound. Glem ikke cluster og namespace for kall utenfor eget namespace:
accessPolicy:
inbound:
rules:
- application: min-frontend
namespace: mitt-team
- application: annen-tjeneste
namespace: annet-team
cluster: prod-gcp
outbound:
rules:
- application: pdl-api
namespace: pdl
- application: downstream-app
namespace: downstream-namespace
external:
- host: api.ekstern-tjeneste.no
Se references/naisjob-example.md for en full Naisjob-mal.
PostgreSQL (GCP SQL)
gcp:
sqlInstances:
- type: POSTGRES_17
tier: db-f1-micro
highAvailability: false
diskAutoresize: false
databases:
- name: myapp-db
envVarPrefix: DB
Gir DB_HOST, DB_PORT, DB_DATABASE, DB_USERNAME, DB_PASSWORD.
HikariCP i containere — pool 3–5, ikke default 10
HikariCP default maximumPoolSize er 10. I Nais-containere er dette feil:
- Containeren har 1–2 CPU-kjerner (
requests.cpu: 100m betyr brøkdel av én kjerne).
- 10 aktive forbindelser gir tråd-kontensjon og kontekstsvitsj-overhead.
- Cloud SQL Proxy og Postgres har egne grenser; mange små poolere × mange replicaer sprenger serveren.
Start med maximumPoolSize: 3–5. Øk bare hvis metrikker viser pool-exhaustion (hikaricp_connections_pending). Se HikariCP About Pool Sizing — formelen connections = ((cores * 2) + effective_spindle_count) gir lave tall i containere.
Kafka
kafka:
pool: nav-dev
Navnekonvensjon for topics: {team}.{domene}.v{versjon}. Dev: partitions: 1, replication: 1. Prod: partitions: 6+, replication: 3.
Azure AD og TokenX
azure:
application:
enabled: true
tenant: nav.no
tokenx:
enabled: true
For ren maskin-til-maskin uten personkontekst: bruk Maskinporten. For partner-integrasjoner som må handle på vegne av en virksomhet i Altinn, bruk Altinn 3 systembruker (Maskinporten + systembruker-token).
Ingress — velg riktig domene
Nav har tre hoveddomener for ingress:
| Domene | Bruk |
|---|
*.nav.no | Publikumsrettede brukerflater (nav.no) |
*.intern.nav.no | Interne ansattflater (krever Nav-nettverk/naisdevice) |
*.ekstern.nav.no | Eksterne brukerflater som ikke ligger på nav.no |
Dev-varianter: *.dev.nav.no, *.intern.dev.nav.no, *.ekstern.dev.nav.no.
ingresses:
- https://min-app.intern.dev.nav.no
Auto-instrumentation (Observability)
observability:
autoInstrumentation:
enabled: true
runtime: java
Tracing sendes til Tempo, logger til Loki (logg til stdout/stderr, gjerne JSON), metrikker til Prometheus.
Pod-lifecycle og graceful shutdown
NAIS injiserer preStop med sleep 5 før SIGTERM, og lastbalansereren slutter å rute trafikk før signalet sendes til appen. Readiness-probes er ikke del av shutdown. Detaljer og anti-mønstre (ingen manuell readiness-toggling, behold terminationGracePeriodSeconds på default 30s): se references/pod-lifecycle.md.
Naisjob — batch-jobber for app-team
Bruk Naisjob når teamet trenger batch-jobber (nattlige kjøringer, engangs-migreringer, rapporter). Samme team-eierskap som Application, men kjører til fullført i stedet for kontinuerlig. Typiske felter: schedule (cron), activeDeadlineSeconds, backoffLimit, og de samme blokkene for resources, accessPolicy, gcp, kafka og azure som Application.
Full mal med Kafka og Azure AD: references/naisjob-example.md.
Boundaries
Always
- Include liveness, readiness, and metrics endpoints (
/isAlive, /isReady, /metrics)
- Set memory limits (prevents OOM)
- Define explicit
accessPolicy (inbound + outbound)
- Use environment-specific manifests (
app-dev.yaml, app-prod.yaml)
Ask first
- Changing production resource requests/replicas
- Adding new GCP resources (cost implications)
- Modifying
accessPolicy in prod
- Adding new ingress domains
Never
- Set
resources.limits.cpu (throttling via CFS-quota)
- Remove
resources.limits.memory
- Store secrets in Git
- Skip health endpoints
- Bruk default HikariCP
maximumPoolSize: 10 i en container