Доцкер: није лош савет

У коментарима на мој чланак Доцкер: лош савет било је много захтева да се објасни зашто је Доцкерфиле описан у њему тако ужасан.

Резиме претходне серије: Два програмера састављају Доцкерфиле у кратком року. У том процесу долази до њих Опс Игор Иванович. Добијени Доцкерфиле је толико лош да је АИ на ивици срчаног удара.

Доцкер: није лош савет

Сада хајде да схватимо шта није у реду са овим Доцкерфилеом.

Дакле, прошла је недеља.

Дев Петиа упознаје Опс Игора Ивановича у трпезарији уз шољицу кафе.

П: Игоре Ивановичу, да ли сте веома заузети? Волео бих да схватим где смо зезнули.

АИ: То је добро, не срећете често програмере који су заинтересовани за експлоатацију.
Прво, да се договоримо око неколико ствари:

  1. Доцкер идеологија: један контејнер - један процес.
  2. Што је мањи контејнер, то боље.
  3. Што више узмете из кеша, то боље.

П: Зашто би био један процес у једном контејнеру?

АИ: Доцкер, када покреће контејнер, прати стање процеса помоћу пид 1. Ако процес умре, Доцкер покушава да поново покрене контејнер. Рецимо да имате неколико апликација које раде у контејнеру, или главна апликација не ради са пид 1. Ако процес умре, Доцкер неће знати за то.

Ако немате додатних питања, покажите нам свој Доцкерфиле.

И Петја је показао:

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"]

АИ: Ох, хајде да то узмемо редом. Почнимо са првим редом:

FROM ubuntu:latest

Узми ознаку latest. Коришћење ознаке latest доводи до непредвидивих последица. Замислите, одржавалац слике прави нову верзију слике са другом листом софтвера, ова слика добија најновију ознаку. И ваш контејнер, у најбољем случају, престаје да се гради, ау најгорем, ухватите грешке које раније нису постојале.

Снимите слику са пуноправним ОС са пуно непотребног софтвера, који надувава запремину контејнера. И што је више софтвера, то је више рупа и рањивости.

Поред тога, што је слика већа, то више простора заузима на хосту и у регистру (да ли негде складиштите слике)?

П: Да, наравно, имамо регистар, ти га поставиш.

АИ: Дакле, о чему ја причам?.. О да, обим... Оптерећење мреже такође расте. За једну слику то није приметно, али када постоји континуирана израда, тестирање и примена, то је приметно. А ако немате Божји режим на АВС-у, добићете и космички рачун.

Због тога морате да изаберете најприкладнију слику, са тачном верзијом и минималним софтвером. На пример, узмите: FROM ruby:2.5.5-stretch

П: Ох, видим. Како и где могу да погледам доступне слике? Како да знам који ми је потребан?

АИ: Обично се слике узимају из доцкерхуб, не бркајте са порнхуб :). Обично постоји неколико склопова за слику:
Алпски: слике су прикупљене на минималистичкој Линук слици, само 5 МБ. Његов недостатак: компајлиран је са сопственом имплементацијом либц, стандардни пакети не раде у њему. Проналажење и инсталирање потребног пакета ће потрајати доста времена.
Сцратцх: основна слика, не користи се за прављење других слика. Намењен је искључиво за покретање бинарних, припремљених података. Идеално за покретање бинарних апликација које укључују све што вам је потребно, као што су ГО апликације.
Заснован на било ком ОС-у, као што је Убунту или Дебиан. Па, мислим да нема потребе да се објашњава.

АИ: Сада морамо да инсталирамо све додатке. пакете и очистите своје кеш меморије. И можете га одмах бацити апт-гет надоградња. У супротном, са сваком градњом, упркос фиксној ознаци основне слике, добиће се различите слике. Ажурирање пакета на слици је задатак одржаваоца и праћено је променом ознаке.

