Pemecahan Masalah Eksekusi Bazel Jarak Jauh dengan Docker Sandbox

Tetap teratur dengan koleksi Simpan dan kategorikan konten berdasarkan preferensi Anda.
Laporkan masalah Lihat sumber

Build Bazel yang berhasil secara lokal mungkin gagal saat dijalankan dari jarak jauh karena pembatasan dan persyaratan yang tidak memengaruhi build lokal. Penyebab paling umum kegagalan tersebut dijelaskan dalam Menyesuaikan Aturan Bazel untuk Eksekusi Jarak Jauh.

Halaman ini menjelaskan cara mengidentifikasi dan menyelesaikan masalah paling umum yang muncul pada eksekusi jarak jauh menggunakan fitur sandbox Docker, yang memberlakukan pembatasan pada build yang sama dengan eksekusi jarak jauh. Hal ini memungkinkan Anda memecahkan masalah build tanpa memerlukan layanan eksekusi jarak jauh.

Fitur sandbox Docker meniru pembatasan eksekusi jarak jauh sebagai berikut:

  • Tindakan build dieksekusi dalam container toolchain. Anda dapat menggunakan container toolchain yang sama untuk menjalankan build secara lokal dan jarak jauh melalui layanan yang mendukung eksekusi jarak jauh dalam container.

  • Tidak ada data yang tidak relevan yang melampaui batas penampung. Hanya input dan output yang dideklarasikan secara eksplisit yang masuk dan keluar dari penampung, dan hanya setelah tindakan build terkait berhasil diselesaikan.

  • Setiap tindakan dieksekusi dalam penampung baru. Container unik yang baru dibuat untuk setiap tindakan build yang dihasilkan.

Anda dapat memecahkan masalah ini menggunakan salah satu metode berikut:

  • Pemecahan masalah secara native. Dengan metode ini, Bazel dan tindakan build-nya berjalan secara native di mesin lokal Anda. Fitur sandbox Docker menerapkan pembatasan pada build yang sama dengan eksekusi jarak jauh. Namun, metode ini tidak akan mendeteksi alat lokal, status, dan kebocoran data ke dalam build Anda, yang akan menyebabkan masalah dengan eksekusi jarak jauh.

  • Pemecahan masalah di penampung Docker. Dengan metode ini, Bazel dan tindakan build-nya berjalan di dalam container Docker, yang memungkinkan Anda mendeteksi alat, status, dan kebocoran data dari mesin lokal ke dalam build selain menerapkan batasan yang sama dengan eksekusi jarak jauh. Metode ini memberikan insight tentang build Anda meskipun bagian build gagal. Metode ini bersifat eksperimental dan tidak didukung secara resmi.

Prasyarat

Sebelum memulai pemecahan masalah, lakukan hal berikut jika Anda belum melakukannya:

  • Instal Docker dan konfigurasikan izin yang diperlukan untuk menjalankannya.
  • Instal Bazel 0.14.1 atau yang lebih baru. Versi sebelumnya tidak mendukung fitur sandbox Docker.
  • Tambahkan repo bazel-toolchains, yang disematkan ke versi rilis terbaru, ke file WORKSPACE build Anda seperti yang dijelaskan di sini.
  • Tambahkan flag ke file .bazelrc Anda untuk mengaktifkan fitur ini. Buat file dalam direktori utama project Bazel Anda jika belum ada. Flag di bawah adalah contoh referensi. Lihat file .bazelrc terbaru dalam repo bazel-toolchain dan salin nilai flag yang ditentukan ke sana untuk konfigurasi docker-sandbox.
# Docker Sandbox Mode
build:docker-sandbox --host_javabase=<...>
build:docker-sandbox --javabase=<...>
build:docker-sandbox --crosstool_top=<...>
build:docker-sandbox --experimental_docker_image=<...>
build:docker-sandbox --spawn_strategy=docker --strategy=Javac=docker --genrule_strategy=docker
build:docker-sandbox --define=EXECUTOR=remote
build:docker-sandbox --experimental_docker_verbose
build:docker-sandbox --experimental_enable_docker_sandbox

