Част 4 от Научете достатъчно Docker да бъде полезен

Джеф Хейл

31 януари 2019 г. · 9 минути четене

В тази статия ще научите как да ускорите циклите на изграждане на вашия Docker и да създадете леки изображения. Придържайки се към метафорите си за храна, ще ядем салата 🥗, докато намаляваме изображенията на Docker - няма повече пица, понички и гевреци.

вашите изображения

В част 3 от тази поредица покрихме дузина инструкции за Dockerfile, които трябва да знаете. Ако сте го пропуснали, разгледайте статията тук:

Научете достатъчно Докер, за да бъдете полезни

Част 3: Инструкции за дузина Dandy Dockerfile

към datadacience.com

Ето таблицата с мами.

FROM - указва основното (парето) изображение.
LABEL —предоставя метаданни. Добро място за включване на информация за поддържащите.
ENV - задава постоянна променлива на средата.
RUN - изпълнява команда и създава слой с изображение. Използва се за инсталиране на пакети в контейнери.
КОПИРАНЕ - копира файлове и директории в контейнера.
ADD - копира файлове и директории в контейнера. Може да разопакова локални .tar файлове.
CMD - предоставя команда и аргументи за изпълняващ контейнер. Параметрите могат да бъдат заменени. Може да има само един CMD.
WORKDIR - задава работната директория за следващите инструкции.
ARG - дефинира променлива, която да се предава на Docker по време на изграждане.
ENTRYPOINT - предоставя команда и аргументи за изпълняващ се контейнер. Аргументите продължават.
EXPOSE - излага порт.
ОБЕМ - създава точка за монтиране на директория за достъп и съхранение на постоянни данни.

Нека сега разгледаме как можем да създадем нашите Dockerfiles, за да спестим време при разработване на изображения и изтегляне на контейнери.

Една от силните страни на Docker е, че той осигурява кеширане, за да ви помогне по-бързо да повторите вашите изображения.

Когато изгражда изображение, Docker стъпва през инструкциите във вашия Dockerfile, изпълнявайки всяко по ред. Докато всяка инструкция се разглежда, Docker търси съществуващо междинно изображение в кеша, което може да използва повторно, вместо да създава ново (дублирано) междинно изображение.

Ако кешът е обезсилен, инструкцията, която го е обезсилила, и всички следващи инструкции на Dockerfile генерират нови междинни изображения. Веднага след като кешът е обезсилен, това е всичко за останалите инструкции в Dockerfile.

Така че започвайки от горната част на Dockerfile, ако основното изображение вече е в кеша, то се използва повторно. Това е хит. В противен случай кешът се обезсилва.

След това следващата инструкция се сравнява с всички дъщерни изображения в кеша, получени от това основно изображение. Всяко кеширано междинно изображение се сравнява, за да се види дали инструкцията намира попадение в кеша. Ако това е пропуск на кеша, кешът се обезсилва. Същият процес се повтаря, докато се стигне до края на Dockerfile.

Повечето нови инструкции просто се сравняват с тези в междинните изображения. Ако има съвпадение, тогава се използва кешираното копие.

Например, когато инструкция RUN pip install -r requirements.txt бъде намерена в Dockerfile, Docker търси същата инструкция в своите локално кеширани междинни изображения. Съдържанието на старите и новите файлове requirements.txt не се сравнява.

Това поведение може да бъде проблематично, ако актуализирате вашия файл requirements.txt с нови пакети и използвате RUN pip install и искате да повторите инсталацията на пакета с новите имена на пакети. Ще покажа няколко решения след малко.

За разлика от други инструкции на Docker, инструкциите ADD и COPY изискват от Docker да погледне съдържанието на файла (ите), за да определи дали има хит в кеша. Контролната сума на препращания файл се сравнява с контролната сума в съществуващите междинни изображения. Ако съдържанието на файла или метаданните са се променили, кешът е обезсилен.

Ето няколко съвета за ефективно използване на кеширането.

  • Кеширането може да бъде изключено чрез подаване на --no-cache = True с docker build .
  • Ако ще правите промени в инструкциите, тогава всеки следващ слой ще се възстановява често. За да се възползвате от кеширането, поставете инструкции, които вероятно ще се променят възможно най-ниско във вашия Dockerfile.
  • Chain RUN apt-get update и apt-get команди за инсталиране, за да се избегнат проблеми с пропуска на кеша.
  • Ако използвате инсталатор на пакети, като например pip, с файл requirements.txt, следвайте модел като този по-долу, за да сте сигурни, че няма да получите остаряло междинно изображение със старите пакети, изброени в requirements.txt.

Това са предложенията за ефективно използване на кеширането на Docker build. Ако имате други, моля, споделете ги в коментарите или в Twitter @discdiver.

Изображенията на Docker могат да станат големи. Искате да ги запазите малки, за да могат бързо да изтеглят и да използват малко ресурси. Нека намалим вашите изображения!

Основният образ на Alpine е пълна дистрибуция на Linux, без много други неща. Обикновено изтеглянето е под 5 MB, но изисква да отделите повече време за писане на кода за зависимостите, необходими за изграждане на работещо приложение.

Ако имате нужда от Python във вашия контейнер, компилацията на Python Alpine е добър компромис. Той съдържа Linux и Python и вие доставяте почти всичко останало.

Изображение, което създадох с последната версия на Python Alpine със скрипт за печат („здравей, свят“), тежи 78,5 MB. Ето Dockerfile:

На уебсайта на Docker Hub основното изображение е посочено като 29 MB. Когато детското изображение е изградено, той изтегля и инсталира Python, което го прави по-голям.

Освен използването на алпийски базови изображения, друг метод за намаляване на размера на вашите изображения е използването на многоетапни компилации. Тази техника също добавя сложност към вашия Dockerfile.

