Vanilla Kubernetes

Drugi deo: Workload platforma, mreža, podaci i bezbednost
ConfigMap – odvajanje konfiguracije od kontejnerske slike
V. Konfiguracija, zdravlje, resursi i raspoređivanje
20. ConfigMap – konfiguracija izvan slike, načini projekcije i kontrolisana promena

Kontejnerska slika treba da sadrži aplikaciju, njene izvršne biblioteke i stabilne podrazumevane vrednosti, ali ne i konfiguraciju koja se razlikuje između razvojnog, testnog i produkcionog okruženja. Kada se adresa zavisnog servisa, nivo logovanja, naziv okruženja ili sadržaj aplikacionog konfiguracionog fajla ugradi direktno u sliku, svaka promena zahteva novu izgradnju, testiranje i distribuciju slike. Takav postupak usporava isporuku, povećava broj gotovo identičnih slika i otežava dokazivanje koja je konfiguracija zaista korišćena u određenom trenutku.

Kubernetes objekat ConfigMap rešava ovaj problem tako što čuva nepoverljive konfiguracione podatke odvojeno od kontejnerske slike i omogućava Podovima da ih koriste kao promenljive okruženja, argumente komandne linije ili fajlove montirane kroz volumen. ConfigMap nije mehanizam za čuvanje lozinki, tokena, privatnih ključeva i sertifikata. Takvi podaci pripadaju objektima tipa Secret ili spoljašnjem sistemu za upravljanje tajnama, uz odgovarajuću enkripciju, kontrolu pristupa i audit.

Administratorski posao zato nije samo da napravi ConfigMap. Administrator mora da odredi šta zaista pripada konfiguraciji, kako će aplikacija učitati podatke, da li podržava ponovno učitavanje bez restarta, kako će se promena verzionisati, ko sme da je izvrši, kako će se validirati i kako će se sistem vratiti na prethodno stanje ako nova vrednost izazove incident.

Uloga ConfigMap objekta u Kubernetes arhitekturi

ConfigMap je namespaced Kubernetes API objekat iz osnovne grupe v1. Njegov sadržaj se čuva u stanju klastera i dostupan je komponentama koje imaju odgovarajuća prava pristupa. Pod ne „kontaktira” ConfigMap kao mrežni servis. Umesto toga, PodSpec sadrži referencu na ConfigMap, a Kubernetes tokom formiranja izvršnog okruženja prosleđuje izabrane vrednosti kontejneru.

ConfigMap najčešće sadrži jednostavne parove ključ–vrednost ili kompletne tekstualne konfiguracione fajlove. Polje data čuva UTF-8 tekstualne vrednosti, dok je binaryData namenjen binarnim podacima kodiranim u base64 obliku u YAML/JSON API reprezentaciji. Ključevi u data i binaryData ne smeju se preklapati; svaki ključ sme sadržati alfanumeričke znakove, crticu, donju crtu ili tačku. ConfigMap ne sme biti veći od 1 MiB. Veći sadržaj treba smestiti u kontejnersku sliku, trajni volumen, objektno skladište, repozitorijum artefakata ili specijalizovani konfiguracioni servis.

Pod i referencirani ConfigMap moraju biti u istom namespace-u. Static Pod manifest ne može da referencira ConfigMap niti druge Kubernetes API objekte, jer kubelet takav Pod pokreće neposredno iz lokalnog manifesta, bez uobičajenog razrešavanja namespaced zavisnosti kroz PodSpec. Četvrti, ređi obrazac jeste da aplikacija pomoću Kubernetes API-ja sama čita ili prati ConfigMap. Tada njen ServiceAccount zaista mora imati precizno ograničena RBAC prava get, a po potrebi list i watch; time aplikacija preuzima i odgovornost za keširanje, ponovne pokušaje i bezbedno ponovno učitavanje.

apiVersion: v1
kind: ConfigMap
metadata:
  name: inventory-web-config
  namespace: inventory-prod
data:
  APP_ENV: production
  LOG_LEVEL: info
  application.properties: |
    server.port=8080
    inventory.api.base-url=http://inventory-api:8080
    inventory.cache.ttl-seconds=300

U ovom primeru ista ConfigMap sadrži pojedinačne vrednosti i jedan višelinijski fajl. To je tehnički dozvoljeno, ali administrator treba da grupiše samo podatke koji imaju isti životni ciklus, istog vlasnika i isti način odobravanja. Konfiguracija aplikacije i konfiguracija nezavisnog pomoćnog agenta često ne treba da budu u istom objektu, jer promena jedne komponente tada nepotrebno utiče na drugu.

Šta treba, a šta ne treba čuvati u ConfigMap objektu

