Cách tạo Dockerfile từ một hình ảnh hiện có

[ad_1]

Hình ảnh Docker được tạo bằng cách xây dựng Dockerfiles. Quá trình xây dựng thực hiện các hướng dẫn trong Dockerfile để tạo các lớp hệ thống tệp tạo thành hình ảnh cuối cùng.

Điều gì sẽ xảy ra nếu bạn đã có một hình ảnh? Bạn có thể lấy Dockerfile mà nó được xây dựng từ đó không? Trong bài viết này, chúng ta sẽ xem xét hai phương pháp có thể đạt được điều này.

Mục tiêu

Khi bạn đang xây dựng hình ảnh Docker của riêng mình, bạn nên lưu trữ các tệp Dockerfiles của mình dưới dạng tệp được kiểm soát phiên bản trong kho lưu trữ nguồn của bạn. Phương pháp này đảm bảo bạn luôn có thể truy xuất các hướng dẫn được sử dụng để lắp ráp hình ảnh của mình.

Đôi khi bạn sẽ không có quyền truy cập vào Dockerfile. Có lẽ bạn đang sử dụng một hình ảnh trong sổ đăng ký công khai nhưng có một kho lưu trữ nguồn không thể truy cập được. Hoặc bạn có thể đang làm việc với các ảnh chụp nhanh hình ảnh không tương ứng trực tiếp với Dockerfile đã được phiên bản. Trong những trường hợp này, bạn cần một kỹ thuật có thể tạo Dockerfile từ một hình ảnh trên máy của bạn.

Docker không cung cấp bất kỳ chức năng tích hợp nào để đạt được điều này. Hình ảnh đã xây dựng thiếu liên kết với Dockerfile mà chúng được tạo từ đó. Tuy nhiên, bạn có thể thiết kế ngược lại quy trình xây dựng để tạo ra một bản vẽ gần đúng của Dockerfile của một hình ảnh theo yêu cầu.

Lệnh Lịch sử Docker

Các docker history lệnh tiết lộ lịch sử lớp của một hình ảnh. Nó hiển thị lệnh được sử dụng để xây dựng từng lớp hệ thống tệp kế tiếp, làm cho nó trở thành điểm khởi đầu tốt khi tái tạo một Dockerfile.

Đây là một Dockerfile đơn giản cho ứng dụng Node.js:

FROM node:16
COPY app.js .
RUN app.js --init
CMD ["app.js"]

Xây dựng hình ảnh bằng cách sử dụng docker build:

$ docker build -t node-app:latest .

Bây giờ, hãy kiểm tra lịch sử lớp của hình ảnh với docker history:

$ docker history node-app: HÌNH ẢNH MỚI NHẤT ĐƯỢC TẠO THEO KÍCH THƯỚC BÌNH LUẬN c06fc21a8eed 8 giây trước / bin / sh -c # (nop) CMD ["app.js"]               0B 74d58e07103b 8 giây trước / bin / sh -c ./app.js --init 0B 22ea63ef9389 19 giây trước / bin / sh -c # (nop) Tệp COPY: 0c0828d0765af4dd ... 50B 424bc28f998d 4 ngày trước / bin / sh -c # (nop) CMD ["node"]                 0B  4 ngày trước / bin / sh -c # (nop) ENTRYPOINT ["docker-entry...   0B        
...

The history includes the complete list of layers in the image, including those inherited from the node:16 base image. Layers are ordered so the most recent one is first. You can spot where the layers created by the sample Dockerfile begin based on the creation time. These show Docker’s internal representation of the COPY and CMD instructions used in the Dockerfile.

The docker history output is more useful when the table’s limited to just showing each layer’s command. You can disable truncation too to view the full command associated with each layer:

$ docker history node-app:latest --format "{{.CreatedBy}}" --no-trunc
/bin/sh -c #(nop)  CMD ["app.js"]/ bin / sh -c ./app.js --init / bin / sh -c # (nop) Tệp SAO CHÉP: 0c0828d0765af4dd87b893f355e5dff77d6932d452f5681dfb98fd9cf05e8eb1 in.  / bin / sh -c # (nop) CMD ["node"]/ bin / sh -c # (nop) ENTRYPOINT ["docker-entrypoint.sh"]...

Từ danh sách các lệnh này, bạn có thể có được cái nhìn tổng quan về các bước thực hiện để lắp ráp hình ảnh. Đối với những hình ảnh đơn giản như hình này, đây có thể là thông tin đủ để tái tạo chính xác một Dockerfile.

Tự động khai thác lớp với Whaler và Dfimage

Sao chép các lệnh ra khỏi docker history là một quá trình gian khổ. Bạn cũng cần loại bỏ /bin/sh -c ở đầu mỗi dòng, vì Docker xử lý mỗi lệnh dưới dạng nhận xét no-op Bash.

May mắn thay, có sẵn các công cụ cộng đồng có thể tự động tạo Dockerfile từ lịch sử lớp của hình ảnh. Với mục đích của bài viết này, chúng tôi sẽ tập trung vào Whaler được đóng gói trong alpine/dfimage (Dockerfile-from-Image) Hình ảnh Docker của tổ chức Alpine.

