Докер: Муу зөвлөгөө биш

Миний нийтлэлийн сэтгэгдэлд Докер: муу зөвлөгөө Докер файл яагаад ийм аймшигтай болохыг тайлбарлах олон хүсэлт ирсэн.

Өмнөх ангийн хураангуй: Хоёр хөгжүүлэгч тодорхой хугацааны дотор Dockerfile-г бүтээдэг. Энэ явцад Опс Игорь Иванович тэдэн дээр ирдэг. Үүссэн Dockerfile нь маш муу тул хиймэл оюун ухаан зүрхний шигдээсийн ирмэг дээр байна.

Докер: Муу зөвлөгөө биш

Одоо энэ Dockerfile-д ямар алдаа байгааг олж мэдье.

Ингээд долоо хоног өнгөрчээ.

Дев Петя хоолны өрөөнд аяга кофе ууж суухдаа Опс Игорь Ивановичтэй уулзав.

П: Игорь Иванович, та маш завгүй байна уу? Бид хаашаа завхруулсныг олж мэдмээр байна.

AI: Сайн байна, та мөлжлөгийг сонирхож буй хөгжүүлэгчидтэй тэр бүр тааралддаггүй.
Эхлээд хэд хэдэн зүйл дээр санал нэгдье:

  1. Докерын үзэл суртал: нэг контейнер - нэг процесс.
  2. Савны хэмжээ бага байх тусмаа сайн.
  3. Кэшээс хэдий чинээ ихийг авна төдий чинээ сайн.

P: Яагаад нэг саванд нэг процесс байх ёстой гэж?

AI: Докер, чингэлэгийг эхлүүлэхдээ процессын төлөвийг pid 1-ээр хянадаг. Хэрэв процесс унтарвал Docker савыг дахин эхлүүлэхийг оролдоно. Танд нэг контейнерт хэд хэдэн програм ажиллаж байгаа эсвэл үндсэн програм нь pid 1-тэй ажиллахгүй байна гэж бодъё. Хэрэв процесс зогсвол Docker энэ талаар мэдэхгүй болно.

Хэрэв танд өөр асуулт байхгүй бол бидэнд Dockerfile-ээ харуулна уу.

Петя үзүүлэв:

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: Өө, дарааллаар нь авч үзье. Эхний мөрөөс эхэлье:

FROM ubuntu:latest

Та шошгыг аваарай latest. Шошго ашиглаж байна latest урьдчилан таамаглах аргагүй үр дагаварт хүргэдэг. Зургийн засварлагч өөр програм хангамжийн жагсаалт бүхий зургийн шинэ хувилбарыг бүтээдэг гэж төсөөлөөд үз дээ, энэ зураг нь хамгийн сүүлийн үеийн шошгыг хүлээн авдаг. Таны чингэлэг хамгийн сайндаа баригдахаа больж, хамгийн муу нь та урьд өмнө байгаагүй алдаануудыг барьж авдаг.

Та олон тооны шаардлагагүй программ хангамж бүхий бүрэн эрхт үйлдлийн системтэй зураг авдаг бөгөөд энэ нь савны эзэлхүүнийг хөөрөгддөг. Програм хангамж их байх тусам цоорхой, эмзэг байдал их байх болно.

Нэмж дурдахад зураг том байх тусам хост болон бүртгэлд илүү их зай эзэлдэг (та зураг хаа нэгтээ хадгалдаг уу)?

P: Тийм ээ, мэдээжийн хэрэг, бид бүртгэлтэй, та үүнийг тохируулаарай.

А.И: Тэгээд би юу яриад байгаа юм бэ?.. Өө тийм, боть... Сүлжээний ачаалал бас л нэмэгдэж байна. Нэг зургийн хувьд энэ нь мэдэгдэхүйц биш боловч тасралтгүй бүтээх, туршилт хийх, байршуулах үед мэдэгдэхүйц юм. Хэрэв танд AWS дээр Бурханы горим байхгүй бол та сансрын төлбөрийг авах болно.

