Jak radzić sobie z trwałą pamięcią masową (np. bazami danych) w Dockerze

Jak ludzie radzą sobie z trwałym przechowywaniem kontenerów Docker?

Obecnie używam takiego podejścia: zbuduj obraz, np. dla PostgreSQL, a następnie uruchom kontener z

docker run --volumes-from c0dbc34fd631 -d app_name/postgres

IMHO, to ma wadę, że nigdy (przez przypadek) nie mogę usunąć kontenera "c0dbc34fd631".

Innym pomysłem byłoby zamontowanie woluminów hostów "-v " w kontenerze, jednak userid wewnątrz kontenera niekoniecznie pasuje do userid z hosta, a następnie uprawnienia mogą być pomieszane.

Uwaga: zamiast --volumes-from 'cryptic_id' Możesz również użyć --volumes-from my-data-container Gdzie my-data-container jest nazwą przypisaną do kontenera wykorzystującego tylko dane, np. docker run --name my-data-container ... (Zobacz akceptowaną ODPOWIEDŹ)

 857
Author: Peter Mortensen, 2013-08-28

14 answers

Docker 1.9.0 i nowszy

Użyj volume API

docker volume create --name hello
docker run -d -v hello:/container/path/for/volume container_image my_command

Oznacza to, że należy zrezygnować z wzorca kontenerów wykorzystujących tylko dane na rzecz nowych woluminów.

W rzeczywistości volume API jest tylko lepszym sposobem na osiągnięcie tego, co było wzorcem data-container.

Jeśli utworzysz kontener z -v volume_name:/container/fs/path Docker automatycznie utworzy dla Ciebie nazwany wolumin, który może:

  1. być wymienione przez docker volume ls
  2. być identyfikowane poprzez docker volume inspect volume_name
  3. Kopia zapasowa jako zwykły katalog
  4. Kopia zapasowa jak poprzednio przez --volumes-from połączenie

Nowy interfejs API woluminów dodaje przydatne polecenie, które pozwala zidentyfikować wiszące woluminy:

docker volume ls -f dangling=true

A następnie usunąć go poprzez jego nazwę:

docker volume rm <volume name>

Jak podkreśla @mpugach w komentarzach, możesz pozbyć się wszystkich zwisających tomów ładnym jednym linerem:

docker volume rm $(docker volume ls -f dangling=true -q)
# Or using 1.13.x
docker volume prune

Docker 1.8.x i poniżej

Podejście, które wydaje się działać najlepiej dla produkcja polega na użyciu tylko kontenera danych .

Kontener danych jest uruchamiany na obrazie typu barebones i w rzeczywistości nie robi nic poza ujawnieniem woluminu danych.

Wtedy możesz uruchomić dowolny inny kontener, aby mieć dostęp do woluminów kontenerów danych:

docker run --volumes-from data-container some-other-container command-to-execute

W to post na blogu {[15] } jest dobry opis tak zwanego kontenera jako wzorca objętości, który wyjaśnia główny punkt posiadania danych tylko kontenerów.

Dokumentacja Dockera zawiera teraz ostateczny opis kontenera jako wzorzec objętości/objętości.

Poniżej znajduje się procedura tworzenia kopii zapasowych / przywracania dla Dockera 1.8.x i niżej.

BACKUP:

sudo docker run --rm --volumes-from DATA -v $(pwd):/backup busybox tar cvf /backup/backup.tar /data
  • --RM: Usuń kontener, gdy wyjścia
  • --volumes-from DATA: dołącz do woluminów współdzielonych przez kontener danych
  • -V $(pwd):/backup: bind montuje bieżący katalog do kontenera; aby zapisać plik tar do
  • busybox: mały prostszy obraz-dobry do szybkiej konserwacji
  • tar cvf / backup / backup.tar / data: tworzy nieskompresowany plik tar wszystkich plików w katalogu / data

RESTORE:

# Create a new data container
$ sudo docker run -v /data -name DATA2 busybox true
# untar the backup files into the new container᾿s data volume
$ sudo docker run --rm --volumes-from DATA2 -v $(pwd):/backup busybox tar xvf /backup/backup.tar
data/
data/sven.txt
# Compare to the original container
$ sudo docker run --rm --volumes-from DATA -v `pwd`:/backup busybox ls /data
sven.txt

