Hình ảnh Docker nhỏ bé tin tưởng vào chính mình*

[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]*

Hình ảnh Docker nhỏ bé tin tưởng vào chính mình*

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

Dự án 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, nhưng chúng bị ràng buộc với máy hiện tại và xét cho cùng, không hỗ trợ Windows hoặc MacOS.

Vì vậy, tôi bắt đầu xây dựng công cụ của riêng mình để tự động xây dựng hình ảnh cơ sở có kích thước nhỏ nhất có thể và cũng có thể chạy bất kỳ ứng dụng nào. Tôi đã sử dụng các gói Ubuntu/Debian, thực hiện lựa chọn (nhận các gói trực tiếp từ kho lưu trữ) và tìm đệ quy các phần phụ thuộc của chúng. Chương trình được cho là 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 nhiều nhất có thể.

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 và 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 đây.

Dự án - đây.

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

Thêm một lời nhận xét