U ConfigMap obično pripadaju nazivi okruženja, nivoi logovanja, adrese internih servisa, vremenski intervali, pragovi, feature flag vrednosti koje nisu bezbednosno osetljive, format izlaza, tekstualni šabloni i konfiguracioni fajlovi aplikacije. Vrednost treba da bude promenljiva između okruženja, ali ne sme biti tajna.

ConfigMap nije zamena za bazu podataka, distribuirani keš, skladište velikih artefakata niti sistem za upravljanje tajnama. U njemu ne treba držati korisničke podatke, poslovne transakcije, pristupne lozinke, API tokene, privatne ključeve, konfiguracije koje sadrže ugrađene kredencijale ili podatke koji se menjaju velikom učestalošću. Svaka izmena je operacija nad Kubernetes API objektom i deo je kontrolnog stanja klastera; ConfigMap zato nije projektovan kao visokofrekventno key-value skladište.

Poseban rizik predstavlja pogrešna pretpostavka da je podatak bezbedan samo zato što se nalazi unutar klastera. Korisnik ili ServiceAccount sa pravom get, list ili watch nad ConfigMap objektima može pročitati njihov sadržaj. Pored toga, vrednosti mogu postati vidljive u manifestima, Git repozitorijumima, CI/CD logovima, izlazu komande kubectl describe ili dijagnostičkim paketima. Klasifikacija podatka mora prethoditi izboru Kubernetes objekta.

Načini prosleđivanja konfiguracije aplikaciji

Kubernetes podržava nekoliko načina korišćenja ConfigMap podataka. Izbor mora pratiti ponašanje aplikacije, a ne administratorsku pogodnost. Aplikacija koja očekuje promenljivu okruženja ne treba bez opravdanja da se menja kako bi čitala fajl, ali administrator mora razumeti da se vrednost promenljive okruženja ne menja u već pokrenutom procesu.

Način korišćenja Ponašanje promene Tipična primena Važno ograničenje
env Vrednost se učitava pri kreiranju kontejnera Pojedinačna promenljiva Potreban je novi Pod da bi proces dobio novu vrednost
envFrom Svi odgovarajući ključevi postaju promenljive okruženja Skup jednostavnih parametara Nevažeći nazivi promenljivih mogu biti preskočeni i prijavljeni događajem
ConfigMap volumen Kubelet periodično projektuje nov sadržaj Konfiguracioni fajlovi Aplikacija mora ponovo pročitati fajl; ažuriranje nije trenutno
subPath montiranje Fajl se montira na određenu putanju Jedan fajl u postojećem direktorijumu Automatsko osvežavanje ConfigMap sadržaja ne funkcioniše
Argument komande Vrednost se proširuje pri pokretanju kontejnera Parametar aplikacionog procesa Potreban je novi Pod za promenu

Za pojedinačnu promenljivu koristi se configMapKeyRef. Prednost je eksplicitnost: iz manifesta se jasno vidi koji ključ aplikacija koristi. Kada se koristi envFrom, svi ključevi ConfigMap objekta pokušavaju da postanu promenljive okruženja. To je praktično za veći broj jednostavnih vrednosti, ali povećava vezu između sadržaja ConfigMap objekta i procesa u kontejneru.

env:
  - name: APP_ENV
    valueFrom:
      configMapKeyRef:
        name: inventory-web-config
        key: APP_ENV
  - name: LOG_LEVEL
    valueFrom:
      configMapKeyRef:
        name: inventory-web-config
        key: LOG_LEVEL

ConfigMap volumen prikazuje svaki izabrani ključ kao fajl. Naziv ključa postaje naziv fajla, osim ako je drugačije mapiran preko items. Aplikacija zatim čita sadržaj sa definisane putanje. Montirana putanja treba da bude samo za čitanje, osim ako aplikacija iz opravdanog razloga kopira konfiguraciju u drugi, upisivi volumen.

volumes:
  - name: application-config
    configMap:
      name: inventory-web-config
      items:
        - key: application.properties
          path: application.properties
containers:
  - name: inventory-web
    volumeMounts:
      - name: application-config
        mountPath: /etc/inventory
        readOnly: true

Montiranje volumena preko celog postojećeg direktorijuma prikriva fajlove koji su se na toj putanji nalazili u kontejnerskoj slici. Ako slika već sadrži druge potrebne fajlove u /etc/inventory, oni neće biti vidljivi nakon montiranja. Administrator zato mora pregledati strukturu slike ili koristiti posebnu praznu putanju. subPath može montirati samo jedan fajl bez prikrivanja direktorijuma, ali tada se gubi automatsko osvežavanje sadržaja i promena zahteva ponovno kreiranje Poda.