Oto fajny artykuł z doskonałego Brian Goff wyjaśnia, dlaczego dobrze jest używać tego samego obrazu dla kontenera i kontenera danych.

 899
Author: tommasop,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-25 04:47:05

W Docker release v1.0, Wiązanie montowania pliku lub katalogu na komputerze hosta może być wykonane za pomocą podanego polecenia:

$ docker run -v /host:/container ...

Powyższy wolumin może być używany jako trwały magazyn na hoście z uruchomionym Dockerem.

 60
Author: amitmula,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-25 04:50:45

Od wersji Docker Compose 1.6 poprawiono obsługę woluminów danych w Docker Compose. Poniższy plik utworzy obraz danych, który będzie trwał pomiędzy ponownym uruchomieniem (a nawet usunięciem) kontenerów nadrzędnych:

Oto zapowiedź bloga: Compose 1.6: nowy plik Compose do definiowania sieci i woluminów

Oto przykładowy plik:

version: "2"

services:
  db:
    restart: on-failure:10
    image: postgres:9.4
    volumes:
      - "db-data:/var/lib/postgresql/data"
  web:
    restart: on-failure:10
    build: .
    command: gunicorn mypythonapp.wsgi:application -b :8000 --reload
    volumes:
      - .:/code
    ports:
      - "8000:8000"
    links:
      - db

volumes:
  db-data:

Z tego co rozumiem: spowoduje to utworzenie kontenera objętości danych (db_data) który będzie trwał między restartami.

Jeśli uruchomisz: docker volume ls powinieneś zobaczyć swój wolumin na liście:

local               mypthonapp_db-data
...

Możesz uzyskać więcej szczegółów na temat objętości danych:

docker volume inspect mypthonapp_db-data
[
  {
    "Name": "mypthonapp_db-data",
    "Driver": "local",
    "Mountpoint": "/mnt/sda1/var/lib/docker/volumes/mypthonapp_db-data/_data"
  }
]

Niektóre testy:

# Start the containers
docker-compose up -d

# .. input some data into the database
docker-compose run --rm web python manage.py migrate
docker-compose run --rm web python manage.py createsuperuser
...

# Stop and remove the containers:
docker-compose stop
docker-compose rm -f

# Start it back up again
docker-compose up -d

# Verify the data is still there
...
(it is)

# Stop and remove with the -v (volumes) tag:

docker-compose stop
docker=compose rm -f -v

# Up again ..
docker-compose up -d

# Check the data is still there:
...
(it is).

