Docker'da kalıcı depolama (örn. Veritabanları) ile nasıl başa çıkılır?


992

Kişiler Docker kaplarınız için kalıcı depolama ile nasıl başa çıkıyor?

Şu anda bu yaklaşımı kullanıyorum: örneğin PostgreSQL için görüntü oluşturmak ve sonra kapsayıcı ile

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

Dezavantajı olan IMHO, ben (yanlışlıkla) "c0dbc34fd631" kapsayıcısını silmemeliyim.

Başka bir fikir kabın içine konak hacimleri "-v" monte etmek olurdu, ancak, kimliği kapsayıcı içindeki ille uymuyor kimliği ana bilgisayardan ve ardından izinleri berbat olabilir.

Not: Bunun yerine, yalnızca veri içeren bir kapsayıcıya atadığınız bir adın nerede olduğunu --volumes-from 'cryptic_id'da kullanabilirsiniz , örneğin (kabul edilen yanıta bakın)--volumes-from my-data-containermy-data-containerdocker run --name my-data-container ...


Üzgünüm, yanlış bir şekilde ifade ettim, demek istediğim: bu görüntüden gelecekteki tüm örneklerim bu kaba bağlı. Bu konteyneri yanlışlıkla silersem başım belada.
juwalter

@AntonStrogonoff - evet, ifade hatası - Demek istediğim: O (muhtemelen) eski kapsayıcıyı hiç silmeyeceğimden emin olmalıyım, çünkü o zaman "kalıcı" depolama referansı da gider
juwalter

olmalı --name. Sahip-name
Shammel Lee

Yanıtlar:


986

Docker 1.9.0 ve üstü

Birim API'sını kullan

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

Bu, yalnızca veri içeren kap modelinin yeni birimler lehine terk edilmesi gerektiği anlamına gelir.

Aslında birim API, veri taşıyıcı modelini elde etmenin daha iyi bir yoludur.

-v volume_name:/container/fs/pathDocker ile bir kap oluşturursanız, sizin için otomatik olarak adlandırılmış bir birim oluşturur:

  1. Aracılığıyla listelenecek docker volume ls
  2. İle tanımlanmalı docker volume inspect volume_name
  3. Normal bir dizin olarak yedeklendi
  4. Bir --volumes-frombağlantı üzerinden eskisi gibi yedeklendi

Yeni birim API'si, sarkan hacimleri belirlemenizi sağlayan kullanışlı bir komut ekler:

docker volume ls -f dangling=true

Ve ardından adıyla kaldırın:

docker volume rm <volume name>

@Mpugach yorumlarda altını çizdiği gibi, tüm sarkan hacimlerden hoş bir tek astarla kurtulabilirsiniz:

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

Docker 1.8.x ve altı

Üretim için en iyi sonuç veren yaklaşım, yalnızca veri içeren bir kap kullanmaktır .

Yalnızca veri kapsayıcısı bir barebone görüntüsünde çalıştırılır ve gerçekte bir veri hacmini göstermekten başka bir şey yapmaz.

Ardından veri kabı hacimlerine erişmek için başka bir kapsayıcı çalıştırabilirsiniz:

docker run --volumes-from data-container some-other-container command-to-execute
  • Burada farklı kapların nasıl düzenleneceğine dair iyi bir resim elde edebilirsiniz.
  • Burada hacimlerin nasıl çalıştığına dair iyi bir fikir var.

Olarak bu blog yazı olarak adlandırılan iyi bir açıklama yoktur birim desen olarak kabın sahip ana nokta açıklık verileri sadece konteyner .

Docker dokümantasyonunda, artık kabın hacim / s örüntüsü olarak TANIMLI açıklaması bulunmaktadır .

Docker 1.8.x ve altı için yedekleme / geri yükleme prosedürü aşağıdadır.

DESTEK OLMAK:

