Como solucionar problemas de execução remota do Bazel com o sandbox do Docker

Informar um problema Mostrar fonte Por noite · 7,3 · 7,2 · 7,1 · 7,0 · 6,5

As compilações do Bazel bem-sucedidas no local podem falhar quando executadas remotamente devido à restrições e requisitos que não afetam builds locais. As mais comuns as causas dessas falhas são descritas em Como adaptar regras do Bazel para execução remota.

Esta página descreve como identificar e resolver os problemas mais comuns que surgem com a execução remota usando o recurso sandbox do Docker, que impõe restrições na compilação são iguais às da execução remota. Isso permite que você para solucionar problemas do seu build sem a necessidade de um serviço de execução remota.

O recurso de sandbox do Docker imita as restrições de execução remota da seguinte forma:

  • As ações de build são executadas em contêineres do conjunto de ferramentas. Você pode usar a mesma contêineres do conjunto de ferramentas para executar sua compilação local e remotamente usando um serviço e oferece suporte à execução remota conteinerizada.

  • Nenhum dado externo cruza os limites do contêiner. Apenas explicitamente entradas e saídas declaradas entram e saem do contêiner e somente após a ação de build associada foi concluída.

  • Cada ação é executada em um novo contêiner. Um contêiner novo e exclusivo criada para cada ação de compilação gerada.

É possível resolver esses problemas usando um dos seguintes métodos:

  • Solução de problemas nativa. Com esse método, O Bazel e as ações de compilação dele são executados nativamente na máquina local. O Docker O recurso sandbox impõe restrições à compilação iguais às do controle remoto execução. No entanto, esse método não detecta ferramentas locais, estados e vazamento de dados no seu build, o que causará problemas na execução remota.

  • Como solucionar problemas em um contêiner do Docker. Com esse método, o Bazel e as ações de compilação são executados dentro de um contêiner do Docker, que permite detectar ferramentas, estados e vazamentos de dados no build, além de impor restrições iguais aos da execução remota. Esse método fornece informações sobre sua mesmo que partes dele falhem. Esse método é experimental e sem suporte oficial.

Pré-requisitos

Antes de iniciar a solução de problemas, faça o seguinte se ainda não tiver feito isso:

  • Instale o Docker e configure as permissões necessárias para executá-lo.
  • Instale o Bazel 0.14.1 ou mais recente. Versões anteriores não são compatíveis com o Docker recurso sandbox.
  • Adicione bazel-Datasets (link em inglês). fixado à versão de lançamento mais recente no arquivo WORKSPACE do build conforme descrito aqui.
  • Adicione sinalizações ao arquivo .bazelrc para ativar o recurso. Crie o arquivo em no diretório raiz do projeto do Bazel, se ele não existir. Sinalizações abaixo são uma amostra de referência. Consulte a versão mais recente .bazelrc no repositório bazel-datasets e copiar os valores das flags definidas lá para a configuração 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

Se as regras exigirem ferramentas adicionais, faça o seguinte:

  1. Criar um contêiner do Docker personalizado instalando ferramentas com um Dockerfile e criação a imagem localmente.

  2. Substitua o valor da sinalização --experimental_docker_image acima pelo nome da imagem personalizada do contêiner.

Solução de problemas nativa

Esse método executa o Bazel e todas as ações de compilação diretamente no sistema máquina virtual e é uma maneira confiável de confirmar se o build terá sucesso quando a execução remota.

No entanto, com esse método, ferramentas, binários e dados instalados localmente podem vazar no seu build, especialmente se ele usar regras de espaço de trabalho de estilo de configuração. Tais vazamentos causam problemas na execução remota. Para detectá-los, solucione problemas em um contêiner do Docker além de resolver problemas de forma nativa.

Etapa 1: executar o build

  1. Adicione a flag --config=docker-sandbox ao comando do Bazel que executa seu build. Exemplo:

    bazel --bazelrc=.bazelrc build --config=docker-sandbox target
    
  2. Execute o build e aguarde a conclusão. O build vai executar até quatro vezes mais lento do que o normal devido ao recurso de sandbox do Docker.

Você pode encontrar o seguinte erro:

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

Se isso acontecer, execute o build novamente com a flag --experimental_docker_verbose. Essa sinalização permite mensagens de erro detalhadas. Esse erro normalmente é causado por instalação defeituosa do Docker ou falta de permissões para executá-lo de acordo com a conta de usuário atual. Consulte a documentação do Docker para mais informações. Se os problemas persistirem, avance para Como solucionar problemas em um contêiner do Docker.

Etapa 2: resolver os problemas detectados

Confira a seguir os problemas mais comuns e as soluções alternativas.

Solução de problemas em um contêiner do Docker

Com esse método, o Bazel é executado em um contêiner do Docker do host, e o build do Bazel ações são executadas dentro de contêineres de conjunto de ferramentas individuais gerados pelo Docker recurso sandbox. O sandbox gera um novo contêiner de conjunto de ferramentas para cada build, e apenas uma é executada em cada contêiner de conjunto de ferramentas.

Esse método oferece controle mais granular das ferramentas instaladas no host de nuvem. Separando a execução do build da execução do respectivo ações de build e mantendo o mínimo de ferramentas instaladas, é possível verificar se o build tem dependências no ambiente de execução local.

Etapa 1: criar o contêiner

  1. Crie um Dockerfile que crie o contêiner do Docker e instale o Bazel com um conjunto mínimo de ferramentas de build:

    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. Crie o contêiner como bazel_container:

    docker build -t bazel_container - < Dockerfile
    

Etapa 2: iniciar o contêiner

Inicie o contêiner do Docker usando o comando mostrado abaixo. No comando, substitua o caminho do código-fonte no host que você quer criar.

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

Esse comando executa o contêiner como raiz, mapeando o soquete do Docker e montando diretório /tmp. Isso permite que o Bazel gere outros contêineres do Docker e vai usar diretórios em /tmp para compartilhar arquivos com esses contêineres. Sua fonte código está disponível em /src dentro do contêiner.

O comando inicia intencionalmente a partir de um contêiner de base debian:stretch que inclui binários incompatíveis com o contêiner rbe-ubuntu16-04 usado como contêiner do conjunto de ferramentas. Se os binários do ambiente local estiverem vazando para o contêiner do conjunto de ferramentas, eles causarão erros de compilação.

Etapa 3: testar o contêiner

Execute estes comandos no contêiner do Docker para testá-lo:

docker ps
bazel version

Etapa 4: executar o build

Execute o build conforme mostrado abaixo. O usuário de saída é raiz, portanto, corresponde ao um diretório que possa ser acessado pelo mesmo caminho absoluto de dentro do host contêiner em que o Bazel é executado, dos contêineres de conjunto de ferramentas gerados pelo Docker sandbox em que as ações de build do Bazel são executadas e da máquina em que os contêineres de host e de ação são executados.

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

Etapa 5: resolver os problemas detectados

É possível resolver falhas de build da seguinte maneira:

  • Se o build falhar com uma mensagem de erro "sem espaço em disco" você poderá aumentar esse inicial ao iniciar o contêiner do host com a sinalização --memory=XX, em que XX é o espaço em disco alocado em gigabytes. Esse recurso é experimental e pode resultarão em comportamento imprevisível.

  • Se o build falhar durante as fases de análise ou carregamento, um ou mais dos suas regras de build declaradas no arquivo WORKSPACE não são compatíveis com a execução remota. Consulte Como adaptar regras do Bazel para execução remota as possíveis causas e soluções.

  • Se o build falhar por qualquer outro motivo, consulte as etapas de solução de problemas na Etapa 2: resolver problemas detectados.