Тиймээс та яг тохирсон хувилбар, хамгийн бага програм хангамжтай хамгийн тохиромжтой зургийг сонгох хэрэгтэй. Жишээ нь: FROM ruby:2.5.5-stretch

П: Өө, би ойлгож байна. Боломжтой зургуудыг хэрхэн, хаанаас үзэх вэ? Надад аль нь хэрэгтэйг би яаж мэдэх вэ?

AI: Ихэвчлэн зураг авдаг dockerhub, pornhub-тэй андуурч болохгүй :). Зургийн хувьд ихэвчлэн хэд хэдэн угсралт байдаг:
Уулын: зургуудыг линуксийн минималист дүрс дээр цуглуулсан, ердөө 5 MB. Үүний сул тал: энэ нь өөрийн libc хэрэгжилтээр эмхэтгэсэн, стандарт багцууд үүнд ажиллахгүй байна. Шаардлагатай багцыг хайж олох, суулгахад маш их цаг хугацаа шаардагдана.
Scratch: үндсэн зураг, бусад зургийг бүтээхэд ашигладаггүй. Энэ нь зөвхөн хоёртын, бэлтгэсэн өгөгдлийг ажиллуулахад зориулагдсан. GO програмууд гэх мэт хэрэгтэй бүх зүйлийг багтаасан хоёртын программуудыг ажиллуулахад тохиромжтой.
Ubuntu эсвэл Debian гэх мэт аливаа үйлдлийн систем дээр суурилсан. За, би тайлбарлах шаардлагагүй гэж бодож байна.

AI: Одоо бид бүх нэмэлтүүдийг суулгах хэрэгтэй. багц болон кэшээ цэвэрлэ. Мөн та үүнийг шууд хаяж болно apt-get upgrade. Үгүй бол үндсэн зургийн тогтмол шошгыг үл харгалзан бүтээх бүрт өөр өөр зураг авах болно. Зурган дээрх багцуудыг шинэчлэх нь засварлагчийн үүрэг бөгөөд шошгыг өөрчлөх замаар дагалддаг.

P: Тийм ээ, би үүнийг хийх гэж оролдсон, ийм болсон.

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: Муу биш, гэхдээ бас ажиллах зүйл бий. Хараач, энэ тушаал байна:

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

Гэхдээ энэ нь бүгд биш юм. Тэнд юу байна, Руби? Дараа нь та эхэндээ төслийг бүхэлд нь хуулах шаардлагагүй болно. Gemfile болон Gemfile.lock файлыг хуулж авахад хангалттай.

Энэ аргын тусламжтайгаар багцын суулгацыг эх сурвалжийн өөрчлөлт болгонд гүйцэтгэхгүй, зөвхөн Gemfile эсвэл Gemfile.lock өөрчлөгдсөн тохиолдолд л хийгдэнэ.

Үүнтэй ижил аргууд нь хамаарлын жагсаалт бүхий файл дээр суурилсан npm, pip, composer болон бусад хамаарлын менежертэй бусад хэлүүдэд ажилладаг.

Эцэст нь би "нэг сав - нэг процесс" гэсэн Докерын үзэл суртлын талаар ярьж байсныг санаж байна уу? Энэ нь хянагч хэрэггүй гэсэн үг. Та мөн адил шалтгааны улмаас systemd суулгаж болохгүй. Үндсэндээ Докер өөрөө хянагч юм. Мөн та үүн дотор олон процесс ажиллуулахыг оролдох үед энэ нь нэг удирдагчийн процесст олон програм ажиллуулахтай адил юм.
Барилга хийхдээ та нэг зураг хийж, дараа нь шаардлагатай тооны савыг ажиллуулж, тус бүрт нэг процесс явагдана.

Гэхдээ энэ талаар дараа дэлгэрэнгүй.

