Kuinka Docker-tottumusteni siistiminen teki minusta tuottavamman

- Väärien pohjakuvien valitseminen
- Salaisuuksien ja tunnusten kovakoodaus
- Viimeisimmän tagin käyttäminen sen sijaan, että käytettäisiin erityisiä versioita
- Puuttuva tai väärin konfiguroitu .dockerignore
- Tehoton kerrosjärjestys
- Kaiken pakkaaminen yhteen vaiheeseen
- Säilöjen käyttäminen rootina
- Resurssirajojen ei asettaminen
- Ylikäyttö etuoikeustilassa
Dockerin käyttöön liittyy monia haasteita. Tässä artikkelissa jaan tärkeimmät virheet, jotka tein, ja miten niiden välttäminen paransi tuottavuuteni.
Kun aloin ensimmäistä kertaa käyttää Dockeria, suurimmat virheeni eivät liittyneet komentoihin tai konfiguraatioon. Ne olivat päätöksiä, jotka myöhemmin aiheuttivat tietoturvaongelmia, turhia kuvia ja tunteja kestäviä virheenkorjauksia. Silloin ainoa tavoitteeni oli saada säilöt toimimaan. En ajatellut parhaita käytäntöjä tai kuinka nuo aikaiset valinnat vaikuttaisivat suorituskykyyn ja turvallisuuteen pitkällä aikavälillä.
Kokemuksen myötä tajusin, että Docker on enemmän kuin pakkaustyökalu; se on työnkulku, joka vaatii huolellista suunnittelua. Vaikka säilötys takaa johdonmukaiset ympäristöt ja helpottaa käyttöönottoa, se tuo mukanaan myös haasteita, kuten tietoturvahaavoittuvuuksia, verkko-ongelmia ja jopa ristiriitoja VPN:ien kanssa.
Tässä artikkelissa jaan suurimmat virheet, jotka tein Dockerin kanssa, ja kuinka niiden korjaaminen lisäsi tuottavuuttani.
Väärien pohjakuvien valitseminen
Yksi suurimmista opetuksistani alussa oli se, että valitsemasi pohjakuvan valinta vaikuttaa kaikkeen: vetämiseen, rakentamiseen, käyttöönottoon, skannaamiseen ja jopa virheenkorjaukseen. Aluksi käytin täysiä käyttöjärjestelmäkuvia, kuten "ubuntu:latest", pelkästään siksi, että ne tuntuivat tutuilta. Mutta nämä suuret kuvat toivat mukanaan piilokustannuksia: hitaammat rakentamiset, painavammat käyttöönotot ja ylisuuria lopullisia säilöjä.
Kun siirryin minimaalisiin ja tarkoituksenmukaisiin kuviin, kuten "Alpine", "Slim" tai virallisiin kielikohtaisiin kuviin, ero oli heti havaittavissa. Kuvani pienenivät, rakentaminen valmistui nopeammin ja tietoturvaskannaukset näyttivät vähemmän haavoittuvuuksia.
Tietenkin minimaalisten kuvien käyttö ei aina ole oikea valinta; jotkin projektit tarvitsevat todella niitä kirjastoja, jotka tulevat Ubuntu- tai Debian-kuvien mukana. Todellinen tuottavuuden lisäys tulee siitä, että valitset pohjakuvan tarkoituksellisesti, etkä tottumuksesta. Valitse kuva, joka vastaa projektisi todellisia tarpeita, ja tunnet parannuksen koko työnkulussasi.
Salaisuuksien ja tunnusten kovakoodaus
Salaisuuksien kovakoodaus oli yksi suurimmista virheistäni alussa. Laitoin asioita, kuten tietokannan URL-osoitteet ja API-avaimet suoraan Dockerfileen, koska se tuntui kätevältä.
Kuitenkin näin tekeminen tarkoitti, että nämä salaisuudet tallennettiin kuvan sisään ja päätyivät lopulta versionhallintaan. Kuka tahansa, joka pääsi kuvalle tai varastoon, pystyi näkemään ne, mikä on vakava tietoturvaongelma.
Turvallisempi tapa on pitää Dockerfile vapaa herkistä tiedoista ja välittää todelliset salaisuudet vain, kun säilö toimii. Esimerkiksi, sen sijaan että kirjoittaisit todelliset arvot Dockerfileen, asetat tyhjät ympäristömuuttujat.
# Pidä Dockerfile puhtaana
ENV DATABASE_URL=""
ENV API_KEY=""Sitten annat todelliset arvot ajonaikana näin.
docker run -e DATABASE_URL="postgres://user:pass@localhost:5432/appdb" -e API_KEY="my_real_key_here" myappTämä pitää salaisuudet kuvan ulkopuolella, estää herkkien tietojen työntämisen Gitiin ja helpottaa arvojen päivittämistä ilman mitään uudelleenrakentamista.
Viimeisimmän tagin käyttäminen sen sijaan, että käytettäisiin erityisiä versioita
Viimeisimmän tagin käyttäminen näyttää helpolta, mutta se johtaa usein arvaamattomiin rakentamisiin. Sama Dockerfile voi käyttäytyä eri tavalla yhdestä päivästä toiseen, koska pohjakuva muuttuu hiljaa taustalla. Esimerkiksi, kirjoittamalla FROM node:latest voi toimia tänään, mutta huomenna Docker voi vetää uudempaa Node-versiota, ja rakennuksesi saattaa epäonnistua ilman, että teet muutoksia.
Asiat sujuivat paljon sujuvammin, kun aloin käyttää erityisiä versioita näin.
FROM node:20
FROM python:3.10Tämä varmistaa vakaat rakennukset, helpottaa virheenkorjausta ja estää yllätysongelmia, joita aiheuttavat piilotetut päivitykset. Se säästää myös aikaa, koska tiedät aina tarkalleen, missä ympäristössä sovelluksesi toimii.
Puuttuva tai väärin konfiguroitu .dockerignore
Yksi virhe, jonka tein aikaisessa vaiheessa, oli .dockerignore-tiedoston käyttämättömyys. Oletusarvoisesti Docker sisällyttää koko projektikansion rakennuskontekstiin, kaikkea "node_modules" ja ".git" -kansioista, väliaikaisista tiedostoista ja jopa suurista tietoaineistoista, joista unohdit. Tämä voi tehdä rakentamisista hitaita ja kuvia tarpeettoman suuria.
Välttääksesi tällaisia tilanteita, luo ".dockerignore" -tiedosto ja kerro Dockerille, mitä ei tule sisällyttää. On suositeltavaa aina sivuuttaa kansiot, kuten ".git", "node_modules", lokit, välimuistit ja väliaikaiset tiedostot.
Se on pieni toimenpide, mutta sen vaikutus voi olla suuri.
askel, joka tekee suurta eroa.
Tehoton kerrosjärjestys
Toinen virhe, jota kannattaa välttää, on Dockerfile-ohjeiden järjestäminen väärään järjestykseen. Docker luo uuden kerroksen jokaiselle ohjeelle. Jos aikaisempi kerros muuttuu, kaikki sen jälkeen rakennetaan uudelleen. Aikaisemmin kirjoitin Dockerfilejä näin.
# Huono kerrosrakennus. Mikä tahansa koodimuutos pakottaa täydelliseen uudelleenrakentamiseen
FROM node:18-alpine
WORKDIR /app
COPY . .
RUN npm install
CMD ["npm", "start"]Tässä COPY .. on sijoitettu liian aikaisin. Vaikka muutin vain yhden JavaScript-tiedoston, Docker joutui asentamaan kaikki riippuvuudet uudelleen, koska välimuisti oli mitätöity. Tämä teki rakennuksistani tarpeettoman hitaita.
Parempi lähestymistapa on erottaa riippuvuudet sovelluskoodista, jotta Docker voi välimuistaa ne oikein.
# Parannettu kerrosrakennus. Riippuvuudet välimuistitetaan erikseen
FROM node:18-alpine
WORKDIR /app
# Kopioi ensin vain riippuvuustiedostot
COPY package*.json ./
RUN npm install
# Kopioi loput sovelluksesta myöhemmin
COPY . .
CMD ["npm", "start"]Optimoidaksesi vielä enemmän, voit ryhmitellä ohjeet sen mukaan, kuinka usein ne muuttuvat.
# Järjestelmäpaketit (harvoin muuttuvat)
RUN apk add --no-cache git bash
# Sovelluksen riippuvuudet (yleensä muuttuvat kuukausittain)
COPY package*.json ./
RUN npm ci --only=production
# Sovelluksen lähdekoodi (muuttuu usein)
COPY . .Sijoittamalla vakaimmat kerrokset ensin ja usein muuttuvat kerrokset viimeiseksi, Docker voi käyttää välimuistissa olevia vaiheita uudelleen.
Kaiken pakkaaminen yhteen vaiheeseen
Kun aloitin Dockerin käytön, en tajunnut, kuinka paljon painoa lisään kuviini, kun pakkaan kaiken: kehitystyökalut, kääntäjät, testausohjelmat ja rakennustulokset, yhteen Dockerfileen. Toimitin kuvia, jotka olivat valtavia, hitaita vetää ja ehdottomasti ei tuotantokelpoisia. Suurin osa tästä tavarasta ei ollut koskaan tarkoitettu tuotantoon, mutta se jäi sinne, koska rakennin kaiken yhdessä vaiheessa.
Kun opin kuinka monivaiheiset rakennukset toimivat, asiat muuttuivat heti. Voisin suorittaa kaikki raskaat vaiheet yhdessä vaiheessa ja sitten luoda puhtaan, minimaalisen lopullisen kuvan, joka sisälsi vain mitä sovellus tarvitsi toimiakseen. Tämä teki kuvistani nopeampia käyttää, turvallisempia ja paljon pienempiä.
Säilöjen käyttäminen rootina
Aloittaessani en pohtinut paljoa, millä käyttäjällä säilöni suoritti. Docker oletuksena käyttää rootia, joten menin vain sen mukaan. Myöhemmin tajusin, että tämä oli vakava virhe. Käyttäminen rootina antaa säilölle paljon enemmän kontrollia kuin useimmat sovellukset koskaan tarvitsevat, ja yksi pieni väärinmääritys voi altistaa järjestelmäsi tarpeettomille riskeille.
Esimerkiksi seuraava tuloste osoittaa, että säilö toimii root-käyttäjänä, mikä tarkoittaa, että sillä on superuser-oikeudet. Se voi muuttaa herkkiä järjestelmäalueita, käyttää järjestelmälaitteita ja jopa vuorovaikuttaa laitteistotason ryhmien kanssa, mikä on vakava turvallisuusriski minkä tahansa tuotantoympäristön osalta.
Kun ymmärsin tämän, vaihdoin luomaan erityisen käyttäjän sisään kuvaan ja käyttämään sovellusta sen käyttäjän kautta sen sijaan, että käyttäisin rootia.
# Luo turvallisempi käyttäjä ja ryhmä sovellusta varten
RUN addgroup -S webgroup && adduser -S webuser -G webgroup
# Kopioi projektitiedostot ja määritä oikea omistus
COPY --chown=webuser:webgroup . /app
# Suorita säilö ei-root-käyttäjänä
USER webuserTällä tavoin ei-root-käyttäjän käyttäminen tekee säilöstä turvallisemman, vähentää oikeuksien riskejä ja noudattaa parhaita turvallisuuskäytäntöjä, lisäämättä monimutkaisuutta.
Resurssirajojen ei asettaminen
Ilman rajoja säilöt voivat kuluttaa kaikki järjestelmän resurssit, hidastaen tai kaatamalla isäntäsi. Koin tämän raskaan rakennuksen aikana; yksi hallitsematon säilö pysäytti kaiken.
Vältä tätä asettamalla aina resurssirajoja, jotta säilösi pysyvät turvallisissa rajoissa. Voit tehdä tämän käyttämällä lippuja kuten --memory, --cpus ja --memory-swap säilöä käynnistäessäsi. Esimerkiksi seuraava komento rajoittaa säilön 500 MB:iin RAM-muistia ja sallii sen käyttää vain yhtä CPU-ytimen.
docker run --memory=500m --cpus=1 my-imagedocker run --name my-app --memory="500m" --cpus="1.0" node:18-alpineYlikäyttö etuoikeustilassa
Kun kohtasin ensimmäisiä ongelmia Docker-konttien kanssa, ajattelin, että --privileged olisi nopea ratkaisu. Se tuntui taikuudelta, yhtäkkiä kaikki toimi!
docker run --privileged my-containerMutta ymmärsin nopeasti, että tämä antaa kontille lähes rajattoman pääsyn isäntäkoneeseen. Se on valtava turvallisuusriski. Usein kaikki, mitä tarvitsin, oli pieni kyky kuten SYS_ADMIN, ei täydellinen etuoikeus.
docker run --cap-add=SYS_ADMIN my-container--privileged -käyttö oli liioiteltua. Siksi vain tarvittavien oikeuksien myöntäminen pitää isäntäjärjestelmän turvallisempana, samalla kun kontti toimii oikein.
Suunnittele Docker-asetuksesi huolellisesti alusta alkaen. Välttämällä näitä yleisiä virheitä, konttisi ovat turvallisempia, nopeampia ja paljon helpommin ylläpidettäviä, jolloin voit keskittyä suurten sovellusten rakentamiseen ja käyttöönottoon sen sijaan, että korjaat jatkuvasti ongelmia.
Nyt kun olet lukenut Kuinka Docker-tottumusteni siistiminen teki minusta tuottavamman loppuun, kutsumme sinut tutustumaan lisää Oppaat-kategoriaan. Löydät sieltä muita mielenkiintoisia artikkeleita, jotka laajentavat tietojasi ja pitävät sinut ajan tasalla. Älä lopeta lukemista ja löytämistä!

Vastaa