Uwagi:

  • Możesz również określić różne sterowniki w bloku volumes. Na przykład, możesz określić sterownik Flocker dla db_data:

    volumes:
      db-data:
        driver: flocker
    
  • ponieważ poprawiają integrację pomiędzy Docker Swarm i Docker Compose (i ewentualnie zacznij integrować Flockera z ekosystemem Dockera (słyszałem plotkę, że Docker kupił Flockera), myślę, że takie podejście powinno stać się coraz potężniejsze.

Zastrzeżenie: to podejście jest obiecujące i z powodzeniem używam go w środowisku programistycznym. Z obawą wykorzystam to jeszcze w produkcji!

 25
Author: toast38coza,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-25 16:09:15

W przypadku, gdy nie jest to jasne z aktualizacji 5 wybranej odpowiedzi, począwszy od Dockera 1.9, można tworzyć woluminy, które mogą istnieć bez powiązania z konkretnym kontenerem, przez co wzorzec "kontener tylko dla danych" staje się przestarzały.

Zobacz kontenery tylko dla danych przestarzałe z docker 1.9.0? #17798.

Myślę, że opiekunowie Dockera zdali sobie sprawę, że wzorce kontenerów wykorzystujących tylko dane to zapach projektu i zdecydowali, że woluminy będą osobną jednostką, która może istnieć bez powiązanego pojemnika.

 15
Author: ben_frankly,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-25 16:03:21

Chociaż jest to część Dockera , która wymaga trochę pracy, powinieneś umieścić wolumin w pliku Dockerfile z instrukcją VOLUME, więc nie musisz kopiować woluminów z innego kontenera.

To sprawi, że Twoje kontenery będą mniej zależne od siebie i nie musisz się martwić o usunięcie jednego kontenera wpływającego na drugi.

 12
Author: Tim Dorr,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-25 04:48:06

Podczas korzystania z Docker Compose, po prostu dołącz nazwany wolumin, na przykład,

version: '2'
services:
  db:
    image: mysql:5.6
    volumes:
      - db_data:/var/lib/mysql:rw
    environment:
      MYSQL_ROOT_PASSWORD: root
volumes:
  db_data:
 9
Author: Czar Pino,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-25 16:17:12

@tommasop ' s answer is good, and explains some of the mechanics of using data-only containers. Ale jako ktoś, kto początkowo myślał, że kontenery danych były głupie, gdy można po prostu powiązać mount a volume z hostem( jak sugerowało kilka innych odpowiedzi), ale teraz zdaje sobie sprawę, że w rzeczywistości kontenery tylko danych są całkiem zgrabne, mogę zaproponować mój własny post na blogu w tym temacie: Dlaczego Docker Data Containers (Volumes!) są dobre

Zobacz też: moja odpowiedź na pytanie " jaki jest (najlepszy) sposób zarządzania uprawnieniami do współdzielonych woluminów Dockera? " na przykład, jak używać kontenerów danych, aby uniknąć problemów, takich jak uprawnienia i mapowanie uid/gid z hostem.

W celu rozwiązania jednego z pierwotnych obaw OP: że kontener danych nie może zostać usunięty. Nawet jeśli kontener danych zostanie usunięty, same dane nie zostaną utracone tak długo, jak każdy kontener ma odniesienie do tego woluminu, tj. każdy kontener, który zamontował wolumin za pomocą --volumes-from. Więc o ile wszystkie powiązane kontenery nie zostaną zatrzymane i usunięte (można uznać to za odpowiednik przypadkowego rm -fr /), Dane są bezpieczne. Kontener danych można zawsze odtworzyć, wykonując --volumes-from dowolny kontener, który ma odniesienie do tego woluminu.

Jak zawsze, zrób kopie zapasowe!

Aktualizacja: Docker ma teraz woluminy, którymi można zarządzać niezależnie od kontenerów, co dodatkowo ułatwia zarządzanie.

 8
Author: Raman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-25 04:59:56

Jeśli chcesz przenieść swoje tomy wokół powinieneś również spojrzeć na Flocker.

Z README:

Flocker to menedżer wolumenów danych i narzędzie do zarządzania klastrami Docker dla wielu hostów. Dzięki niemu możesz kontrolować swoje dane za pomocą tych samych narzędzi, których używasz w swoich bezpaństwowych aplikacjach, wykorzystując moc ZFS na Linuksie.

Oznacza to, że możesz uruchamiać swoje bazy danych, kolejki i magazyny wartości kluczy w Dockerze i przenosić je tak łatwo, jak reszta podania.

 7
Author: Johann Romefort,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-25 15:50:08

Istnieje kilka poziomów zarządzania trwałymi danymi, w zależności od potrzeb:

  • przechowuj go na swoim komputerze
    • użyj znacznika -v host-path:container-path, aby zapisać dane katalogu kontenera do katalogu hosta.
    • Tworzenie kopii zapasowych/przywracanie odbywa się poprzez uruchomienie kontenera kopii zapasowych/przywracania (takiego jak tutumcloud/dockup) zamontowanego w tym samym katalogu.
  • Utwórz kontener danych i zamontuj jego woluminy do kontenera aplikacji
    • Tworzenie kontenera aby eksportować wolumin danych, użyj --volumes-from, Aby zamontować te dane w kontenerze aplikacji.
    • Kopia zapasowa / Przywracanie tak samo jak w powyższym rozwiązaniu.
  • użyj wtyczki Docker volume, która wspiera zewnętrzną / zewnętrzną usługę
      Wtyczki Docker volume umożliwiają dostęp do twojego źródła danych z dowolnego miejsca - NFS, AWS (S3, EFS i EBS).]}
    • w zależności od wtyczki/usługi, można dołączyć jeden lub wiele kontenerów do jednego woluminu.
    • w zależności od usługa, kopie zapasowe / przywracania mogą być zautomatyzowane dla Ciebie.
    • chociaż ręczne wykonywanie tego zadania może być kłopotliwe, niektóre rozwiązania orkiestracyjne - takie jak Rancher - mają to upieczone i proste w użyciu.
    • konwój jest najprostszym rozwiązaniem do zrobienia tego ręcznie.
 5
Author: Will Stern,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-25 16:19:52

