EDUCATION · DOCKER · CONTAINERS

🐳 Docker un konteinerizācija

Vienkāršā valodā, ar drošības skatījumu - no ceļakartes (kāpēc konteineri radās un kurp ved) līdz komandām, videi un drošībai. Katrā tēmā skaidras priekšrocības un trūkumi. Pēc starptautiskās prakses (OCI, NIST SP 800-190, CIS Docker Benchmark). Piemēri ir vispārīgi, paredzēti apmācībām.

Kur Docker iederas un kurp tas ved

Ceļakarte: no servera līdz konteineru infrastruktūrai

Ceļakarte no fiziskiem serveriem līdz konteineru orķestrēšanai Seši soļi izvietošanas attīstībā - fiziskie serveri, virtuālās mašīnas, konteiners, attēls un reģistrs, Docker Compose un orķestrēšana - ar pieaugošu drošības nozīmi virzienā uz produkciju. No servera līdz konteineru infrastruktūrai Pelēkais - pirms Docker · krāsainais - šī ceļveža tēmas 1 Fiziskie serveri viena lietotne 2 Virtuālās mašīnas vairākas OS 3 Konteiners kopīgs kodols 4 Attēls + reģistrs iepako, koplieto 5 Compose daudz konteineru 6 Orķestrēšana mērogs, K8s Laiks · briedums · mērogs Drošība: jo tuvāk produkcijai, jo kritiskāka izolācija · uzticami un skenēti attēli · noslēpumi ārpus attēla · tīkla segmentācija Šis ceļvedis: konteiners → attēls → komandas → Compose → drošība

Kā lasīt ceļvedi

Roadmap parāda, kāpēc konteineri radās (VM bija smagas) un kurp tie ved (orķestrēšana produkcijā). Nākamās cilnes iet soli pa solim - no viena konteinera līdz daudzkonteineru videi un drošībai.

Atsauce

Izvietošanas attīstība: fiziski serveri → virtualizācija → konteineri → orķestrēšana (Kubernetes). OCI · NIST SP 800-190.

Drošības skatījums

Katrs solis pievieno drošības uzdevumus: izolācija (konteiners), uzticami attēli (reģistrs), noslēpumi un tīkli (Compose), politikas un skenēšana (orķestrēšana).

Konteinerizācijas pamati

Virtuālā mašīna vs konteiners

Virtuālās mašīnas un konteineri salīdzinājums Pa kreisi virtuālās mašīnas, kur katrai ir sava pilna operētājsistēma; pa labi konteineri, kas dala vienu resursdatora kodolu un tāpēc ir vieglāki. Virtuālā mašīna vs konteiners Konteineri dala resursdatora kodolu - tāpēc vieglāki un ātrāki Virtuālās mašīnas Lietotne A Lietotne B Lietotne C Viesa OS Viesa OS Viesa OS Hipervizors Infrastruktūra Konteineri Lietotne A Lietotne B Lietotne C Bibliotēkas Bibliotēkas Bibliotēkas Docker Engine Resursdatora OS - viens kopīgs kodols Infrastruktūra savs kodols katrai VM = spēcīga izolācija, bet smags kopīgs kodols = viegls, bet vājāka izolācija Drošība: kopīgs kodols → izrāviens (escape) var apdraudēt resursdatoru

Konteineri ir viegli un ātri tāpēc, ka dala resursdatora kodolu - bet tieši tāpēc izolācija ir vājāka nekā virtuālajām mašīnām. Tas ir galvenais drošības kompromiss.

🏢 Analoģija bez priekšzināšanām

Iedomājies dzīvojamo māju. Virtuālā mašīna ir tā, it kā katram iedzīvotājam uzbūvētu pilnīgi atsevišķu māju - ar savu pamatu, jumtu un ūdensvadu. Droši (viena mājas problēma neskar kaimiņus), bet dārgi un lēni uzbūvēt. Konteiners ir kā dzīvoklis daudzdzīvokļu mājā - katram iedzīvotājam savas telpas ar savām durvīm, bet pamats, jumts un caurules ir KOPĪGAS visai ēkai. Lētāk un ātrāk uzcelt, bet plānāka starpsiena nozīmē, ka nopietna problēma (piemēram, ugunsgrēks pamatos) var skart visus iedzīvotājus reizē. Resursdators (host) šajā analoģijā ir pati ēka - fiziskais vai virtuālais serveris, uz kura Docker darbojas.

