Docker Sandbox를 사용한 Bazel 원격 실행 문제 해결

<ph type="x-smartling-placeholder"></ph> 문제 신고 <ph type="x-smartling-placeholder"></ph> 소스 보기 1박 · 7.3 · 7.2 · 7.1 · 7.0 · 6.5 를 참조하세요.

로컬에서 성공한 Bazel 빌드는 원격 실행 시 로컬 빌드에 영향을 미치지 않는 제한 사항과 요구 사항을 지원합니다. 가장 일반적인 이러한 실패의 원인은 원격 실행을 위한 Bazel 규칙 조정에 설명되어 있습니다.

이 페이지에서는 문제를 일으키는 가장 일반적인 문제를 식별하고 해결하는 방법을 설명합니다. Docker 샌드박스 기능을 사용하여 원격 실행이 발생할 때 원격 실행과 동일한 제한이 있어야 합니다. 이렇게 하면 빌드 문제를 해결할 수 있습니다.

Docker 샌드박스 기능은 원격 실행 제한을 모방하고 다음과 같습니다.

  • 빌드 작업이 도구 모음 컨테이너에서 실행됩니다. 같은 서비스를 통해 로컬 및 원격으로 빌드를 실행하는 도구 모음 컨테이너 컨테이너화된 원격 실행을 지원합니다

  • 컨테이너 경계를 넘나드는 관련 없는 데이터는 없습니다. 명시적으로만 선언된 입력 및 출력이 컨테이너에 들어오고 나간 후 연결된 빌드 작업이 성공적으로 완료됩니다.

  • 각 작업은 새 컨테이너에서 실행됩니다. 새로운 고유 컨테이너는 생성할 때마다 생성됩니다

를 통해 개인정보처리방침을 정의할 수 있습니다.

이러한 문제는 다음 방법 중 하나를 사용하여 해결할 수 있습니다.

  • 기본적으로 문제를 해결합니다. 이 방법을 사용하면 Bazel 및 빌드 작업은 로컬 머신에서 기본적으로 실행됩니다. Docker 샌드박스 기능은 원격 실행할 수 있습니다 그러나 이 방법은 로컬 도구, 상태 및 데이터가 유출되어 원격 실행에 문제가 발생할 수 있습니다.

  • Docker 컨테이너에서 문제를 해결합니다. 이 방법을 사용하면 Bazel과 빌드 작업이 Docker 컨테이너 내에서 실행되므로 이를 통해 로컬 리소스에서 툴, 상태, 데이터 유출을 빌드에 자동화하는 기능을 추가하며 원격 실행과 같아야 합니다. 이 방법을 사용하면 빌드의 일부가 실패하더라도 빌드에 사용될 수 있습니다 이 방법은 실험용입니다. 공식적으로 지원되지 않습니다

기본 요건

아직 문제 해결을 시작하지 않았다면 문제 해결을 시작하기 전에 다음을 수행합니다.

  • Docker를 설치하고 실행에 필요한 권한을 구성합니다.
  • Bazel 0.14.1 이상을 설치합니다. 이전 버전은 Docker를 지원하지 않음 샌드박스 기능입니다.
  • bazel-toolchains 추가 최신 출시 버전에 고정된 저장소(빌드의 WORKSPACE 파일) 여기
  • 기능을 사용 설정하려면 .bazelrc 파일에 플래그를 추가합니다. 다음 위치에 파일을 만듭니다. Bazel 프로젝트의 루트 디렉터리가 없는 경우 이 디렉터리를 복사합니다. 아래 플래그 참조 샘플입니다. 자세한 내용은 .bazelrc 드림 파일을 만들고 정의된 플래그 값을 복사합니다. 구성 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. Dockerfile로 도구를 설치하여 커스텀 Docker 컨테이너를 만듭니다. 및 빌드 이미지를 로컬로 저장합니다

  2. 위에서 --experimental_docker_image 플래그의 값을 커스텀 컨테이너 이미지의 이름입니다.

기본적으로 문제 해결

이 메서드는 Bazel 및 모든 빌드 작업을 로컬 빌드가 성공할지 여부를 확인할 수 있는 신뢰할 수 있는 방법입니다. 실행할 수 있습니다

그러나 이 방법을 사용하면 로컬에 설치된 도구, 바이너리, 데이터가 유출될 수 있습니다. (특히 configure-style WORKSPACE 규칙을 사용하는 경우) 이러한 유출은 원격 실행에 문제를 일으킵니다. 감지하려면 Docker 컨테이너에서 문제를 해결하세요 문제를 해결할 수 있습니다