П: Би ойлгож байна гэж бодож байна. Юу болсныг хараарай:

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

Бид савыг эхлүүлэх үед демонуудын хөөргөлтийг хүчингүй болгож чадах уу?

AI: Тийм ээ, тийм. Дашрамд хэлэхэд та CMD болон ENTRYPOINT хоёуланг нь ашиглаж болно. Мөн ялгаа нь юу болохыг олж мэдэх нь таны гэрийн даалгавар юм. Хабре дээр энэ сэдвээр сайн зүйл бий нийтлэл.

Ингээд цааш явцгаая. Та зангилааг суулгахын тулд файлыг татаж авах боловч энэ нь танд хэрэгтэй зүйлийг агуулна гэсэн баталгаа байхгүй. Бид баталгаажуулалтыг нэмэх хэрэгтэй. Жишээлбэл, иймэрхүү:

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

Шалгах нийлбэрийг ашиглан та зөв файлыг татаж авсан эсэхээ шалгаж болно.

P: Гэхдээ хэрэв файл өөрчлөгдвөл угсралт амжилтгүй болно.

AI: Тийм ээ, хачирхалтай нь энэ нь бас нэг давуу тал юм. Та файл өөрчлөгдсөнийг мэдэх бөгөөд тэнд юу өөрчлөгдсөнийг харах боломжтой болно. Та хэзээ ч мэдэхгүй, тэд хүрч болох бүх зүйлийг устгах эсвэл арын хаалга үүсгэдэг скрипт нэмсэн.

П: Баярлалаа. Эцсийн Dockerfile дараах байдлаар харагдах болно.

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% SLA болон алдаагүй кодын талаар хэдэн секунд бодсоны дараа тэрээр асуулт асууна.

AI: Та гуалингаа хаана хадгалдаг вэ?

P: Мэдээж production.log дээр. Дашрамд хэлэхэд, тийм ээ, гэхдээ бид sshгүйгээр яаж хандах вэ?

AI: Хэрэв та тэдгээрийг файлд үлдээвэл танд зориулж шийдлийг аль хэдийн зохион бүтээсэн болно. Docker exec команд нь контейнер доторх дурын командыг гүйцэтгэх боломжийг олгодог. Жишээлбэл, та гуалингаар муур хийж болно. Мөн түлхүүрийг ашиглан -энэ болон bash-г ажиллуулж (хэрэв саванд суулгасан бол) танд контейнерт интерактив хандах боломжийг олгоно.

Гэхдээ та бүртгэлээ файлд хадгалах ёсгүй. Хамгийн багадаа энэ нь савны хяналтгүй өсөлтөд хүргэдэг бөгөөд хэн ч логыг эргүүлдэггүй. Бүх бүртгэлийг stdout руу илгээх ёстой. Тэнд тэдгээрийг командыг ашиглан аль хэдийн үзэх боломжтой докерын бүртгэлүүд.

П: Игорь Иванович, магадгүй би бүртгэлийг суурилуулсан лавлах, физик цэг дээр хэрэглэгчийн өгөгдөл болгон байрлуулж болох уу?

AI: Та зангилааны дискэнд ачаалагдсан өгөгдлийг устгахаа мартаагүй нь сайн хэрэг. Та үүнийг лог ашиглан хийж болно, зүгээр л эргэлтийг тохируулахаа бүү мартаарай.
Ингээд л гүйж болно.

П: Игорь Иванович, та надад юу уншихыг зөвлөж чадах уу?

AI: Эхлээд унш Docker хөгжүүлэгчдийн зөвлөмж, Докерийг тэднээс илүү мэддэг хүн бараг байхгүй.

Мөн та дадлага хийлгэхийг хүсвэл зориорой эрчимтэй. Эцсийн эцэст практикгүйгээр онол үхсэн.

Эх сурвалж: www.habr.com

сэтгэгдэл нэмэх