Jika aturan Anda memerlukan alat tambahan, lakukan hal berikut:

  1. Buat container Docker kustom dengan menginstal alat menggunakan Dockerfile dan mem-build image secara lokal.

  2. Ganti nilai flag --experimental_docker_image di atas dengan nama image container kustom Anda.

Memecahkan masalah secara native

Metode ini mengeksekusi Bazel dan semua tindakan build-nya secara langsung pada mesin lokal dan merupakan cara yang andal untuk mengonfirmasi apakah build Anda akan berhasil saat dijalankan dari jarak jauh.

Namun, dengan metode ini, alat, biner, dan data yang terinstal secara lokal dapat bocor ke dalam build Anda, terutama jika menggunakan aturan WORKSPACE bergaya konfigurasi. Kebocoran tersebut akan menyebabkan masalah pada eksekusi jarak jauh; untuk mendeteksinya, pecahkan masalah dalam container Docker selain memecahkan masalah secara native.

Langkah 1: Jalankan build

  1. Tambahkan flag --config=docker-sandbox ke perintah Bazel yang menjalankan build Anda. Contoh:

    bazel --bazelrc=.bazelrc build --config=docker-sandbox target
    
  2. Jalankan build dan tunggu hingga selesai. Build akan berjalan empat kali lebih lambat dari biasanya karena fitur sandbox Docker.

Anda mungkin mengalami error berikut:

ERROR: 'docker' is an invalid value for docker spawn strategy.

Jika ya, jalankan build lagi dengan flag --experimental_docker_verbose. Tanda ini memungkinkan pesan error panjang. Error ini biasanya disebabkan oleh penginstalan Docker yang rusak atau kurangnya izin untuk menjalankannya di akun pengguna saat ini. Lihat dokumentasi Docker untuk informasi selengkapnya. Jika masalah terus berlanjut, lanjutkan ke Pemecahan masalah di penampung Docker.

Langkah 2: Selesaikan masalah yang terdeteksi

Berikut adalah masalah yang paling sering terjadi dan solusinya.

  • File, alat, biner, atau resource yang dirujuk oleh hierarki runfile Bazel tidak ada.. Konfirmasikan bahwa semua dependensi target yang terpengaruh telah dideklarasikan secara eksplisit. Lihat Mengelola dependensi implisit untuk informasi selengkapnya.

  • File, alat, biner, atau resource yang direferensikan oleh jalur absolut atau variabel PATH tidak ada. Konfirmasikan bahwa semua alat yang diperlukan telah diinstal dalam container toolchain dan gunakan aturan toolchain untuk mendeklarasikan dependensi yang mengarah ke resource yang hilang dengan benar. Lihat Memanggil alat build melalui aturan toolchain untuk informasi selengkapnya.

  • Eksekusi biner gagal. Salah satu aturan build merujuk pada biner yang tidak kompatibel dengan lingkungan eksekusi (penampung Docker). Lihat Mengelola biner yang bergantung pada platform untuk informasi selengkapnya. Jika Anda tidak dapat menyelesaikan masalah ini, hubungi bazel-discuss@google.com untuk mendapatkan bantuan.

  • File dari @local-jdk tidak ada atau menyebabkan error. Biner Java di mesin lokal Anda mengalami kebocoran pada build sembari tidak kompatibel dengan build tersebut. Gunakan java_toolchain dalam aturan dan target Anda, bukan @local_jdk. Hubungi bazel-discuss@google.com jika Anda memerlukan bantuan lebih lanjut.

  • Error lainnya. Hubungi bazel-discuss@google.com untuk mendapatkan bantuan.

Memecahkan masalah di container Docker

Dengan metode ini, Bazel berjalan di dalam container Docker host, dan tindakan build Bazel dieksekusi dalam container toolchain individual yang dihasilkan oleh fitur sandbox Docker. Sandbox menampilkan penampung toolchain baru untuk setiap tindakan build dan hanya satu tindakan yang dieksekusi di setiap penampung toolchain.

