No docker, os arquivos criados dentro de contêineres tendem a ter propriedade imprevisível durante a inspeção do host. O proprietário dos arquivos em um volume é root (uid 0) por padrão, mas assim que contas de usuário não root estão envolvidas no contêiner e gravando no sistema de arquivos, os proprietários se tornam mais ou menos aleatórios da perspectiva do host.
É um problema quando você precisa acessar os dados de volume do host usando a mesma conta de usuário que está chamando os comandos docker.
Soluções alternativas típicas são
- forçar uIDs de usuários no momento da criação em Dockerfiles (não portátil)
- passando o UID do usuário host para o
docker run
comando como uma variável de ambiente e, em seguida, executando algunschown
comandos nos volumes em um script de ponto de entrada.
Ambas as soluções podem fornecer algum controle sobre as permissões reais fora do contêiner.
Eu esperava que os namespaces do usuário fossem a solução final para esse problema. Executei alguns testes com a versão 1.10 lançada recentemente e --userns-remap definido para minha conta de desktop. No entanto, não tenho certeza se isso pode tornar mais fácil lidar com a propriedade de arquivos em volumes montados, infelizmente poderia ser o contrário.
Suponha que eu inicie este contêiner básico
docker run -ti -v /data debian:jessie /bin/bash
echo 'hello' > /data/test.txt
exit
Em seguida, inspecione o conteúdo do host:
ls -lh /var/lib/docker/100000.100000/volumes/<some-id>/_data/
-rw-r--r-- 1 100000 100000 6 Feb 8 19:43 test.txt
Este número '100000' é um sub-UID do meu usuário host, mas como não corresponde ao UID do meu usuário, ainda não consigo editar o test.txt sem privilégios. Este subusuário não parece ter nenhuma afinidade com meu usuário regular real fora do docker. Não está mapeado de volta.
As soluções alternativas mencionadas anteriormente nesta postagem, que consistiam em alinhar UIDs entre o host e o contêiner, não funcionam mais devido ao UID->sub-UID
mapeamento que ocorre no namespace.
Então, há uma maneira de executar o docker com o namespace do usuário habilitado (para maior segurança), enquanto ainda possibilita que o usuário host que executa o docker possua os arquivos gerados nos volumes?
Respostas:
Se você pode pré-organizar usuários e grupos com antecedência, então é possível atribuir UIDs e GIDs de maneira específica para que os usuários do host correspondam aos usuários com namespace dentro dos contêineres.
Aqui está um exemplo (Ubuntu 14.04, Docker 1.10):
Crie alguns usuários com IDs numéricos fixos:
Edite manualmente intervalos de IDs subordinados gerados automaticamente em arquivos
/etc/subuid
e/etc/subgid
:(observe que não há registros para
ns1-root
ens1-user1
devido aMAX_UID
eMAX_GID
limites em/etc/login.defs
)Habilite namespaces de usuário em
/etc/default/docker
:Reinicie o daemon
service docker restart
, certifique-se de que o/var/lib/docker/500000.500000
diretório seja criado.Agora, dentro dos contêineres você tem
root
euser1
, e no host -ns1-root
ens1-user1
, com IDs correspondentesATUALIZAÇÃO: para garantir que usuários não root tenham IDs fixos em contêineres (por exemplo, usuário1 1000: 1000), crie-os explicitamente durante a construção da imagem.
Passeio de teste:
Prepare um diretório de volume
Experimente de um contêiner
Experimente com o anfitrião
Não é portátil e parece um hack, mas funciona.
fonte
subUID lower bound + UID in image
se estivermos executando muitas imagens diferentes com um usuário com ID definido como 1000?Uma solução alternativa é atribuir dinamicamente o uid do usuário no tempo de construção para corresponder ao host.
Exemplo
Dockerfile
:Em seguida, construa como:
e execute como:
Se você já tiver um contêiner, crie um contêiner de wrapper com o seguinte
Dockerfile
:Isso pode ser embrulhado
docker-compose.yml
como:Em seguida, crie e execute como:
fonte
Você pode evitar problemas de permissão usando o
docker cp
comando .Aqui está seu exemplo alterado para usar
docker cp
:No entanto, se você deseja apenas ler os arquivos de um contêiner, não precisa do volume nomeado. Este exemplo usa um contêiner nomeado em vez de um volume nomeado:
Considero os volumes nomeados úteis quando desejo copiar arquivos em um contêiner, conforme descrito nesta pergunta .
fonte
docker cp
envolve a duplicação de dados. Além disso, de acordo com o documento, ao copiar dados para um contêiner, ele define os IDs de propriedade de acordo com o usuário root, que muitas vezes não é a conta que executa o aplicativo em contêiner. Não consigo ver como isso resolve nosso problema.docker cp
oferece controle total sobre a propriedade do arquivo ao transmitir um arquivo tar para dentro ou para fora de um contêiner. Você pode ajustar a propriedade e as permissões de cada entrada no arquivo tar à medida que o transmite, para que não fique limitado ao usuário root.