To zależy od Twojego scenariusza (to nie jest odpowiednie dla środowiska produkcyjnego), ale tutaj jest jeden sposób:

Tworzenie kontenera MySQL Docker

Chodzi o to, aby użyć katalogu na Twoim hoście do przechowywania danych.

 4
Author: ben schwartz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-25 04:49:46

Ostatnio pisałem o potencjalnym rozwiązaniu i aplikacji demonstrującej technikę. Uważam, że jest dość wydajny podczas opracowywania i produkcji. Mam nadzieję, że to pomoże lub pobudzi jakieś pomysły.

Repo: https://github.com/LevInteractive/docker-nodejs-example
Artykuł: http://lev-interactive.com/2015/03/30/docker-load-balanced-mongodb-persistence/

 2
Author: slth,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-04-02 12:29:18

Używam predefiniowanego katalogu na hoście do zapisywania danych dla PostgreSQL. Również w ten sposób można łatwo przenieść istniejące instalacje PostgreSQL do kontenerów Docker: https://crondev.com/persistent-postgresql-inside-docker/

 1
Author: Alen Komljen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-25 16:04:25

Moim rozwiązaniem jest użycie nowego docker cp, który jest teraz w stanie kopiować dane z kontenerów, bez względu na to, czy jest uruchomiony, czy nie i udostępniać wolumin hosta do dokładnie tego samego miejsca, w którym aplikacja bazodanowa tworzy pliki bazy danych wewnątrz kontenera. To podwójne rozwiązanie działa bez kontenera wykorzystującego tylko dane, prosto z oryginalnego kontenera bazy danych.

Więc mój skrypt init systemd bierze zadanie tworzenia kopii zapasowej bazy danych do archiwum na hoście. Umieściłem znacznik czasu w nazwie pliku, aby nigdy nie przepisać pliku.

Robi to na ExecStartPre:

ExecStartPre=-/usr/bin/docker cp lanti-debian-mariadb:/var/lib/mysql /home/core/sql
ExecStartPre=-/bin/bash -c '/usr/bin/tar -zcvf /home/core/sql/sqlbackup_$$(date +%%Y-%%m-%%d_%%H-%%M-%%S)_ExecStartPre.tar.gz /home/core/sql/mysql --remove-files'

I robi to samo na ExecStopPost też:

ExecStopPost=-/usr/bin/docker cp lanti-debian-mariadb:/var/lib/mysql /home/core/sql
ExecStopPost=-/bin/bash -c 'tar -zcvf /home/core/sql/sqlbackup_$$(date +%%Y-%%m-%%d_%%H-%%M-%%S)_ExecStopPost.tar.gz /home/core/sql/mysql --remove-files'

Plus wystawiłem folder z hosta jako wolumin do dokładnie tego samego miejsca, w którym przechowywana jest baza danych:

mariadb:
  build: ./mariadb
  volumes:
    - $HOME/server/mysql/:/var/lib/mysql/:rw

To działa świetnie na mojej maszynie wirtualnej (buduję stos LEMP dla siebie): https://github.com/DJviolin/LEMP

Ale nie wiem, czy jest to" kuloodporne " rozwiązanie, gdy twoje życie zależy od tego w rzeczywistości (na przykład sklep internetowy z transakcjami w dowolnych możliwych milisekundach)?

W 20 min 20 sek od tego oficjalnego filmu keynote Dockera, prezenter robi to samo z bazą danych:

pierwsze kroki z Dockerem

"dla bazy danych mamy wolumin, więc możemy się upewnić, że gdy baza danych idzie w górę iw dół, nie tracimy danych, gdy kontener bazy danych zatrzymał się."

 0
Author: Lanti,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-25 15:56:46

Użyj twierdzenia o stałej objętości (PVC) z usługi Kubernetes, która jest narzędziem do zarządzania kontenerami Docker i planowania:

Trwałe Wolumeny

Zalety korzystania z Kubernetes w tym celu są następujące:

  • Możesz używać dowolnej pamięci masowej, takiej jak NFS lub inna pamięć masowa, a nawet gdy węzeł jest wyłączony, pamięć masowa nie musi być.
  • ponadto dane w takich woluminach można skonfigurować tak, aby były przechowywane nawet po zniszczeniu samego kontenera - tak że może być odzyskany, w razie potrzeby, przez inny pojemnik.
 0
Author: Santanu Dey,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-25 16:12:07