Preko polja items mogu se izabrati samo potrebni ključevi, promeniti njihova relativna imena i odrediti režim dozvola preko defaultMode ili pojedinačnog mode. Vrednosti režima u YAML-u mogu se pisati oktalno, na primer 0440; u JSON-u se navode decimalno. Dozvole nisu zamena za pravilno podešen securityContext, vlasništvo i najmanji potreban pristup procesu. Ako u items nedostaje neopcioni ključ, volumen se ne kreira i Pod neće normalno startovati.

Referenca može biti označena sa optional: true. Tada odsutan ConfigMap ili ključ ne blokira Pod: promenljiva ili fajl neće biti prisutni, a mount putanja volumena ipak može postojati. Ova mogućnost je bezbedna samo ako aplikacija ima dokumentovanu i proverenu podrazumevanu konfiguraciju. Za obavezne produkcione parametre opcionalnost često prikriva grešku i odlaže incident do trenutka kada aplikacija počne pogrešno da se ponaša.

Ažuriranje ConfigMap sadržaja i životni ciklus Podova

Najvažnija operativna razlika postoji između konfiguracije prosleđene kao promenljiva okruženja i konfiguracije montirane kao volumen. Promenljive okruženja postaju deo okruženja procesa kada se kontejner pokrene. Izmena ConfigMap objekta ne menja okruženje već pokrenutog procesa. Deployment zato mora da kreira nove Podove, na primer komandom kubectl rollout restart ili promenom Pod template-a kroz deklarativni deployment proces.

Kod ConfigMap volumena kubelet eventualno osvežava projektovane fajlove. Promena nije sinhrona ni trenutna, jer zavisi od periodičnog kubelet sync ciklusa i podešene strategije detekcije promene (Watch, TTL keš ili direktno čitanje). Zvanični primer za TTL pristup navodi da kašnjenje može dostići zbir kubelet sync perioda i TTL-a keša; podrazumevane vrednosti u tom primeru su po jedan minut. Promena anotacije Poda može pokrenuti raniju proveru, ali to nije zamena za projektovan rollout proces. Čak i kada se fajl promeni, aplikacija mora da podržava ponovno čitanje konfiguracije, signal za reload ili sopstveni file watcher. Bez toga proces nastavlja da koristi vrednosti koje je učitao pri pokretanju.

Zbog ove razlike status „ConfigMap je ažuriran” ne dokazuje da aplikacija koristi novu vrednost. Potrebne su najmanje tri odvojene provere: sadržaj API objekta, sadržaj unutar Poda i efektivno ponašanje aplikacije. Ako se konfiguracija koristi kao promenljiva okruženja, provera u starom Podu će namerno pokazati staru vrednost sve dok Pod ne bude zamenjen.

U produkciji se često koristi verzionisani naziv, na primer inventory-web-config-v2026-07-01, ili generator koji u ime dodaje hash sadržaja. Promena reference u Pod template-u tada automatski pokreće Deployment rollout, a prethodna ConfigMap ostaje dostupna za rollback. Ovaj pristup daje bolju sledljivost od menjanja jednog objekta „u mestu”, ali zahteva kontrolisano uklanjanje starih verzija.

Immutable ConfigMap objekti

ConfigMap može imati polje immutable: true. Nakon toga nije moguće menjati sadržaj polja data i binaryData, niti vratiti objekat u promenljivo stanje. Za novu konfiguraciju mora se napraviti novi ConfigMap i ažurirati referenca u workload objektu. Brisanje immutable ConfigMap objekta je moguće, ali je rizično ako ga aktivni ili budući Podovi i dalje referenciraju.

apiVersion: v1
kind: ConfigMap
metadata:
  name: inventory-web-config-v1
  namespace: inventory-prod
immutable: true
data:
  APP_ENV: production
  LOG_LEVEL: info

Immutable objekti smanjuju rizik od nenamerne izmene aktivne konfiguracije i mogu smanjiti opterećenje API servera i kubelet komponenti u klasterima sa veoma velikim brojem montiranih ConfigMap objekata. Pogodni su za kontrolisane GitOps i CI/CD tokove u kojima svaka promena dobija novu verziju. Nisu pogodni kada je očekivano često ručno menjanje istog objekta ili kada aplikacija zavisi od dinamičkog osvežavanja montiranog fajla.

Deklarativno upravljanje, verzionisanje i kontrola promene

Ručno izvršavanje komande kubectl create configmap --from-literal korisno je za laboratoriju i brzu dijagnostiku, ali produkciona konfiguracija treba da ima kontrolisani izvor istine. Manifesti ili ulazni konfiguracioni fajlovi čuvaju se u odobrenom repozitorijumu, prolaze pregled promene i primenjuju se automatizovanim procesom. Pre primene administrator treba da koristi kubectl diff, validaciju šeme, aplikacione provere sintakse i, kada je dostupno, serverski dry-run.

kubectl diff -f inventory-web-config.yaml
kubectl apply --dry-run=server -f inventory-web-config.yaml
kubectl apply -f inventory-web-config.yaml