sudo docker run --rm --volumes-from DATA -v $(pwd):/backup busybox tar cvf /backup/backup.tar /data
  • --rm: kap çıkarken çıkarın
  • --volumes-from DATA: DATA kabı tarafından paylaşılan birimlere ekleyin
  • -v $ (pwd): / backup: geçerli dizini konteynere bağla; tar dosyasını
  • busybox: küçük ve basit bir görüntü - hızlı bakım için iyi
  • tar cvf /backup/backup.tar / data: / data dizinindeki tüm dosyaların sıkıştırılmamış bir tar dosyasını oluşturur

ONARMAK:

# 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

İşte mükemmel Brian Goff'un aynı görüntüyü bir kapsayıcı ve veri kapsayıcısı için neden kullanmanın iyi olduğunu açıklayan güzel bir makale .


8
Farklı bir ihtiyaç için farklı bir araçtır. --volumes-fromdisk alanı --linkpaylaşmanıza izin hizmetleri paylaşmanıza izin verin.
tommasop

3
Çalışmalarda özellikle bu tür bir şey için tasarlanmış başka bir proje var, belki de bu cevaba izlemek için bir referans olarak ekleyin? github.com/ClusterHQ/flocker
Andre

9
Veri kaplarının hiçbir anlamı yoktur ve gerçekten kötü bir fikirdir! Kapsayıcı, yalnızca bir işlem bu işlem yapılırken bir şey ifade eder, aksi takdirde yalnızca bir ana bilgisayar dosya sisteminin parçasıdır. Sadece ve en iyi seçenek olan -v ile bir birim bağlayabilirsiniz. Kullandığınız dosya sistemi ve fiziksel disk üzerinde denetiminiz vardır.
Boynux

11
Evet, Docker 1.9'dan itibaren, docker volume create --name mydataVeri Hacmi Kapsayıcısı üzerinde birimler API ( ) ile Adlandırılmış Birimler oluşturmak tercih edilir. Docker'daki kişiler, Veri Hacmi Konteynerlerinin “ artık önerilen bir model olarak kabul edilmediğini ”, “ adlandırılan hacimlerin çoğu (hepsi değilse de) vakalarda yalnızca veri hacimlerinin yerini alabilmesi gerektiğini ” ve “kullanmak için hiçbir neden göremiyorum yalnızca veri içeren kapsayıcılar . ”
Quinn Komutanı

8
@coding, üzgün olduğun için üzgünüm, kısmen cevapları 3 yıllık bir gecikmeyle değerlendiriyorsun, kısmen de cevap tüm tarihinde doğru. Herhangi bir tavsiyeniz varsa, cevabı entegre edebilmem ve insanların üzgün olmamasına yardımcı olabilmem için yorum yapmaktan çekinmeyin
tommasop

75

In Docker sürüm 1.0 a , belirli bir komutla yapılabilir ana makinede bir dosyanın veya dizinin monte bağlayıcı:

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

Yukarıdaki birim Docker çalıştıran ana bilgisayarda kalıcı bir depolama alanı olarak kullanılabilir.


3
Şu anda daha fazla oy alan hacim konteyneri yaklaşımından çok daha az karmaşık olduğu için bu önerilen cevap olmalıdır
insitusec

2
Keşke bu birim bağlama komutunu kullanırken bir host-uid: container-uid ve host-gid: container-gid eşlemesi belirtmek için bir bayrak olsaydı.
rampion

35

Docker Compose 1.6'dan itibaren, Docker Compose'daki veri hacimleri için geliştirilmiş destek var. Aşağıdaki oluşturma dosyası, üst kapların yeniden başlatılması (hatta kaldırılması) arasında devam edecek bir veri görüntüsü oluşturur:

İşte blog duyurusu: Oluştur 1.6: Ağları ve birimleri tanımlamak için yeni Oluştur dosyası

Bir örnek oluşturma dosyası:

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:

