Como faço para implantar um contêiner docker e um contêiner de dados associado, incluindo conteúdo?

Vou começar admitindo que sou muito novo no Docker e posso estar abordando esse problema a partir do conjunto errado de suposições... deixe-me saber se é esse o caso. Eu vi muita discussão sobre como o Docker é útil para implantação, mas nenhum exemplo de como isso realmente é feito.

Aqui está a maneira que eu pensamento isso funcionaria:

  1. crie o contêiner de dados para armazenar alguns dados persistentes na máquina A
  2. crie o contêiner do aplicativo que usa volumes do contêiner de dados
  3. faça algum trabalho, potencialmente alterando os dados no contêiner de dados
  4. pare o recipiente de Aplicação
  5. commit & amp; marcar o recipiente de dados
  6. empurre o contêiner de dados para um repositório (privado)
  7. puxe & amp; executar a imagem do Passo 6 na máquina B
  8. pegue onde você parou na máquina B

A etapa principal aqui é a Etapa 5, que eu pensei que salvaria o estado atual (incluindo o conteúdo do sistema de arquivos). Você poderia então empurrar esse estado para um repositório & amp; puxá-lo de outro lugar, dando-lhe um novo recipiente que é essencialmente idêntico ao original.

Mas não parece funcionar assim. O que eu acho é que a Etapa 5 não faz o que eu acho que faz ou a Etapa 7 (puxando & executando a imagem) "redefine" o contêiner para seu estado inicial.

Eu montei um conjunto de três imagens e contêineres do Docker para testar isso: um contêiner de dados, um gravador que grava uma string aleatória em um arquivo no contêiner de dados a cada 30 s e um leitor que simplesmente echoes o valor no arquivo do contêiner de dados e sai.

Recipiente de dados

Criado com

docker run \    --name datatest_data \    -v /datafolder \    myrepository:5000/datatest-data:latest

Dockerfile:

FROM ubuntu:trusty# make the data folder#RUN mkdir /datafolder# write something to the data file#RUN echo "no data here!" > /datafolder/data.txt# expose the data folder#VOLUME /datafolder

Escritor

Criado com

docker run \    --rm \    --name datatest_write \    --volumes-from datatest_data \    myrepository:5000/datatest-write:latest

Dockerfile:

FROM ubuntu:trusty# Add script#ADD run.sh /usr/local/sbin/run.shRUN chmod 755 /usr/local/sbin/*.shCMD ["/usr/local/sbin/run.sh"]

run.sh

#!/bin/bashwhile :do    sleep 30s    NEW_STRING=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 32 | head -n 1)    echo "$NEW_STRING" >> /datafolder/data.txt    date >> /datafolder/data.txt    echo "wrote '$NEW_STRING' to file"done

Este script grava uma string aleatória e a data/hora para /datafolder/data.txt no contêiner de dados.

Leitor

Criado com

docker run \    --rm \    --name datatest_read \    --volumes-from datatest_data \    myrepository:5000/datatest-read:latest

Dockerfile:

FROM ubuntu:trusty# Add scriptsADD run.sh /run.shRUN chmod 0777 /run.shCMD ["/run.sh"]

run.sh:

#!/bin/bashecho "reading..."echo "-----"cat /datafolder/data.txtecho "-----"

Quando eu construir & amp; executar esses contêineres, eles funcionam bem e funcionam da maneira que eu espero:

Parar & amp; Iniciar na máquina de desenvolvimento:

  1. criar o contêiner de dados
  2. executar o escritor
  3. execute o leitor imediatamente, veja o " sem dados aqui!" mensagem
  4. espere um pouco
  5. execute o leitor, veja a string aleatória
  6. pare o escritor
  7. reinicie o escritor
  8. execute o leitor, veja a mesma string aleatória

Mas cometer & amp; empurrando não fazer o que eu espero:

  1. criar o contêiner de dados
  2. executar o escritor
  3. execute o leitor imediatamente, veja o " sem dados aqui!" mensagem
  4. espere um pouco
  5. execute o leitor, veja a string aleatória
  6. pare o escritor
  7. commit & amp; marcar o recipiente de dados com docker commit datatest_data myrepository:5000/datatest-data:latest
  8. empurre para o repositório
  9. excluir todos os recipientes & amp; recriá-los

Neste ponto, eu esperaria executar o leitor & amp; ver a mesma string aleatória, uma vez que o contêiner de dados foi comprometido, empurrado para o repositório e, em seguida, recriado a partir da mesma imagem no repositório. No entanto, o que eu realmente vejo é o "sem dados aqui!" mensagem.