Priekšrocības (+)

  • Pārnesamība - vienādi darbojas izstrādē, testā un ražošanā
  • Ātrs starts (sekundes) un efektīva resursu izmantošana
  • Viegli mērogot, atjaunināt un atgriezt versiju
  • Atkārtojama vide - "strādā uz mana datora" problēma pazūd
  • Lietotnes izolētas cita no citas

Trūkumi un riski (-)

  • Kopīgs kodols - vājāka izolācija nekā VM (izrāviena risks)
  • Dati ir īslaicīgi - bez volume tie pazūd
  • Plašāka drošības virsma - attēli ar ievainojamībām (CVE)
  • Nepareiza konfigurācija (root, --privileged) = augsts risks
  • Mērogā - orķestrēšanas sarežģītība un jaunas prasmes

Drošības skatījums

Izolāciju nodrošina Linux kodola mehānismi (namespaces, cgroups, capabilities). Root konteinerā plus kodola ievainojamība = izrāviens uz resursdatoru. Tāpēc: nedarbini kā root un atmet liekās privilēģijas.

Kad konteineri der

Konteineri der lielākajai daļai lietotņu - mikroservisiem, izstrādes videm, CI/CD, ātrai mērogošanai. Ja jāpalaiž pilnīgi neuzticams kods (piemēram, svešu lietotāju augšupielādēti skripti) - apsver VM vai papildu izolācijas slāni (gVisor, Kata Containers).

Atsauce

OCI (Open Container Initiative) - attēlu un izpildlaika standarti · NIST SP 800-190 · Linux namespaces / cgroups · Docker / containerd.

Divi galvenie jēdzieni

Attēls (image) = veidne · konteiners = darbojošās instance

Attēls, reģistrs un konteiners Attēls tiek lejupielādēts no reģistra un ir tikai lasāms slāņu kopums; docker run izveido konteineru, kas ir attēls plus rakstāms slānis. Attēls → konteiners Attēls = recepte (veidne) · konteiners = gatavs ēdiens (darbojošās instance) Reģistrs Docker Hub · GHCR · privāts Attēls (image) - tikai lasāms slānis: lietotnes kods slānis: bibliotēkas slānis: izpildvide slānis: minimāla bāzes sistēma Konteiners - darbojas rakstāms slānis lietotnes kods (lasāms) bibliotēkas (lasāms) izpildvide (lasāms) bāzes OS (lasāms) docker pull docker run Viens attēls → daudz konteineru · rakstāmais slānis pazūd, kad konteineru dzēš

Pielietojums

Attēls ir nemainīga veidne, ko var koplietot un versionēt; no viena attēla palaiž daudzus vienādus konteinerus. Tāpēc vide ir atkārtojama un paredzama.

Atsauce

OCI Image Specification · Docker Hub / GitHub Container Registry (GHCR) · attēlu slāņi (layers) un to kešošana.

Drošības skatījums

Attēls no neuzticama avota var saturēt ievainojamības vai aizmugures durvis. Lieto oficiālus vai parakstītus attēlus, skenē tos (CVE) un fiksē versijas. Rakstāmais slānis ir īslaicīgs - pastāvīgiem datiem vajag volume.

Seko līdzi un izmēģini pats

Praktisks piemērs: no viena faila līdz strādājošai tīmekļa lapai

Ceļš no koda līdz darbojošās konteineram Kods un Dockerfile tiek pārvērsti attēlā ar docker build, attēls tiek palaists kā konteiners ar docker run un augšupielādēts reģistrā ar docker push. No koda līdz rezultātam Viens un tas pats ceļš uz izstrādātāja datora un ražošanā Kods lietotne + Dockerfile Attēls iepakota veidne Konteiners = darbojošās lietotne build run Reģistrs koplietošana docker build -t mana-lapa . docker run mana-lapa docker push Kāpēc tas ir svarīgi Attēls satur VISU, kas lietotnei vajadzīgs → tas pats attēls darbojas identiski jebkur (izstrādē, testā, ražošanā).

Tālāk - reāls piemērs ar precīzām komandām un to, ko tieši redzēsi ekrānā. Vari sekot līdzi uz sava datora, ja Docker ir instalēts.

1

Sagatavo divus failus vienā mapē

Tev vajag tikai vienu HTML failu (tavu lapu) un vienu Dockerfile (instrukciju Docker'am). Neviena programmēšana nav nepieciešama.

mana-lapa/
├── index.html      ← tava tīmekļa lapa
└── Dockerfile       ← instrukcija, kā to iepakot
2

Uzraksti Dockerfile - 2 rindas

Dockerfile vienmēr ir vienkāršs teksta fails bez paplašinājuma. Šīs divas rindas nozīmē: "sāc ar gatavu web serveri" un "iekopē manu failu tajā vietā, kur serveris meklē lapas".

FROM nginx:alpine          ← 1) izmanto gatavu web servera attēlu
COPY index.html /usr/share/nginx/html/  ← 2) iekopē tavu failu iekšā
3