Anlayabildiğim kadarıyla: Bu db_datayeniden başlatmalar arasında devam edecek bir veri hacmi konteyner ( ) oluşturur.

Eğer koşarsanız: docker volume lshacminizin listelendiğini görmelisiniz:

local               mypthonapp_db-data
...

Veri hacmi hakkında daha fazla bilgi edinebilirsiniz:

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

Bazı testler:

# 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).

Notlar:

  • Ayrıca volumesblokta çeşitli sürücüler belirtebilirsiniz . Örneğin, db_data için Flocker sürücüsünü belirtebilirsiniz:

    volumes:
      db-data:
        driver: flocker
    
  • Docker Swarm ve Docker Compose arasındaki entegrasyonu geliştirdikçe (ve Flocker'ı Docker eko sistemine entegre etmeye başladığında (Docker'ın Flocker'ı satın aldığını söylediklerini duydum), bu yaklaşımın giderek daha güçlü hale gelmesi gerektiğini düşünüyorum.

Yasal Uyarı: Bu yaklaşım umut vericidir ve bunu bir geliştirme ortamında başarıyla kullanıyorum. Bunu henüz üretimde kullanmak endişeliydim!



17

Seçilen yanıtın 5. güncellemesinden anlaşılamaması durumunda, Docker 1.9'dan itibaren, belirli bir kapla ilişkilendirilmeden var olabilecek birimler oluşturabilir ve böylece "salt veri taşıyıcısı" kalıbını geçersiz kılabilirsiniz.

Bkz. Yalnızca veri taşıyıcıları docker 1.9.0 ile kullanılmıyor mu? # 17798 .

Docker çalışanları sadece veri içeren kap modelinin bir tasarım kokusu olduğunu fark ettiler ve hacimleri ilişkili bir kap olmadan var olabilecek ayrı bir varlık yapmaya karar verdiler.


13

Bu, Docker'ın hala biraz çalışma gerektiren bir parçası olmasına rağmen , birimi VOLUME talimatıyla Dockerfile'a koymalısınız gerekir, böylece birimleri başka bir kaptan kopyalamanız gerekmez.

Bu, konteynırlarınızı daha az bağımlı hale getirecektir ve bir konteynerin diğerini etkileyen silinmesi konusunda endişelenmenize gerek yoktur.


Flip-side argümanı, "yalnızca veri" kapsayıcılarının veri hacmine son çare referansı haline docker rm
gelmesidir

2
Docker'ın bu resmi kılavuzu aksini önermektedir: Docker'ın docs.docker.com/userguide/dockervolumes/… "Veri hacimleri, kabın yaşam döngüsünden bağımsız olarak verileri kalıcı tutmak üzere tasarlanmıştır. Bu nedenle Docker, bir konteyneri kaldırdığınızda birimleri asla otomatik olarak silmeyecektir. Artık bir kap tarafından başvurulan "çöp toplama" birimleri. "
Alex

12

Docker Compose kullanırken , adlandırılmış bir birim eklemeniz yeterlidir, örneğin:

version: '2'
services:
  db:
    image: mysql:5.6
    volumes:
      - db_data:/var/lib/mysql:rw
    environment:
      MYSQL_ROOT_PASSWORD: root
volumes:
  db_data:

9

@ tommasop'un yanıtı iyidir ve yalnızca veri içeren kapları kullanmanın bazı tekniklerini açıklar. Ancak, başlangıçta bir kapsayıcıyı bir ana bilgisayara bağlayabildiğinde (diğer yanıtların önerdiği gibi) veri kapsayıcılarının aptal olduğunu düşündüğü gibi, ancak şimdi aslında sadece veri içeren kapların oldukça düzgün olduğunu fark ettim. bu konuda blog yazısı: Docker Veri Kapları (Ciltler!) Neden İyi

Ayrıca bakınız: cevabım soruya " Docker hacimleri paylaştı izinlerini yönetmek için (en iyi) yolu nedir? " ev sahibi ile izinler ve uid / gid haritalama gibi sorunlardan kaçınmak için veri konteynerleri nasıl kullanılacağına ilişkin bir örnek için.

OP'nin asıl endişelerinden birini ele almak için: veri taşıyıcısının silinmemesi gerekir. Veri kabı silinmiş olsa bile, herhangi bir kap bu birime, yani birimi bağlayan herhangi bir kaba başvurduğu sürece, verilerin kendisi kaybolmaz --volumes-from. Bu nedenle, ilgili tüm kaplar durdurulup silinmedikçe (bunu bir kazayla eşdeğer olarak düşünebiliriz rm -fr /) veriler güvenlidir. Bu --volumes-frombirime referansı olan herhangi bir kapsayıcı oluşturarak veri kapsayıcısını her zaman yeniden oluşturabilirsiniz .

Her zaman olduğu gibi yedekler alın!

GÜNCELLEME: Docker artık konteynırlardan bağımsız olarak yönetilebilen birimlere sahip, bu da daha kolay yönetilmesini sağlıyor.


9

İhtiyaçlarınıza bağlı olarak kalıcı verileri yönetmenin birkaç düzeyi vardır:

  • Ana makinenizde saklayın
    • -v host-path:container-pathKapsayıcı dizini verilerini bir ana bilgisayar dizininde saklamak için bayrağı kullanın .
    • Yedeklemeler / geri yüklemeler, aynı dizine monte edilmiş bir yedekleme / geri yükleme kapsayıcısı (tutumcloud / dockup gibi) çalıştırılarak gerçekleşir.
  • Bir veri kabı oluşturun ve birimlerini uygulama kabınıza bağlayın
    • Veri hacmini dışa aktaran bir kap oluşturun, kullanın --volumes-from bu verileri uygulama kabınıza bağlamak için .
    • Yukarıdaki çözümle aynı yedekleme / geri yükleme.
  • Harici / üçüncü taraf bir hizmeti destekleyen bir Docker birim eklentisi kullanın
    • Docker birim eklentileri, veri kaynağınızın her yerden gelmesini sağlar - NFS, AWS (S3, EFS ve EBS)
    • Eklentiye / hizmete bağlı olarak, tek bir birime tek veya birden çok kap ekleyebilirsiniz.
    • Servise bağlı olarak, yedeklemeler / geri yüklemeler sizin için otomatikleştirilebilir.
    • Bu manuel olarak yapmak zor olsa da, Rancher gibi bazı düzenleme çözümleri fırında pişirilmiş ve kullanımı basittir.
    • Konvoy bunu manuel olarak yapmak için en kolay çözümdür.

8

Birimlerinizi hareket ettirmek istiyorsanız Flocker'a da bakmalısınız .

README'den:

Flocker bir veri birimi yöneticisi ve çok ana bilgisayarlı Docker küme yönetim aracıdır. Bununla, Linux'ta ZFS'nin gücünü kullanarak vatansız uygulamalarınız için kullandığınız araçları kullanarak verilerinizi kontrol edebilirsiniz.

Bu, veritabanlarınızı, kuyruklarınızı ve anahtar / değer depolarınızı Docker'da çalıştırabileceğiniz ve uygulamanızın geri kalanıyla kolayca taşıyabileceğiniz anlamına gelir.


1
Teşekkürler Johann. ClusterHQ'da çalışıyorum ve sadece ZFS tabanlı depolamanın ötesine geçtiğimizi belirtmek istedim. Artık Flocker'ı Amazon EBS veya Google Persistent Disk gibi bir depolama birimiyle kullanabilirsiniz. Depolama seçeneklerinin tam listesi: docs.clusterhq.com/en/latest/supported/…
ferrantim

1
Flocker durduruldu ve kullanılmamalıdır portworx.com/…
jesugmz

5

Senaryonuza bağlıdır (bu bir üretim ortamı için gerçekten uygun değildir), ancak işte bir yol:

MySQL Docker Kapsayıcısı Oluşturma

Bu özeti, veri kalıcılığı için ana makinenizdeki bir dizini kullanmaktır.


6
Teşekkürler Ben, ancak - bu yaklaşımla görebildiğim sorunlardan biri: dosya sistemi kaynağı (dizin, dosyalar) docker / lxc kapsayıcısı (misafir) içindeki bir uid'e ait olabilir - muhtemelen bir uid ile çarpışabilir ev sahibi ...
juwalter

1
Ben kök tarafından çalıştırılır gibi oldukça güvenli olduğunu düşünüyorum, ama en iyi yerel dev / geçici entegrasyon testi için uygun bir kesmek olduğunu kabul ediyorum. Bu kesinlikle daha fazla desen / düşünce ortaya çıkmasını görmek istediğim bir alandır. Bu soruya docker-dev google grubuna bakmalısın / göndermelisin
ben schwartz

Ben, bu çözüm için teşekkürler! Buna bir kesmek demezdim, hacim olarak konteynerden çok daha güvenilir görünüyor . Verilerin yalnızca kaptan kullanılması durumunda herhangi bir dezavantaj görüyor musunuz? (UID bu durumda önemli değil)
johndodo



0

Benim çözümüm, yeni docker cp artık çalışıp çalışmadığına bakılmaksızın, verileri kapsayıcılardan kopyalayabilen olanı ve bir ana bilgisayar birimini veritabanı uygulamasının kapsayıcı içindeki veritabanı dosyalarını oluşturduğu konumla paylaşmaktır. . Bu çift çözüm, doğrudan orijinal veritabanı kapsayıcısından yalnızca veri kapsayıcısı olmadan çalışır.

Bu yüzden benim sistemd init betiğim, veritabanını ana bilgisayardaki bir arşive yedekleme görevini üstleniyor. Dosya adını hiçbir zaman yeniden yazmamak için zaman damgası yerleştirdim.

ExecStartPre üzerinde yapıyor:

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'

Ve aynı şeyi ExecStopPost'ta da yapıyor:

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'

Ayrıca ana bilgisayardan bir birim olarak veritabanının depolandığı tam olarak aynı konuma maruz bıraktım:

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

VM'imde harika çalışıyor (kendim için bir LEMP yığını oluşturuyorum): https://github.com/DJviolin/LEMP

Ama hayatınız gerçekten buna bağlı olduğunda "kurşun geçirmez" bir çözüm olup olmadığını bilmiyorum (örneğin, herhangi bir milisaniyede işlemlerle web mağazası)?

Bu resmi Docker açılış videosundan 20 dakika 20 saniye sonra sunum yapan kişi veritabanıyla aynı şeyi yapar:

Docker'ı Kullanmaya Başlama

"Veritabanı için bir birimimiz var, bu yüzden veritabanı yukarı ve aşağı gittikçe, veritabanı kapsayıcısı durduğunda verileri kaybetmediğimizden emin olabiliriz."


Ne demek istiyorsun "... faydalan ..." ? Ve "... olası milisaniyelerdeki işlemler" ?
Peter Mortensen

0

Docker konteyner yönetimi ve zamanlama aracı olan Kubernetes'ten Kalıcı Hacim Talebi (PVC) kullanın:

Kalıcı Hacimler

Bu amaçla Kubernetes kullanmanın avantajları:

  • NFS veya başka bir depolama alanı gibi herhangi bir depolama alanı kullanabilirsiniz ve düğüm kapalı olsa bile depolama biriminin depolanmasına gerek yoktur.
  • Ayrıca, bu tür birimlerdeki veriler, kabın kendisi yok edildikten sonra bile saklanacak şekilde yapılandırılabilir - böylece gerekirse başka bir kap tarafından geri alınabilir.
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.