Docker: pole halb nõuanne

Minu artikli kommentaarides Docker: halb nõuanne oli palju taotlusi selgitada, miks selles kirjeldatud Dockerfile oli nii kohutav.

Eelmise episoodi kokkuvõte: Kaks arendajat koostavad Dockeri faili lühikese tähtaja jooksul. Selle käigus tuleb nende juurde Ops Igor Ivanovitš. Saadud Dockerfile on nii halb, et AI on südameataki äärel.

Docker: pole halb nõuanne

Nüüd selgitame välja, mis sellel Dockerfile'il viga on.

Niisiis, nädal on möödas.

Dev Petya kohtub Ops Igor Ivanovitšiga söögitoas kohvitassi taga.

P: Igor Ivanovitš, kas sa oled väga hõivatud? Tahaksin aru saada, kus me jama läksime.

AI: See on hea, te ei kohta sageli arendajaid, kes on huvitatud kasutamisest.
Esmalt lepime kokku mõnes asjas:

  1. Dockeri ideoloogia: üks konteiner – üks protsess.
  2. Mida väiksem konteiner, seda parem.
  3. Mida rohkem te vahemälust võtate, seda parem.

P: Miks peaks ühes konteineris olema üks protsess?

AI: Docker jälgib konteineri käivitamisel protsessi olekut pid 1 abil. Kui protsess sureb, proovib Docker konteinerit taaskäivitada. Oletame, et teil on konteineris mitu rakendust või põhirakendus ei tööta pid 1-ga. Kui protsess katkeb, ei saa Docker sellest teada.

Kui teil pole lisaküsimusi, näidake meile oma Dockeri faili.

Ja Petya näitas:

FROM ubuntu:latest

# Копируем исходный код
COPY ./ /app
WORKDIR /app

# Обновляем список пакетов
RUN apt-get update 

# Обновляем пакеты
RUN apt-get upgrade

# Устанавливаем нужные пакеты
RUN apt-get -y install libpq-dev imagemagick gsfonts ruby-full ssh supervisor

# Устанавливаем bundler
RUN gem install bundler

# Устанавливаем nodejs используется для сборки статики
RUN curl -sL https://deb.nodesource.com/setup_9.x | sudo bash -
RUN apt-get install -y nodejs

# Устанавливаем зависимости
RUN bundle install --without development test --path vendor/bundle

