[tham khảo truyện cổ tích dành cho trẻ em Mỹ "Chiếc động cơ nhỏ có thể" - khoảng. làn đường]*

Cách tự động tạo hình ảnh Docker nhỏ cho nhu cầu của bạn
Nỗi ám ảnh bất thường
Trong vài tháng qua, tôi bị ám ảnh bởi hình ảnh Docker có thể nhỏ đến mức nào mà ứng dụng vẫn chạy được?
Tôi hiểu, ý tưởng này thật kỳ lạ.
Trước khi đi vào chi tiết và kỹ thuật, tôi muốn giải thích lý do tại sao vấn đề này khiến tôi khó chịu đến vậy và nó khiến bạn lo lắng như thế nào.
Tại sao kích thước lại quan trọng
Bằng cách giảm nội dung của hình ảnh Docker, nhờ đó chúng tôi giảm được danh sách các lỗ hổng. Ngoài ra, chúng tôi làm cho hình ảnh sạch hơn vì chúng chỉ chứa những gì cần thiết để chạy ứng dụng.
Có một lợi thế nhỏ nữa - hình ảnh được tải xuống nhanh hơn một chút, nhưng theo tôi, điều này không quá quan trọng.
Xin lưu ý: Nếu bạn lo lắng về kích thước, bản thân Alpine có vẻ ngoài nhỏ và có thể sẽ phù hợp với bạn.
Hình ảnh không thể phân phối
cung cấp một loạt các hình ảnh “không phân phối” cơ bản, chúng không chứa trình quản lý gói, shell và các tiện ích khác mà bạn quen thấy trên dòng lệnh. Do đó, hãy sử dụng các trình quản lý gói như pip и apt sẽ không làm việc:
FROM gcr.io/distroless/python3
RUN pip3 install numpy
Dockerfile sử dụng hình ảnh không phân phối Python 3
Sending build context to Docker daemon 2.048kB
Step 1/2 : FROM gcr.io/distroless/python3
---> 556d570d5c53
Step 2/2 : RUN pip3 install numpy
---> Running in dbfe5623f125
/bin/sh: 1: pip3: not found
Pip không có trong hình ảnh
Thông thường, vấn đề này được giải quyết bằng cách xây dựng nhiều giai đoạn:
FROM python:3 as builder
RUN pip3 install numpy
FROM gcr.io/distroless/python3
COPY --from=builder /usr/local/lib/python3.7/site-packages /usr/local/lib/python3.5/
Lắp ráp nhiều giai đoạn
Kết quả là một hình ảnh có kích thước 130 MB. Không tệ lắm! Để so sánh: hình ảnh Python mặc định nặng 929MB và hình ảnh “mỏng hơn” (3,7-slim) - 179 MB, hình ảnh núi cao (3,7-alpine) là 98,6 MB, trong khi hình ảnh không phân phối cơ sở được sử dụng trong ví dụ là 50,9 MB.
Công bằng mà nói thì trong ví dụ trước chúng ta đang sao chép toàn bộ thư mục /usr/local/lib/python3.7/site-packages, có thể chứa các phần phụ thuộc mà chúng tôi không cần. Mặc dù rõ ràng là sự khác biệt về kích thước của tất cả các hình ảnh cơ sở Python hiện có là khác nhau.
Tại thời điểm viết bài, Google distroless không hỗ trợ nhiều hình ảnh: Java và Python vẫn đang ở giai đoạn thử nghiệm và Python chỉ tồn tại cho 2,7 và 3,5.
Hình ảnh nhỏ
Trở lại với nỗi ám ảnh của tôi về việc tạo ra những hình ảnh nhỏ.
Nói chung, tôi muốn xem hình ảnh không phân phối được tạo ra như thế nào. Dự án distroless sử dụng công cụ xây dựng của Google bazel. Tuy nhiên, việc cài đặt Bazel và viết hình ảnh của riêng bạn tốn rất nhiều công sức (và thành thật mà nói, việc phát minh lại bánh xe rất thú vị và mang tính giáo dục). Tôi muốn đơn giản hóa việc tạo các hình ảnh nhỏ hơn: hành động tạo một hình ảnh phải cực kỳ đơn giản, tầm thường. Vì vậy, không có tệp cấu hình nào cho bạn, chỉ một dòng trong bảng điều khiển: просто собрать образ для <приложение>.
Vì vậy, nếu bạn muốn tạo hình ảnh của riêng mình thì hãy biết: có một hình ảnh docker độc đáo như vậy, scratch. Scratch là một hình ảnh "trống", không có tập tin nào trong đó, mặc dù nó nặng theo mặc định - wow! - 77 byte.
FROM scratch
Hình ảnh vết xước
Ý tưởng của một hình ảnh đầu là bạn có thể sao chép bất kỳ phần phụ thuộc nào từ máy chủ vào đó và sử dụng chúng bên trong Dockerfile (điều này giống như sao chép chúng vào apt và cài đặt từ đầu) hoặc sau này khi hình ảnh Docker được hiện thực hóa. Điều này cho phép bạn kiểm soát hoàn toàn nội dung của vùng chứa Docker và do đó kiểm soát hoàn toàn kích thước của hình ảnh.
Bây giờ chúng ta cần bằng cách nào đó thu thập những phụ thuộc này. Các công cụ hiện có như apt Cho phép bạn tải xuống các gói phần mềm, nhưng chúng bị ràng buộc với máy tính hiện tại và cuối cùng không hỗ trợ... Windows hoặc MacOS.
Vì vậy, tôi quyết định tự xây dựng một công cụ có thể tự động tạo ảnh hệ thống cơ bản với kích thước nhỏ nhất có thể và chạy bất kỳ ứng dụng nào trên đó. Tôi đã sử dụng các gói phần mềm. Ubuntu/DebianChương trình đã thực hiện việc lựa chọn (lấy trực tiếp các gói từ kho lưu trữ) và tìm kiếm các phần phụ thuộc của chúng một cách đệ quy. Mục tiêu là chương trình sẽ tự động tải xuống phiên bản ổn định mới nhất của gói, giảm thiểu rủi ro bảo mật.
Tôi đặt tên cho công cụ này fetchy, bởi vì anh ấy... tìm và mang... những gì cần thiết [từ tiếng Anh “lấy”, “mang” - khoảng. làn đường]. Công cụ này hoạt động thông qua giao diện dòng lệnh, nhưng đồng thời cung cấp API.
Để lắp ráp một hình ảnh bằng cách sử dụng fetchy (lần này hãy chụp ảnh Python), bạn chỉ cần sử dụng CLI như thế này: fetchy dockerize python. Bạn có thể được yêu cầu hệ điều hành và tên mã mục tiêu vì fetchy hiện chỉ sử dụng các gói dựa trên Debian и Ubuntu.
Bây giờ bạn có thể chọn những phần phụ thuộc nào không cần thiết chút nào (trong ngữ cảnh của chúng tôi) và loại trừ chúng. Ví dụ, Python phụ thuộc vào Perl, mặc dù nó vẫn hoạt động tốt khi không cài đặt Perl.
Những phát hiện
Hình ảnh Python được tạo bằng lệnh fetchy dockerize python3.5 chỉ nặng 35 MB (tôi chắc chắn rằng trong tương lai nó có thể còn nhẹ hơn nữa). Hóa ra là chúng tôi đã cố gắng loại bỏ thêm 15 WW nữa từ hình ảnh không phân phối.
Bạn có thể xem tất cả các hình ảnh được thu thập cho đến nay .
Dự án - .
Nếu bạn thiếu các tính năng, chỉ cần tạo một yêu cầu - tôi sẽ sẵn lòng trợ giúp :) Hơn nữa, tôi hiện đang nỗ lực tích hợp các trình quản lý gói khác vào tìm nạp để không cần xây dựng nhiều giai đoạn.
Nguồn: www.habr.com
