661 Stimmen

Wie man einen Docker-Container aktualisiert, nachdem sich das Image geändert hat

Sagen wir, ich habe das offizielle mysql:5.6.21 Image abgerufen.

Ich habe dieses Image bereitgestellt, indem ich mehrere Docker-Container erstellt habe.

Diese Container laufen seit einiger Zeit, bis MySQL 5.6.22 veröffentlicht wird. Das offizielle Image von mysql:5.6 wird mit dem neuen Release aktualisiert, aber meine Container laufen immer noch mit 5.6.21.

Wie übertrage ich die Änderungen im Image (dh das Upgrade der MySQL-Distribution) auf alle meine vorhandenen Container? Was ist der richtige Docker-Weg, dies zu tun?

686voto

Yaroslav Stavnichiy Punkte 19828

Nachdem ich die Antworten ausgewertet und das Thema studiert habe, möchte ich zusammenfassen.

Der Docker-Weg zur Aktualisierung von Containern scheint wie folgt zu sein:

Anwendungscontainer sollten keine Anwendungsdaten speichern. Auf diese Weise können Sie den App-Container durch seine neuere Version jederzeit ersetzen, indem Sie so etwas ausführen:

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

Sie können Daten entweder auf dem Host (in einem als Volume eingehängten Verzeichnis) oder in speziellen Datencontainern speichern. Lesen Sie mehr darüber

Das Aktualisieren von Anwendungen (z. B. mit yum/apt-get upgrade) innerhalb von Containern gilt als Anti-Pattern. Anwendungscontainer sollen unveränderlich sein, was reproduzierbares Verhalten garantieren soll. Einige offizielle Anwendungsimages (besonders mysql:5.6) sind nicht einmal für Selbstaktualisierungen konzipiert (apt-get upgrade funktioniert nicht).

Ich möchte allen danken, die ihre Antworten gegeben haben, damit wir alle unterschiedlichen Ansätze sehen konnten.

98voto

kMaiSmith Punkte 1081

Ich mag es nicht, Volumes als Link zu einem Hostverzeichnis einzubinden, also habe ich ein Muster entwickelt, um Docker-Container mit ausschließlich von Docker verwalteten Containern zu aktualisieren. Das Erstellen eines neuen Docker-Containers mit --volumes-from gibt dem neuen Container mit den aktualisierten Images eine gemeinsame Verwaltung von den von Docker verwalteten Volumes.

docker pull mysql
docker create --volumes-from my_mysql_container [...] --name my_mysql_container_tmp mysql

Indem du das ursprüngliche my_mysql_container noch nicht sofort entfernst, hast du die Möglichkeit, zum bekannten funktionierenden Container zurückzukehren, falls der aktualisierte Container nicht über die richtigen Daten verfügt oder einen Funktionstest nicht besteht.

An diesem Punkt führe ich normalerweise die Sicherungsskripte für den Container aus, um mir im Falle eines Fehlers ein Sicherheitsnetz zu geben

docker stop my_mysql_container
docker start my_mysql_container_tmp

Jetzt hast du die Möglichkeit sicherzustellen, dass die Daten, die du im neuen Container erwartest, vorhanden sind, und einen Funktionscheck durchzuführen.

docker rm my_mysql_container
docker rename my_mysql_container_tmp my_mysql_container

Die Docker-Volumes bleiben bestehen, solange irgendein Container sie verwendet, daher kannst du den ursprünglichen Container sicher löschen. Sobald der ursprüngliche Container entfernt ist, kann der neue Container den Namen des ursprünglichen übernehmen, um alles so hübsch zu machen wie zu Beginn.

Es gibt zwei Hauptvorteile bei der Verwendung dieses Musters zur Aktualisierung von Docker-Containern. Erstens eliminiert es die Notwendigkeit, Volumes an Hostverzeichnisse zu binden, indem es Volumes direkt auf aktualisierte Container überträgt. Zweitens gerätst du nie in die Situation, dass kein funktionierender Docker-Container vorhanden ist; also wenn das Update fehlschlägt, kannst du leicht zur vorherigen Arbeitsweise zurückkehren, indem du den ursprünglichen Docker-Container erneut startest.