Metode ini memberikan kontrol yang lebih terperinci untuk alat yang diinstal di lingkungan host. Dengan memisahkan eksekusi build dari eksekusi tindakan build-nya dan meminimalkan alat yang diinstal, Anda dapat memverifikasi apakah build Anda memiliki dependensi pada lingkungan eksekusi lokal.

Langkah 1: Build container

  1. Buat Dockerfile yang membuat container Docker dan menginstal Bazel dengan serangkaian alat build minimal:

    FROM debian:stretch
    
    RUN apt-get update && apt-get install -y apt-transport-https curl software-properties-common git gcc gnupg2 g++ openjdk-8-jdk-headless python-dev zip wget vim
    
    RUN curl -fsSL https://download.docker.com/linux/debian/gpg | apt-key add -
    
    RUN add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/debian $(lsb_release -cs) stable"
    
    RUN apt-get update && apt-get install -y docker-ce
    
    RUN wget https://releases.bazel.build/<latest Bazel version>/release/bazel-<latest Bazel version>-installer-linux-x86_64.sh -O ./bazel-installer.sh && chmod 755 ./bazel-installer.sh
    
    RUN ./bazel-installer.sh
    
  2. Build container sebagai bazel_container:

    docker build -t bazel_container - < Dockerfile
    

Langkah 2: Mulai container

Mulai container Docker menggunakan perintah yang ditampilkan di bawah ini. Pada perintah tersebut, ganti jalur ke kode sumber di host yang ingin Anda buat.

docker run -it \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -v /tmp:/tmp \
  -v your source code directory:/src \
  -w /src \
  bazel_container \
  /bin/bash

Perintah ini menjalankan container sebagai root, yang memetakan soket docker, dan memasang direktori /tmp. Hal ini memungkinkan Bazel menghasilkan container Docker lain dan menggunakan direktori pada /tmp untuk berbagi file dengan container tersebut. Kode sumber Anda tersedia di /src dalam penampung.

Perintah sengaja dimulai dari container dasar debian:stretch yang menyertakan biner yang tidak kompatibel dengan container rbe-ubuntu16-04 yang digunakan sebagai container toolchain. Jika biner dari lingkungan lokal bocor ke dalam container toolchain, biner tersebut akan menyebabkan error build.

Langkah 3: Uji penampung

Jalankan perintah berikut dari dalam container Docker untuk mengujinya:

docker ps
bazel version

Langkah 4: Jalankan build

Jalankan build seperti yang ditunjukkan di bawah. Pengguna output di-root agar sesuai dengan direktori yang dapat diakses dengan jalur absolut yang sama dari dalam container host tempat Bazel berjalan, dari container toolchain yang dihasilkan fitur sandbox Docker tempat tindakan build Bazel dijalankan, serta dari mesin lokal tempat host dan container tindakan berjalan.

bazel --output_user_root=/tmp/bazel_docker_root --bazelrc=.bazelrc \ build --config=docker-sandbox target

Langkah 5: Selesaikan masalah yang terdeteksi

Anda dapat mengatasi kegagalan build sebagai berikut:

  • Jika build gagal dengan menampilkan error "out of disk space", Anda dapat meningkatkan batas ini dengan memulai container host dengan flag --memory=XX dengan XX adalah ruang disk yang dialokasikan dalam gigabyte. Ini bersifat eksperimental dan dapat menghasilkan perilaku yang tidak dapat diprediksi.

  • Jika build gagal selama fase analisis atau pemuatan, satu atau beberapa aturan build Anda yang dideklarasikan dalam file WORKSPACE tidak kompatibel dengan eksekusi jarak jauh. Lihat Menyesuaikan Aturan Bazel untuk Eksekusi Jarak Jauh untuk mengetahui kemungkinan penyebab dan solusinya.

  • Jika build gagal karena alasan lain, lihat langkah-langkah pemecahan masalah dalam Langkah 2: Selesaikan masalah yang terdeteksi.