1단계: 빌드 실행

  1. 실행하는 Bazel 명령어에 --config=docker-sandbox 플래그를 추가합니다. 확인할 수 있습니다 예를 들면 다음과 같습니다.

    bazel --bazelrc=.bazelrc build --config=docker-sandbox target
    
  2. 빌드를 실행하고 완료될 때까지 기다립니다. 빌드는 최대 4개의 정상보다 배 느립니다.

다음과 같은 오류가 발생할 수 있습니다.

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

그러면 --experimental_docker_verbose 플래그를 사용하여 빌드를 다시 실행합니다. 이 플래그는 상세 오류 메시지를 사용 설정합니다. 이 오류는 일반적으로 Docker 설치에 문제가 있거나 표시됩니다. Docker 문서를 참조하세요. 를 참조하세요. 문제가 지속되면 Docker 컨테이너에서의 문제 해결로 건너뛰세요.

2단계: 감지된 문제 해결하기

다음은 가장 일반적으로 발생하는 문제와 해결 방법입니다.

  • Bazel 실행 파일 트리에서 참조하는 파일, 도구, 바이너리 또는 리소스는 누락됩니다. 영향을 받은 대상의 모든 종속 항목이 명시적으로 선언되어 있을 수 있습니다. 자세한 내용은 암시적 종속 항목 관리 를 참조하세요.

  • 절대 경로나 PATH에서 참조하는 파일, 도구, 바이너리 또는 리소스 변수가 없습니다. 모든 필수 도구가 도구 모음 컨테이너에 추가하고 도구 모음 규칙을 사용하여 누락된 리소스를 가리키는 종속 항목을 선언합니다. 자세한 내용은 도구 모음 규칙을 통해 빌드 도구 호출 를 참조하세요.

  • 바이너리 실행이 실패합니다. 빌드 규칙 중 하나는 바이너리 실행 환경 (Docker 컨테이너)과 호환되지 않습니다. 자세한 내용은 플랫폼 종속 바이너리 관리 를 참조하세요. 문제를 해결할 수 없으면 bazel-discuss@google.com으로 문의하세요. 에 문의하세요.

  • @local-jdk의 파일이 누락되었거나 오류가 발생했습니다. Java 바이너리 빌드에 유출되는 문제가 있는 경우 있습니다. java_toolchain 사용 를 @local_jdk 대신에 사용하세요. 추가 도움이 필요한 경우 bazel-discuss@google.com으로 문의하세요.

  • 기타 오류. 도움이 필요하면 bazel-discuss@google.com에 문의하세요.

Docker 컨테이너에서 문제 해결

이 방법을 사용하면 Bazel이 호스트 Docker 컨테이너 내에서 실행되고 Bazel의 빌드가 Docker에 의해 생성된 개별 도구 모음 컨테이너 내에서 실행되는 작업 샌드박스 기능입니다. 샌드박스에서는 각 도구 모음에 대해 각 도구 모음 컨테이너에서 하나의 작업만 실행됩니다.

이 방법을 사용하면 호스트에 설치된 도구를 보다 세밀하게 제어할 수 있습니다. 환경입니다 빌드 실행을 설치된 도구를 최소한으로 유지하는 것이 빌드에 로컬 실행 환경에 대한 종속 항목이 있는지 여부

1단계: 컨테이너 빌드

  1. Docker 컨테이너를 만들고 Bazel을 설치하는 Dockerfile 만들기 최소한의 빌드 도구 세트로 빌드하세요.

    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이 실행되는 도구 모음 컨테이너에서 Bazel의 빌드 작업이 실행되는 샌드박스 기능과 로컬 호스트 및 작업 컨테이너가 실행되는 머신입니다.

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

5단계: 감지된 문제 해결

다음과 같이 빌드 실패를 해결할 수 있습니다.

  • '디스크 공간 부족'으로 인해 빌드가 실패하는 경우 이 값을 --memory=XX 플래그로 호스트 컨테이너를 시작하여 한도를 지정합니다. 여기서 XX 는 할당된 디스크 공간(GB)입니다. 이 기능은 실험 단계이며 예측할 수 없는 동작이 발생할 수 있습니다.

  • 분석 또는 로드 단계에서 빌드가 실패하면 WORKSPACE 파일에 선언된 빌드 규칙이 실행할 수 있습니다 원격 실행을 위해 Bazel 규칙 조정을 참조하세요. 원인과 해결 방법을 참고하시기 바랍니다.

  • 다른 이유로 빌드가 실패하면 2단계: 감지된 문제 해결하기의 문제 해결 단계를 참고하세요.