banner large

Cara Membuat Dockerfile Dari Gambar yang Ada

Comment
X
Share

Gambar Docker dibuat dengan membangun Dockerfiles. Proses build menjalankan instruksi di Dockerfile untuk membuat lapisan sistem file yang membentuk gambar akhir.

Bagaimana jika Anda sudah memiliki gambar? Bisakah Anda mengambil Dockerfile tempat pembuatannya? Pada artikel ini, kita akan melihat dua metode yang dapat mencapai hal ini.

Objektif

Saat Anda membuat image Docker Anda sendiri, Anda harus menyimpan Dockerfiles Anda sebagai file yang dikontrol versi di repositori sumber Anda. Praktik ini memastikan Anda selalu dapat mengambil kembali instruksi yang digunakan untuk merakit gambar Anda.

Terkadang Anda tidak akan memiliki akses ke Dockerfile. Mungkin Anda menggunakan gambar yang ada di registri publik tetapi memiliki repositori sumber yang tidak dapat diakses. Atau Anda bisa bekerja dengan snapshot gambar yang tidak secara langsung sesuai dengan Dockerfile berversi. Dalam kasus ini, Anda memerlukan teknik yang dapat membuat Dockerfile dari gambar di mesin Anda.

Docker tidak menawarkan fungsionalitas bawaan untuk mencapai ini. Gambar yang dibangun tidak memiliki hubungan dengan Dockerfile tempat mereka dibuat. Namun, Anda dapat merekayasa balik proses pembuatan untuk menghasilkan perkiraan yang baik dari Dockerfile gambar sesuai permintaan.

Perintah Sejarah Docker

Itu docker history perintah mengungkapkan sejarah lapisan gambar. Ini menunjukkan perintah yang digunakan untuk membangun setiap lapisan sistem file yang berurutan, menjadikannya titik awal yang baik saat mereproduksi Dockerfile.

Berikut Dockerfile sederhana untuk aplikasi Node.js:

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

Bangun gambar menggunakan docker build:

$ docker build -t node-app:latest .

Sekarang periksa riwayat lapisan gambar dengan docker history:

$ docker history node-app:GAMBAR terbaru DIBUAT OLEH UKURAN KOMENTAR c06fc21a8eed 8 detik yang lalu /bin/sh -c #(nop) CMD ["app.js"]               0B 74d58e07103b 8 detik yang lalu /bin/sh -c ./app.js --init 0B 22ea63ef9389 19 detik yang lalu /bin/sh -c #(nop) COPY file:0c0828d0765af4dd... 50B 424bc28f998d 4 hari yang lalu /bin/sh -c #(tidak) CMD ["node"]                 0B  4 hari yang lalu /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) SALIN file:0c0828d0765af4dd87b893f355e5dff77d6932d452f5681dfb98fd9cf05e8eb1 di .  /bin/sh -c #(tidak) CMD ["node"]/bin/sh -c #(nop) ENTRYPOINT ["docker-entrypoint.sh"]...

Dari daftar perintah ini, Anda dapat memperoleh gambaran umum tentang langkah-langkah yang diambil untuk merakit gambar. Untuk gambar sederhana seperti ini, ini bisa menjadi informasi yang cukup untuk mereproduksi Dockerfile secara akurat.

Mengotomatiskan Ekstraksi Lapisan dengan Whaler dan Dfimage

Menyalin perintah dari docker history adalah proses yang melelahkan. Anda juga perlu menanggalkan /bin/sh -c di awal setiap baris, karena Docker menangani setiap instruksi sebagai komentar Bash tanpa operasi.

Untungnya ada alat komunitas yang tersedia yang dapat mengotomatiskan pembuatan Dockerfile dari riwayat lapisan gambar. Untuk tujuan artikel ini, kami akan fokus pada Whaler yang dikemas ke dalam alpine/dfimage (Dockerfile-from-Image) Gambar Docker oleh organisasi Alpine.