Alguém pode explicar onde eu estou errado aqui? Ou, alternativamente, Aponte-me para um exemplo de como a implantação é feita com o Docker?

Você tem uma suposição errada sobre como os volumes funcionam no docker. Vou tentar explicar como os volumes se relacionam com contêineres docker e imagens docker e, espero, diferenças entre volumes de dados e contentores de volume de dados vai ficar claro.

Primeiro, vamos lembrar algumas definições

Docker imagens

As imagens do Docker são essencialmente um sistema de arquivos de união + metadados. Você pode inspecionar o conteúdo do sistema de arquivos Docker image union com o docker export comando, e você pode inspecionar uma imagem do docker metadados com o docker inspect comando.

Volumes de dados

do Guia do usuário do Docker:

Um volume de dados é um diretório especialmente designado dentro de um ou mais contêineres que ignora o sistema de arquivos Union para fornecer vários recursos úteis para dados persistentes ou compartilhados.

É importante notar aqui que um determinado volume (como o diretório ou arquivo que contém dados) é reutilizável somente se existir pelo menos um contêiner docker usando-o. As imagens do Docker não têm volumes, elas só têm metadados que eventualmente informam onde os volumes seriam montados no sistema de arquivos union. Os volumes de dados não fazem parte do sistema de arquivos docker containers union, então onde eles estão? em /var/lib/docker/volumes no host docker (enquanto os contêineres são armazenados em /var/lib/docker/containers).

Contentores de volume de dados

Esse tipo especial de contêiner não tem nada de especial. Eles são apenas contêineres interrompidos usando um volume de dados com o único e único objetivo de ter pelo menos um contêiner usando esse volume de dados. Lembre-se, assim que o último contêiner (em execução ou interrompido) usando um determinado volume de dados for excluído, esse volume ficará inacessível por meio do docker run --volumes-from Opcao.

Trabalhando com contêineres de volume de dados

Como criar um contêiner de volume de dados

A imagem usada para criar um contêiner de volume de dados não tem importância, pois esse contêiner pode permanecer parado e ainda preencher sua finalidade. Então, para criar um contêiner de dados chamado datatest_data para um volume em /datafolder você só precisa correr:

docker run --name datatest_data --volume /datafolder busybox true

Aqui base é o nome da imagem (um convenientemente pequeno) e true é um comando que fornecemos apenas para evitar ver o daemon do docker reclamar de um comando ausente. De qualquer forma, depois de ter um contêiner parado chamado datatest_data com o único propósito de permitir que você alcance esse volume com o --volumes-from opção do docker run comando.

Como ler a partir de um contêiner de volume de dados

Eu conheço duas maneiras de ler um volume de dados: o primeiro é através de um contêiner. Se você não puder ter um shell em um contêiner existente para acessar esse volume de dados, poderá executar um novo contêiner com o --volumes-from opção com o único propósito de ler esses dados.

Por exemplo:

docker run --rm --volumes-from datatest_data busybox cat /datafolder/data.txt

A outra maneira é copiar o volume do /var/lib/docker/volumes pasta. Você pode descobrir o nome do volume nessa pasta inspecionando os metadados de um contêiner usando o volume. Ver resposta para mais detalhes.

Trabalhando com volumes (desde Docker 1.9.0)

Como criar um volume (desde o Docker 1.9.0)

Docker 1.9.0 introduziu um novo comando docker volume que permite criar volumes :

docker volume create --name hello

Como ler de um volume (desde Docker 1.9.0)

Digamos que você criou um volume chamado hello com docker volume create --name hello, você pode montá-lo em um recipiente com o -v Opcao :

docker run -v hello:/data busybox ls /data

Sobre cometer & amp; empurrando recipientes

Agora deve ficar claro que, como os volumes de dados não fazem parte de um contêiner (o sistema de arquivos union), comprometer um contêiner para produzir uma nova imagem do docker não persistirá nenhum dado que estaria em um volume de dados.

Fazendo backups de volumes de dados

O guia do usuário do docker tem um bom artigo sobre fazendo backups de volumes de dados.


Bom artigo reagarding volumes: http://container42.com/2014/11/03/docker-indepth-volumes/

Você também pode usar um contêiner de dados do docker para implantar o código

Não sei se é uma boa prática, mas faço assim :

FROM ubuntu:trusty# make the data folder#RUN mkdir /data-image# in my case, I have a # ADD dest.tar /data-image/## but to follow your example :# write something to the data fileRUN echo "no data here!" > /data-image/data.txt# expose the data folder #VOLUME /datafolderENTRYPOINT cp -r /data-image/* /datafolder/

Agora você pode empurrar sua imagem e usar volumes-de , etc ...