Ръководство за намаляване на размера на вашите Docker изображения

Замисляли ли сте се защо вашият контейнер за Docker за едно приложение нараства до 400 MB? Или може би защо еднократно двоично приложение от няколко десетки MB води до изображение на Docker с много MB?

контейнери

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

Образът на контейнера на Docker е по същество натрупани файлове, които по-късно се създават като екземпляр на работещ контейнер. Docker използва дизайна на Union File System (UnionFS), при който файловете са групирани в слоеве. Всеки слой може да съдържа един или повече файлове и всеки слой е позициониран отгоре на предишния слой. Това е виртуалното обединяване на цялото съдържание на всички слоеве, което ние като крайни потребители преживяваме като единна файлова система:

Окончателният изглед на файловата система, представен ни от основната имплементация на UnionFS (Docker поддържа немалко различни чрез добавящи се драйвери за съхранение), има общия размер на всички слоеве, които съдържа. Когато Docker създава контейнер за изображение, той използва всички слоеве на изображението във формат само за четене, добавяйки тънък слой за четене и запис върху тях. Този тънък слой за четене и запис е това, което ни позволява действително да модифицираме файлове в работещ контейнер на Docker:

Какво се случва, ако даден файл бъде изтрит в Layer 4 по-горе? Въпреки че изтритият файл вече няма да се показва в наблюдаваната файлова система, размерът, който първоначално е заемал, все още ще бъде част от отпечатъка на контейнера, тъй като файлът е включен в по-нисък слой, само за четене.

Относително лесно е да започнете с малък двоичен файл на приложението и да завършите с изображение на контейнер за мазнини. В следващите раздели ще изследваме различни методи, за да поддържаме размера на нашите изображения възможно най-тънък.

Кой е най-често срещаният начин, по който изграждаме нашите изображения на Docker?

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

За да разберем по-добре какво наистина се случва при издаване на горната команда, трябва да имаме предвид, че компилацията на Docker е процес клиент-сървър. CLI на Docker (клиент), където изпълняваме командата за изграждане на docker, използва основния механизъм на Docker (сървър) за изграждане на изображение на контейнер. За да ограничи достъпа до основната файлова система на клиента, процесът на изграждане трябва да знае какъв е коренът на виртуалната файлова система. По точно този път всяка команда във вашия Dockerifle се опитва да намери файлови ресурси, които потенциално могат да попаднат в изгражданото изображение.

Нека разгледаме за момент местоположението, където обикновено поставяме нашия Dockerfile. В основата на проекта, може би? Е, комбинирайте Dockerfile в корена на проекта с docker компилация и ние ефективно добавихме пълната папка на проекта като потенциални файлови ресурси за компилацията. Това може да доведе до ненужно добавяне на множество MB и хиляди файлове в контекста на компилация. Ако небрежно дефинираме команда ADD/COPY в Dockerfile, всички тези файлове могат да бъдат част от крайното изображение. По-голямата част от времето това не е необходимо, тъй като само няколко избрани артефакта на проекта трябва да бъдат включени в окончателното изображение на контейнера.

Винаги проверявайте дали сте осигурили подходящ път за изграждане на docker build и дали вашият Dockerfile не добавя ненужни файлове към вашето изображение. Ако по някаква причина наистина трябва да определите корена на проекта си като контекст на изграждане, можете избирателно да включвате/изключвате файлове чрез .dockerignore .

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

Както беше обсъдено в раздела за слоевете на изображението на Docker, по-горе, поради UnionFS, какъвто и да е файлов ресурс, влизащ в слой, остава в слоя, дори ако rm този файл в следващ слой. Нека да видим това с примерен Dockerfile: