Resumindo: estou tentando montar um diretório de host no Docker, mas não consigo acessá-lo no contêiner, mesmo que as permissões de acesso sejam boas.
Os detalhes:
estou fazendo
sudo docker run -i -v /data1/Downloads:/Downloads ubuntu bash
e depois
ls -al
Isso me dá:
total 8892
drwxr-xr-x. 23 root root 4096 Jun 18 14:34 .
drwxr-xr-x. 23 root root 4096 Jun 18 14:34 ..
-rwxr-xr-x. 1 root root 0 Jun 18 14:34 .dockerenv
-rwx------. 1 root root 9014486 Jun 17 22:09 .dockerinit
drwxrwxr-x. 18 1000 1000 12288 Jun 16 11:40 Downloads
drwxr-xr-x. 2 root root 4096 Jan 29 18:10 bin
drwxr-xr-x. 2 root root 4096 Apr 19 2012 boot
drwxr-xr-x. 4 root root 340 Jun 18 14:34 dev
drwxr-xr-x. 56 root root 4096 Jun 18 14:34 etc
drwxr-xr-x. 2 root root 4096 Apr 19 2012 home
e muito mais linhas como essa (acho que essa é a parte relevante).
Se eu fizer
cd /Downloads
ls
o resultado é
ls: cannot open directory .: Permission denied
O host é o Fedora 20, com Docker 1.0.0 e go1.2.2.
O que está acontecendo de errado?
fonte
-v $(pwd):/app:ro,Z
. Isso deve ser marcado como a resposta correta.É uma questão do SELinux .
Você pode emitir temporariamente
no host para acessar ou adicione uma regra SELinux executando
fonte
AVISO: Esta solução tem riscos de segurança.
Tente executar o contêiner como privilegiado:
Outra opção (que eu não tentei) seria criar um contêiner privilegiado e, em seguida, criar contêineres não privilegiados dentro dele.
fonte
--privileged=true
--privileged
é um risco de segurançaNormalmente, os problemas de permissão com uma montagem de volume do host ocorrem porque o uid / gid dentro do contêiner não tem acesso ao arquivo de acordo com as permissões uid / gid do arquivo no host. No entanto, este caso específico é diferente.
O ponto no final da string de permissão
drwxr-xr-x.
, indica que o SELinux está configurado. Ao usar uma montagem de host com o SELinux, você precisa passar uma opção extra para o final da definição de volume:Seu comando de montagem de volume ficaria assim:
Veja mais sobre montagens de host com o SELinux em: https://docs.docker.com/storage/#configure-the-selinux-label
Para outras pessoas que veem esse problema com contêineres em execução como um usuário diferente, é necessário garantir que o uid / gid do usuário dentro do contêiner tenha permissões para o arquivo no host. Nos servidores de produção, isso geralmente é feito controlando o uid / gid no processo de criação da imagem para corresponder a um uid / gid no host que tem acesso aos arquivos (ou melhor ainda, não use montagens de host na produção).
Um volume nomeado é geralmente preferido para hospedar montagens porque inicializará o diretório de volumes a partir do diretório de imagens, incluindo qualquer propriedade e permissão de arquivo. Isso acontece quando o volume está vazio e o contêiner é criado com o volume nomeado.
Os usuários do MacOS agora têm o OSXFS, que lida com o uid / gid automaticamente entre o host e os contêineres do Mac. Um lugar em que não ajuda são os arquivos de dentro da VM incorporada que são montados no contêiner, como /var/lib/docker.sock.
Para ambientes de desenvolvimento em que o host uid / gid pode mudar por desenvolvedor, minha solução preferida é iniciar o contêiner com um ponto de entrada em execução como raiz, corrigir o uid / gid do usuário dentro do contêiner para corresponder ao volume do host uid / gid e então use
gosu
para soltar da raiz para o usuário do contêiner para executar o aplicativo dentro do contêiner. O script importante para isso estáfix-perms
nos meus scripts de imagem base, que podem ser encontrados em: https://github.com/sudo-bmitch/docker-baseA parte importante do
fix-perms
script é:Isso coloca o uid do usuário dentro do contêiner, o uid do arquivo e, se não corresponderem, chama
usermod
para ajustar o uid. Por fim, ele faz uma busca recursiva para corrigir os arquivos que não mudaram os uids. Eu gosto disso melhor do que executar um contêiner com um-u $(id -u):$(id -g)
sinalizador, porque o código do ponto de entrada acima não exige que cada desenvolvedor execute um script para iniciar o contêiner, e quaisquer arquivos fora do volume que pertencem ao usuário terão suas permissões corrigidas.Você também pode fazer com que o docker inicialize um diretório de host de uma imagem usando um volume nomeado que executa uma montagem de ligação. Esse diretório deve existir com antecedência e você precisa fornecer um caminho absoluto para o diretório do host, diferente dos volumes do host em um arquivo de composição que podem ser caminhos relativos. O diretório também deve estar vazio para a janela de encaixe inicializá-lo. Existem três opções diferentes para definir um volume nomeado para uma montagem de ligação:
Por fim, se você tentar usar espaços de nome de usuário, verá que os volumes do host têm problemas de permissão porque os uid / gid dos contêineres são alterados. Nesse cenário, provavelmente é mais fácil evitar volumes de host e usar apenas volumes nomeados.
fonte
Em access.redhat.com:Sharing_Data_Across_Containers :
Parece ser apenas uma solução alternativa, mas tentei e funciona.
fonte
Eu verifiquei que
chcon -Rt svirt_sandbox_file_t /path/to/volume
funciona e você não precisa executar como um contêiner privilegiado.Isto é sobre:
fonte
Tente
docker volume create
.Consulte o documento https://docs.docker.com/engine/reference/commandline/volume_create/
fonte
Eu tive um problema semelhante, o meu foi causado por uma incompatibilidade entre o UID do host e o UID do usuário do contêiner. A correção foi passar o UID do usuário como argumento para a construção do docker e criar o usuário do contêiner com o mesmo UID.
No DockerFile:
Na etapa de construção:
Depois disso, executar o contêiner e os comandos de acordo com o OP me deu o resultado esperado.
fonte
Resolvi esse problema usando um contêiner de dados, isso também tem a vantagem de isolar os dados da camada de aplicativo. Você pode executá-lo assim:
Este tutorial fornece uma boa explicação sobre o uso de contêineres de dados.
fonte
Na minha situação, o problema era diferente. Não sei por que, mas mesmo que o diretório no host tivesse
chmod 777
rodado nele, dentro do docker era visível como755
.Correndo dentro do contêiner
sudo chmod 777 my_volume_dir
consertou.fonte
chmod 777
quase nunca conserta alguma coisa.sudo -s
fez o truque para mim no MACfonte