บิลด์ Bazel ที่ประสบความสำเร็จในเครื่องอาจล้มเหลวเมื่อดำเนินการจากระยะไกลเนื่องจากข้อจำกัดและข้อกำหนดที่ไม่ส่งผลกระทบต่อบิลด์ในเครื่อง สาเหตุของความล้มเหลวดังกล่าวที่พบได้บ่อยที่สุดมีอธิบายอยู่ในการปรับกฎของ Bazel สำหรับการดำเนินการระยะไกล
หน้านี้จะอธิบายวิธีระบุและแก้ไขปัญหาที่พบบ่อยที่สุดเกี่ยวกับการดำเนินการจากระยะไกลโดยใช้ฟีเจอร์แซนด์บ็อกซ์ของ Docker ซึ่งจะมีข้อจำกัดเกี่ยวกับบิลด์ที่เทียบเท่ากับการดำเนินการจากระยะไกล วิธีนี้ช่วยให้คุณแก้ปัญหาบิลด์ได้โดยไม่ต้องใช้บริการดำเนินการระยะไกล
ฟีเจอร์แซนด์บ็อกซ์ของ Docker จะเลียนแบบข้อจำกัดของการดำเนินการระยะไกลดังต่อไปนี้
สร้างการดำเนินการที่ดำเนินการในคอนเทนเนอร์ Toolchain คุณใช้คอนเทนเนอร์เครื่องมือเชนเดียวกันเพื่อเรียกใช้บิลด์ภายในและระยะไกลผ่านบริการที่รองรับการดำเนินการระยะไกลที่มีคอนเทนเนอร์ได้
ไม่มีข้อมูลที่ไม่เกี่ยวข้องข้ามขอบเขตคอนเทนเนอร์ มีเพียงอินพุตและเอาต์พุตที่ประกาศอย่างชัดแจ้งเท่านั้นที่จะเข้าและออกจากคอนเทนเนอร์ได้ และหลังจากที่การดำเนินการบิลด์ที่เกี่ยวข้องเสร็จสมบูรณ์แล้วเท่านั้น
การดำเนินการแต่ละอย่างจะดำเนินการในคอนเทนเนอร์ใหม่ ระบบจะสร้างคอนเทนเนอร์ใหม่ที่ไม่ซ้ำกัน สำหรับการทำงานของบิลด์แต่ละรายการ
คุณแก้ปัญหาเหล่านี้ได้โดยใช้วิธีใดวิธีหนึ่งต่อไปนี้
การแก้ปัญหาตั้งแต่ต้น วิธีนี้ทำให้ Bazel และการทำงานของบิลด์จะทำงานในเครื่องของคุณได้ตั้งแต่ต้น ฟีเจอร์แซนด์บ็อกซ์ของ Docker กำหนดข้อจำกัดให้กับบิลด์ที่เทียบเท่ากับการดำเนินการระยะไกล อย่างไรก็ตาม วิธีนี้จะตรวจไม่พบเครื่องมือ สถานะ และข้อมูลในเครื่องที่รั่วไหลในบิลด์ ซึ่งจะทำให้เกิดปัญหากับการดำเนินการระยะไกล
การแก้ปัญหาในคอนเทนเนอร์ Docker เมื่อใช้วิธีนี้ Bazel และการทำงานของบิลด์จะทำงานภายในคอนเทนเนอร์ Docker ซึ่งจะช่วยให้คุณตรวจหาเครื่องมือ สถานะ และข้อมูลที่รั่วไหลจากเครื่องภายในไปยังบิลด์ นอกเหนือจากการกำหนดข้อจำกัดได้เท่ากับการดำเนินการระยะไกล วิธีการนี้ให้ข้อมูลเชิงลึกเกี่ยวกับงานสร้างของคุณแม้ว่าบางส่วนของบิลด์จะล้มเหลวก็ตาม วิธีนี้อยู่ในขั้นทดลองและยังไม่มีการสนับสนุนอย่างเป็นทางการ
สิ่งที่ต้องดำเนินการก่อน
ก่อนที่จะเริ่มแก้ปัญหา โปรดทำดังต่อไปนี้หากยังไม่ได้ดำเนินการ
- ติดตั้ง Docker และกำหนดค่าสิทธิ์ที่จำเป็นต่อการเรียกใช้
- ติดตั้ง Bazel 0.14.1 ขึ้นไป เวอร์ชันก่อนหน้านี้ไม่รองรับฟีเจอร์แซนด์บ็อกซ์ของ Docker
- เพิ่มที่เก็บ bazel-toolchains ซึ่งปักหมุดไว้ในเวอร์ชันล่าสุดลงในไฟล์
WORKSPACE
ของบิลด์ตามที่อธิบายไว้ที่นี่ - เพิ่มแฟล็กในไฟล์
.bazelrc
เพื่อเปิดใช้ฟีเจอร์นี้ สร้างไฟล์ในไดเรกทอรีรูทของโปรเจ็กต์ Bazel หากยังไม่มี แฟล็กด้านล่างคือตัวอย่างอ้างอิง โปรดดูไฟล์.bazelrc
ล่าสุดในที่เก็บ bazel-toolchains และคัดลอกค่าของ Flag ที่กำหนดไว้สำหรับการกำหนดค่า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
หากกฎของคุณต้องใช้เครื่องมือเพิ่มเติม ให้ทำดังนี้
สร้างคอนเทนเนอร์ Docker ที่กำหนดเองโดยการติดตั้งเครื่องมือโดยใช้ Dockerfile และสร้างอิมเมจในเครื่อง
แทนที่ค่าของ Flag
--experimental_docker_image
ด้านบนด้วยชื่ออิมเมจคอนเทนเนอร์ที่กำหนดเอง
แก้ปัญหาตั้งแต่ต้น
วิธีนี้เรียกใช้ Bazel และการดำเนินการบิลด์ทั้งหมดในเครื่องภายในโดยตรงและเป็นวิธีที่เชื่อถือได้ในการยืนยันว่าบิลด์ของคุณจะสำเร็จหรือไม่เมื่อเรียกใช้จากระยะไกล
อย่างไรก็ตาม เมื่อใช้วิธีนี้ เครื่องมือ ไบนารี และข้อมูลที่ติดตั้งไว้ในเครื่องอาจรั่วไหลในบิลด์ โดยเฉพาะอย่างยิ่งหากใช้กฎ WORKSPACE รูปแบบการกำหนดค่า การรั่วไหลดังกล่าวจะทำให้เกิดปัญหากับการดำเนินการจากระยะไกล หากต้องการตรวจหาการรั่วไหลดังกล่าว ให้แก้ปัญหาในคอนเทนเนอร์ Docker เพิ่มเติมจากการแก้ปัญหาด้วยตนเอง
ขั้นตอนที่ 1: เรียกใช้บิลด์
เพิ่มแฟล็ก
--config=docker-sandbox
ลงในคำสั่ง Bazel ที่ดำเนินการกับบิลด์ของคุณ เช่นbazel --bazelrc=.bazelrc build --config=docker-sandbox target
เรียกใช้บิลด์และรอให้การสร้างเสร็จสมบูรณ์ บิลด์จะทำงานช้ากว่าปกติถึง 4 เท่าเนื่องจากฟีเจอร์แซนด์บ็อกซ์ของ Docker
คุณอาจพบข้อผิดพลาดต่อไปนี้
ERROR: 'docker' is an invalid value for docker spawn strategy.
หากสร้างแล้ว ให้เรียกใช้บิลด์อีกครั้งด้วยแฟล็ก --experimental_docker_verbose
การตั้งค่าสถานะนี้จะเปิดใช้ข้อความแสดงข้อผิดพลาดแบบละเอียด ข้อผิดพลาดนี้มักเกิดจากการติดตั้ง Docker ที่มีข้อผิดพลาดหรือการไม่มีสิทธิ์ดำเนินการในบัญชีผู้ใช้ปัจจุบัน ดูข้อมูลเพิ่มเติมได้ในเอกสารประกอบของ Docker หากปัญหายังคงอยู่ ให้ข้ามไปที่การแก้ปัญหาในคอนเทนเนอร์ Docker
ขั้นตอนที่ 2: แก้ปัญหาที่ตรวจพบ
ต่อไปนี้คือปัญหาที่พบบ่อยที่สุดและวิธีแก้ไขเบื้องต้น
ไม่มีไฟล์ เครื่องมือ ไบนารี หรือทรัพยากรที่โครงสร้าง Runfiles ของ Bazel อ้างอิง ยืนยันว่าทรัพยากร Dependency ทั้งหมดของเป้าหมายที่ได้รับผลกระทบได้รับการประกาศอย่างชัดแจ้งแล้ว ดูข้อมูลเพิ่มเติมได้ที่การจัดการทรัพยากร Dependency โดยนัย
ไฟล์ เครื่องมือ ไบนารี หรือทรัพยากรที่อ้างอิงโดยเส้นทางสัมบูรณ์หรือตัวแปร
PATH
ขาดหายไป ยืนยันว่าได้ติดตั้งเครื่องมือที่จำเป็นทั้งหมดในคอนเทนเนอร์ Toolchain แล้วและใช้กฎของเครื่องมือเชนเพื่อประกาศทรัพยากร Dependency ที่ชี้ไปยังทรัพยากรที่ขาดหายไปอย่างเหมาะสม ดูข้อมูลเพิ่มเติมได้ที่การเรียกใช้เครื่องมือสร้างผ่านกฎเครื่องมือเชนการดำเนินการแบบไบนารีไม่สำเร็จ มีกฎบิลด์ข้อหนึ่งที่อ้างอิงไบนารีที่เข้ากันไม่ได้กับสภาพแวดล้อมการดำเนินการ (คอนเทนเนอร์ Docker) ดูข้อมูลเพิ่มเติมได้ที่การจัดการไบนารีที่ขึ้นอยู่กับแพลตฟอร์ม หากแก้ปัญหาไม่ได้ โปรดติดต่อ bazel-discuss@google.com เพื่อขอความช่วยเหลือ
ไฟล์จาก
@local-jdk
หายไปหรือก่อให้เกิดข้อผิดพลาด ไบนารีของ Java ในเครื่องของคุณกำลังรั่วไหลในบิลด์ เนื่องจากไม่สามารถทำงานร่วมกับบิลด์ได้ ใช้java_toolchain
ในกฎและเป้าหมายแทน@local_jdk
โปรดติดต่อ bazel-discuss@google.com หากต้องการความช่วยเหลือเพิ่มเติมข้อผิดพลาดอื่นๆ โปรดติดต่อ bazel-discuss@google.com เพื่อขอความช่วยเหลือ
การแก้ปัญหาในคอนเทนเนอร์ Docker
วิธีนี้ทำให้ Bazel ทำงานภายในคอนเทนเนอร์ Docker ของโฮสต์ และบิลด์ของ Bazel จะดำเนินการภายในคอนเทนเนอร์ Toolchain แต่ละคอนเทนเนอร์ที่เกิดจากฟีเจอร์แซนด์บ็อกซ์ของ Docker แซนด์บ็อกซ์จะสร้างคอนเทนเนอร์ Toolchain ใหม่เอี่ยมสำหรับการดำเนินการบิลด์แต่ละรายการ และจะดำเนินการเพียงครั้งเดียวในคอนเทนเนอร์ Toolchain แต่ละรายการ
วิธีการนี้ให้การควบคุมเครื่องมือที่ติดตั้งในสภาพแวดล้อมของโฮสต์ได้ละเอียดยิ่งขึ้น การแยกการดำเนินการของบิลด์ออกจากการดำเนินการบิลด์และคงเครื่องมือที่ติดตั้งไว้ให้น้อยที่สุดจะช่วยให้คุณตรวจสอบได้ว่าบิลด์มีทรัพยากร Dependency ในสภาพแวดล้อมการดำเนินการภายในหรือไม่
ขั้นตอนที่ 1: สร้างคอนเทนเนอร์
สร้าง
Dockerfile
ที่สร้างคอนเทนเนอร์ Docker และติดตั้ง Bazel ด้วยชุดเครื่องมือบิลด์ขั้นต่ำ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
สร้างคอนเทนเนอร์เป็น
bazel_container
:docker build -t bazel_container - < Dockerfile
ขั้นตอนที่ 2: เริ่มใช้คอนเทนเนอร์
เริ่มต้นคอนเทนเนอร์ Docker โดยใช้คำสั่งที่แสดงด้านล่าง ในคำสั่งนี้ ให้ใช้คำสั่งให้แทนที่เส้นทางไปยังซอร์สโค้ดบนโฮสต์ที่คุณต้องการสร้าง
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
คำสั่งนี้จะเรียกใช้คอนเทนเนอร์เป็นรูท แมปซ็อกเก็ต Docker และต่อเชื่อมไดเรกทอรี /tmp
วิธีนี้ช่วยให้ Bazel สร้างคอนเทนเนอร์ Docker อื่นๆ และใช้ไดเรกทอรีภายใต้ /tmp
เพื่อแชร์ไฟล์กับคอนเทนเนอร์เหล่านั้นได้ คุณจะดูซอร์สโค้ดได้ที่ /src
ภายในคอนเทนเนอร์
คำสั่งเริ่มต้นจากคอนเทนเนอร์ฐาน debian:stretch
ที่มีไบนารีเข้ากันไม่ได้กับคอนเทนเนอร์ rbe-ubuntu16-04
ที่ใช้เป็นคอนเทนเนอร์ Toolchain หากไบนารีจากสภาพแวดล้อมในเครื่องรั่วไหลลงในคอนเทนเนอร์เครื่องมือเชน จะทำให้เกิดข้อผิดพลาดในการสร้างได้
ขั้นตอนที่ 3: ทดสอบคอนเทนเนอร์
เรียกใช้คำสั่งต่อไปนี้จากภายในคอนเทนเนอร์ Docker เพื่อทดสอบ
docker ps
bazel version
ขั้นตอนที่ 4: เรียกใช้บิลด์
เรียกใช้บิลด์ดังที่แสดงด้านล่าง เอาต์พุตของผู้ใช้คือรูทเพื่อให้สอดคล้องกับไดเรกทอรีที่เข้าถึงได้ด้วยเส้นทางสัมบูรณ์เดียวกันจากภายในคอนเทนเนอร์โฮสต์ที่ Bazel ทำงาน จากคอนเทนเนอร์เครื่องมือเชนที่สร้างโดยฟีเจอร์แซนด์บ็อกซ์ของ Docker ที่การทำงานของบิลด์ของ Bazel ทำงานอยู่ และจากเครื่องภายในที่คอนเทนเนอร์โฮสต์และคอนเทนเนอร์ดำเนินการทำงานอยู่
bazel --output_user_root=/tmp/bazel_docker_root --bazelrc=.bazelrc \ build --config=docker-sandbox target
ขั้นตอนที่ 5: แก้ปัญหาที่ตรวจพบ
คุณแก้ไขความล้มเหลวของบิลด์ได้ดังนี้
หากบิลด์ล้มเหลวเนื่องจากข้อผิดพลาด "ไม่มีพื้นที่ในดิสก์" คุณเพิ่มขีดจำกัดนี้ได้โดยเริ่มต้นคอนเทนเนอร์ของโฮสต์ด้วยแฟล็ก
--memory=XX
โดยที่XX
คือพื้นที่ในดิสก์ที่จัดสรรเป็นกิกะไบต์ นี่เป็นการทดลองและอาจทำให้เกิด พฤติกรรมที่คาดเดาไม่ได้หากบิลด์ล้มเหลวในระหว่างช่วงการวิเคราะห์หรือการโหลด กฎบิลด์อย่างน้อย 1 รายการที่ประกาศในไฟล์ WORKSPACE ใช้ไม่ได้กับการดำเนินการระยะไกล ดูการปรับกฎของ Bazel สำหรับการดำเนินการระยะไกลสำหรับสาเหตุที่เป็นไปได้และวิธีแก้ปัญหาเฉพาะหน้า
หากบิลด์ล้มเหลวด้วยเหตุผลอื่น โปรดดูขั้นตอนการแก้ปัญหาในขั้นตอนที่ 2: แก้ปัญหาที่ตรวจพบ