Kustomize configMapGenerator može generisati ConfigMap iz fajlova ili literal vrednosti i po podrazumevanom ponašanju dodati hash sadržaja u naziv. Kada Deployment referencira generisani objekat, promena sadržaja proizvodi novo ime i novu verziju Pod template-a. To je koristan obrazac za pouzdan rollout, ali tim mora razumeti kako alat menja reference i kako se uklanjaju zastareli objekti.

ConfigMap ne treba ručno menjati direktno u produkciji pomoću interaktivnog editora, osim u odobrenoj hitnoj proceduri. Takva izmena stvara odstupanje između klastera i repozitorijuma, može biti prepisana sledećom automatizacijom i otežava audit. Ako je hitna promena neophodna, treba je odmah zabeležiti, potvrditi efektivno stanje i preneti istu izmenu u izvor istine.

Prava pristupa i bezbednosna odgovornost

ConfigMap je namespaced resurs, pa RBAC prava treba ograničiti na konkretan namespace i potreban skup glagola. Aplikaciji koja samo dobija ConfigMap kroz PodSpec najčešće nije potrebno da njen ServiceAccount direktno čita ConfigMap preko Kubernetes API-ja. Kubelet i kontrolne komponente obavljaju projektovanje vrednosti. Dodeljivanje aplikaciji prava list ili watch nad svim ConfigMap objektima bez poslovnog razloga nepotrebno širi posledice kompromitovanja Poda.

Administrator koji priprema promenu obično zahteva get, create, patch i update nad ConfigMap objektima, kao i get nad Deployment i Pod objektima radi validacije. Pravo delete treba dodeliti samo kada je potrebno za upravljanje životnim ciklusom. Prava za restart ili izmenu Deployment objekta moraju biti posebno odobrena, jer promena ConfigMap objekta i pokretanje novog rollout-a predstavljaju dve različite operacije.

kubectl auth can-i get configmaps -n inventory-prod
kubectl auth can-i update configmaps -n inventory-prod
kubectl auth can-i patch deployments.apps -n inventory-prod
kubectl auth can-i delete configmaps -n inventory-prod

Rezultat yes potvrđuje autorizaciju trenutnog identiteta, ali ne potvrđuje da je promena poslovno odobrena. Tehnička mogućnost nije isto što i ovlašćenje prema proceduri promene. Administrator mora proveriti tiket, vlasnika aplikacije, period održavanja, plan rollback-a i očekivani uticaj pre izmene produkcionog sistema.

Najčešće greške i način dijagnostike


Integrisani praktikum: kontrolisana promena konfiguracije produkcione web aplikacije

Poslovni i tehnički kontekst. Tim održava internu aplikaciju inventory-web u namespace-u inventory-prod. Aplikacija je raspoređena kao Deployment sa dve replike i dostupna je preko Service objekta inventory-web. Konfiguracioni fajl application.properties montira se iz ConfigMap objekta inventory-web-config-v1. Potrebno je promeniti nivo logovanja sa info na debug radi vremenski ograničene dijagnostike i smanjiti cache TTL sa 300 na 60 sekundi. Promena mora proizvesti kontrolisani rolling update, bez prekida dostupnosti, uz mogućnost brzog vraćanja na prethodnu verziju.

Cilj. Napraviti novu immutable ConfigMap verziju, validirati sadržaj, povezati je sa Deployment objektom, proveriti rollout i ponašanje aplikacije, izvršiti negativni test i pripremiti rollback. Stari ConfigMap se ne menja niti briše tokom praktične promene.

Referentno okruženje. Kubernetes klaster podržane verzije, radna stanica sa odgovarajućom verzijom alata kubectl, aktivan kubeconfig kontekst, namespace inventory-prod, postojeći Deployment i Service inventory-web. Kontejner sluša na portu 8080 i izlaže HTTP endpoint /healthz. Slika aplikacije čita fajl /etc/inventory/application.properties pri pokretanju.

Potrebna prava. Čitanje ConfigMap, Deployment, ReplicaSet, Pod, Service i Event objekata; kreiranje ConfigMap objekta; izmena Deployment objekta; čitanje Pod logova; izvršavanje komande u Podu radi validacije. Brisanje ConfigMap objekata nije potrebno za implementaciju.

