Sicra Header Logo
  • Karriere
  • Om oss
  • Folk
NorskEnglish
Kontakt oss
  1. Kunnskap
  2. Innsikter
  3. Blogg
Blogg
31.12.2025
min tid å lese

[Min reise mot CCIE Automation #10] Fra Docker Compose til Kubernetes

I blogg #10 i serien Min reise mot CCIE Automation tar jeg steget fra Docker Compose til Kubernetes. Med utgangspunkt i Nautix-plattformen viser jeg hvordan deler av løsningen kan migreres til et lokalt Kubernetes-oppsett ved hjelp av kind, og hvordan dette dekker kravene i CCIE Automation Blueprint 4.3 – fra deklarative utrullinger og secrets-håndtering til ingress, helsesjekker og livssyklusstyring.

<span id="hs_cos_wrapper_name" class="hs_cos_wrapper hs_cos_wrapper_meta_field hs_cos_wrapper_type_text" style="" data-hs-cos-general-type="meta_field" data-hs-cos-type="text" >[Min reise mot CCIE Automation #10] Fra Docker Compose til Kubernetes</span>
bilde
Bjørnar LintvedtSenior Network Engineer

Senior Network Engineer med fokus på nettverk, sikkerhet og automasjon.

(Denne artikkelen var tidligere en del av Bluetree.no. Siden Sicra og Bluetree har slått seg sammen, er nå innhold fra Bluetree overført til Sicra.)

[Min reise mot CCIE Automation #10] Fra Docker Compose til Kubernetes er del av en serie som dokumenterer min reise mot CCIE Automation. I forrige innlegg fokuserte jeg på sikker kodepraksis i Python. I dette innlegget tar jeg neste steg ved å migrere deler av plattformen fra Docker Compose til Kubernetes.

Blogg #10

Frem til nå har Nautix kjørt ved hjelp av Docker Compose. Det fungerte godt i de tidlige fasene, men for Blueprint 4.3 – Package and deploy a solution by using Kubernetes, var det på tide å ta neste steg.

I dette innlegget viser jeg hvordan jeg migrerte deler av Nautix til Kubernetes, kjørt lokalt på utviklingslaptopen min, og hvordan dette mapper direkte til CCIE Automation blueprinten.

Hvorfor Kubernetes?

Docker Compose er utmerket for lokal utvikling, men Kubernetes gir deg:

  • Deklarative utrullinger

  • Innebygd helsesjekk og selvreparasjon

  • Innebygd håndtering av secrets og konfigurasjon

    Service discovery og lastbalansering

  • En konsistent operasjonell modell på tvers av miljøer

Lokalt Kubernetes-oppsett med kind

For lokal utvikling valgte jeg kind (Kubernetes IN Docker).

Hvorfor kind?

  • Lettvekts og rask

  • Kjører fullstendig inne i Docker

  • Perfekt for lab og eksperimentering

  • Bruker ekte Kubernetes-API-er og verktøy

Forutsetninger

  • Docker Desktop (med WSL2-integrasjon)

  • kubectl

  • kind

Opprette et kind-cluster med ingress-støtte

Jeg opprettet clustret med eksplisitte port-mappinger slik at ingress-controlleren kunne nås fra laptopen min:

# kind-nautix.yaml
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
extraPortMappings:
- containerPort: 80
hostPort: 80
- containerPort: 443
hostPort: 443


Opprett clustret:

kind create cluster --name nautix --config kind-nautix.yaml


Installer ingress-nginx:

kubectl apply -f \
https://raw.githubusercontent.com/kubernetes/ingress-nginx/main/deploy/static/provider/kind/deploy.yaml

På dette tidspunktet hadde jeg et fullt fungerende Kubernetes-cluster kjørende lokalt.

Namespace: isolering av Nautix

Først opprettet jeg et dedikert namespace:

apiVersion: v1
kind: Namespace
metadata:
name: nautix
kubectl apply -f k8s/00-namespace.yaml
kubectl config set-context --current --namespace=nautix

Namespaces er et enkelt, men kraftig konsept – de gir isolasjon og gjør det langt enklere å resonere rundt ressurser.

Håndtering av secrets

I Docker Compose havner secrets ofte i .env-filer.
I Kubernetes er secrets førsteklasses objekter.

I stedet for å commite secrets til Git, opprettet jeg dem imperativt ved hjelp av kubectl:

kubectl create secret generic nautix-secrets \
--from-literal=VAULT_DEV_ROOT_TOKEN_ID=root-token \
-n nautix

Dette oppretter et innebygd Kubernetes Secret som trygt kan refereres av Deployments uten å lagre sensitive verdier i kildekode.

Utrulling av Inventory-tjenesten

Inventory-tjenesten er et stateless Flask API, noe som gjør den til en perfekt kandidat for en Deployment.


Inventory Deployment

apiVersion: apps/v1
kind: Deployment
metadata:
name: inventory
namespace: nautix
spec:
replicas: 1
selector:
matchLabels:
app: inventory
template:
metadata:
labels:
app: inventory
spec:
containers:
- name: inventory
image: nautix-inventory:dev
ports:
- containerPort: 8000
readinessProbe:
httpGet:
path: /healthz
port: 8000
initialDelaySeconds: 3
livenessProbe:
httpGet:
path: /healthz
port: 8000
initialDelaySeconds: 10


Inventory Service

apiVersion: v1
kind: Service
metadata:
name: inventory
namespace: nautix
spec:
selector:
app: inventory
ports:
- port: 8000
type: ClusterIP

Deploymenten håndterer pod-livssyklus og replikaer, mens Service gir et stabilt nettverkspunkt internt i clustret.

Utrulling av Vault med persistent lagring

Vault kjører i dev-modus i denne laben, men jeg ønsket likevel å demonstrere volumer og persistent lagring.


PersistentVolumeClaim

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: vault-data
namespace: nautix
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi


Vault Deployment

apiVersion: apps/v1
kind: Deployment
metadata:
name: vault
namespace: nautix
spec:
replicas: 1
selector:
matchLabels:
app: vault
template:
metadata:
labels:
app: vault
spec:
containers:
- name: vault
image: vault:1.8.7
ports:
- containerPort: 8200
env:
- name: VAULT_DEV_LISTEN_ADDRESS
value: "0.0.0.0:8200"
- name: VAULT_DEV_ROOT_TOKEN_ID
valueFrom:
secretKeyRef:
name: nautix-secrets
key: VAULT_DEV_ROOT_TOKEN_ID
volumeMounts:
- name: data
mountPath: /vault/file
volumes:
- name: data
persistentVolumeClaim:
claimName: vault-data


Vault Service

apiVersion: v1
kind: Service
metadata:
name: vault
namespace: nautix
spec:
selector:
app: vault
ports:
- port: 8200
type: ClusterIP

Eksponering av tjenester med Ingress

For å eksponere tjenestene eksternt brukte jeg host-basert ruting via Ingress:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nautix
namespace: nautix
spec:
ingressClassName: nginx
rules:
- host: inventory.nautix.local
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: inventory
port:
number: 8000
- host: vault.nautix.local
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: vault
port:
number: 8200

Med riktige host-oppføringer på laptopen min kunne jeg nå nå:

  • http://inventory.nautix.local

  • http://vault.nautix.local

Starte alt opp

Med alle manifestene på plass:

kubectl apply -f k8s/


Verifiser:

kubectl get pods
kubectl get svc
kubectl get ingress

På dette tidspunktet kjørte både Inventory og Vault fullt ut inne i Kubernetes.

Håndtering av pod-livssyklus med kubectl

Det er her Kubernetes virkelig skinner.


Skalering

kubectl scale deploy inventory --replicas=3
kubectl get pods -l app=inventory


Logger

kubectl logs deploy/inventory
kubectl logs -f deploy/inventory


Selvreparasjon

kubectl delete pod <inventory-pod>

Podden blir automatisk opprettet på nytt – ingen manuell inngripen nødvendig.

Helsesjekker og selvreparasjon

I stedet for Docker Compose depends_on bruker Kubernetes readiness- og liveness-probes.

  • Readiness styrer om trafikk sendes til en pod

  • Liveness styrer når en pod skal restartes

Dette gjør plattformen langt mer robust som standard.

Avsluttende tanker

Ved å migrere selv en liten del av Nautix til Kubernetes, klarte jeg å demonstrere alle kravene i Blueprint 4.3 ved hjelp av reelle arbeidslaster:

  • Deklarative utrullinger

  • Sikker håndtering av secrets

  • Persistent lagring

  • Ingress-ruting

  • Helsesjekker

  • Skalering og livssyklushåndtering

  • Full kontroll via kubectl

Nyttige lenker

  • GitLab Repo – Min CCIE Automation kode
  • Kubernetes dokumentasjon

Bloggserie

  • [Min reise mot CCIE Automation #1] Introduksjon + bygging av en Python CLI-applikasjon

  • [Min reise mot CCIE Automation #2] Inventory REST API og mikrotjenestearkitektur

  • [Min reise mot CCIE Automation #3] Orchestration API og NETCONF

  • [Min reise mot CCIE Automation #4] Automatisering av nettverksoppdagelse og rapporter med Python og Ansible

  • [Min reise mot CCIE Automation #5] Bygging av nettverkspipelines for pålitelige endringer med pyATS og GitLab CI

  • [Min reise mot CCIE Automation #6] Automatisering av Cisco ACI-utrulling med Terraform, Vault og GitLab CI

  • [Min reise mot CCIE Automation #7] Utforsking av Model-Driven Telemetry for sanntidsinnsikt i nettverket

  • [Min reise mot CCIE Automation #8] Utforsking av ThousandEyes og automatisering av Enterprise Agent-utrulling

  • [Min reise mot CCIE Automation #9] Anvendelse av OWASP Secure Coding Practices

Trenger du bistand?

Vi tar gjerne en uforpliktende prat.
Kontakt oss

Les mer

Cybertrusselbildet 2026: Innsikt fra Arctic Wolf sin trusselrapport
Blogg

Cybertrusselbildet 2026: Innsikt fra Arctic Wolf sin trusselrapport

Arctic Wolf Threat Report 2026: Ransomware er fortsatt trussel nummer én.
IAM for dummies
Blogg

IAM for dummies

En enkel og praktisk innføring i IAM og hvorfor riktig tilgang er avgjørende.
Hvordan redusere kostnad i Microsoft Sentinel og Defender XDR
Blogg

Hvordan redusere kostnad i Microsoft Sentinel og Defender XDR

Kostnader og valg for logging i Microsoft Sentinel og Defender XDR.
Sicras sikkerhetstriangel: Helhetlig IT- og OT-sikkerhet gjennom ledelse, overvåkning og ekspertise
Blogg

Sicras sikkerhetstriangel: Helhetlig IT- og OT-sikkerhet gjennom ledelse, overvåkning og ekspertise

Sicras sikkerhetstriangel gir helhetlig sikkerhet på tvers av IT, OT og ledelse.

Hold deg oppdatert
Motta siste nytt fra Sicra

Linker
BærekraftFAQPartnereSertifiseringerKarrierePresse
Kontakt
Tel: +47 648 08 488
E-post: firmapost@sicra.no

Posthuset, Biskop Gunnerus' gate 14A, 0185 Oslo

Følg oss på LinkedIn
Sertifiseringer
iso27001-white
ISO 27001
miljofyrtarnlogo-hvit-rgb
Miljøfyrtårn
Sicra Footer Logo
Sicra © 2025
Personvern