Uzbūvē attēlu - docker build

Atver termināli šajā mapē un ieraksti šo komandu. "-t mana-lapa" dod attēlam nosaukumu "mana-lapa", lai to varētu vēlāk atrast; pēdējais punkts "." nozīmē "meklē Dockerfile šeit, pašreizējā mapē".

$ docker build -t mana-lapa .
Sending build context to Docker daemon
Step 1/2 : FROM nginx:alpine
Step 2/2 : COPY index.html /usr/share/nginx/html/
Successfully tagged mana-lapa:latest
4

Palaid konteineru - docker run

"-d" palaiž konteineru fonā (terminālis paliek brīvs); "-p 8080:80" savieno tava datora portu 8080 ar portu 80 konteinera iekšpusē (tur klausās nginx).

$ docker run -d -p 8080:80 mana-lapa
a1b2c3d4e5f6...  ← konteinera ID (garš, unikāls kods)
5

Apskaties rezultātu

Atver pārlūkprogrammu un dodies uz šo adresi - redzēsi savu index.html lapu, ko apkalpo konteinerī darbojošais nginx.

http://localhost:8080  ← atver šo pārlūkā
6

Apturi un iztīri, kad pabeidzis

docker ps parāda darbojošos konteinerus un to ID; ar šo ID vari konteineru apturēt un pēc tam dzēst.

$ docker ps
CONTAINER ID   IMAGE       PORTS                  STATUS
a1b2c3d4e5f6   mana-lapa   0.0.0.0:8080->80/tcp   Up 2 minutes

$ docker stop a1b2c3d4e5f6
$ docker rm a1b2c3d4e5f6

Ko tu tikko izdarīji

Uzbūvēji savu pirmo attēlu, palaidi to kā konteineru un redzēji rezultātu pārlūkā - tas ir viss cikls. Tālākās cilnes paskaidro katru komandu sīkāk un ko darīt, ja vajag vairāk nekā vienu konteineru.

Atsauce

Dockerfile reference · OCI Image Spec · CI/CD konveijeros attēlu būvē un skenē automātiski (sk. "Droša izstrāde" ceļvedi).

Piezīme

Ja mapē ir arī citi faili (piemēram, noslēpumi vai .git), pievieno .dockerignore failu, lai tie NEnonāktu attēlā - tas strādā tāpat kā .gitignore.

Katras komandas daļas ir precīzi definētas

Galvenās Docker komandas

Docker komandas uzbūve (anatomija) Komanda docker run -d -p 8080:80 mana-lapa sadalīta piecās daļās ar precīzu katras daļas nozīmi - programma, apakškomanda, karodziņš, porta kartējums un attēla nosaukums. Komandas uzbūve - katrai daļai precīza nozīme Turpinām iepriekšējo piemēru - katra daļa skaidrota atsevišķi, lai nekas nav interpretējams docker run -d -p 8080:80 mana-lapa Katra daļa nozīmē tieši šo un neko citu: docker programma - Docker komandrindas rīks, ar kuru dod visas pavēles run apakškomanda - "palaid jaunu konteineru no attēla" -d karodziņš "detached" - darbojas fonā, terminālis paliek brīvs -p 8080:80 porta kartējums: KREISAIS_SKAITLIS = tavs dators, LABAIS = konteinera iekšpuse mana-lapa attēla nosaukums - PRECĪZI norāda, KURU attēlu palaist docker <komanda> [karodziņi] [arguments] Šī uzbūve atkārtojas VISĀS Docker komandās zemāk - komanda vienmēr pirms karodziņiem

Konteinera dzīves cikls: uzbūvēts attēls → docker run → darbojas → docker stop → apturēts → docker rm → dzēsts. Katru pāreju izraisa TIEŠI viena komanda.

Attēli

docker build -t mana-lapa .izveido attēlu no Dockerfile šajā mapē; "-t mana-lapa" piešķir tam nosaukumu
docker imagesparāda VISUS attēlus, kas saglabāti tavā datorā
docker pull nginx:alpinelejupielādē gatavu attēlu "nginx" no Docker Hub (noklusētā reģistra)
docker push mana-lapaaugšupielādē tavu attēlu reģistrā (vispirms nepieciešams docker login)
docker rmi mana-lapadzēš attēlu no tava datora (rmi = remove image)