Многоетапните компилации използват множество инструкции от. Можете избирателно да копирате файлове, наречени компилационни артефакти, от един етап на друг. Можете да оставите всичко, което не искате в окончателното изображение. Този метод може да намали общия ви размер на изображението.

Всяка инструкция ОТ

  • започва нов етап от изграждането.
  • оставя след себе си всяка държава, създадена в предходни етапи.
  • може да използва различна основа.

Ето модифициран пример за многоетапна компилация от документите на Docker:

Обърнете внимание, че ние назоваваме първия етап, като добавяме име към инструкцията FROM към име. След това посоченият етап е посочен в инструкцията COPY - от = по-късно в Dockerfile.

Многоетапните компилации имат смисъл в някои случаи, когато ще правите много контейнери в производството. Многоетапните компилации могат да ви помогнат да изцедите всяка последна унция (грам, ако мислите в метрични стойности) от размера на вашето изображение. Понякога обаче многоетапните компилации добавят повече сложност, което може да направи изображенията по-трудни за поддръжка, така че вероятно няма да ги използвате в повечето компилации. Вижте допълнително обсъждане на компромисите тук и усъвършенстваните модели тук.

За разлика от това, всеки трябва да използва файл .dockerignore, за да поддържа изображенията на Docker слаби.

.dockerignore файловете са нещо, за което трябва да знаете като човек, който познава достатъчно Docker, за да бъде полезен d̶a̶n̶g̶e̶r̶o̶u̶s̶.

.dockerignore е подобен на .gitignore. Това е файл със списък с шаблони, които Docker да съвпада с имената на файловете и да ги изключва при създаване на изображение.

Поставете вашия .dockerignore файл в същата папка като вашия Dockerfile и останалата част от вашия контекст на компилация.

Когато стартирате docker build за създаване на изображение, Docker проверява за .dockerignore файл. Ако някой бъде намерен, той преминава през файла ред по ред и използва Go’s filepath.Match правила - и няколко от собствените правила на Docker - за да съответства на имената на файловете за изключване. Помислете за глобални модели в стил Unix, а не за регулярни изрази.

Така * .jpg ще изключи файлове с разширение .jpg. А видеоклиповете ще изключат папката с видеоклипове и нейното съдържание.

Можете да обясните какво правите във вашия .dockerignore с коментари, които започват с # .

Използването на .dockerignore за изключване на файлове, които не са ви необходими, от вашето изображение на Docker е добра идея. .dockerignore може:

  • ще ви помогне да не разкривате тайните си. Никой не иска пароли в изображенията си.
  • намаляване на размера на изображението. По-малкото файлове означава по-малки и по-бързи изображения.
  • намаляване на обезсилването на кеш на компилация. Ако регистрационните файлове или други файлове се променят и кешът на изображението ви е обезсилен поради това, това забавя цикъла ви на изграждане.

Това са причините да се използва .dockerignore файл. Вижте документите за повече подробности.

Нека да разгледаме как да намерите размера на изображенията и контейнерите на Docker от командния ред.

  • За да видите приблизителния размер на работещ контейнер, можете да използвате командния докер контейнер ls -s .
  • Изпълнението на docker image ls показва размерите на вашите изображения.
  • За да видите размера на междинните изображения, които съставляват вашето изображение, използвайте историята на изображенията на докер my_image: my_tag .
  • Стартиращото изображение на docker inspect my_image: таг ще ви покаже много неща за вашето изображение, включително размерите на всеки слой. Слоевете са малко по-различни от изображенията, които съставляват цяло изображение. Но можете да мислите за тях като за еднакви цели за повечето цели. Разгледайте тази страхотна статия от Найджъл Браун, ако искате да се впуснете в сложностите на слоя и междинните изображения.
  • Инсталирането и използването на пакета за гмуркане улеснява проглеждането на съдържанието на вашия слой.

Актуализирах горния раздел на 8 февруари 2019 г., за да използвам имена на команди за управление. В следващата част от тази поредица ще се потопим по-нататък в обичайните команди на Docker. Последвайте ме, за да сте сигурни, че няма да го пропуснете.

Сега нека разгледаме няколко най-добри практики за отслабване на нещата.

1. Използвайте официално основно изображение, когато е възможно. Официалните изображения се актуализират редовно и са по-сигурни от неофициалните изображения.
2. Използвайте варианти на алпийски изображения, когато е възможно, за да запазите вашите изображения леки.
3. Ако използвате apt, комбинирайте RUN apt-get update с apt-get install в същата инструкция. След това свържете няколко пакета в тази инструкция. Избройте пакетите в азбучен ред на няколко реда с символа \. Например:

Този метод намалява броя на слоевете, които трябва да бъдат изградени, и поддържа нещата приятни и подредени.
4. Включете && rm -rf/var/lib/apt/lists/* в края на инструкцията RUN, за да изчистите подходящия кеш, за да не се съхранява в слоя. Вижте повече в Docker Docks. Благодаря на Виджай Рагаван Аравамудхан за това предложение. Актуализирано на 4 февруари 2019 г.
5. Използвайте разумно кеширането, като поставяте инструкции, които може да се променят по-ниско във вашия Dockerfile.
6. Използвайте .dockerignore файл, за да предпазите нежеланите и ненужните файлове от вашето изображение.
7. Вижте гмуркане - много страхотен инструмент за проверка на слоевете на изображението на Docker и за подпомагане на подрязването на мазнините.
8. Не инсталирайте пакети, от които не се нуждаете. Дъ! Но често срещано.

Сега знаете как да направите изображения на Docker, които се изграждат бързо, изтеглят се бързо и не заемат много място. Както при здравословното хранене, знанието е половината от успеха. Насладете се на своите зеленчуци! 🥗