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

17

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

Aqui está a maneira que eu pensei que funcionaria:

  1. crie o contêiner de dados para manter alguns dados persistentes na máquina A
  2. crie o contêiner de aplicativos que usa volumes do contêiner de dados
  3. faz algum trabalho, potencialmente alterando os dados no contêiner de dados
  4. pare o contêiner de aplicativos
  5. confirmar & marcar o contêiner de dados
  6. envie o contêiner de dados para um repositório (particular)
  7. puxe & executar a imagem da etapa 6 na máquina B
  8. continue de onde parou na máquina B

O passo chave aqui é o passo 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 & puxá-lo de outro lugar, dando-lhe um novo recipiente que é essencialmente idêntico ao original.

Mas parece que não funciona assim. O que eu acho é que ou o passo 5 não faz o que eu acho que faz ou o passo 7 (puxando e rodando a imagem) "redefine" o container para o estado inicial.

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

Contêiner 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

Writer

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.sh
RUN chmod 755 /usr/local/sbin/*.sh

CMD ["/usr/local/sbin/run.sh"]

run.sh

#!/bin/bash

while :
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 escreve uma string aleatória e a data / hora para /datafolder/data.txt no container 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 scripts
ADD run.sh /run.sh
RUN chmod 0777 /run.sh

CMD ["/run.sh"]

run.sh:

#!/bin/bash

echo "reading..."

echo "-----"

cat /datafolder/data.txt

echo "-----"

Quando eu criar & executar esses contêineres, eles funcionam bem e funcionam do jeito que eu esperava:

Parar & Comece na máquina de desenvolvimento:

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

Mas cometer & empurrando não faça o que eu espero:

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

Nesse ponto, esperaria executar o leitor & veja a mesma cadeia aleatória, já que o contêiner de dados foi confirmado, enviado para o repositório e 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 estou errado aqui? Ou, alternativamente, aponte-me para um exemplo de como a implantação é feita com o Docker?

    
por Kryten 29.09.2014 / 17:15

2 respostas

21

Você tem uma suposição errada sobre como os volumes funcionam no docker. Tentarei explicar como os volumes se relacionam com contêineres docker e imagens docker e esperamos que as diferenças entre volumes de dados e contêineres de volume de dados ficarão claras.

Primeiro, vamos relembrar algumas definições

Imagens do Docker

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 da união da imagem do docker com o comando docker export e pode inspecionar um metadado da imagem do docker com o comando docker inspect .

Volumes de dados

do Guia do usuário do Docker :

A data volume is a specially-designated directory within one or more containers that bypasses the Union File System to provide several useful features for persistent or shared data.

É importante observar 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 de união dos contêineres do Docker, então onde eles estão? sob /var/lib/docker/volumes no host do docker (enquanto os contêineres são armazenados em /var/lib/docker/containers ).

Contêineres de volume de dados

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

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 um contêiner pode permanecer parado e ainda preencher sua finalidade. Portanto, para criar um contêiner de dados chamado datatest_data para um volume em /datafolder , você só precisa executar:

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 que o daemon do docker se queixe de um comando ausente. De qualquer forma, depois que você tiver um contêiner interrompido chamado datatest_data com o único propósito de permitir que você alcance esse volume com a opção --volumes-from do comando docker run .

Como ler 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 a opção --volumes-from com o único objetivo de ler esses dados.

Por exemplo:

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

A outra maneira é copiar o volume da pasta /var/lib/docker/volumes . Você pode descobrir o nome do volume nessa pasta inspecionando os metadados de um dos contêineres usando o volume. Veja esta resposta para detalhes.

Trabalhando com volumes (desde o Docker 1.9.0)

Como criar um volume (desde o Docker 1.9.0)

O 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 o Docker 1.9.0)

Digamos que você tenha criado um volume chamado hello com docker volume create --name hello , você pode montá-lo em um contêiner com a opção -v :

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

Sobre como cometer & 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), a confirmação de um contêiner para produzir uma nova imagem do docker não persistirá em nenhum volume de dados.

Fazendo backups de volumes de dados

O guia do usuário do Docker tem um belo artigo sobre backup de volumes de dados .

Bom artigo sobre o volume de reagentes: link

    
por 29.09.2014 / 23:54
1

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

Eu não sei se é uma boa prática, mas eu 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 file
RUN echo "no data here!" > /data-image/data.txt

# expose the data folder 
#
VOLUME /datafolder

ENTRYPOINT cp -r /data-image/* /datafolder/

Agora você pode enviar sua imagem e usar volumes, etc.

    
por 07.01.2016 / 17:22

Tags