로컬에서 성공하는 Bazel 빌드는 로컬 빌드에 영향을 미치지 않는 제한사항과 요구사항으로 인해 원격으로 실행될 때 실패할 수 있습니다. 이러한 실패의 가장 일반적인 원인은 원격 실행을 위한 Bazel 규칙 조정에 설명되어 있습니다.
이 페이지에서는 원격 실행과 동일한 빌드에 제한사항을 적용하는 Docker 샌드박스 기능을 사용하여 원격 실행에서 발생하는 가장 일반적인 문제를 식별하고 해결하는 방법을 설명합니다. 이를 통해 원격 실행 서비스 없이 빌드의 문제를 해결할 수 있습니다.
Docker 샌드박스 기능은 다음과 같이 원격 실행의 제한사항을 모방합니다.
빌드 작업은 도구 모음 컨테이너에서 실행됩니다. 컨테이너화된 원격 실행을 지원하는 서비스를 통해 동일한 도구 모음 컨테이너를 사용하여 빌드를 로컬 및 원격으로 실행할 수 있습니다.
불필요한 데이터가 컨테이너 경계를 넘지 않습니다. 명시적으로 선언된 입력 및 출력만 컨테이너에 들어가고 나갈 수 있으며 연결된 빌드 작업이 성공적으로 완료된 후에만 가능합니다.
각 작업은 새 컨테이너에서 실행됩니다. 생성된 각 빌드 작업에 대해 고유한 새 컨테이너가 생성됩니다.
다음 방법 중 하나를 사용하여 이러한 문제를 해결할 수 있습니다.
기본적으로 문제 해결. 이 방법을 사용하면 Bazel 및 빌드 작업이 로컬 머신에서 기본적으로 실행됩니다. Docker 샌드박스 기능은 원격 실행과 동일한 빌드에 제한사항을 적용합니다. 하지만 이 방법은 원격 실행에 문제를 일으키는 빌드로 유출되는 로컬 도구, 상태, 데이터를 감지하지 않습니다.
Docker 컨테이너에서 문제 해결. 이 방법을 사용하면 Bazel 및 빌드 작업이 Docker 컨테이너 내에서 실행되므로 원격 실행과 동일한 제한사항을 적용하는 것 외에도 로컬 머신에서 빌드로 유출되는 도구, 상태, 데이터를 감지할 수 있습니다. 이 방법을 사용하면 빌드의 일부가 실패하더라도 빌드에 대한 통계를 얻을 수 있습니다. 이 방법은 실험용이며 공식적으로 지원되지 않습니다.
기본 요건
문제 해결을 시작하기 전에 아직 하지 않은 경우 다음을 실행하세요.
- Docker를 설치하고 이를 실행하는 데 필요한 권한을 구성합니다.
- Bazel 0.14.1 이상을 설치합니다. 이전 버전은 Docker 샌드박스 기능을 지원하지 않습니다.
- 여기에 설명된 대로 최신 출시 버전에 고정된 bazel-toolchains
저장소를 빌드의
WORKSPACE파일 에 추가합니다. .bazelrc파일에 플래그를 추가하여 기능을 사용 설정합니다. 파일이 없으면 Bazel 프로젝트의 루트 디렉터리에 파일을 만듭니다. 아래 플래그 는 참조 샘플입니다. bazel-toolchains 저장소에서 최신.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
규칙에 추가 도구가 필요한 경우 다음을 실행하세요.
Dockerfile을 사용하여 도구를 설치하고 이미지를 로컬로 빌드하여 커스텀 Docker 컨테이너를 만듭니다.
위의
--experimental_docker_image플래그 값을 커스텀 컨테이너 이미지의 이름으로 바꿉니다.
기본적으로 문제 해결
이 메서드는 Bazel 및 모든 빌드 작업을 로컬 머신에서 직접 실행하며 빌드가 원격으로 실행될 때 성공하는지 확인하는 안정적인 방법입니다.
하지만 이 방법을 사용하면 특히 구성 스타일 WORKSPACE 규칙을 사용하는 경우 로컬로 설치된 도구, 바이너리, 데이터가 빌드로 유출될 수 있습니다. 이러한 유출은 원격 실행에 문제를 일으키므로 이를 감지하려면 기본적으로 문제 해결 외에도 Docker 컨테이너에서 문제 해결을 실행하세요.
1단계: 빌드 실행
빌드를 실행하는 Bazel 명령어에
--config=docker-sandbox플래그를 추가합니다. 예를 들면 다음과 같습니다.bazel --bazelrc=.bazelrc build --config=docker-sandbox target빌드를 실행하고 완료될 때까지 기다립니다. Docker 샌드박스 기능으로 인해 빌드가 평소보다 최대 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의 파일이 누락되었거나 오류가 발생합니다. 로컬 머신의 자바 바이너리가 빌드와 호환되지 않으면서 빌드로 유출되고 있습니다.@local_jdk대신 규칙 및 타겟에서java_toolchain을 사용합니다. 추가 지원이 필요한 경우 bazel-discuss@google.com에 문의하세요.기타 오류. bazel-discuss@google.com에 문의하여 도움을 받으세요.
Docker 컨테이너에서 문제 해결
이 방법을 사용하면 Bazel이 호스트 Docker 컨테이너 내에서 실행되고 Bazel의 빌드 작업은 Docker 샌드박스 기능으로 생성된 개별 도구 모음 컨테이너 내에서 실행됩니다. 샌드박스는 각 빌드 작업에 대해 새로운 도구 모음 컨테이너를 생성하며 각 도구 모음 컨테이너에서 하나의 작업만 실행됩니다.
이 방법을 사용하면 호스트 환경에 설치된 도구를 더 세부적으로 제어할 수 있습니다. 빌드 실행과 빌드 작업 실행을 분리하고 설치된 도구를 최소한으로 유지하면 빌드에 로컬 실행 환경에 대한 종속 항목이 있는지 확인할 수 있습니다.
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컨테이너를
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에 있습니다.
이 명령어는 의도적으로 도구 모음 컨테이너로 사용되는 rbe-ubuntu16-04 컨테이너와 호환되지 않는 바이너리를 포함하는 debian:stretch 기본 컨테이너로 시작합니다. 로컬 환경의 바이너리가
도구 모음 컨테이너로 유출되면 빌드 오류가 발생합니다.
3단계: 컨테이너 테스트
Docker 컨테이너 내에서 다음 명령어를 실행하여 테스트합니다.
docker psbazel version
4단계: 빌드 실행
아래와 같이 빌드를 실행합니다. 출력 사용자는 루트이므로 Bazel이 실행되는 호스트 컨테이너 내부, Bazel의 빌드 작업이 실행되는 Docker 샌드박스 기능으로 생성된 도구 모음 컨테이너, 호스트 및 작업 컨테이너가 실행되는 로컬 머신에서 동일한 절대 경로로 액세스할 수 있는 디렉터리에 해당합니다.
bazel --output_user_root=/tmp/bazel_docker_root --bazelrc=.bazelrc \ build --config=docker-sandbox target5단계: 감지된 문제 해결
빌드 실패는 다음과 같이 해결할 수 있습니다.
빌드가 "디스크 공간 부족" 오류로 실패하면 이 한도를
--memory=XX플래그를 사용하여 호스트 컨테이너를 시작하여 늘릴 수 있습니다. 여기서XX는 할당된 디스크 공간(기가바이트)입니다. 이는 실험용이며 예측할 수 없는 동작이 발생할 수 있습니다.분석 또는 로드 단계에서 빌드가 실패하면 WORKSPACE 파일에 선언된 빌드 규칙 중 하나 이상이 원격 실행과 호환되지 않습니다. 가능한 원인과 해결 방법은 원격 실행을 위한 Bazel 규칙 조정 을 참고하세요.
다른 이유로 빌드가 실패하면 2단계: 감지된 문제 해결의 문제 해결 단계를 참고하세요.