Konteineri

docker run -d -p 8080:80 mana-lapapalaiž jaunu konteineru fonā, tavs ports 8080 → konteinera ports 80
docker psparāda TIKAI darbojošos konteinerus
docker ps -aparāda VISUS konteinerus, arī apturētos (-a = all)
docker stop IDaptur darbojošos konteineru (dati konteinerī paliek)
docker exec -it ID shatver interaktīvu komandrindu KONTEINERA IEKŠPUSĒ (-it = interaktīvi)
docker rm IDNEATGRIEZENISKI dzēš apturētu konteineru

Docker Compose

docker compose up -dizveido un palaiž VISUS servisus no compose.yaml, fonā
docker compose downaptur un noņem visus servisus un tīklu (dati volumes SAGLABĀJAS)
docker compose logs -fseko VISU servisu žurnāliem reāllaikā (-f = "seko"/follow)
docker compose psparāda compose vides servisu statusu

Diagnostika un tīrīšana

docker logs -f IDseko VIENA konteinera izvadei reāllaikā (Ctrl+C, lai izietu)
docker inspect IDparāda pilnu tehnisko informāciju (IP adrese, volumes u.c.)
docker statsrāda CPU/atmiņas patēriņu VISIEM darbojošamies konteineriem
docker system pruneDZĒŠ apturētos konteinerus un neizmantotos attēlus - prasa apstiprinājumu

Ko nozīmē "ID" piemēros

"ID" = konteinera identifikators no docker ps kolonnas CONTAINER ID. Pietiek pirmie 3-4 simboli (piem., a1b2), vai lieto konteinera vārdu, ja to piešķīri ar --name.

Bīstamās komandas

--privileged izslēdz gandrīz visu izolāciju - konteiners iegūst tikpat daudz tiesību, cik resursdatora root lietotājam. Tikpat bīstami ir dot konteinerim piekļuvi Docker vadības kanālam (/var/run/docker.sock) - tas ļauj kontrolēt VISUS pārējos konteinerus un pašu resursdatoru. Lieto abus TIKAI ar skaidru iemeslu.

Daudzkonteineru vide vienā failā

Docker Compose - visa vide ar vienu komandu

Docker Compose vides izveide Viens compose.yaml fails apraksta vairākus servisus; docker compose up izveido visus konteinerus vienā tīklā ar kopīgu datu glabātuvi. Viens fails → visa vide compose.yaml apraksta servisus, tīklu un datus; docker compose up to izveido compose.yaml services: web: build: . ports: ["8080:80"] db: image: postgres:16 volumes: [data:/data] cache: image: redis:7 volumes: data: up -d Tīkls: appnet web :8080 db postgres cache redis volume data docker compose up -d → 3 konteineri vienā tīklā · db dati glabājas volume · down noņem

Iedomājies: tavai "mana-lapa" vajag arī datubāzi. Bez Compose tev būtu manuāli jāpalaiž divi "docker run", jāizveido tīkls un jāsavieno tie. Ar Compose - viens fails, viena komanda.

$ docker compose up -d
 Network appnet       Created
 Container app-web-1     Started
 Container app-db-1      Started
 Container app-cache-1   Started

$ docker compose ps
NAME             IMAGE          STATUS         PORTS
app-web-1        app-web        Up 5 seconds   0.0.0.0:8080->80/tcp
app-db-1         postgres:16    Up 5 seconds
app-cache-1      redis:7        Up 5 seconds

Pielietojums

Reālas lietotnes reti ir viens konteiners - parasti web + datubāze + kešs. Compose apraksta tos visus vienā failā un palaiž ar vienu komandu; visi automātiski redz cits citu tīklā.

Atsauce

Compose Specification (compose.yaml) - lieto "docker compose" (v2), NE novecojušo "docker-compose" (v1). Mērogā - Kubernetes.

Piezīme

Konteineri ir īslaicīgi - datubāzes datus glabā volume, citādi tie pazūd pēc "down". Noslēpumus (paroles) padod caur vides mainīgajiem, ne failā.

Labākā prakse un drošība

Mazāks, drošāks, ātrāks attēls

