informasi kontak saya
Surat[email protected]
2024-07-12
한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina
buildx adalah alat pembangunan yang secara resmi disediakan oleh Docker. Ini dapat membantu pengguna membangun image Docker dengan cepat dan efisien, dan mendukung pembangunan berbagai platform. Dengan menggunakan buildx, pengguna dapat membuat image untuk beberapa arsitektur, seperti arsitektur x86 dan arm, dalam satu perintah tanpa harus mengoperasikan beberapa perintah build secara manual. Selain itu, buildx juga mendukung konstruksi multi-tahap dan caching Dockerfile, yang dapat sangat meningkatkan efisiensi dan kecepatan konstruksi gambar.
buildx adalah plug-in CLI yang mengelola build Docker. Lapisan yang mendasarinya menggunakan BuildKit untuk memperluas kemampuan build Docker.
BuildKit adalah mesin build berkinerja tinggi yang secara resmi disediakan oleh Docker, yang dapat digunakan untuk menggantikan mesin build asli Docker. Dibandingkan dengan mesin aslinya, BuildKit memiliki kecepatan build yang lebih cepat, paralelisme yang lebih tinggi, penggunaan sumber daya yang lebih sedikit, dan keamanan yang lebih baik.
Untuk menginstal dan menggunakan buildx, nomor versi Docker Engine lebih besar atau sama dengan 19.03.
Pembuatnya mendukung berbagai strategi untuk membangun gambar lintas platform.
Jika Anda menggunakan Docker Desktop, QEMU sudah didukung dan merupakan strategi paling sederhana untuk membangun image lintas platform. Itu tidak memerlukan perubahan apa pun pada Dockerfile asli. BuildKit akan mengimplementasikan eksekusi program lintas platform melalui fungsi kernel Linux binfmt_misc.
prinsip bekerja:
QEMU adalah simulator prosesor yang dapat mensimulasikan arsitektur CPU yang berbeda. Kita dapat memahaminya sebagai bentuk lain dari mesin virtual. Di buildx, QEMU digunakan untuk mengeksekusi biner untuk arsitektur non-native selama proses build. Misalnya, saat membuat image ARM pada host x86, QEMU dapat mensimulasikan lingkungan ARM dan menjalankan binari ARM.
binfmt_misc adalah modul kernel Linux yang memungkinkan pengguna mendaftarkan format file yang dapat dieksekusi dan penerjemah yang sesuai.Ketika kernel menemukan file yang dapat dieksekusi dengan format yang tidak diketahui, binfmt_misc digunakan untuk menemukan penerjemah yang terkait dengan format file (dalam hal ini QEMU) dan menjalankan file tersebut . Fungsi ini dimatikan pada platform rk3568.
Kombinasi QEMU dan binfmt_misc memungkinkan pembangunan lintas platform melalui buildx. Hal ini memungkinkan kami membuat image Docker untuk satu arsitektur pada host untuk arsitektur lain tanpa harus memiliki perangkat keras target sebenarnya.
Meskipun Docker Desktop telah dikonfigurasi sebelumnya dengan dukungan binfmt_misc untuk platform lain, untuk versi Docker lainnya, Anda mungkin perlu menggunakan image tonistiigi/binfmt untuk memulai kontainer istimewa untuk mendapatkan dukungan.
docker run --privileged --rm tonistiigi/binfmt --install all
Menjalankan perintah ini akan menginstal program penerjemah dengan arsitektur berbeda, yaitu simulator qemu di direktori /usr/bin:
Modul binfmt_misc dimuat di server kompilasi kami:
Docker Buildx adalah fitur eksperimental Docker yang memperluas kemampuan build Docker, termasuk penggunaan multi-node, qemu, dll. QEMU adalah perangkat lunak mesin virtual sumber terbuka yang dapat mensimulasikan berbagai CPU dan perangkat keras lainnya, memungkinkan kita membangun image sistem operasi lain pada satu sistem operasi.
Menggunakan fungsi qemu di Docker Buildx dapat membantu kita membuat image Docker untuk berbagai arsitektur berbeda (seperti ARM, MIPS, dll.).
Berikut ini adalah contoh sederhana yang menunjukkan cara menggunakan Docker Buildx dan QEMU untuk membangun image Docker untuk arsitektur ARM:
- # 创建一个新的 buildkit 实例
- docker buildx create --name mybuilder --use
-
- # 启动 buildkit 实例
- docker buildx start mybuilder
-
- # 启用 QEMU 驱动支持
- docker buildx inspect --bootstrap
-
- # 构建一个面向 ARM 架构的 Docker 镜像
- docker buildx build --platform linux/arm/v7 -t myimage:latest .
Dalam contoh ini,--platform
Parameternya menentukan bahwa platform target yang ingin kita bangun adalah ARM v7. Dengan cara ini, Docker akan menggunakan QEMU untuk mensimulasikan lingkungan ARM dan membangun image Docker untuk arsitektur ARM pada mesin arsitektur x86.
binfmt-misc adalah fungsi yang disediakan oleh kernel Linux mirip dengan asosiasi file di Windows, tetapi lebih kuat dari asosiasi file adalah ia tidak hanya dapat menilai berdasarkan nama akhiran file, tetapi juga dapat dibuka menggunakan program berbeda berdasarkan file tersebut konten (Byte Ajaib) . Skenario penggunaan umumnya adalah menggunakan qemu untuk menjalankan file biner pada platform arsitektur lain.
Aktifkan binfmt-lain-lain
Untuk mengaktifkannya sementara, gunakan perintah berikut:
$ sudo mount binfmt_misc -t binfmt_misc /proc/sys/fs/binfmt_misc
Metode ini akan menjadi tidak valid setelah dimulai ulang. Jika Anda ingin menerapkannya dalam waktu lama, Anda dapat menambahkan baris ke file /etc/fstab:
none /proc/sys/fs/binfmt_misc binfmt_misc defaults 0 0
Anda dapat menggunakan perintah berikut untuk memeriksa apakah pembukaan berhasil:
- $ mount | grep binfmt_misc
- binfmt_misc on /proc/sys/fs/binfmt_misc type binfmt_misc (rw,relatime)
- $ ls -l /proc/sys/fs/binfmt_misc
- 总用量 0
- --w------- 1 root root 0 2月 5 22:55 register
- -rw-r--r-- 1 root root 0 2月 5 22:55 status
Pertama siapkan program dengan arsitektur arm64. Setelah menjalankannya, kesalahan dilaporkan:
bash: ./go-test:无法执行二进制文件: 可执行文件格式错误
Sekarang, mari kita jalankan perintah apt install qemu-user-binfmt, lalu jalankan program arm64 di atas dan ternyata dapat berjalan normal. Setelah menginstal qemu-user-binfmt, beberapa file akan dibuat di direktori /proc/sys/fs/binfmt_misc, termasuk satu qemu-aarch64.
- root@ubuntu:/proc/sys/fs/binfmt_misc# cat qemu-aarch64
- enabled
- interpreter /usr/bin/qemu-aarch64-static
- flags: OC
- offset 0
- magic 7f454c460201010000000000000000000200b700
- mask ffffffffffffff00fffffffffffffffffeffffff
- root@ubuntu:/proc/sys/fs/binfmt_misc#
File ini menjelaskan file aturan:
Baris pertama yang diaktifkan menunjukkan bahwa aturan tersebut diaktifkan;
Penerjemah baris kedua /usr/bin/qemu-aarch64-static menunjukkan penggunaan /usr/bin/qemu-aarch64-static untuk mengeksekusi file biner;
Baris ketiga: OC melambangkan bendera lari, arti spesifiknya adalah sebagai berikut:
P: singkatan dari melestarikan-argv, artinya saat memanggil simulator, parameter asli (argv) akan dipertahankan.Hal ini berguna untuk situasi di mana program senyap perlu mengetahui namanya sendiri (yaitu argv[0]) saat runtime
O: mewakili offset, artinya sebelum memulai simulator, offset perlu dibaca dari file biner, dan offset ini akan digunakan sebagai parameter simulator.
C: adalah singkatan dari kredensial, artinya emulator akan berjalan dengan ID pengguna dan ID grup yang sama dengan yang digunakan oleh program aslinya, yang membantu memastikan bahwa emulator berjalan dengan izin yang sama dengan program aslinya.
Baris keempat: offset 0 berarti mulai membaca file dari nilai 0;
Baris kelima: magic 7f454c460201010000000000000000000200b700 mewakili modulo byte yang akan dicocokkan;
Bidang ajaib pada header file ELF arsitektur arm64 adalah sebagai berikut, artinya sistem file binfmt_misc dapat menentukan simulator arsitektur mana yang akan digunakan untuk menjalankan file berdasarkan bidang ajaib pada file ELF:
Di bawah ini adalah dua arsitektur yang berbeda
Arsitektur Mips: 7f454c4601020100000000000000000000020008
arsitektur arm64: 7f454c460201010000000000000000000200b700
Baris 6: mask ffffffffffffff00ffffffffffffffffffffffff mewakili byte mask, yang dapat digunakan untuk mengabaikan beberapa byte yang tidak penting dalam file.
Sekarang kami menggunakanburuh pelabuhanPerintah menjalankan gambar arm64:
- $ docker run -it arm64v8/ubuntu bash
- Unable to find image 'arm64v8/ubuntu:latest' locally
- latest: Pulling from arm64v8/ubuntu
- 005e2837585d: Pull complete
- Digest: sha256:ba545858745d6307f0d1064d0d25365466f78d02f866cf4efb9e1326a4c196ca
- Status: Downloaded newer image for arm64v8/ubuntu:latest
- standard_init_linux.go:207: exec user process caused "no such file or directory"
Setelah beberapa eksplorasi, saya menemukan bahwa selama saya menjalankan perintah berikut:apt install qemu-user-static
, lalu mulai buruh pelabuhanwadahItu normal.
Kompleksitas kompilasi silang tidak terletak pada Docker, tetapi pada program itu sendiri. Misalnya, program Go dapat dengan mudah dikompilasi silang. Anda hanya perlu menjalankan dua variabel lingkungan GOOS dan GOARCH saat membuat program menggunakan go build.
Untuk menggunakan buildx untuk membangun image lintas platform, pertama-tama kita perlu membuat pembuat, yang dapat diterjemahkan sebagai pembuat.
Gunakan perintah docker buildx ls untuk melihat daftar pembuat:
- root@ubuntu:/proc# docker buildx ls
- NAME/NODE DRIVER/ENDPOINT STATUS PLATFORMS
- mybuild * docker-container
- mybuild0 unix:///var/run/docker.sock running linux/arm64*, linux/amd64, linux/amd64/v2, linux/amd64/v3, linux/amd64/v4, linux/386
- vigilant_hugle docker-container
- vigilant_hugle0 unix:///var/run/docker.sock stopped
- default docker
- default default running linux/amd64, linux/386
Tanda * menunjukkan pembuat yang sedang digunakan. Saat kami menjalankan perintah docker build, kami menggunakan pembuat ini untuk membuat image. DRIVER/ENDPOINT pada kolom kedua menunjukkan driver yang digunakan. buildx mendukung driver berikut:
Karena pembuat default yang menggunakan driver docker tidak mendukung pembuatan image lintas platform menggunakan satu perintah (parameter --platform dari pembuat default hanya menerima satu nilai), kita perlu membuat pembuat baru menggunakan driver docker-container .
Sintaks perintahnya adalah sebagai berikut:
$ docker buildx create --name=<builder-name> --driver=<driver> --driver-opt=<driver-options>
Arti dari parameter adalah sebagai berikut;
--name: Nama yang dibuat, wajib diisi.
--driver: Driver pembuat, defaultnya adalah wadah buruh pelabuhan.
--driver-opt: opsi driver. Misalnya, opsi --driver-opt=image=moby/buildkit:v0.11.3 dapat menginstal versi BuildKit yang ditentukan.
Kita dapat membuat pembangun baru menggunakan perintah berikut:
- $ docker buildx create --name mybuilder
- mybuilder
Periksa kembali daftar pembuatnya:
- $ docker buildx ls
- NAME/NODE DRIVER/ENDPOINT STATUS BUILDKIT PLATFORMS
- mybuilder * docker-container
- mybuilder0 unix:///var/run/docker.sock inactive
- default docker
- default default running 20.10.21 linux/arm64, linux/amd64, linux/riscv64, linux/ppc64le, linux/s390x, linux/386, linux/arm/v7, linux/arm/v6
- desktop-linux docker
- desktop-linux desktop-linux running 20.10.21 linux/arm64, linux/amd64, linux/riscv64, linux/ppc64le, linux/s390x, linux/386, linux/arm/v7, linux/arm/v6
Anda dapat menemukan bahwa build yang dipilih telah dialihkan ke Mybuilder. Jika tidak dipilih, Anda perlu menggunakan perintah docker buildx use mybuilder secara manual untuk mengganti build.
Mybuilder kami yang baru dibuat saat ini tidak aktif dan perlu dijalankan sebelum dapat digunakan.
- $ docker buildx inspect --bootstrap mybuilder
- [+] Building 16.8s (1/1) FINISHED
- => [internal] booting buildkit 16.8s
- => => pulling image moby/buildkit:buildx-stable-1 16.1s
- => => creating container buildx_buildkit_mybuilder0 0.7s
- Name: mybuilder
- Driver: docker-container
-
- Nodes:
- Name: mybuilder0
- Endpoint: unix:///var/run/docker.sock
- Status: running
- Buildkit: v0.9.3
- Platforms: linux/arm64, linux/amd64, linux/riscv64, linux/ppc64le, linux/s390x, linux/386, linux/mips64le, linux/mips64, linux/arm/v7, linux/arm/v6
Subperintah inspeksi digunakan untuk memeriksa status build. Gunakan parameter --bootstrap untuk memulai pembuat mybuilder. Periksa kembali daftar pembuat.
- $ docker buildx ls
- NAME/NODE DRIVER/ENDPOINT STATUS BUILDKIT PLATFORMS
- mybuilder * docker-container
- mybuilder0 unix:///var/run/docker.sock running v0.9.3 linux/arm64, linux/amd64, linux/riscv64, linux/ppc64le, linux/s390x, linux/386, linux/mips64le, linux/mips64, linux/arm/v7, linux/arm/v6
- default docker
- default default running 20.10.21 linux/arm64, linux/amd64, linux/riscv64, linux/ppc64le, linux/s390x, linux/386, linux/arm/v7, linux/arm/v6
- desktop-linux docker
- desktop-linux desktop-linux running 20.10.21 linux/arm64, linux/amd64, linux/riscv64, linux/ppc64le, linux/s390x, linux/386, linux/arm/v7, linux/arm/v6
Nilai yang ditampilkan di kolom PLATFORMS
linux/arm64, linux/amd64, linux/riscv64, linux/ppc64le, linux/s390x, linux/386, linux/mips64le, linux/mips64, linux/arm/v7, linux/arm/v6 didukung oleh pembuat saat ini Semua platform.
Sekarang gunakan perintah docker ps untuk melihat bahwa wadah BuildKit yang sesuai dengan pembuat mybuilder telah dimulai.
- $ docker ps
- CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
- b8887f253d41 moby/buildkit:buildx-stable-1 "buildkitd" 4 minutes ago Up 4 minutes buildx_buildkit_mybuilder0
Kontainer ini digunakan untuk membantu kami dalam membangun image lintas platform.
$ docker buildx build --platform linux/arm64,linux/amd64 -t jianghushinian/hello-go .
Sintaks docker buildx build sama dengan docker build. Parameter --platform menunjukkan platform target untuk membangun gambar, -t menunjukkan Tag gambar, . menunjukkan bahwa konteksnya adalah direktori saat ini。
Satu-satunya hal yang tidak berfungsi adalah dukungan untuk parameter --platform. Parameter --platform dari docker build hanya mendukung penyampaian satu informasi platform, seperti --platform linux/arm64, yang berarti bahwa satu gambar platform dapat dibangun pada suatu waktu.
Menggunakan docker buildx build untuk membuat image mendukung transmisi beberapa informasi platform secara bersamaan, dipisahkan dengan koma bahasa Inggris, sehingga mewujudkan fungsi membuat beberapa image lintas platform hanya dengan satu perintah.
Setelah menjalankan perintah di atas, kita akan mendapat peringatan:
WARNING: No output specified with docker-container driver. Build result will only remain in the build cache. To push result image into registry use --push or to load image into docker use --load
Peringatan ini mengingatkan kita bahwa kita belum menentukan output untuk driver docker-container. Hasil yang dihasilkan hanya akan disimpan dalam cache build. Gunakan --push untuk memasukkan image ke repositori jarak jauh Docker Hub, dan gunakan --load untuk menyimpan gambar secara lokal.
Ini karena mybuilder yang baru kami buat memulai sebuah container untuk menjalankan BuildKit. Ia tidak dapat secara langsung mengeluarkan gambar lintas platform yang dibangun ke mesin lokal atau mendorongnya ke jarak jauh.
Kita dapat mencoba menentukan --load untuk menyimpan gambar di host lokal.
- $ docker buildx build --platform linux/arm64,linux/amd64 -t jianghushinian/hello-go . --load
- [+] Building 0.0s (0/0)
- ERROR: docker exporter does not currently support exporting manifest lists
Hasilnya akan menjadi log kesalahan. Tampaknya ini tidak mendukung ekspor gambar lintas platform ke lokal. Ini sebenarnya karena beberapa --platforms diteruskan. Jika --platform hanya melewati satu platform, Anda dapat menggunakan --load untuk menampilkan gambar yang dibuat ke dalamnya mesin.
Kemudian kita hanya dapat mendorong gambar lintas platform ke gudang jarak jauh melalui parameter --push. Namun, sebelum melakukan ini, Anda perlu memastikan untuk menggunakan login buruh pelabuhan untuk menyelesaikan login.
$ docker buildx build --platform linux/arm64,linux/amd64 -t jianghushinian/hello-go . --push
Sekarang masuk ke Docker Hub dan Anda dapat melihat gambar lintas platform yang didorong.
Kita juga dapat menggunakan imagestools untuk memeriksa informasi manifes dari gambar lintas platform. Perintah ini hanya dapat digunakan untuk mendapatkan informasi gambar di gudang, dan gambar lokal tidak dapat dilihat.
- $ docker buildx imagetools inspect jianghushinian/hello-go
- Name: docker.io/jianghushinian/hello-go:latest
- MediaType: application/vnd.docker.distribution.manifest.list.v2+json
- Digest: sha256:51199dadfc55b23d6ab5cfd2d67e38edd513a707273b1b8b554985ff562104db
-
- Manifests:
- Name: docker.io/jianghushinian/hello-go:latest@sha256:8032a6f23f3bd3050852e77b6e4a4d0a705dfd710fb63bc4c3dc9d5e01c8e9a6
- MediaType: application/vnd.docker.distribution.manifest.v2+json
- Platform: linux/arm64
-
- Name: docker.io/jianghushinian/hello-go:latest@sha256:fd46fd7e93c7deef5ad8496c2cf08c266bac42ac77f1e444e83d4f79d58441ba
- MediaType: application/vnd.docker.distribution.manifest.v2+json
- Platform: linux/amd64
Seperti yang Anda lihat, gambar lintas platform ini berisi gambar dari dua platform target, yaitu linux/arm64 dan linux/amd64.