П: Да, покушао сам то да урадим, испало је овако:

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/*

АИ: Није лоше, али има и на чему радити. Види, ево ове команде:

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

... не брише податке са коначне слике, већ само креира додатни слој без ових података. Тачно овако:

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/* 

Али то није све. Шта имаш тамо, Руби? Тада не морате да копирате цео пројекат на почетку. Довољно је копирати Гемфиле и Гемфиле.лоцк.

Са овим приступом, инсталација пакета неће бити извршена за сваку промену извора, већ само ако су се променили Гемфиле или Гемфиле.лоцк.

Исте методе функционишу и за друге језике са менаџером зависности, као што су нпм, пип, цомпосер и други на основу датотеке са листом зависности.

И коначно, сећате се да сам на почетку говорио о Доцкер идеологији „један контејнер - један процес“? То значи да супервизор није потребан. Такође не би требало да инсталирате системд из истих разлога. У суштини, сам Доцкер је супервизор. А када покушате да покренете више процеса у њему, то је као да покрећете више апликација у једном надзорном процесу.
Приликом изградње, направићете једну слику, а затим покренути потребан број контејнера тако да се у сваком покрене један процес.

Али о томе више касније.

П: Мислим да разумем. Погледајте шта се дешава:

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"]

Можемо ли да заобиђемо покретање демона приликом покретања контејнера?

АИ: Да, тако је. Узгред, можете користити и ЦМД и ЕНТРИПОИНТ. А да откријете у чему је разлика је ваш домаћи задатак. Има један добар на ову тему на Хабреу чланак.

Дакле, идемо даље. Преузмите датотеку да бисте инсталирали чвор, али нема гаранције да ће садржати оно што вам је потребно. Морамо да додамо валидацију. На пример, овако:

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/* 

Користећи контролну суму можете потврдити да сте преузели исправну датотеку.

П: Али ако се датотека промени, изградња неће успети.

АИ: Да, и што је чудно, ово је такође плус. Знаћете да се датотека променила и моћи ћете да видите шта је ту промењено. Никад се не зна, додали су, рецимо, скрипту која брише све што може да досегне, или ствара бацкдоор.

П: Хвала. Испоставило се да ће коначни Доцкерфиле изгледати овако:

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"]

П: Игоре Ивановичу, хвала вам на помоћи. Време је да трчим, данас морам да направим још 10 обавеза.

Игор Иванович, заустављајући погледом исхитреног колегу, отпија гутљај јаке кафе. Након што је неколико секунди размишљао о СЛА од 99.9% и коду без грешака, поставља питање.

АИ: Где чувате дневнике?

П: Наравно, у продуцтион.лог. Успут, да, али како им можемо приступити без ссх-а?

АИ: Ако их оставите у фајловима, решење је већ измишљено за вас. Команда доцкер екец вам омогућава да извршите било коју команду у контејнеру. На пример, можете направити мачку за трупце. И помоћу кључа -то а покретање басх-а (ако је инсталиран у контејнеру) ће вам дати интерактивни приступ контејнеру.

Али не би требало да чувате евиденције у датотекама. То у најмању руку доводи до неконтролисаног раста контејнера и нико не ротира трупце. Све евиденције треба послати на стдоут. Тамо се већ могу видети помоћу команде доцкер евиденције.

П: Игоре Ивановичу, можда могу да ставим логове у монтирани директоријум, на физички чвор, као корисничке податке?

АИ: Добро је што нисте заборавили да уклоните податке учитане на диск чвора. То можете да урадите и са евиденцијама, само не заборавите да подесите ротацију.
То је то, можеш да трчиш.

П: Игоре Ивановичу, можете ли ми саветовати шта да читам?

АИ: Прво, прочитајте препоруке Доцкер програмера, ретко ко познаје Доцкер боље од њих.

А ако желите да добијете праксу, идите на интензиван. На крају крајева, теорија без праксе је мртва.

Извор: ввв.хабр.цом

Додај коментар