การแก้ปัญหาการเรียกใช้ Bazel Remote ด้วย Docker Sandbox

วันที่ รายงานปัญหา ดูแหล่งที่มา ตอนกลางคืน · 7.3 · 7.2 · 7.1 · 7.0 · 6.5

บิลด์ 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

หากกฎของคุณต้องใช้เครื่องมือเพิ่มเติม ให้ทำดังนี้

  1. สร้างคอนเทนเนอร์ Docker ที่กำหนดเองโดยการติดตั้งเครื่องมือโดยใช้ Dockerfile และการสร้าง รูปภาพในเครื่อง

  2. แทนที่ค่าของแฟล็ก --experimental_docker_image ด้านบนด้วยฟังก์ชัน ชื่อของอิมเมจคอนเทนเนอร์ที่กำหนดเอง

แก้ปัญหาตั้งแต่ต้น

เมธอดนี้จะเรียกใช้ Bazel และการดำเนินการบิลด์ทั้งหมดในเครื่องโดยตรง และเป็นวิธีที่เชื่อถือได้ในการยืนยันว่าบิลด์ของคุณจะประสบความสำเร็จหรือไม่ ดำเนินการจากระยะไกล

อย่างไรก็ตาม เครื่องมือ ไบนารี และข้อมูลที่ติดตั้งในเครื่องอาจรั่วไหลหากใช้วิธีนี้ ลงในบิลด์ โดยเฉพาะเมื่อใช้การกำหนดค่ากฎ WORKSPACE การรั่วไหลดังกล่าวจะทำให้เกิดปัญหากับการดำเนินการจากระยะไกล เพื่อตรวจหาปัญหา ให้แก้ปัญหาในคอนเทนเนอร์ Docker นอกเหนือจากการแก้ไขปัญหาเบื้องต้น

ขั้นตอนที่ 1: เรียกใช้บิลด์

  1. เพิ่ม Flag --config=docker-sandbox ในคำสั่ง Bazel ที่ดำเนินการ งานสร้างของคุณ เช่น

    bazel --bazelrc=.bazelrc build --config=docker-sandbox target
    
  2. เรียกใช้บิลด์และรอให้การสร้างเสร็จสมบูรณ์ บิลด์จะแสดงได้สูงสุด 4 ช้ากว่าปกติเนื่องจากฟีเจอร์แซนด์บ็อกซ์ของ Docker

คุณอาจพบข้อผิดพลาดต่อไปนี้

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

หากสร้างแล้ว ให้เรียกใช้บิลด์อีกครั้งด้วยแฟล็ก --experimental_docker_verbose การตั้งค่าสถานะนี้จะเปิดใช้ข้อความแสดงข้อผิดพลาดแบบละเอียด ข้อผิดพลาดนี้มักเกิดจาก การติดตั้ง Docker มีข้อผิดพลาดหรือไม่มีสิทธิ์ดำเนินการภายใต้ บัญชีผู้ใช้ปัจจุบัน ดูเอกสารประกอบของ Docker เพื่อดูข้อมูลเพิ่มเติม หากปัญหายังคงอยู่ ให้ข้ามไปที่การแก้ปัญหาในคอนเทนเนอร์ Docker

ขั้นตอนที่ 2: แก้ปัญหาที่ตรวจพบ

ต่อไปนี้คือปัญหาที่พบบ่อยที่สุดและวิธีแก้ไขเบื้องต้น

  • ไฟล์ เครื่องมือ ไบนารี หรือทรัพยากรที่โครงสร้างการเรียกใช้ไฟล์ Bazel อ้างอิงคือ ขาดหายไป ยืนยันว่าทรัพยากร Dependency ทั้งหมดของเป้าหมายที่ได้รับผลกระทบได้รับแล้ว ประกาศอย่างชัดแจ้ง โปรดดู การจัดการทรัพยากร Dependency โดยนัย เพื่อดูข้อมูลเพิ่มเติม

  • ไฟล์ เครื่องมือ ไบนารี หรือทรัพยากรที่อ้างอิงโดยเส้นทางสัมบูรณ์หรือ PATH ไม่มีตัวแปร ยืนยันว่าได้ติดตั้งเครื่องมือที่จำเป็นทั้งหมดแล้วภายใน คอนเทนเนอร์เครื่องมือเชนและใช้กฎของเครื่องมือเชนอย่างเหมาะสม ประกาศทรัพยากร 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: สร้างคอนเทนเนอร์

  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
    
  2. สร้างคอนเทนเนอร์เป็น 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 ที่ใช้เป็น คอนเทนเนอร์เชนเครื่องมือ หากไบนารีจากสภาพแวดล้อมในเครื่องรั่วไหลไปยัง คอนเทนเนอร์เชนเครื่องมือ จะทำให้เกิดข้อผิดพลาดในบิลด์

ขั้นตอนที่ 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: แก้ปัญหาที่ตรวจพบ