Tenho um diretório com permissões para o usuário1:
$ ls -la owned-by-u1
drwxr-xr-x 19 u1 u1 4096 Sep 4 16:22 owned-by-u1
$ ls -nla
drwx------ 19 1001 1001 4096 Sep 4 16:22 owned-by-u1
quando mapeio esse diretório como volume para um contêiner postgres, ele altera o proprietário do diretório para o ID de usuário 999, que pode mapear diferentes nomes de usuários.
$ ls -la owned-by-u1
drwx------ 19 gitlab-runner u1 4096 Sep 4 16:22 owned-by-u1
$ ls -nla
drwx------ 19 999 1001 4096 Sep 4 16:22 owned-by-u1
Eu executo o contêiner assim
docker run -d \
--name aaa-postgres \
-e POSTGRES_PASSWORD=mysecretpassword \
-e PGDATA=/var/lib/postgresql/pgdata \
-v /home/u1/tt/owned-by-u1:/var/lib/postgresql/pgdata \
postgres
Alguém pode explicar o mecanismo, por favor?
O dockerd está sendo executado como root (não sem root) e o remapeamento de UID não está habilitado.
Se eu habilitar o remapeamento de uid, o contêiner trava:
chmod: changing permissions of '/var/lib/postgresql/pgdata': Operation not permitted
find: ‘/var/lib/postgresql/pgdata’: Permission denied
chown: changing ownership of '/var/lib/postgresql/pgdata': Operation not permitted
O que é esperado porque a raiz interna não é uma raiz real:
$ docker run \
--name aaa-postgres \
--entrypoint "" \
-e POSTGRES_PASSWORD=mysecretpassword \
-e PGDATA=/var/lib/postgresql/pgdata \
-v /home/max/tt/owned-by-u1:/var/lib/postgresql/pgdata \
postgres cat /proc/self/uid_map
dá isso
0 296608 65536
que está de acordo com /etc/subuid:
$ cat /etc/subuid
dockremap:296608:65536
Aqui estão algumas informações sobre o Docker:
$ docker context ls
NAME DESCRIPTION DOCKER ENDPOINT ERROR
default * Current DOCKER_HOST based configuration unix:///var/run/docker.sock
desktop-linux Docker Desktop npipe:////./pipe/dockerDesktopLinuxEngine
$ docker version
Client: Docker Engine - Community
Server: Docker Engine - Community
Não há mapeamento de UIDs em montagens de volume entre o contêiner docker e o host. Mas os nomes de usuários em ambos são controlados pelo arquivo
/etc/passwd
and/etc/group
que é específico para o host e o contêiner (então o nome de usuário no host não corresponderá ao nome de usuário para o mesmo uid dentro do contêiner).Com o modo sem raiz e namespaces de usuário, os contêineres podem ter seus IDs de usuário e grupo mapeados (seguindo
/etc/subuid
mapeamentos/etc/subgid
e um usuário especificado para o mecanismo do docker). Quando o uid e o gid dos contêineres são deslocados, esse uid e gid deslocados aparecerão em processos no host e o usuário tentando acessar quaisquer montagens de ligação. Nesse cenário, a raiz no contêiner não é raiz no host, então as operações do sistema de arquivos que tentam alterar a propriedade de um arquivo no host falharão da mesma forma que se você tentasse executá-las como um usuário aleatório de alto número fora de um contêiner. Se o arquivo no host for de propriedade de um uid e gid fora dos intervalos mapeados, acredito que ele apareça como ninguém no contêiner e qualquer tentativa de modificar o arquivo falhará, pois o usuário do contêiner não tem acesso.Com o
postgres
exemplo, ele é configurado para iniciar como root e modificar permissões de arquivo como parte do entrypoint. Você deve evitar montagens host/bind e, em vez disso, usar um volume nomeado para esse cenário. Você pode ver oschown
comandos para opostgres
usuário em/usr/local/bin/docker-entrypoint.sh
, e o usuário atual e o usuário postgres dentro do contêiner com:Observe que, com o Docker Desktop, há uma VM na qual o mecanismo do Docker está sendo executado, e essa VM tem um driver de sistema de arquivos que monta os sistemas de arquivos do host na VM de uma forma que mapeia automaticamente o uid e o gid para o usuário do host ao gravar arquivos para evitar problemas de permissão.