# Чистим за собой кэши
RUN rm -rf /usr/local/bundle/cache/*.gem 
RUN apt-get clean 
RUN rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* 
RUN rake assets:precompile
# Запускаем скрипт, при старте контейнера, который запустит все остальное.
CMD ["/app/init.sh"]

AI: Oh, võtame selle järjekorras. Alustame esimesest reast:

FROM ubuntu:latest

Sa võtad sildi latest. Sildi kasutamine latest viib ettearvamatute tagajärgedeni. Kujutage ette, pildi hooldaja loob pildist uue versiooni erineva tarkvaraloendiga, see pilt saab uusima sildi. Ja teie konteiner parimal juhul lõpetab ehitamise ja halvimal juhul tabate vigu, mida varem polnud.

Teete pildi täisväärtusliku OS-iga, kus on palju ebavajalikku tarkvara, mis suurendab konteineri mahtu. Ja mida rohkem tarkvara, seda rohkem auke ja turvaauke.

Lisaks, mida suurem on pilt, seda rohkem ruumi võtab see hostis ja registris (kas salvestate pilte kuhugi)?

P: Jah, muidugi, meil on register, teie seadistate selle.

AI: No millest ma räägin?.. Ah jaa, mahud... Ka võrgu koormus kasvab. Üksiku pildi puhul pole see märgatav, kuid pidev ehitamine, testimine ja juurutamine on see märgatav. Ja kui teil pole AWS-is Jumala režiimi, saate ka kosmilise arve.

Seetõttu peate valima sobivaima pildi koos täpse versiooni ja minimaalse tarkvaraga. Näiteks võtke: FROM ruby:2.5.5-stretch

P: Oh, ma näen. Kuidas ja kust saadaolevaid pilte vaadata? Kuidas ma tean, millist ma vajan?

AI: tavaliselt tehakse pildid asukohast dockerhub, ärge ajage pornhubiga segi :). Tavaliselt on pildi jaoks mitu komplekti:
Alpine: pildid kogutakse minimalistlikule Linuxi kujutisele, ainult 5 MB. Selle miinus: see on koostatud oma libc-rakendusega, standardpaketid selles ei tööta. Vajaliku paketi leidmine ja paigaldamine võtab palju aega.
Kraapige: põhipilt, mida ei kasutata teiste piltide koostamiseks. See on ette nähtud ainult ettevalmistatud binaarsete andmete käitamiseks. Ideaalne binaarrakenduste käitamiseks, mis sisaldavad kõike vajalikku, näiteks GO-rakendused.
Põhineb mis tahes OS-il, näiteks Ubuntu või Debian. Noh, ma arvan, et pole vaja seletada.

AI: Nüüd peame installima kõik lisad. paketid ja tühjendage vahemälud. Ja võite selle kohe ära visata apt-get upgrade. Vastasel juhul saadakse iga ehitusega, hoolimata põhipildi fikseeritud sildist, erinevad pildid. Pildil olevate pakettide värskendamine on hooldaja ülesanne ja sellega kaasneb sildi muutmine.

P: Jah, ma proovisin seda teha, see tuli välja selline:

WORKDIR /app
COPY ./ /app

RUN curl -sL https://deb.nodesource.com/setup_9.x | bash - 
    && apt-get -y install libpq-dev imagemagick gsfonts ruby-full ssh supervisor nodejs 
    && gem install bundler 
    && bundle install --without development test --path vendor/bundle

RUN rm -rf /usr/local/bundle/cache/*.gem 
    && apt-get clean  
    && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*

AI: Pole paha, aga seal on ka, mille kallal töötada. Vaata, siin on see käsk:

RUN rm -rf /usr/local/bundle/cache/*.gem 
    && apt-get clean  
    && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*  

... ei kustuta andmeid lõplikult pildilt, vaid loob ainult lisakihi ilma nende andmeteta. Õigesti nii:

RUN curl -sL https://deb.nodesource.com/setup_9.x | bash - 
    && apt-get -y install libpq-dev imagemagick gsfonts nodejs 
    && gem install bundler 
    && bundle install --without development test --path vendor/bundle   
    && rm -rf /usr/local/bundle/cache/*.gem 
    && apt-get clean  
    && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* 

Kuid see pole veel kõik. Mis sul seal on, Ruby? Siis ei pea te kogu projekti alguses kopeerima. Piisab kopeerida Gemfile ja Gemfile.lock.

Selle lähenemisviisi korral ei käivitata komplekti installimist iga allika muudatuse korral, vaid ainult siis, kui Gemfile või Gemfile.lock on muutunud.

Samad meetodid töötavad ka teiste sõltuvushalduriga keelte puhul, näiteks npm, pip, composer ja teised, mis põhinevad sõltuvuste loendiga failil.

Ja lõpuks, mäletan, et alguses rääkisin Dockeri ideoloogiast “üks konteiner – üks protsess”? See tähendab, et juhendajat pole vaja. Samadel põhjustel ei tohiks te ka systemd installida. Põhimõtteliselt on Docker ise järelevaataja. Ja kui proovite selles mitut protsessi käivitada, on see nagu mitme rakenduse käitamine ühes juhendaja protsessis.
Ehitamisel teete ühe pildi ja seejärel käivitate vajaliku arvu konteinereid, et igas töötaks üks protsess.

Aga sellest pikemalt hiljem.

P: Ma arvan, et saan aru. Vaata, mis juhtub:

FROM ruby:2.5.5-stretch

WORKDIR /app
COPY Gemfile* /app

RUN curl -sL https://deb.nodesource.com/setup_9.x | bash - 
    && apt-get -y install libpq-dev imagemagick gsfonts nodejs 
    && gem install bundler 
    && bundle install --without development test --path vendor/bundle   
    && rm -rf /usr/local/bundle/cache/*.gem 
    && apt-get clean  
    && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* 

COPY . /app
RUN rake assets:precompile

CMD ["bundle”, “exec”, “passenger”, “start"]

Kas me saame konteineri käivitamisel deemonite käivitamise alistada?

AI: Jah, see on õige. Muide, saate kasutada nii CMD-d kui ka ENTRYPOINTi. Ja selle erinevuse väljaselgitamine on teie kodutöö. Habres on sellel teemal hea artikkel artikkel.

Niisiis, lähme edasi. Laadite sõlme installimiseks alla faili, kuid pole garantiid, et see sisaldab seda, mida vajate. Peame lisama valideerimise. Näiteks nii:

RUN curl -sL https://deb.nodesource.com/setup_9.x > setup_9.x 
    && echo "958c9a95c4974c918dca773edf6d18b1d1a41434  setup_9.x" | sha1sum -c - 
    &&  bash  setup_9.x 
    && rm -rf setup_9.x 
    && apt-get -y install libpq-dev imagemagick gsfonts nodejs 
    && gem install bundler 
    && bundle install --without development test --path vendor/bundle   
    && rm -rf /usr/local/bundle/cache/*.gem 
    && apt-get clean  
    && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* 

Kontrollsumma abil saate kontrollida, kas laadisite alla õige faili.

P: Aga kui fail muutub, siis ehitamine ebaõnnestub.

AI: Jah, ja kummalisel kombel on see ka pluss. Saate teada, et fail on muutunud, ja näete, mida seal muudeti. Kunagi ei tea, nad lisasid näiteks skripti, mis kustutab kõik, milleni jõuab, või loob tagaukse.

P: Aitäh. Selgub, et lõplik Dockerfile näeb välja selline:

FROM ruby:2.5.5-stretch

WORKDIR /app
COPY Gemfile* /app

RUN curl -sL https://deb.nodesource.com/setup_9.x > setup_9.x 
    && echo "958c9a95c4974c918dca773edf6d18b1d1a41434  setup_9.x" | sha1sum -c - 
    &&  bash  setup_9.x 
    && rm -rf setup_9.x 
    && apt-get -y install libpq-dev imagemagick gsfonts nodejs 
    && gem install bundler 
    && bundle install --without development test --path vendor/bundle   
    && rm -rf /usr/local/bundle/cache/*.gem 
    && apt-get clean  
    && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* 

COPY . /app
RUN rake assets:precompile

CMD ["bundle”, “exec”, “passenger”, “start"]

P: Igor Ivanovitš, tänan teid abi eest. Mul on aeg jooksma hakata, ma pean täna tegema veel 10 kohustust.

Igor Ivanovitš, peatades pilguga kiirustades kolleegi, võtab lonksu kanget kohvi. Mõtiskledes mõne sekundi 99.9% SLA ja veavaba koodi üle, esitab ta küsimuse.

AI: Kus te palke hoiate?

P: Muidugi tootmises.logis. Muide, jah, aga kuidas me saame neile juurdepääsu ilma ssh-ta?

AI: Kui jätate need failidesse, on teie jaoks lahendus juba leiutatud. Docker exec käsk võimaldab teil konteineris täita mis tahes käsku. Näiteks võite teha kassi palkide jaoks. Ja kasutades võtit - see on ja bashi käivitamine (kui konteinerisse on installitud) annab teile interaktiivse juurdepääsu konteinerile.

Kuid te ei tohiks logisid failidesse salvestada. See viib vähemalt konteineri kontrollimatu kasvuni ja keegi ei pööra palke ümber. Kõik logid tuleb saata stdoutile. Seal saab neid juba käsu abil vaadata dokkide palgid.

P: Igor Ivanovitš, võib-olla saan logid kasutajaandmetena panna ühendatud kataloogi, füüsilisele sõlmele?

AI: Hea, et te ei unustanud sõlme kettale laaditud andmeid eemaldada. Saate seda teha ka logidega, lihtsalt ärge unustage pöörlemist seadistada.
See on kõik, võite joosta.

P: Igor Ivanovitš, kas saate mulle nõu anda, mida lugeda?

AI: Esiteks lugege Dockeri arendajate soovitused, vaevalt keegi tunneb Dockerit paremini kui nemad.

Ja kui soovite saada praktikat, minge aadressile intensiivne. Lõppude lõpuks on teooria ilma praktikata surnud.

Allikas: www.habr.com

Lisa kommentaar