Como atualizar o container do acoplador após a alteração da sua imagem
estes contentores estão a funcionar há algum tempo até que o MySQL 5.6.22 seja libertado. A imagem oficial do mysql: 5.6 é atualizada com o novo lançamento, mas meus contêineres ainda funcionam 5.6.21.
Como propagar as alterações na imagem (isto é, actualizar a MySQL distro) para todos os meus recipientes existentes? Qual é a maneira correcta de atracar? de fazer isto?
13 answers
A forma de actualizar os contentores parece ser a seguinte:
Os recipientes de aplicação não devem conservar os dados da aplicação. Desta forma, poderá substituir o contentor de aplicações pela sua versão mais recente a qualquer momento, executando algo do género:
docker pull mysql
docker stop my-mysql-container
docker rm my-mysql-container
docker run --name=my-mysql-container --restart=always \
-e MYSQL_ROOT_PASSWORD=mypwd -v /my/data/dir:/var/lib/mysql -d mysql
Pode guardar os dados na máquina(na pasta montada como volume) ou no (s) recipiente (S) Especial (s) apenas para dados. Continuar sobre isso aqui, Aqui , e Aqui.
Actualizar as aplicações (p.ex. com yum / apt-get upgrade) dentro dos recipientes é considerado um anti-padrão . Os recipientes de aplicação devem ser imutáveis, o que deve garantir um comportamento reprodutível. Algumas imagens oficiais da aplicação (mysql:5.6 em particular) nem sequer são projetadas para auto-atualização (apt-get upgrade não vai funcionar).
Gostaria de agradecer a todos os que deram as suas respostas, por isso ... podíamos ver abordagens diferentes.--volumes-from <container>
dará ao novo container com as imagens atualizadas propriedade compartilhada dos volumes gerenciados pelo docker.
docker pull mysql
docker create --volumes-from my_mysql_container [...] --name my_mysql_container_tmp mysql
Ao NÃO remover imediatamente o my_mysql_container
original ainda, você tem a capacidade de voltar para o recipiente de trabalho conhecido se o recipiente melhorado não tem o dados certos,ou falha num teste de sanidade.
docker stop my_mysql_container
docker start my_mysql_container_tmp
Agora você tem a oportunidade de se certificar de que os dados que você espera estar no novo recipiente estão lá e fazer uma verificação de sanidade.
docker rm my_mysql_container
docker rename my_mysql_container_tmp my_mysql_container
Os volumes do acoplador ficarão por aqui enquanto qualquer contentor os estiver a usar, para que possa apagar o contentor original em segurança. Uma vez o recipiente original é removido, o novo recipiente pode assumir o nome do original para fazer tudo tão bonito como era para começar.
Existem duas grandes vantagens em utilizar este padrão para actualizar os contentores do Cais. Em primeiro lugar, elimina a necessidade de montar volumes para hospedar diretórios, permitindo que os volumes sejam diretamente transferidos para um recipiente atualizado. Em segundo lugar, você nunca está em uma posição onde não há um container docker de trabalho; assim, se a atualização falhar, você pode facilmente reverter para como estava a funcionar antes, girando novamente o contentor original do ancoradouro.Gostaria de acrescentar que, se quiser fazer este processo automaticamente (transferir, parar e reiniciar um novo contentor com as mesmas configurações descritas por @Yaroslav), poderá usar a Torre de Vigilância. Um programa que actualiza automaticamente os seus contentores quando são alterados https://github.com/v2tec/watchtower
Considere para estas respostas:
- o nome da base de dados é
app_schema
- o nome do contentor é
app_db
- a senha de root é:
root123
Como actualizar o MySQL ao armazenar os dados da aplicação dentro do recipiente
Isto é considerado uma má prática, Porque se você perder o recipiente, você perderá os dados. Embora seja uma má prática, aqui está uma maneira possível de fazê-lo:
1) Faça uma pesquisa de base de dados como SQL:
docker exec app_db sh -c 'exec mysqldump app_schema -uroot -proot123' > database_dump.sql
2) Actualizar a imagem:
docker pull mysql:5.6
3) Actualizar o contentor:
docker rm -f app_db
docker run --name app_db --restart unless-stopped \
-e MYSQL_ROOT_PASSWORD=root123 \
-d mysql:5.6
4) repor o resultado da base de Dados:
docker exec app_db sh -c 'exec mysql -uroot -proot123' < database_dump.sql
Como actualizar o contentor MySQL usando um volume externo
Usar um volume externo é uma forma melhor de gerir os dados, e torna mais fácil actualizar o MySQL. Perder o recipiente não vai perder nenhum dado. Você pode usar docker-compose para facilitar a gestão de aplicações de Docker multi-container numa única máquina:
1) Crie o ficheiro docker-compose.yml
para gerir as suas aplicações:
version: '2'
services:
app_db:
image: mysql:5.6
restart: unless-stopped
volumes_from: app_db_data
app_db_data:
volumes: /my/data/dir:/var/lib/mysql
2) Actualizar o MySQL (da mesma pasta que o ficheiro docker-compose.yml
):
docker-compose pull
docker-compose up -d
Nota: o último comando acima irá actualizar a imagem MySQL, recriar e iniciar o contentor com a nova imagem.
Resposta semelhante à acima
docker images | awk '{print $1}' | grep -v 'none' | grep -iv 'repo' | xargs -n1 docker pull
- em resumo
Sincronizar com o registo de imagens de Serviço ( https://docs.docker.com/compose/compose-file/#image):
docker-compose pull
Recriar o contentor se o ficheiro de composição do 'docker' ou a imagem tiverem mudado:
docker-compose up -d
- antecedentes
A gestão da imagem do contentor é uma das razões para usar a composição do 'docker' (ver https://docs.docker.com/compose/reference/up/)
Se houver contentores existentes para um serviço, e a configuração ou imagem do serviço tiver sido alterada após a criação do contentor, a docker-compose recolhe as alterações, parando e recriando os contentores (preservando volumes montados). Para evitar que a composição detecte alterações, use a bandeira --no-recriar.
Aspecto de gestão de dados também coberto pelo acoplador-composto através de montagem externa "volumes" (ver https://docs.docker.com/compose/compose-file/#volumes ) ou recipiente de dados.
Isto deixa intactas potenciais questões de compatibilidade retroativa e migração de dados, mas estas são questões "aplicativas", não específicas do acoplador, que têm de ser verificadas com notas de lançamento e testes...
Aqui está o que parece usar {[[0] } ao construir um personalizado Dockerfile
.
- crie primeiro o seu ficheiro de Dockerfile personalizado, adicionando um número de versão seguinte para diferenciar. Ex:
docker build -t imagename:version .
Isto irá armazenar a sua nova versão localmente. - corre
docker-compose down
- edite o seu ficheiro
docker-compose.yml
para reflectir o novo nome da imagem que definiu no Passo 1. - corre
docker-compose up -d
Ele vai procurar localmente para a imagem e usar o seu atualizado.
- editar -
Os meus passos acima são mais verbos do que precisam de ser. Optimizei o meu fluxo de trabalho, incluindo o parâmetro build: .
no meu ficheiro de composição de docker. Os passos parecem agora:
-
Verifique se o meu ficheiro Dockerfile é o que eu quero que pareça.
- Defina o número de versão do meu nome de imagem no meu ficheiro de composição do 'docker'.
- Se a minha imagem ainda não foi construída: executar
docker-compose build
- corre
docker-compose up -d
A partir de http://blog.stefanxo.com/2014/08/update-all-docker-images-at-once/
Pode actualizar todas as suas imagens existentes usando o seguinte 'pipeline' de comandos:
docker images | awk '/^REPOSITORY|\<none\>/ {next} {print $1}' | xargs -n 1 docker pull
Você precisa reconstruir todas as imagens e reiniciar todos os recipientes, ou de alguma forma atualizar o software e reiniciar o banco de dados. Não há nenhum caminho de atualização, mas que você projetar a si mesmo.
Se não quiser usar a composição do 'Docker', posso recomendar portainer . Tem uma função recriar que lhe permite recriar uma imagem enquanto puxa a imagem mais recente.
Ele usa o 'docker-py' para comunicar com os contentores do 'docker' em execução e actualizar os pacotes ou executar qualquer comando arbitrário único
Exemplos:
docker run --rm -v /var/run/docker.sock:/tmp/docker.sock itech/docker-run exec
date
em todos os contentores em execução e devolver os resultados, mas poderá emitir qualquer comando.docker-run exec "uname -a"
Para actualizar os pacotes (actualmente apenas usando o apt-get):
docker run --rm -v /var/run/docker.sock:/tmp/docker.sock itech/docker-run update
Você pode criar e usar um nome alternativo e usá-lo como uma linha de comando regular por exemplo
alias docker-run='docker run --rm -v /var/run/docker.sock:/tmp/docker.sock itech/docker-run'
Certifique-se de que está a usar volumes para todos os dados persistentes (configuração, registos ou dados da aplicação) que armazena nos contentores relacionados com o estado dos processos dentro desse contentor. Actualize o seu ficheiro de Dockerfile e reconstrua a imagem com as alterações que deseja, e reinicie os contentores com os seus volumes montados no local apropriado.
Idealmente, eu preferiria gerar uma nova versão da imagem Docker e ter todos os recipientes baseados em uma versão anterior dessa imagem automaticamente atualizada para a nova imagem "no lugar."Mas isto o mecanismo não parece existir.
Então o próximo melhor design que eu fui capaz de criar até agora é fornecer uma maneira de ter o container atualizado-similar a como um aplicativo desktop verifica para atualizações e depois atualiza-se a si mesmo. No meu caso, isto provavelmente significará criar um script que envolve git puxa de uma etiqueta bem conhecida.
A imagem / contentor não muda, mas os" internos " do contentor mudam. Você poderia imaginar fazer o mesmo com apt-get, yum, ou o que for apropriado para o seu ambiente. Junto com isso, eu atualizaria o myserver:a última imagem no registro para que quaisquer novos contêineres fossem baseados na última imagem.
Estaria interessado em saber se há alguma arte anterior que aborde este cenário.