Como faço para montar um Private / proc dentro de um namespace dentro de um contêiner docker?

Eu tenho a necessidade de criar namespaces dentro de um contêiner Docker. E como parte disso, precisarei montar um /proc privado para o namespace interno. Percebo que terei que executar o contêiner com certos privilégios para fazer isso acontecer, mas prefiro habilitar o conjunto mais mínimo.

Trabalho:

$ sudo docker run --privileged --security-opt=seccomp=unconfined \ -it fedora:rawhide /usr/bin/unshare -Ufmp -r \ /bin/sh -c 'mount -t proc proc /proc'

Isso não faz:

$ sudo docker run --cap-add=sys_admin --security-opt=seccomp=unconfined \  -it fedora:rawhide /usr/bin/unshare -Ufmp -r \   /bin/sh -c 'mount -t proc proc /proc'mount: /proc: cannot mount proc read-only.

Então, basta desligar os filtros seccomp e adicionar CAP_SYS_ADMIN não basta. O e chega?

Actualizacao: Selinux faz parte do problema. Se você desativar o selinux enforcement globalmente, ele funcionará. Mas, você também pode desativar a aplicação de um contêiner específico com --security-opt label:disable, e isso está documentado no seção de configuração de segurança do manual do Docker online:

sudo docker run --cap-add=sys_admin --security-opt label:disable \ -it fedora:rawhide /usr/bin/unshare -fmp /bin/sh -c \ 'mount --make-private / ; mount -t proc proc /proc'

Mas isso falha se o -U e -r bandeiras são adicionadas de volta a unshare. E, claro, adicionando --privileged para o comando docker run funciona muito bem, mesmo com o -U e -r bandeira.

No momento, estou tentando usar o rastreamento do kernel para descobrir o que, exatamente, está me dando um EPERM. É um erro muito inespecífico para obter.

Este comando funciona:

sudo docker run --cap-add=sys_admin --security-opt label:disable -it fedora:rawhide /bin/sh -c 'for dir in $(awk '"'"'/\/proc\// { print $5; }'"'"' /proc/1/mountinfo ); do umount "$dir"; done; /usr/bin/unshare -Ufmp -r /bin/sh -c '"'"'mount --make-private / ; mount -t proc proc /proc ; ls /proc'"'"

Eu não dividi em várias linhas porque a citação é realmente importante. Basicamente, ele desmonta um monte de coisas em /proc antes de executar unshare e montagem /proc no namespace do Usuário filho.

Docker monta sobre um monte de diretórios e arquivos em /proc com seus próprios diretórios que são diretórios tmpfs vazios e arquivos nulos. Vários arquivos em /proc representar valores que são aplicáveis a todo o sistema. Na verdade, /proc/kcore permitiria que você lesse a memória do kernel dentro do contêiner se você fosse root, o que, uma vez que muitas pessoas querem acreditar que os contêineres são algum tipo de VM leve ou algo assim, surpreenderia muitas pessoas.

O kernel em (a partir da versão 4.14 de qualquer maneira) fs/namespace.c:mnt_already_visible verifica se você está montando um sistema de arquivos já montado e se esse sistema de arquivos tiver coisas montadas como Sistemas de arquivos filhos e essas montagens tiverem o sinalizador MNT_LOCKED, ele falhará. O sinalizador MNT_LOCKED parece ser aplicado (não procurei onde isso está no kernel) a todas as montagens sempre que você cria um namespace de usuário para evitar que você desmonte as coisas nesse namespace (porque você obtém privilégios 'dentro' do namespace do Usuário) e torne as coisas ocultas visíveis novamente.

O comando que postei usa um script awk no conteúdo de /proc/1/mountinfo para retirar todos os subdiretórios e arquivos em /proc esse Docker montou e desmonta todos eles. Isso faz com que o /proc sistema de arquivos montável em namespaces de usuário aninhados novamente.

SamYaple no canal # docker no Freenode tem sido muito útil aqui, e isso pode ser um problema de cgroups. Parece haver um cgroup de ‘dispositivos’.

Isso não vai ajudá-lo, mas TBH: estou realmente surpreso que esta não seja uma opção padrão de montagem, pois parece um requisito bastante comum para mim. Eu preciso disso:)… Estou executando um único binário e incluindo todas as suas bibliotecas, então não há necessidade de um Base-O/S no contêiner - então não tenho um, mas parece querer /proc para alguns recursos. O mesmo aconteceria com binários estáticos , como os ’ Go ’ - eles poderiam ser instalados sem uma base-O/S em um contêiner. Eu tentei `-v / proc: / proc ’ e não ajuda pelo motivo que você dá.

você já tentou usar -v / proc: / proc ?

@c4f4t0r-Bem, isso não faria o que eu quero. Não quero que o / proc do docker de namespace esteja sendo executado (presumivelmente o namespace de nível raiz).

@c4f4t0r-usando ftrace, as fontes do kernel e algum pensamento criativo, descobri o problema. security - How do I mount a private /proc inside a namespace inside a docker container? - Server Fault