9 modulis · 9.3
Docker compose ir užkarda
9 modulis: Docker ir docker compose · Skaitymo laikas: 12 min.
Mokymosi tikslas: Po šios pamokos galėsite aprašyti paslaugas compose faile, jas paleisti, atnaujinti ir sustabdyti, ir paaiškinsite, kodėl Docker paskelbti prievadai apeina ufw ir kaip to išvengti.
Pagrindinės sąvokos: compose.yaml, services, image, ports, volumes, environment, .env, restart, networks, depends_on, healthcheck, docker compose up -d, pull, logs, down, nebenaudojamas version:, Docker ir ufw, DOCKER-USER, skelbimas per 127.0.0.1, slaptieji duomenys, docker.sock
Kodėl compose?
Su docker run (pamoka 9.2) paleidžiate vieną konteinerį su ilga parinkčių eilute. Tikra programa dažnai susideda iš kelių konteinerių: programos, duomenų bazės, atvirkštinio tarpinio serverio (reverse proxy). Prisiminti tas eilutes ir po perkrovimo ar atnaujinimo jas vėl įvesti ranka anksčiau ar vėliau nepavyks.
Docker Compose aprašo visus programos konteinerius viename faile: compose.yaml. Šį failą laikote atskirame kataloge, pavyzdžiui, /srv/status/compose.yaml, ir viską valdote su docker compose. Failas kartu yra ir Jūsų dokumentacija: kas veikia, koks atvaizdas (image), kokie prievadai, kur saugomi duomenys. Įtraukite šį katalogą į atsarginę kopiją (pamoka 8.1), ir programą naujame serveryje galėsite atkurti per kelias minutes.
Įskiepis vadinasi docker compose (su tarpu, 2 versija). Senoji atskira programa docker-compose (su brūkšneliu) yra pakeista; ją dar matysite senuose vadovuose. Taip pat nebenaudojamas laukas version: "3.8" senų failų viršuje: Compose visada naudoja naujausią schemą, o radęs version: tik parodo įspėjimą.
Kaip skaityti compose failą
Pavyzdys su programa ir PostgreSQL duomenų baze:
# /srv/notities/compose.yaml
services:
app:
image: ghcr.io/example/notities:1.4
restart: unless-stopped
ports:
- "127.0.0.1:8081:8080"
environment:
DB_HOST: db
DB_USER: notities
DB_PASSWORD: ${DB_PASSWORD}
depends_on:
db:
condition: service_healthy
db:
image: postgres:17
restart: unless-stopped
environment:
POSTGRES_USER: notities
POSTGRES_PASSWORD: ${DB_PASSWORD}
volumes:
- db-data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U notities"]
interval: 10s
retries: 5
volumes:
db-data:Žingsnis po žingsnio:
- services: kiekviena paslauga tampa konteineriu. Pavadinimas (
app,db) kartu yra ir mazgo vardas (hostname), pagal kurį konteineriai randa vienas kitą. Compose programai sukuria atskirą tinklą, todėlappjungiasi prie duomenų bazės adresudb:5432. - image: visada su versijos žyma (pamoka 9.1).
- restart: ką Docker daro, kai konteineris sustoja arba serveris perkraunamas.
unless-stoppedjį vėl paleidžia, nebent Jūs jį sustabdėte sąmoningai. Be restart taisyklės Jūsų programa po perkrovimo (pamoka 4.2) nebepasileis. - ports: prievadą skelbia tik programa ir tik per
127.0.0.1. Duomenų bazė nieko neskelbia: programa ją pasiekia per vidinį tinklą. Duomenų bazė suports: - "5432:5432"yra viena dažniausių klaidų (žr. toliau). - environment: programos nustatymai. Slaptažodis čia neįrašytas tiesiogiai, o nurodytas kaip
${DB_PASSWORD}. - volumes: pavadintas tomas
db-dataišsaugo duomenų bazę, kai konteineris pakeičiamas. - depends_on su healthcheck: programa pasileidžia tik tada, kai duomenų bazė iš tiesų parengta, o ne vien paleista.
Slaptieji duomenys .env faile
Compose tokius kintamuosius kaip ${DB_PASSWORD} nuskaito iš failo .env tame pačiame kataloge:
# /srv/notities/.env
DB_PASSWORD=Kies-hier-een-lang-willekeurig-wachtwoordanna@web1:/srv/notities$ sudo chmod 600 .envTaip slaptažodis nepatenka į compose failą, kurį galbūt laikote Git saugykloje arba įklijuojate forume, prašydami pagalbos. Įrašykite .env į .gitignore. Slaptažodį sukurkite slaptažodžių tvarkykle arba su openssl rand -base64 24.
Kasdienis naudojimas
Visas komandas vykdote kataloge, kuriame yra compose failas:
anna@web1:/srv/notities$ sudo docker compose config # patikrinti failą su įrašytais kintamaisiais
anna@web1:/srv/notities$ sudo docker compose up -d # paleisti viską (arba atnaujinti pagal failą)
anna@web1:/srv/notities$ sudo docker compose ps # kiekvienos paslaugos būsena
anna@web1:/srv/notities$ sudo docker compose logs -f app
anna@web1:/srv/notities$ sudo docker compose pull # atsisiųsti naujus atvaizdus
anna@web1:/srv/notities$ sudo docker compose up -d # pakeisti konteinerius naujais atvaizdais
anna@web1:/srv/notities$ sudo docker compose down # sustabdyti ir pašalinti konteineriusdown tomų nepaliečia. down -v ištrina ir programos tomus, o kartu ir Jūsų duomenų bazę. Įveskite tai tik tada, kai tikrai norite pradėti iš naujo.
docker compose config atitinka nginx -t ir sshd -t: ji parodo, kaip Compose supranta Jūsų failą su įrašytomis visų kintamųjų reikšmėmis, dar prieš ką nors paleidžiant. Atkreipkite dėmesį, kad šios išvesties niekur neįklijuotumėte, nes joje yra slaptažodžiai.
Docker apeina ufw
Dabar svarbiausias šio modulio saugumo klausimas. Pamokoje 5.2 nustatėte ufw taip: „viską atmesti, išskyrus SSH, 80 ir 443“. Galėtumėte tikėtis, kad konteineris su ports: - "5432:5432" tada bus nepasiekiamas. Taip nėra.
Docker dokumentacijoje tai pasakyta tiesiai: Docker ir ufw naudoja užkardos taisykles tarpusavyje nesuderinamu būdu. Kai paskelbiate prievadą, Docker pats įrašo taisykles į branduolio užkardą. Tos taisyklės nukreipia srautą į konteinerį (adresų transliacija, DNAT) dar prieš pritaikant ufw taisykles. Taigi paketas apeina ufw. ufw status nerodo nieko ypatingo, nors prievadas pasiekiamas iš viso interneto. Tas pats galioja ir firewalld.
Be to, jei adresas nenurodytas, Docker skelbia per 0.0.0.0 ir [::], t. y. ir per IPv4, ir per IPv6 (pamoka 9.1).
Trys būdai tai padaryti teisingai, nuo paprasčiausio iki sudėtingiausio:
- Neskelbkite nieko, kas neturi būti vieša. Duomenų bazėms, podėliams (cache) ir vidinėms paslaugoms
ports:nenurodoma. Tos pačios compose programos konteineriai vienas kitą pasiekia per vidinį tinklą. - Skelbkite per loopback.
"127.0.0.1:8081:8080". Tada prieigą turi tik pats serveris, o priekyje pastatote atvirkštinį tarpinį serverį (nginx arba Caddy, modulis 7), kuris klauso 443 prievado. Docker tai galima nustatyti ir kaip numatytąjį elgesį: daemon nustatymas nukreipia visus be adreso paskelbtus prievadus į127.0.0.1. - Taisyklės DOCKER-USER grandinėje. Docker sukuria tuščią grandinę
DOCKER-USER, kuri tikrinama prieš jo paties taisykles. Ten galite įrašyti savo taisykles, pavyzdžiui, „į paskelbtus prievadus gali jungtis tik šis IP adresas“. Tai pažengusiųjų darbas su iptables arba nftables, ir čia lengva suklysti. Daugumai mažų serverių pakanka 1 ir 2 būdų.
Visada tikrinkite iš išorės, kaip pamokoje 5.1: nc -vz -w 3 <ip> 5432 iš savo nešiojamojo kompiuterio arba kurso patikra užduotyse Z5.1 ir Z10.4.
Dar du dalykai, kurių nedarykite
- Nemontuokite
/var/run/docker.sockį konteinerį, nebent tiksliai žinote kodėl. Konteineris, turintis prieigą prie Docker lizdo (socket), gali pats paleisti konteinerius, taip pat ir tokį, kuris mato visą pagrindinio serverio diską (pamoka 9.2). Kai kurios pagalbinės programos (valdymo skydeliai, automatiniai atnaujintojai) to prašo; iš esmės tai reiškia, kad tai programai suteikiate root teises. - Nenaudokite
privileged: truearnetwork_mode: hostvien todėl, kad taip parašyta vadove. Abi parinktys didele dalimi panaikina konteinerio izoliaciją. Naudokite tik tada, kai kūrėjas paaiškina, kodėl to reikia.
Santrauka
- Compose failas (
compose.yaml) aprašo visus programos konteinerius; jis kartu yra dokumentacija ir turi patekti į atsarginę kopiją. - Naudokite versijų žymas, restart taisyklę, pavadintus tomus, healthcheck, kur įmanoma, o slaptuosius duomenis laikykite
.envfaile su 600 teisėmis. docker compose config,up -d,ps,logs,pull,down;down -vištrina ir tomus.- Paskelbti prievadai apeina ufw ir firewalld. Skelbkite tik tai, kas turi būti vieša, o visa kita per
127.0.0.1su atvirkštiniu tarpiniu serveriu priekyje. - Jokio docker.sock,
privilegedarnetwork_mode: hostbe svarios priežasties.
Testas (quiz)
Užduotis
Užduotis Z9.3: Compose failo patikrinimas. Pavyzdiniame faile compose-nakijken.txt (kaip tekstiniame faile) pateiktas nedidelės internetinės parduotuvės compose failas su programa, duomenų baze, podėliu ir administravimo įrankiu. Jame yra šešios klaidos, aptartos šioje pamokoje arba pamokose 9.1 ir 9.2. Prie kiekvieno sunumeruoto eilučių bloko nurodykite, ar jis teisingas, ar klaidingas, o prie kiekvienos klaidos pasirinkite tinkamą pataisymą. Programa palygina atsakymus su nustatytu raktu. Jei turite savo compose failą, po to patikrinkite jį pagal tuos pačius punktus.
Skaitykite daugiau
- Docker dokumentacija, How Compose works (compose.yaml): https://docs.docker.com/compose/intro/compose-application-model/
- Docker dokumentacija, Version and name top-level elements: https://docs.docker.com/reference/compose-file/version-and-name/
- Docker dokumentacija, Packet filtering and firewalls (Docker and ufw): https://docs.docker.com/engine/network/packet-filtering-firewalls/
- Docker dokumentacija, Port publishing and mapping: https://docs.docker.com/engine/network/port-publishing/
- Docker dokumentacija, Interpolation (kintamieji ir .env): https://docs.docker.com/reference/compose-file/interpolation/
- VPS: nuo pirmojo prisijungimo iki saugaus serverio 6.2: Jūsų darbo aplankas su compose.yaml, .env ir Caddy
- VPS: nuo pirmojo prisijungimo iki saugaus serverio 6.3: Docker ir užkarda: kaip saugiai publikuoti prievadus
