Não tenho 100% de certeza se esta é uma pergunta U&L ou SO . No geral, estou postando no U&L, pois é relacionado ao sistema operacional .
Fundo
Até onde eu sei, o Linux carregará bibliotecas compartilhadas (arquivos .so) mapeando-as na memória como copy-on-write. Uma vantagem disso é que vários processos que compartilham a mesma biblioteca grande compartilharão a mesma RAM física para grande parte do conteúdo dessa biblioteca.
Isso não acontece necessariamente com o Docker porque os processos são executados em seu próprio "contêiner" com base em uma "imagem" e cada imagem contém sua própria cópia de bibliotecas compartilhadas. Isso é deliberado. Ele permite que os programas sejam enviados com suas próprias dependências (bibliotecas) que podem ser substancialmente diferentes das bibliotecas já instaladas no sistema.
Portanto, um programa executado nativamente em um host do Docker não compartilhará a mesma memória para bibliotecas que um programa executado em um contêiner do Docker porque o programa no contêiner do Docker foi mapeado para diferentes cópias das bibliotecas.
Camadas do Docker explicadas
As imagens do Docker são criadas em camadas. Cada camada adiciona à inferior, às vezes substituindo os arquivos existentes. Nem todo arquivo é alterado em todas as camadas.
O Docker permite criar novas imagens adicionando novas camadas a uma imagem mais antiga. Quando isso acontece, você acaba com várias imagens compartilhando as mesmas camadas. As imagens compartilham cópias idênticas de alguns dos mesmos arquivos.
O Docker mantém as camadas separadamente, pelo menos antes do tempo de execução. Por exemplo: ao puxar uma imagem do Docker Hub, o Docker busca as imagens buscando as camadas constituintes de cada imagem. Ele apenas busca as camadas que ainda não possui.
O que eu não sei
Ao criar ou executar um contêiner, o Docker deve montar as camadas em um único sistema de arquivos coerente. Não sei como faz isso. Poderia:
- Copie os arquivos em um só lugar
- Crie links físicos em um só lugar
- Use um sistema de arquivos de sobreposição
Dependendo do que ele faz, os arquivos originados da mesma camada podem ser cópias idênticas ou podem ser exatamente o mesmo arquivo no sistema de arquivos.
Em última análise, isso afetará o que acontece quando os arquivos são mapeados na memória por vários processos.
O que estou realmente tentando descobrir?
Eu quero saber se a execução de dois contêineres de duas imagens diferentes compartilhará a mesma RAM para uma única biblioteca compartilhada originada em uma única camada.
Pelo menos em algumas configurações, sim, os containers podem compartilhar mapeamentos de memória para arquivos da mesma camada em imagens diferentes.
Aqui está um experimento para demonstrar isso. Estou usando duas imagens diferentes, uma baseada na outra:
Eu iniciei dois contêineres, apenas usando o shell do ponto de entrada:
Vamos examinar a biblioteca C usada por esses dois shells:
Ambas as bibliotecas mapeadas têm o mesmo dispositivo e inode, portanto, são o mesmo arquivo e seus mapeamentos serão compartilhados sempre que possível.