Saya kira Anda sedikit familiar dengan Docker dan mengetahui dasar-dasar seperti menjalankan container docker dll.
Pada artikel sebelumnya kita telah membahas mengupdate docker container dan menulis file docker.
Apa sebenarnya yang memodifikasi gambar buruh pelabuhan?
Gambar kontainer dibuat berlapis-lapis (atau merupakan kumpulan lapisan), setiap instruksi Dockerfile membuat lapisan gambar. Sebagai contoh, perhatikan file Docker berikut:
FROM alpine:latest
RUN apk add --no-cache python3
ENTRYPOINT ["python3", "-c", "print('Hello World')"]
Karena ada total tiga perintah Dockerfile, gambar yang dibangun dari Dockerfile ini, akan berisi total tiga lapisan.
Anda dapat mengonfirmasinya dengan membuat gambar:
docker image built -t dummy:0.1 .
Dan kemudian menggunakan perintah docker image history
pada gambar yang dibuat.
articles/Modify a Docker Image on modify-docker-images [?] took 12s
❯ docker image history dummy:0.1
IMAGE CREATED CREATED BY SIZE COMMENT
b997f897c2db 10 seconds ago /bin/sh -c #(nop) ENTRYPOINT ["python3" "-c… 0B
ee217b9fe4f7 10 seconds ago /bin/sh -c apk add --no-cache python3 43.6MB
28f6e2705743 35 hours ago /bin/sh -c #(nop) CMD ["/bin/sh"] 0B
<missing> 35 hours ago /bin/sh -c #(nop) ADD file:80bf8bd014071345b… 5.61MB
Abaikan lapisan '
Masing-masing lapisan ini hanya-baca. Ini bermanfaat karena karena lapisan ini hanya-baca, tidak ada proses yang terkait dengan instance berjalan dari gambar ini yang akan dapat mengubah konten gambar ini, oleh karena itu, lapisan ini dapat dibagikan oleh banyak wadah tanpa harus menyimpan salinan untuk setiap contoh. Tetapi agar proses container dapat melakukan r/w, lapisan lain ditambahkan di atas lapisan RO yang ada saat membuat container, ini dapat ditulis dan tidak dibagikan oleh container lain.
Kelemahan dari lapisan r/w ini adalah bahwa perubahan yang dibuat pada lapisan ini tidak persisten, meskipun Anda dapat menggunakan volume untuk mempertahankan beberapa data, terkadang Anda mungkin perlu/ingin menambahkan lapisan sebelum beberapa lapisan yang ada, atau menghapus lapisan dari gambar atau cukup ganti layer. Inilah alasan mengapa seseorang mungkin ingin memodifikasi docker
yang ada gambar.
Dalam artikel ini, saya akan membahas semua kasus yang saya sebutkan di atas, menggunakan metode yang berbeda.
Metode memodifikasi gambar buruh pelabuhan
Ada dua cara Anda dapat memodifikasi gambar buruh pelabuhan.
- Melalui Dockerfiles.
- Menggunakan perintah
docker container commit
.
Saya akan menjelaskan kedua metode tersebut, dan pada akhirnya, saya juga akan menambahkan use case mana yang lebih baik untuk metode tersebut dalam konteks.
Metode 1:Memodifikasi gambar buruh pelabuhan melalui Dockerfile
Memodifikasi gambar buruh pelabuhan pada dasarnya berarti memodifikasi lapisan gambar. Sekarang karena setiap perintah Dockerfile mewakili satu lapisan gambar, memodifikasi setiap baris Dockerfile akan mengubah gambar masing-masing juga.
Jadi, jika Anda ingin menambahkan lapisan ke gambar, Anda cukup menambahkan instruksi Dockerfile lain ke dalamnya, untuk menghapusnya Anda akan menghapus satu baris dan untuk mengubah lapisan, Anda akan mengubah baris yang sesuai.
Ada dua cara Anda dapat menggunakan Dockerfile untuk memodifikasi gambar.
- Menggunakan gambar yang ingin Anda ubah sebagai gambar dasar dan buat gambar anak.
- Memodifikasi file Docker sebenarnya dari gambar yang ingin Anda ubah.
Mari saya jelaskan metode mana yang harus digunakan kapan, dan bagaimana caranya.
1. Menggunakan gambar sebagai gambar dasar
Ini adalah saat Anda mengambil gambar yang ingin Anda ubah, dan menambahkan lapisan ke dalamnya untuk membuat gambar anak baru. Kecuali jika gambar dibuat dari awal, setiap gambar merupakan modifikasi dari gambar dasar induk yang sama.
Pertimbangkan Dockerfile sebelumnya. Katakanlah gambar yang dibuat dari gambar itu bernama dummy:0.1
. Sekarang jika saya berpikir bahwa saya sekarang perlu menggunakan Perl daripada Python3 untuk mencetak "Hello World", tetapi saya juga tidak ingin menghapus Python3, saya bisa menggunakan dummy:0.1
gambar sebagai gambar dasar (karena Python3 sudah ada) dan bangun dari itu seperti berikut
FROM dummy:0.1
RUN apk add --no-cache perl
ENTRYPOINT ["perl", "-e", "print \"Hello World\n\""]
Di sini saya membangun di atas dummy:0.1
, menambahkan lebih banyak lapisan sesuai keinginan saya.
Metode ini tidak akan banyak membantu jika tujuan Anda adalah mengubah atau menghapus beberapa lapisan yang ada. Untuk itu, Anda perlu mengikuti metode selanjutnya.
2. Memodifikasi Dockerfile gambar
Karena lapisan gambar yang ada bersifat hanya-baca, Anda tidak dapat langsung memodifikasinya melalui Dockerfile baru. Dengan FROM
perintah di Dockerfile, Anda mengambil beberapa gambar sebagai dasar dan membangun di itu, atau menambahkan lapisan ke dalamnya.
Beberapa tugas mungkin mengharuskan kami untuk mengubah lapisan yang ada, meskipun Anda dapat melakukannya menggunakan metode sebelumnya dengan sekumpulan RUN
yang kontradiktif instruksi (seperti menghapus file, menghapus/mengganti paket yang ditambahkan di beberapa lapisan sebelumnya), ini bukan solusi ideal atau apa yang saya rekomendasikan. Karena menambahkan lapisan tambahan dan meningkatkan ukuran gambar cukup banyak.
Metode yang lebih baik adalah tidak menggunakan gambar sebagai gambar dasar, tetapi ubah Dockerfile sebenarnya dari gambar itu. Pertimbangkan lagi Dockerfile sebelumnya, bagaimana jika saya tidak harus menyimpan Python3 di gambar itu, dan mengganti paket Python3 dan perintahnya dengan yang Perl?
Jika mengikuti metode sebelumnya saya harus membuat Dockerfile baru seperti ini -
FROM dummy:0.1
RUN apk del python3 && apk add --no-cache perl
ENTRYPOINT ["perl", "-e", "print \"Hello World\n\""]
Jika dibangun, akan ada total lima lapisan dalam gambar ini.
articles/Modify a Docker Image on modify-docker-images [?] took 3s
❯ docker image history dummy:0.2
IMAGE CREATED CREATED BY SIZE COMMENT
2792036ddc91 10 seconds ago /bin/sh -c #(nop) ENTRYPOINT ["perl" "-e" "… 0B
b1b2ec1cf869 11 seconds ago /bin/sh -c apk del python3 && apk add --no-c… 34.6MB
ecb8694b5294 3 hours ago /bin/sh -c #(nop) ENTRYPOINT ["python3" "-c… 0B
8017025d71f9 3 hours ago /bin/sh -c apk add --no-cache python3 && … 43.6MB
28f6e2705743 38 hours ago /bin/sh -c #(nop) CMD ["/bin/sh"] 0B
<missing> 38 hours ago /bin/sh -c #(nop) ADD file:80bf8bd014071345b… 5.61MB
Selain itu, ukuran gambarnya adalah 83,8 MB.
articles/Modify a Docker Image on modify-docker-images [?]
❯ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
dummy 0.2 2792036ddc91 19 seconds ago 83.8MB
Sekarang alih-alih melakukan itu, ambil Dockerfile awal, dan ubah yang Python3 menjadi Perl seperti itu
FROM alpine:latest
RUN apk add --no-cache perl
ENTRYPOINT ["perl", "-e", "print \"Hello World\n\""]
Jumlah lapisan telah berkurang menjadi 3, dan ukurannya sekarang menjadi 40,2 MB.
articles/Modify a Docker Image on modify-docker-images [?] took 3s
❯ docker image history dummy:0.3
IMAGE CREATED CREATED BY SIZE COMMENT
f35cd94c92bd 9 seconds ago /bin/sh -c #(nop) ENTRYPOINT ["perl" "-e" "… 0B
053a6a6ba221 9 seconds ago /bin/sh -c apk add --no-cache perl 34.6MB
28f6e2705743 38 hours ago /bin/sh -c #(nop) CMD ["/bin/sh"] 0B
<missing> 38 hours ago /bin/sh -c #(nop) ADD file:80bf8bd014071345b… 5.61MB
articles/Modify a Docker Image on modify-docker-images [?]
❯ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
dummy 0.3 f35cd94c92bd 29 seconds ago 40.2MB
Gambar berhasil diubah.
Metode sebelumnya lebih berguna ketika Anda hanya akan menambahkan lapisan di atas yang sudah ada, tetapi tidak banyak membantu ketika mencoba untuk mengubah lapisan yang ada seperti menghapus satu, mengganti satu, menyusun ulang yang sudah ada dan segera. Di situlah metode ini bersinar.
Metode 2:Memodifikasi gambar menggunakan komit buruh pelabuhan
Ada metode lain di mana Anda dapat mengambil snapshot dari container yang sedang berjalan, dan mengubahnya menjadi gambarnya sendiri.
Mari kita membuat dummy:0.1
gambar yang identik, tetapi kali ini tanpa menggunakan Dockerfile. Karena saya menggunakan alpine:latest
sebagai dummy:0.1
's, putar wadah gambar itu.
docker run --rm --name alpine -ti alpine ash
Sekarang di dalam wadah, tambahkan paket Python3, apk add --no-cache python3
. Setelah selesai, buka jendela terminal baru dan jalankan perintah berikut (atau yang serupa)
docker container commit --change='ENTRYPOINT ["python3", "-c", "print(\"Hello World\")"]' alpine dummy:0.4
Dengan --change
tandai Saya menambahkan instruksi Dockerfile ke dummy:04
yang baru gambar (dalam hal ini, ENTRYPOINT
instruksi).
Dengan docker container commit
perintah, pada dasarnya Anda mengubah lapisan r/w terluar menjadi lapisan r/o, menambahkannya ke lapisan gambar yang ada dan membuat gambar baru. Metode ini lebih intuitif/interaktif sehingga Anda mungkin ingin menggunakan ini daripada Dockerfiles, tetapi pahamilah bahwa ini tidak terlalu dapat direproduksi. Aturan yang sama juga berlaku untuk menghapus atau mengubah lapisan yang ada, menambahkan lapisan hanya untuk menghapus sesuatu atau mengubah sesuatu yang dilakukan di lapisan sebelumnya bukanlah ide terbaik, setidaknya dalam sebagian besar kasus.
Itu menyimpulkan artikel ini. Saya harap ini membantu Anda, jika Anda memiliki pertanyaan, beri komentar di bawah.