63voto

Ronan Fauglas Punkte 822

Nur um eine allgemeinere (nicht mysql-spezifische) Antwort bereitzustellen...

  1. Kurz gesagt

Synchronisieren mit Service-Image-Registry (https://docs.docker.com/compose/compose-file/#image):

docker-compose pull 

Container neu erstellen, wenn sich die docker-compose-Datei oder das Image geändert haben:

docker-compose up -d
  1. Hintergrund

Die Verwaltung des Containerimages ist einer der Gründe für die Verwendung von Docker-Compose (siehe https://docs.docker.com/compose/reference/up/)

Wenn es vorhandene Container für einen Dienst gibt und die Konfiguration oder das Image des Dienstes nach der Erstellung des Containers geändert wurde, holt docker-compose up die Änderungen durch Stoppen und Neuerstellen der Container ab (wobei gemountete Volumes erhalten bleiben). Verwenden Sie die Option --no-recreate, um zu verhindern, dass Compose Änderungen übernimmt.

Auch die Datenverwaltung wird von docker-compose durch gemountete externe "Volumes" (Siehe https://docs.docker.com/compose/compose-file/#volumes) oder Datencontainer abgedeckt.

Dies lässt potenzielle Abwärtskompatibilitäts- und Datenmigrationsprobleme unberührt, aber dies sind "applikative" Probleme, die nicht spezifisch für Docker sind und die gegen Release-Notes und Tests geprüft werden müssen...

30voto

Ich möchte hinzufügen, dass wenn Sie diesen Prozess automatisch durchführen möchten (Download, Stoppen und Neustarten eines neuen Containers mit den gleichen Einstellungen, wie von @Yaroslav beschrieben), WatchTower verwenden können. Ein Programm, das Ihre Container automatisch aktualisiert, wenn sie geändert werden https://github.com/v2tec/watchtower

19voto

Alexandre V. Punkte 373

Betrachten Sie dazu folgende Antworten:

  • Der Name der Datenbank ist app_schema
  • Der Container-Name ist app_db
  • Das Root-Passwort ist root123

Wie man MySQL aktualisiert, wenn Anwendungsdaten im Container gespeichert werden

Dies gilt als schlechte Praxis, denn wenn Sie den Container verlieren, verlieren Sie die Daten. Obwohl es als schlechte Praxis gilt, hier ist eine mögliche Methode, es zu tun:

1) Führen Sie ein Datenbank-Dump als SQL durch:

docker exec app_db sh -c 'exec mysqldump app_schema -uroot -proot123' > database_dump.sql

2) Aktualisieren Sie das Image:

docker pull mysql:5.6

3) Aktualisieren Sie den Container:

docker rm -f app_db
docker run --name app_db --restart unless-stopped \
-e MYSQL_ROOT_PASSWORD=root123 \
-d mysql:5.6

4) Stellen Sie den Datenbank-Dump wieder her:

docker exec app_db sh -c 'exec mysql -uroot -proot123' < database_dump.sql

Wie man den MySQL-Container mit einem externen Volume aktualisiert

Die Verwendung eines externen Volumes ist eine bessere Möglichkeit, Daten zu verwalten, und es erleichtert die Aktualisierung von MySQL. Beim Verlieren des Containers gehen keine Daten verloren. Sie können docker-compose verwenden, um das Verwalten von Multi-Container Docker-Anwendungen auf einem einzelnen Host zu erleichtern:

1) Erstellen Sie die Datei docker-compose.yml, um Ihre Anwendungen zu verwalten:

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) Aktualisieren Sie MySQL (aus dem gleichen Ordner wie die docker-compose.yml Datei):

docker-compose pull
docker-compose up -d

Hinweis: Der letzte oben genannte Befehl wird das MySQL-Image aktualisieren, den Container mit dem neuen Image neu erstellen und starten.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X