Chạy dfimage hình ảnh và cung cấp thẻ Docker sẽ xuất ra tệp Dockerfile có thể được sử dụng để tái tạo hình ảnh được tham chiếu. Bạn phải liên kết ổ cắm Docker của máy chủ lưu trữ vào dfimage vùng chứa để nó có thể truy cập danh sách hình ảnh của bạn và kéo thẻ nếu cần.

$ docker run --rm 
    -v /var/run/docker.sock:/var/run/docker.sock 
    alpine/dfimage node-app:latest

Analyzing node-app:latest
Docker Version: 20.10.13
GraphDriver: overlay2
Environment Variables
|PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
|NODE_VERSION=16.14.2
|YARN_VERSION=1.22.18

Image user
|User is root

Dockerfile:
...
ENTRYPOINT ["docker-entrypoint.sh"]
CMD ["node"]
COPY file:bcbc3d5784a8f1017653685866d30e230cae61d0da13dae32525b784383ac75f in .
    app.js

RUN ./app.js --init
CMD ["app.js"]

Dockerfile đã tạo chứa mọi thứ bạn cần để bắt đầu scratch (một hệ thống tệp trống) đến lớp cuối cùng của hình ảnh được chỉ định. Nó bao gồm tất cả các lớp đến từ hình ảnh cơ sở. Bạn có thể thấy những thứ này trong phần đầu tiên ENTRYPOINTCMD hướng dẫn trong đầu ra mẫu ở trên (các lớp hình ảnh cơ sở khác đã được bỏ qua vì lợi ích ngắn gọn).

Ngoại trừ COPY, các hướng dẫn cụ thể cho hình ảnh của chúng tôi khớp với những gì được viết trong Dockerfile ban đầu. Bây giờ bạn có thể sao chép các hướng dẫn này vào một Dockerfilehoặc sử dụng toàn bộ dfimage đầu ra hoặc bằng cách chỉ lấy phần liên quan đến hình ảnh cuối cùng. Tùy chọn thứ hai chỉ là một khả năng nếu bạn biết danh tính của hình ảnh cơ sở ban đầu để bạn có thể thêm FROM hướng dẫn lên đầu tệp.

Những hạn chế

Trong nhiều trường hợp dfimage sẽ có thể tập hợp một Dockerfile có thể sử dụng được. Tuy nhiên, nó không hoàn hảo và không được đảm bảo chính xác. Mức độ khác biệt so với Dockerfile ban đầu của hình ảnh sẽ khác nhau tùy thuộc vào các hướng dẫn đã được sử dụng.

Không phải tất cả các hướng dẫn đều được ghi lại trong lịch sử lớp. Những cái không được hỗ trợ sẽ bị mất và bạn không thể xác định được chúng là gì. Độ chính xác tốt nhất đạt được với lệnh và hướng dẫn siêu dữ liệu như RUN, ENV, WORKDIR, ENTRYPOINTCMD. RUN các hướng dẫn vẫn có thể bị thiếu nếu lệnh của chúng không dẫn đến thay đổi hệ thống tệp, nghĩa là không có lớp hình ảnh mới nào được tạo.

COPYADD hướng dẫn đưa ra những thách thức độc đáo. Lịch sử không chứa đường dẫn tệp máy chủ lưu trữ đã được sao chép vào vùng chứa. Bạn có thể thấy một bản sao đã xảy ra nhưng đường dẫn nguồn tham chiếu đến băm tệp đã được sao chép vào hình ảnh từ ngữ cảnh bản dựng.

Khi bạn đến đích cuối cùng, điều này có thể đủ để giúp bạn tìm ra những gì đã được sao chép và lý do tại sao. Sau đó, bạn có thể sử dụng thông tin này để nội suy một đường dẫn nguồn mới vào Dockerfile mà bạn có thể sử dụng cho các bản dựng trong tương lai. Trong các trường hợp khác, việc kiểm tra tệp bên trong hình ảnh có thể giúp tiết lộ mục đích của bản sao để bạn có thể xác định tên tệp có ý nghĩa cho đường dẫn máy chủ.

Bản tóm tắt

Hình ảnh Docker không bao gồm một cách trực tiếp để làm việc ngược lại với Dockerfile mà chúng được xây dựng từ đó. Tuy nhiên, vẫn có thể ghép quá trình xây dựng lại với nhau. Đối với những hình ảnh đơn giản với ít hướng dẫn, bạn thường có thể thực hiện các hướng dẫn theo cách thủ công bằng cách xem CREATED BY cột trong docker history đầu ra của lệnh.

Hình ảnh lớn hơn với các quy trình xây dựng phức tạp hơn được phân tích tốt nhất bằng các công cụ như dfimage. Điều này thực hiện công việc khó khăn trong việc phân tích chi tiết docker history đầu ra cho bạn, tạo ra một Dockerfile mới phù hợp với nỗ lực tốt nhất cho bản gốc.

Các nỗ lực thiết kế ngược không hoàn hảo và một số hướng dẫn Dockerfile bị mất hoặc bị sai sót trong quá trình xây dựng. Do đó, bạn không nên cho rằng Dockerfiles được tạo theo cách này là bản trình bày chính xác của bản gốc. Bạn có thể phải thực hiện một số điều chỉnh thủ công để ADDCOPY cũng như hướng dẫn, phục hồi các đường dẫn tệp máy chủ lưu trữ đã được chuyển đổi để tạo tham chiếu ngữ cảnh.



[ad_2]

Đánh giá dịch vụ post
Chat Zalo
0903064855