Preduslovi. Promena je odobrena, vlasnik aplikacije je potvrdio dozvoljene vrednosti, postoji period pojačanog nadzora, readiness proba je funkcionalna, a prethodni manifest Deployment objekta dostupan je u repozitorijumu. Direktorijum inventory-config-change biće napravljen na administratorskoj radnoj stanici.

  1. Proveriti aktivni kontekst, identitet i autorizaciju. Pogrešan kubeconfig kontekst može primeniti ispravnu konfiguraciju na pogrešan klaster. Prvo se prikazuje trenutni kontekst, zatim dostupnost namespace-a i potrebna prava.
    kubectl config current-context
    kubectl get namespace inventory-prod
    kubectl auth can-i get configmaps -n inventory-prod
    kubectl auth can-i create configmaps -n inventory-prod
    kubectl auth can-i patch deployments.apps -n inventory-prod
    kubectl auth can-i get pods/log -n inventory-prod
    kubectl auth can-i create pods/exec -n inventory-prod
    Validacija: kontekst mora odgovarati planiranom produkcionom klasteru, namespace mora biti u stanju Active, a svaka neophodna autorizaciona provera mora vratiti yes. Rezultat no nije razlog za traženje širih administratorskih prava bez procedure, već za eskalaciju vlasniku RBAC politike.
  2. Snimiti početno stanje i proveriti zdravlje aplikacije. Pre promene se dokumentuju Deployment, Podovi, postojeća ConfigMap referenca i događaji. Time se razlikuju prethodno postojeći problemi od posledica nove konfiguracije.
    mkdir -p inventory-config-change
    kubectl get deployment inventory-web -n inventory-prod -o yaml \
      > inventory-config-change/deployment-before.yaml
    kubectl get configmap inventory-web-config-v1 -n inventory-prod -o yaml \
      > inventory-config-change/configmap-v1-before.yaml
    kubectl get deployment inventory-web -n inventory-prod
    kubectl get pods -n inventory-prod \
      -l app.kubernetes.io/name=inventory-web -o wide
    kubectl get events -n inventory-prod \
      --sort-by=.metadata.creationTimestamp | tail -n 20
    kubectl rollout status deployment/inventory-web -n inventory-prod \
      --timeout=120s
    Validacija: Deployment treba da ima 2/2 dostupne replike, Podovi treba da budu Running i Ready, bez ponavljanih upozorenja kao što su FailedMount, BackOff ili Unhealthy. Ako početno stanje nije zdravo, promena se zaustavlja dok se ne proceni postojeći incident.
  3. Potvrditi način na koji Deployment koristi ConfigMap. Ne treba pretpostaviti da je konfiguracija montirana kao volumen samo na osnovu naziva objekta. Pregleda se Pod template i tačna referenca.
    kubectl get deployment inventory-web -n inventory-prod \
      -o jsonpath='{.spec.template.spec.volumes[*].configMap.name}{"\n"}'
    kubectl get deployment inventory-web -n inventory-prod \
      -o jsonpath='{range .spec.template.spec.containers[*].volumeMounts[*]}{.name}{" => "}{.mountPath}{" subPath="}{.subPath}{"\n"}{end}'
    Validacija: prvi izlaz mora sadržati inventory-web-config-v1, a volumen mora biti montiran na /etc/inventory bez subPath vrednosti. Iako bi volumen mogao dinamički da se osvežava, u ovom scenariju koristi se verzionisani immutable objekat i kontrolisani rollout.
  4. Proveriti trenutno efektivnu konfiguraciju u oba Poda. API objekat i PodSpec nisu dovoljan dokaz. Potrebno je pročitati montirani fajl unutar svakog aktivnog Poda.
    for pod in $(kubectl get pods -n inventory-prod \
      -l app.kubernetes.io/name=inventory-web \
      -o jsonpath='{.items[*].metadata.name}'); do
      echo "=== ${pod} ==="
      kubectl exec -n inventory-prod "${pod}" -- \
        cat /etc/inventory/application.properties
    done
    Validacija: oba Poda treba da prikažu logging.level.root=info i inventory.cache.ttl-seconds=300. Različit sadržaj između replika predstavlja konfiguraciono odstupanje koje mora biti istraženo pre nastavka.
  5. Napraviti deklarativni manifest nove ConfigMap verzije. Nova verzija dobija naziv inventory-web-config-v2, oznake za vlasništvo i anotaciju sa razlogom promene. Objekat je immutable kako bi odobreni sadržaj ostao nepromenljiv.
    cat > inventory-config-change/inventory-web-config-v2.yaml <<'EOF'
    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: inventory-web-config-v2
      namespace: inventory-prod
      labels:
        app.kubernetes.io/name: inventory-web
        app.kubernetes.io/component: configuration
        app.kubernetes.io/managed-by: kubectl
      annotations:
        change.tashizza.example/reference: "CHG-2026-0728"
        change.tashizza.example/purpose: "Temporary diagnostic logging and cache TTL reduction"
    immutable: true
    data:
      application.properties: |
        server.port=8080
        inventory.api.base-url=http://inventory-api:8080
        inventory.cache.ttl-seconds=60
        logging.level.root=debug
    EOF
    Validacija: lokalni fajl treba pregledati pre slanja API serveru. Posebno se proveravaju namespace, naziv, YAML uvlačenje, dozvoljene aplikacione vrednosti i odsustvo tajni.
    cat inventory-config-change/inventory-web-config-v2.yaml
    grep -nE 'password|token|secret|private.key' \
      inventory-config-change/inventory-web-config-v2.yaml || true
    Odsustvo izlaza druge komande ne predstavlja potpunu bezbednosnu analizu, ali pomaže u otkrivanju očigledno pogrešno unetih osetljivih polja.
  6. Izvršiti serversku validaciju i pregled razlike. Serverski dry-run koristi validaciju API servera bez trajnog kreiranja objekta. Pošto objekat još ne postoji, kubectl diff treba da prikaže dodavanje nove ConfigMap.
    kubectl apply --dry-run=server \
      -f inventory-config-change/inventory-web-config-v2.yaml
    kubectl diff \
      -f inventory-config-change/inventory-web-config-v2.yaml
    Validacija: dry-run mora vratiti potvrdu bez greške, a diff sme da sadrži samo planiranu novu ConfigMap. Greške u YAML-u, nedozvoljena polja ili admission politici moraju se ispraviti u izvornom manifestu, ne zaobići opcijom koja isključuje validaciju.
  7. Kreirati novu ConfigMap i proveriti sadržaj iz API-ja. Primena nove verzije ne menja aktivne Podove jer Deployment još uvek referencira v1.
    kubectl apply \
      -f inventory-config-change/inventory-web-config-v2.yaml
    kubectl get configmap inventory-web-config-v2 -n inventory-prod
    kubectl get configmap inventory-web-config-v2 -n inventory-prod \
      -o jsonpath='{.immutable}{"\n"}{.data.application\.properties}{"\n"}'
    Validacija: objekat mora postojati, polje immutable mora biti true, a sadržaj mora imati TTL 60 i nivo logovanja debug. Deployment i postojeći Podovi u ovom trenutku treba i dalje da koriste verziju v1.
  8. Izvršiti negativni test nepromenljivosti. Test potvrđuje da API server odbija pokušaj izmene sadržaja immutable ConfigMap objekta. Koristi se serverski dry-run kako se ne bi izvršila stvarna promena.
    kubectl patch configmap inventory-web-config-v2 \
      -n inventory-prod \
      --type=merge \
      --patch '{"data":{"application.properties":"invalid=true"}}' \
      --dry-run=server
    Očekivani rezultat: API server treba da odbije zahtev zato što je polje sa podacima immutable. Ako komanda neočekivano uspe, treba proveriti da li je objekat zaista kreiran sa immutable: true i da li se koristi očekivani klaster.
  9. Pregledati planiranu izmenu Deployment objekta. Referenca se prvo menja na lokalnoj kopiji manifesta kako bi diff prikazao tačan efekat. Ne treba menjati naziv ConfigMap objekta pomoću nekontrolisane tekstualne zamene ako se isti tekst pojavljuje na više mesta.
    cp inventory-config-change/deployment-before.yaml \
      inventory-config-change/deployment-v2.yaml
    python3 - <<'PY'
    from pathlib import Path
    
    path = Path("inventory-config-change/deployment-v2.yaml")
    text = path.read_text()
    old = "name: inventory-web-config-v1"
    new = "name: inventory-web-config-v2"
    
    if text.count(old) != 1:
        raise SystemExit(
            f"Expected exactly one ConfigMap reference, found {text.count(old)}"
        )
    
    path.write_text(text.replace(old, new))
    PY
    kubectl diff -f inventory-config-change/deployment-v2.yaml
    Validacija: diff treba da prikaže samo očekivanu promenu reference sa inventory-web-config-v1 na inventory-web-config-v2. Serverski generisana polja iz sačuvanog YAML-a mogu stvarati šum, pa je u produkcionom repozitorijumu bolji čist deklarativni manifest bez statusa i runtime metapodataka.
  10. Promeniti samo ConfigMap referencu u aktivnom Deployment objektu. Za praktični scenario koristi se JSON patch sa preciznom putanjom. Pre izvršavanja mora biti potvrđeno da je ConfigMap volumen prvi element niza volumena. U standardizovanom produkcionom procesu prednost ima promena deklarativnog manifesta u repozitorijumu.
    kubectl get deployment inventory-web -n inventory-prod \
      -o jsonpath='{.spec.template.spec.volumes[0].name}{" => "}{.spec.template.spec.volumes[0].configMap.name}{"\n"}'
    
    kubectl patch deployment inventory-web -n inventory-prod \
      --type=json \
      -p='[
      {
        "op": "test",
        "path": "/spec/template/spec/volumes/0/configMap/name",
        "value": "inventory-web-config-v1"
      },
      {
        "op": "replace",
        "path": "/spec/template/spec/volumes/0/configMap/name",
        "value": "inventory-web-config-v2"
      }
    ]'
    Validacija: operacija test sprečava promenu ako aktivno stanje nije ono koje administrator očekuje. Uspešna promena menja Pod template i pokreće novi Deployment rollout.
  11. Pratiti rolling update i događaje. Tokom rollout-a proveravaju se dostupnost, novi ReplicaSet, status novih Podova i događaji. Ne treba odmah brisati stari ReplicaSet niti ConfigMap v1.
    kubectl rollout status deployment/inventory-web \
      -n inventory-prod --timeout=180s
    kubectl get deployment,replicaset,pods -n inventory-prod \
      -l app.kubernetes.io/name=inventory-web -o wide
    kubectl get events -n inventory-prod \
      --sort-by=.metadata.creationTimestamp | tail -n 30
    Validacija: rollout mora biti uspešno završen, Deployment mora ponovo imati 2/2 dostupne replike, a novi Podovi ne smeju imati FailedMount, CrashLoopBackOff ili neuspešne readiness probe događaje. Ako rollout ne napreduje, ne nastavlja se sa dodatnim izmenama dok se ne pregledaju opis i logovi problematičnog Poda.
  12. Potvrditi novu konfiguraciju u svakom novom Podu. Provera se izvodi nad svim replikama, jer uspešan status Deployment objekta ne dokazuje da svaka instanca koristi očekivani fajl.
    for pod in $(kubectl get pods -n inventory-prod \
      -l app.kubernetes.io/name=inventory-web \
      -o jsonpath='{.items[*].metadata.name}'); do
      echo "=== ${pod} ==="
      kubectl exec -n inventory-prod "${pod}" -- \
        cat /etc/inventory/application.properties
    done
    Validacija: svaki Pod mora prikazati inventory.cache.ttl-seconds=60 i logging.level.root=debug. Ako jedan Pod prikazuje staru konfiguraciju, proveravaju se njegov owner ReplicaSet, starost i referenca volumena u efektivnom PodSpec-u.
  13. Izvršiti funkcionalnu proveru preko Service objekta. Privremeni Pod koristi se kao interni klijent. Opcija --rm uklanja ga po završetku, pa je pogodna za kontrolisanu proveru bez trajnog dijagnostičkog resursa.
    kubectl run inventory-config-test \
      -n inventory-prod \
      --image=curlimages/curl:8.12.1 \
      --restart=Never \
      --rm -i \
      --command -- \
      curl --fail --silent --show-error \
      http://inventory-web:8080/healthz
    Validacija: komanda mora završiti izlaznim kodom 0 i vratiti očekivani odgovor health endpoint-a. Ako DNS ime ne može da se razreši, problem nije nužno u ConfigMap objektu; proveravaju se Service, Endpoints odnosno EndpointSlice objekti i DNS. Ako veza postoji, ali je odgovor HTTP 5xx, pregledaju se aplikacioni logovi.
  14. Pregledati aplikacione logove i potvrditi očekivani efekat. Logovi kontejnera dostupni su preko kubelet i container runtime infrastrukture, a administrator im pristupa komandom kubectl logs. U centralizovanom sistemu logovanja treba koristiti isti vremenski opseg i identifikatore novih Podova.
    kubectl logs deployment/inventory-web -n inventory-prod \
      --all-pods=true --since=10m --prefix=true | tail -n 200
    Validacija: ne sme biti grešaka parsiranja konfiguracije, poruka o nedostupnom inventory-api servisu niti kontinuiranog restartovanja. Treba potvrditi pojavu očekivanih debug poruka bez nekontrolisanog rasta volumena logova. Ako debug nivo izlaže osetljive poslovne podatke, promenu treba odmah vratiti i prijaviti bezbednosnom vlasniku.
  15. Pripremiti i po potrebi izvršiti rollback. Najbezbedniji povratak u ovom scenariju jeste vraćanje reference na poznatu immutable verziju v1. Deployment istorija takođe može vratiti prethodni Pod template, ali eksplicitna referenca olakšava razumevanje ciljnog stanja.

    Upozorenje: rollback ponovo menja Pod template i pokreće zamenu Podova. Ne izvršava se istovremeno sa drugim rollout-om niti bez procene dostupnosti.

    kubectl patch deployment inventory-web -n inventory-prod \
      --type=json \
      -p='[
        {
          "op": "test",
          "path": "/spec/template/spec/volumes/0/configMap/name",
          "value": "inventory-web-config-v2"
        },
        {
          "op": "replace",
          "path": "/spec/template/spec/volumes/0/configMap/name",
          "value": "inventory-web-config-v1"
        }
      ]'
    
    kubectl rollout status deployment/inventory-web \
      -n inventory-prod --timeout=180s
    Validacija: nakon rollback-a oba nova Poda moraju biti Ready, montirani fajl mora ponovo sadržati TTL 300 i nivo logovanja info, a health endpoint mora vratiti uspešan odgovor. Ako promena ostaje aktivna, rollback komande se čuvaju u zapisu promene, ali se ne izvršavaju.
  16. Završiti promenu i planirati cleanup. ConfigMap v1 se ne briše odmah nakon uspešnog rollout-a. Zadržava se najmanje tokom definisanog perioda rollback-a i dok se ne potvrdi da ga nijedan aktivni workload ne referencira.
    kubectl get deployment inventory-web -n inventory-prod \
      -o jsonpath='{.spec.template.spec.volumes[*].configMap.name}{"\n"}'
    kubectl get pods -n inventory-prod \
      -l app.kubernetes.io/name=inventory-web \
      -o jsonpath='{range .items[*]}{.metadata.name}{" => "}{.spec.volumes[*].configMap.name}{"\n"}{end}'
    kubectl get configmaps -n inventory-prod \
      -l app.kubernetes.io/name=inventory-web
    Validacija: aktivni Deployment i svi njegovi Podovi moraju referencirati istu odobrenu verziju. Stari objekat može se ukloniti tek kroz zasebnu odobrenu cleanup promenu, nakon isteka perioda povratka i provere svih referenci.

