이 도움말에서는 Bazel의 샌드박스 및 샌드박스 디버깅에 대해 설명합니다. 환경입니다
샌드박싱은 프로세스를 격리하는 권한 제한 전략입니다. 시스템의 리소스에서 서로 분리될 수 있습니다 Bazel의 경우 이는 파일을 제한합니다. 액세스할 수 있습니다.
Bazel의 파일 시스템 샌드박스는 컴파일러와 기타 도구에서 소스를 볼 수 없도록 알려진 입력을 포함함 파일에 대한 절대 경로를 알고 있지 않은 한 액세스해서는 안 되는 파일.
샌드박싱은 어떤 방식으로도 호스트 환경을 숨기지 않습니다. 프로세스는 자유롭게 파일 시스템의 모든 파일에 액세스할 수 있습니다. 하지만 사용자 인터페이스 네임스페이스가 있는 경우 프로세스는 작업 디렉터리 외부의 파일을 수정할 수 없습니다. 이렇게 하면 빌드 그래프에 다른 빌드에 영향을 줄 수 있는 숨겨진 종속 항목이 빌드 재현성에 영향을 줄 수 있습니다.
더 구체적으로 Bazel은 각 작업의 execroot/
디렉터리를 구성합니다.
이 디렉터리는 실행 시 작업의 작업 디렉터리 역할을 합니다. execroot/
작업에 대한 모든 입력 파일을 포함하며 모든
생성합니다. 그런 다음 Bazel은 운영체제 제공 기법을 사용하여
컨테이너(Linux의 경우) 및 sandbox-exec
의 경우(macOS의 경우)
execroot/
샌드박스를 사용하는 이유
작업 샌드박스가 없으면 Bazel은 도구가 선언되지 않은 도구를 사용하는지 알 수 없습니다. 입력 파일( 합니다. 선언되지 않은 입력 파일 중 하나가 변경되어도 Bazel은 여전히 빌드가 최신 상태이며 작업을 다시 빌드하지 않을 것이라고 생각합니다. 이렇게 하면 잘못된 증분 빌드가 생성됩니다.
캐시 항목을 잘못 재사용하면 원격 캐싱 중에 문제가 발생합니다. 가 공유 캐시의 잘못된 캐시 항목은 프로젝트의 모든 개발자에게 영향을 미칩니다. 전체 원격 캐시를 지우는 것은 실행 가능한 해결책이 아닙니다.
샌드박싱은 원격 실행 동작을 모방(빌드가 잘 작동하는 경우) 샌드박싱을 사용하면 원격 실행에서도 작동할 가능성이 높습니다. 이를 통해 원격 실행을 통해 필요한 모든 파일 (로컬 도구 포함)을 업로드하고, 다음에 비해 컴파일 클러스터의 유지보수 비용을 크게 절감할 수 있습니다. 클러스터의 모든 머신에 새 컴파일러를 사용해 보거나 기존 도구를 변경하려는 경우
사용해야 할 샌드박스 전략
사용할 샌드박스 유형이 있는 경우
전략 플래그를 참조하세요. sandboxed
사용
전략에 따라 Bazel은 아래 나열된 샌드박스 구현 중 하나를 선택합니다.
덜 밀폐된 일반적인 샌드박스보다 OS 전용 샌드박스를 선호합니다.
영구 작업자는 다음을 통과하면 일반 샌드박스에서 실행됩니다.
--worker_sandboxing
플래그
local
(standalone
) 전략은 어떤 종류의 샌드박스도 실행하지 않습니다.
작업 디렉터리를
실행되어야 합니다
processwrapper-sandbox
는 아무것도 필요하지 않은 샌드박스 전략입니다.
'고급' 모든 POSIX 시스템에서 즉시 작동합니다. 그것은
원래 포드를 가리키는 심볼릭 링크로 구성된 샌드박스 디렉토리를
소스 파일: 작업 디렉터리 세트로 작업의 명령줄을 실행합니다.
execroot 대신 이 디렉터리로 옮긴 다음 알려진 출력 아티팩트를
execroot로 푸시하고 샌드박스를 삭제합니다. 이렇게 하면
선언되지 않은 입력 파일을 실수로 사용하지 못하도록 하고
execroot에 알 수 없는 출력 파일이 산재해 있습니다.
linux-sandbox
는 한 걸음 더 나아가
processwrapper-sandbox
Docker가 내부적으로 수행하는 작업과 마찬가지로
격리할 Linux 네임스페이스 (사용자, 마운트, PID, 네트워크 및 IPC 네임스페이스)
삭제할 수 있습니다 즉, 전체 파일 시스템이 읽기 전용으로 전환됩니다.
수정할 수 없으므로 이 작업은 실수로
호스트 파일 시스템의 이름을 지정합니다. 이렇게 하면 버그가 있는 테스트와 같은 상황이 실수로 발생하는 것을 방지할 수 있습니다.
$HOME 디렉터리를 -rf'합니다. 원하는 경우 작업이
네트워크 액세스 linux-sandbox
에서 PID 네임스페이스를 사용하여 작업을 방지합니다.
다른 프로세스를 보지 못하도록 하고 모든 프로세스 (데몬 포함)를 안정적으로 종료
끝부분에 있습니다.
darwin-sandbox
도 비슷하지만 macOS용입니다. Apple의 sandbox-exec
도구를 사용합니다.
Linux 샌드박스와 거의 동일한 결과를 얻을 수 있습니다.
linux-sandbox
와 darwin-sandbox
는 모두 '중첩된' 환경에서 작동하지 않습니다.
운영 체제가 제공하는 메커니즘의 제한으로 인해
있습니다 Docker는 컨테이너 매직을 위해 Linux 네임스페이스도 사용하므로
linux-sandbox
를 Docker 컨테이너 내에서 쉽게 실행할 수 없습니다.
docker run --privileged
macOS에서는 sandbox-exec
이미 샌드박스 처리된 프로세스입니다. 따라서 이 경우 Bazel은
자동으로 processwrapper-sandbox
사용으로 대체됩니다.
실수로
덜 엄격한 실행 전략 — 실행 목록을 명시적으로 수정
Bazel이 사용하려는 전략 (예: bazel build
--spawn_strategy=worker,linux-sandbox
)
동적 실행에는 일반적으로 로컬 실행을 위한 샌드박스가 필요합니다. 이 기능을 선택 해제하려면
--experimental_local_lockfree_output
플래그를 전달합니다. 자동으로 동적 실행
샌드박스 영구 작업자를 지원합니다.
샌드박스의 단점
샌드박스를 사용하면 추가 설정 및 해체 비용이 발생합니다. 이 비용의 크기 다양한 요인에 따라 달라질 수 있으며, 호스트 OS의 성능에 영향을 줄 수 있습니다. Linux의 경우 샌드박스 처리된 빌드가 몇 퍼센트 더 느려집니다.
--reuse_sandbox_directories
을(를) 설정하면 설정 및 해제 비용을 줄일 수 있습니다.샌드박스는 도구에 있을 수 있는 모든 캐시를 효과적으로 비활성화합니다. 다음을 수행할 수 있습니다. 영구 작업자를 사용해 덜 발생할 수도 있습니다.
멀티플렉스 작업자에는 명시적인 작업자 지원이 필요합니다. 있습니다. 멀티플렉스 샌드박스를 지원하지 않는 작업자는 다음과 같이 실행됩니다. 단일 플렉스 작업자가 동적으로 실행될 수 있기 때문에 추가 메모리가 낭비될 수 있습니다.
디버깅
샌드박스 관련 문제를 디버깅하려면 아래 전략을 따르세요.
비활성화된 네임스페이스
일부 플랫폼에서는
Google Kubernetes Engine
Debian Linux 커널을 사용하는 경우, 사용자 네임스페이스는 기본적으로 비활성화되므로
보안 문제를 일으킬 수 있습니다 /proc/sys/kernel/unprivileged_userns_clone
파일이
존재하고 0이 포함된 경우 다음을 실행하여 사용자 네임스페이스를 활성화할 수 있습니다.
sudo sysctl kernel.unprivileged_userns_clone=1
규칙 실행 실패
시스템 설정으로 인해 샌드박스에서 규칙을 실행하지 못할 수 있습니다. 만약
namespace-sandbox.c:633: execvp(argv[0], argv): No such file or
directory
같은 메시지가 표시되면 --strategy=Genrule=local
를 사용해 샌드박스를 비활성화해 보세요.
genrules 및 --spawn_strategy=local
를 사용하는 다른 규칙입니다.
빌드 실패에 대한 상세 디버깅
빌드에 실패하면 --verbose_failures
및 --sandbox_debug
를 사용하여
Bazel은 빌드가 실패했을 때 실행된 정확한 명령어와
샌드박스를 설정하는 것입니다.
오류 메시지 예시:
ERROR: path/to/your/project/BUILD:1:1: compilation of rule
'//path/to/your/project:all' failed:
Sandboxed execution failed, which may be legitimate (such as a compiler error),
or due to missing dependencies. To enter the sandbox environment for easier
debugging, run the following command in parentheses. On command failure, a bash
shell running inside the sandbox will then automatically be spawned
namespace-sandbox failed: error executing command
(cd /some/path && \
exec env - \
LANG=en_US \
PATH=/some/path/bin:/bin:/usr/bin \
PYTHONPATH=/usr/local/some/path \
/some/path/namespace-sandbox @/sandbox/root/path/this-sandbox-name.params --
/some/path/to/your/some-compiler --some-params some-target)
이제 생성된 샌드박스 디렉터리를 검사하여 Bazel이 어떤 파일을 만들고 명령어를 다시 실행하여 어떻게 작동하는지 확인합니다.
Bazel은 클러스터 내부에서 Cloud Storage를 사용할 때
--sandbox_debug
디버깅 중인 경우가 아니라면
시간이 지남에 따라 디스크를 가득 채우므로 --sandbox_debug