Menjalankan dfimage image dan memasok tag Docker akan menampilkan Dockerfile yang dapat digunakan untuk mereproduksi gambar yang direferensikan. Anda harus mengikat soket Docker host Anda ke dalam dfimage wadah sehingga dapat mengakses daftar gambar Anda dan menarik tag jika diperlukan.

$ 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 yang dibuat berisi semua yang Anda butuhkan untuk memulai scratch (sistem file kosong) ke lapisan terakhir dari gambar yang ditentukan. Ini mencakup semua lapisan yang berasal dari gambar dasar. Anda dapat melihat ini di bagian pertama ENTRYPOINT dan CMD instruksi dalam output sampel di atas (lapisan gambar dasar lainnya telah dihilangkan demi singkatnya).

Kecuali COPY, instruksi khusus untuk gambar kami cocok dengan apa yang tertulis di Dockerfile asli. Anda sekarang dapat menyalin instruksi ini ke yang baru Dockerfilebaik menggunakan keseluruhan dfimage output atau dengan mengambil hanya bagian yang berkaitan dengan gambar akhir. Opsi terakhir hanya kemungkinan jika Anda mengetahui identitas gambar dasar asli sehingga Anda dapat menambahkan FROM instruksi ke bagian atas file.

Keterbatasan

Dalam banyak kasus dfimage akan dapat merakit Dockerfile yang dapat digunakan. Meskipun demikian itu tidak sempurna dan kecocokan yang tepat tidak dijamin. Tingkat perbedaan dibandingkan dengan Dockerfile asli gambar akan bervariasi tergantung pada instruksi yang digunakan.

Tidak semua instruksi ditangkap dalam riwayat lapisan. Yang tidak didukung akan hilang dan Anda tidak dapat menentukan apa itu. Akurasi terbaik diperoleh dengan perintah dan instruksi metadata seperti RUN, ENV, WORKDIR, ENTRYPOINTdan CMD. RUN instruksi masih bisa hilang jika perintahnya tidak menghasilkan perubahan sistem file, artinya tidak ada lapisan gambar baru yang dibuat.

COPY dan ADD instruksi menyajikan tantangan yang unik. Riwayat tidak berisi jalur file host yang disalin ke dalam wadah. Anda dapat melihat salinan terjadi tetapi jalur sumber mereferensikan hash file yang disalin ke dalam gambar dari konteks build.

Saat Anda mendapatkan tujuan akhir, ini bisa cukup untuk membantu Anda mengetahui apa yang telah disalin dan mengapa. Anda kemudian dapat menggunakan informasi ini untuk menginterpolasi jalur sumber baru ke dalam Dockerfile yang dapat Anda gunakan untuk build mendatang. Dalam kasus lain, memeriksa file di dalam gambar mungkin membantu mengungkapkan tujuan penyalinan sehingga Anda dapat menentukan nama file yang berarti untuk jalur host.

Ringkasan

Gambar Docker tidak menyertakan cara langsung untuk bekerja mundur ke Dockerfile tempat mereka dibuat. Masih mungkin untuk menyatukan proses pembuatannya. Untuk gambar sederhana dengan sedikit instruksi, Anda sering dapat mengerjakan instruksi secara manual dengan melihat CREATED BY kolom di docker history keluaran perintah.

Gambar yang lebih besar dengan proses pembuatan yang lebih kompleks paling baik dianalisis dengan alat seperti dfimage. Ini melakukan kerja keras untuk menguraikan verbose docker history output untuk Anda, menghasilkan Dockerfile baru yang merupakan upaya terbaik yang cocok untuk kemungkinan yang asli.

Upaya rekayasa terbalik tidak sempurna dan beberapa instruksi Dockerfile hilang atau rusak selama proses pembuatan. Akibatnya Anda tidak boleh menganggap Dockerfiles yang dibuat dengan cara ini adalah representasi akurat dari aslinya. Anda mungkin harus melakukan beberapa penyesuaian manual untuk ADD dan COPY instruksi juga, membangkitkan jalur file host yang dikonversi untuk membangun referensi konteks.

Leave a Reply

Your email address will not be published.