Merljivi kriterijumi prihvatanja. Nova ConfigMap postoji kao immutable objekat; Deployment referencira odobrenu verziju; rollout se završava u roku od 180 sekundi; dostupne su 2 od 2 replike; svi Podovi imaju isti sadržaj konfiguracionog fajla; health endpoint vraća uspešan HTTP odgovor; nema događaja FailedMount, BackOff ili Unhealthy; logovi ne sadrže greške parsiranja konfiguracije; rollback postupak je dokumentovan i proveren na nivou komande, reference i očekivanog rezultata.

Administratorske prakse

Kontrolna lista

Zaključak

ConfigMap omogućava da jedna proverena kontejnerska slika radi u različitim okruženjima bez ugrađivanja promenljivih operativnih vrednosti u samu sliku. Njegova vrednost nije samo u čuvanju parova ključ–vrednost, već u jasnom razdvajanju odgovornosti: razvojni tim definiše kako aplikacija prima i validira konfiguraciju, platforma obezbeđuje pouzdano projektovanje podataka, a administrator kontroliše verziju, prava pristupa, rollout, validaciju i povratak na prethodno stanje.

Nakon ove lekcije administrator treba da razume razliku između konfiguracije učitane kao promenljiva okruženja i konfiguracije montirane kao fajl, uključujući posledice za ponovno učitavanje i restart Podova. Treba da ume da napravi deklarativan i po potrebi immutable ConfigMap, poveže ga sa workload objektom, proveri sadržaj u API-ju i unutar kontejnera, prati rolling update, tumači događaje i logove i potvrdi funkcionalni rezultat kroz aplikacioni endpoint.