Docker labākā prakse trīs jomās Ieteikumi trīs grupās - attēla veidošana, izpildlaika drošība un piegāde - pēc starptautiskās prakses. Labākā prakse un drošība Mazs attēls = mazāka uzbrukuma virsma un ātrāks starts Attēls · Mazs bāzes attēls (alpine/distroless) · Multi-stage būve (mazāks gala attēls) · Fiksē versijas (nginx:1.27, ne latest) · .dockerignore (bez liekiem failiem) · Viena lietotne uz konteineru · Biežāk mainīgo liec Dockerfile beigās Izpildlaiks · Nedarbini kā root (USER) · Tikai-lasāma failu sistēma · Atmet liekās privilēģijas (capabilities) · NEKAD --privileged bez vajadzības · Ierobežo CPU/atmiņu · Rootless režīms, ja iespējams Piegāde · Skenē attēlus (CVE) pirms izlaišanas · Noslēpumi ārpus attēla · Paraksti attēlus (izcelsme) · Uzticami bāzes attēli (oficiālie) · Regulāri pārbūvē (jaunie ielāpi) · SBOM - sastāvdaļu saraksts OCI · NIST SP 800-190 · CIS Docker Benchmark · Docker labākās prakses vadlīnijas

Konkrēts piemērs - tas pats mērķis (palaist Node.js lietotni), bet viena versija ir riskanta, otra droša:

Riskanti

FROM ubuntu:latest
COPY . /app
WORKDIR /app
RUN npm install
CMD ["node", "server.js"]

"latest" = neparedzams (mainās bez brīdinājuma); nav USER rindas → darbojas kā root; nav .dockerignore → noslēpumi/.git var nokļūt attēlā.

Droši

FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --omit=dev
COPY . .
USER node
CMD ["node", "server.js"]

Fiksēta versija (20-alpine); mazs bāzes attēls; USER node = darbojas BEZ root tiesībām; atkarības kopētas pirms koda (ātrāka atkārtota būve).

Kāpēc mazs attēls

Mazāks bāzes attēls (alpine, distroless) satur mazāk pakotņu → mazāk ievainojamību, ātrāka lejupielāde un starts. Multi-stage būve izmet būvēšanas rīkus no gala attēla.

Atsauce

NIST SP 800-190 (Application Container Security Guide) · CIS Docker Benchmark · OCI · Docker Official Images.

Drošības piezīme

Konteiners dala resursdatora kodolu - root konteinerā ir bīstamāks nekā VM. Nedarbini kā root, atmet liekās privilēģijas un nekad neizmanto --privileged bez skaidras vajadzības.

Vārdnīca

Galvenie jēdzieni vienkāršā valodā (oriģināls un nozīme).

konteiners
izolēta, viegla lietotnes pakete ar visu vajadzīgo, kas dala resursdatora kodolu.
attēls / image
tikai-lasāma konteinera veidne (šablons), no kuras palaiž konteinerus.
Dockerfile
teksta instrukcijas, kā salikt attēlu (bāze, atkarības, kods, palaišana).
apakškomanda
otrais vārds komandā, piem. "run" komandā docker run - nosaka, KO Docker darīs.
karodziņš / flag
komandas papildu parametrs ar defisi priekšā (piem. -d, -p), kas maina tās darbību.
porta kartējums
-p 8080:80 nozīmē: tavs dators (8080) → konteiners (80). Kreisā puse VIENMĒR resursdators.
būves konteksts
mape, ko Docker izmanto attēla būvēšanai - parasti norādīta ar punktu (.) komandas beigās.
reģistrs / registry
attēlu krātuve - Docker Hub, GHCR vai privāts.
tags
attēla versijas apzīmējums, piem. mana-lapa:1.0.
volume
pastāvīga datu glabātuve ārpus konteinera (pārdzīvo tā dzēšanu).
bind mount
resursdatora mapes piesaiste konteinerā (bieži izstrādē).
tīkls / network
konteineru savstarpējā saziņa pēc servisa nosaukuma.
Compose
daudzkonteineru vides definīcija vienā compose.yaml failā.
Kubernetes
konteineru orķestrēšana mērogā (daudz mašīnu, auto-atjaunošana).
OCI
Open Container Initiative - attēlu un izpildvides standarti.
kodols / kernel
operētājsistēmas pamatkomponente, kas pārvalda aparatūru un procesus; konteineri to dala ar resursdatoru.
daemon
Docker fona serviss (dockerd), kas pārvalda konteinerus.
ephemeral
īslaicīgs - konteineru var iznīcināt un no jauna radīt jebkurā brīdī.
multi-stage
būve vairākos posmos, lai gala attēls būtu mazs (bez būvēšanas rīkiem).
distroless
minimāls bāzes attēls bez čaulas un pakotņu pārvaldnieka (mazāka virsma).
rootless
Docker darbība bez root privilēģijām (drošāk).