Posebna odgovornost odnosi se na produkcione rizike. Pogrešan ključ može sprečiti pokretanje kontejnera, neispravan konfiguracioni fajl može izazvati restart petlju, promena nivoa logovanja može preopteretiti sistem za logove, a tajna greškom sačuvana u ConfigMap objektu može postati dostupna širokom krugu identiteta i alata. Uspešan API zahtev zato nije dovoljan kriterijum uspeha. Promena je završena tek kada su nove replike dostupne, efektivna konfiguracija potvrđena, aplikaciono ponašanje provereno i rollback ostao izvodljiv.

Granice tehnologije moraju ostati jasne. ConfigMap nije skladište tajni, baza podataka, repozitorijum velikih fajlova niti sistem za visokofrekventnu dinamičku konfiguraciju. Zahtevi za enkripcijom i rotacijom tajni, složenim validacionim šemama, distribucijom velikih artefakata ili trenutnim globalnim osvežavanjem mogu zahtevati Secret objekte, spoljašnji secrets manager, operator, CustomResourceDefinition ili namenski konfiguracioni servis.

Administrator sme da izvrši samo promene za koje ima i tehničko pravo i proceduralno odobrenje. Nejasno vlasništvo konfiguracije, sumnja da sadržaj uključuje tajne, neusaglašena očekivanja o reload ponašanju, neuspešna readiness proba, nedostupan rollback ili neočekivan uticaj na više aplikacija predstavljaju razlog za zaustavljanje promene i eskalaciju vlasniku aplikacije, platformskom arhitekti ili bezbednosnom timu. Profesionalno upravljanje ConfigMap objektima podrazumeva da svaka vrednost ima vlasnika, razlog, istoriju, validaciju i bezbedan put povratka.

← Prethodna lekcija Povratak na sadržaj Sledeća lekcija →