Konteyner çıktığında verilerimi kaybediyorum


394

Docker'ın Etkileşimli eğitimine ve SSS'ye rağmen , konteyner çıktığında verilerimi kaybediyorum.

Docker'ı burada açıklandığı gibi yükledim: http://docs.docker.io/en/latest/installation/ubuntulinux ubuntu 13.04 ile ilgili herhangi bir sorun yaşamadan.

Ancak çıkışta tüm verileri kaybeder.

iman@test:~$ sudo docker version
Client version: 0.6.4 
Go version (client): go1.1.2 
Git commit (client): 2f74b1c 
Server version: 0.6.4 
Git commit (server): 2f74b1c 
Go version (server): go1.1.2 
Last stable version: 0.6.4 


iman@test:~$ sudo docker run ubuntu ping
2013/10/25 08:05:47 Unable to locate ping 
iman@test:~$ sudo docker run ubuntu apt-get install ping
Reading package lists... 
Building dependency tree... 
The following NEW packages will be installed: 
  iputils-ping 
0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded. 
Need to get 56.1 kB of archives. 
After this operation, 143 kB of additional disk space will be used. 
Get:1 http://archive.ubuntu.com/ubuntu/ precise/main iputils-ping amd64 3:20101006-1ubuntu1 [56.1 kB] 
debconf: delaying package configuration, since apt-utils is not installed 
Fetched 56.1 kB in 0s (195 kB/s) 
Selecting previously unselected package iputils-ping. 
(Reading database ... 7545 files and directories currently installed.) 
Unpacking iputils-ping (from .../iputils-ping_3%3a20101006-1ubuntu1_amd64.deb) ... 
Setting up iputils-ping (3:20101006-1ubuntu1) ... 
iman@test:~$ sudo docker run ubuntu ping
2013/10/25 08:06:11 Unable to locate ping 
iman@test:~$ sudo docker run ubuntu touch /home/test
iman@test:~$ sudo docker run ubuntu ls /home/test
ls: cannot access /home/test: No such file or directory 

Ayrıca aynı sonuçla etkileşimli oturumlarla test ettim. Bir şey unuttum mu?

DÜZENLEME: YENİ DOCKER KULLANICILARI İÇİN ÖNEMLİ

@ Mohammed-noureldin ve diğerlerinin söylediği gibi, aslında bu bir kap DEĞİLDİR . Her seferinde yeni bir kap oluşturur.


10
Bu " kapsayıcı çıkma " olarak adlandırılamaz , sadece yeni bir kapsayıcı oluşturuyorsunuz, çıkış sözcüğü kullanmak çok kafa karıştırıcı olabilir (bu yüzden kafam karıştı).
Mohammed Noureldin

1
@MohammedNoureldin, haklısın, çıkmak doğru değil, ama tam olarak sen, ben ve başkalarının düşündükleri bu. Yani söz konusu daha iyi bir kelime, düzenlemeniz soruya cevap veriyor! Yeni arayıcılar burada bulamayacak!
iman

Docker ile başlangıç ​​noktamda, aslında SİZİN sorunuzdan dolayı, bu adresin YANLIŞ olduğunu düşünüyorum. Yeni başlık incelendi ve kabul edildi, bazıları neden yanlış bir başlıkta ısrar ederse, sizin sorunuz ve kararınız olduğunu anlamıyorum.
Mohammed Noureldin

3
@MohammedNoureldin ile hemfikirim. Belirli bir başlık, örnek ve kabul edilen cevabın kombinasyonu gelecekteki okuyucuların ve özellikle yeni başlayanların anlamalarına yardımcı olmaz Docker. Yeni başlayanlar kesinlikle böyle bir şey arayacağından, başlığı ve orijinal soruyu saklamayı öneriyorum. Ancak, yazıyı yazarken neden yanlış düşüncelerinizi açıklayan bir şey eklemiyorsunuz? Her şeyi netleştirmeye yardımcı olacaktır. Bu bizim SO'daki kültürümüz ... değil mi? :-)
tgogos

2
Ben bu sorun vardı ... u her zaman u çalıştırmak konteyner çalıştırmak zorunda değilsiniz ... bir görüntü agane çalıştırmak yeni bir kapsayıcı bu docker başlatmak yardımcı olacaktır <konteyner id> docker eklemek <konteyner id>
fatemeh

Yanıtlar:


399

Sen gerek işlemek Eğer konteyner yaptığınız değişiklikleri ve çalıştırın. Bunu dene:

sudo docker pull ubuntu

sudo docker run ubuntu apt-get install -y ping

Ardından bu komutu kullanarak kapsayıcı kimliğini alın:

sudo docker ps -l

Kapsayıcıda değişiklik yapın:

sudo docker commit <container_id> iman/ping 

Ardından kapsayıcıyı çalıştırın:

sudo docker run iman/ping ping www.google.com

Bu çalışmalı.


9
Bu yüzden verileri korumak için her çalıştırmadan sonra kesinliği kullanmalıyım .
iman

5
Taahhüt, yalnızca kapta DEĞİŞİKLİKLER yaptığınızda (yeni araçlar veya veriler yüklemek gibi) kullanılmalıdır, böylece bu değişiklikler kaydedilir ve bir dahaki sefere yeni bir kapsayıcı çalıştırdığınızda, son kaydetme veya taahhüt, verilerinizi koruyarak.
Unferth

7
@ Değişiklik yapmaya devam etmek istersem ne olur? Şimdiye kadar ile daha fazla görüntü oluşturuyor <none>. Varolan bir görüntünün üstündeki taahhüdü nasıl eklerim?
Marconi

62
Art arda değişiklikler yapmak "docker yolu" değildir. Bir DOCKERFILE kullanın.
user2105103

23
Konteynerin içinden nasıl taahhüt ederdin? Şu senaryoyu inceleyin: 1) Kapsayıcıyı şu şekilde çalıştırıyorum: docker run -i -t myimage / bin / bash 2) Bazı değişiklikler yapıyorum 3) Kapsayıcıdan işlem yapamıyorum, bu yüzden kaptan çıktığımda, önceki değişiklikleri işleme şansım olmadan tüm verilerimi
kaybedecek

374

Bir docker runkapsayıcı başlatmak için kullandığınızda , belirttiğiniz görüntüye dayalı olarak yeni bir kap oluşturur .

Buradaki diğer yararlı yanıtların yanı sıra, mevcut bir kapsayıcıdan çıktıktan sonra yeniden başlatabileceğinizi ve değişikliklerinizin hala orada olduğunu unutmayın.

docker start f357e2faab77 # restart it in the background
docker attach f357e2faab77 # reattach the terminal & stdin

88
docker psyalnızca docker kaplarını çalıştırdığınızı gösterir. docker ps -aayrıca çıkış yapmış olanları ve koşmaya devam edebileceğinizi gösterir. Bir taahhüt ancak her kullanımdan sonra ileride kullanmak üzere bir enstantane yapmak istiyorsanız gereklidir, aksi takdirde konteynerin kendisi kullanmaya devam etmeniz için yapışır.
user1278519

2
Soru lütfen, bu yüzden bir jenkinssunucu docker indirmek ve ben CI ana bilgisayarımda çalıştırmak ve ben bazı işler çalışır ve sonuç olarak jenkins sunucusu bazı günlükleri diske yazar. şimdi sunucum (docker'ımı barındıran) yeniden başlatılırsa ve yeniden başlarsam jenkins docker'ım tüm günlük dosyalarını kaybettiğim anlamına mı gelir? eğer öyleyse jenkins, örneğin CI'deki jenkins kurulumumu kolaylaştırmak için docker'ı nasıl kullanabilirim ?
Jas

2
@Jas Aynı kaba yapışır ve yenilerini oluşturmazsanız, sorun olmaz. Docker'ın bugünlerde yeniden başlatma ilkeleri var, böylece makineyi yeniden başlattığınızda aynı kapsayıcıyı yeniden başlatacak şekilde yapılandırabilirsiniz. Ayrıca cenkins'lerinizi dışarıdan (yedekler vb.) Erişebilmek için bir birime koymanızı tavsiye ederim.
ZeissS

7
docker cp $(docker ps -alq):/path/to/file .
Çıktıktan

3
ayrıca bir kapsayıcıyı adına göre başlatabilir ve ekleyebilirsiniz. (ör. docker run -it --name my_debian debianve sonra docker start my_debian && docker attach my_debian)
Johnny Willer

128

Kapsayıcı verilerini sürdürmenin aşağıdaki yolları vardır:

  1. Docker birimleri

  2. Liman işçiliği

    a) Ubuntu görüntüsünden kap oluşturun ve bir bash terminali çalıştırın.

       $ docker run -i -t ubuntu:14.04 /bin/bash
    

    b) Terminal montaj kıvrımının içinde

       # apt-get update
       # apt-get install curl
    

    c) Konteyner terminalinden çıkın

       # exit
    

    d) Aşağıdaki komutu uygulayarak kapsayıcı kimliğinizi not edin:

       $ docker ps -a
    

    e) kapsayıcıyı yeni resim olarak kaydet

       $ docker commit <container_id> new_image_name:tag_name(optional)
    

    f) kıvrılma yüklü olarak yeni görüntünüzü görebildiğinizi doğrulayın.

       $ docker images           
    
       $ docker run -it new_image_name:tag_name bash
          # which curl
            /usr/bin/curl
    

exitÖnceden gerekli docker commitmi? Teşekkürler.
Abhishek Anand

2
@AbhishekVe evet, çünkü docker runkomutla konteynerde bash çalıştırıyorsunuz ve -ive -tseçenekleri (TTY ile etkileşimli) nedeniyle orada kalıyorsunuz . Ancak, Docker makinenizde konteynerin dışında çalışır, bu nedenle içeriden konteynırda gerekli değişiklikleri yaptıktan sonra, sistem kabuğuna geri dönmek için exitkabın kabuğuna (veya Ctrl + D) ihtiyacınız vardır. Ayrıca , komutta yazılan farklı kabukları gösteren cevabın #ve $içindeki notuna da dikkat edin .
Erik

Kısa soru: Taahhüt etmezsem verileri kaybettim. Bu açık. Ama nginx yapılandırmasını değiştirdiğimde, neden güncel kalıyor? @Erik
grep

@grep Açık ve tekrarlanabilir bir MWE'niz varsa, bu özel kullanım durumu hakkında henüz bir soru yoksa, lütfen yeni soru sorun.
Erik

3. docker stopardından docker start.
carillonator

59

Unferth'in cevabına ek olarak , bir Dockerfile oluşturmanız önerilir .

Boş bir dizinde, aşağıdaki içeriğe sahip "Dockerfile" adlı bir dosya oluşturun .

FROM ubuntu
RUN apt-get install ping
ENTRYPOINT ["ping"]

Dockerfile dosyasını kullanarak bir görüntü oluşturun . Bir etiketi kullanalım, böylece onaltılık görüntü numarasını hatırlamamız gerekmez.

$ docker build -t iman/ping .

Ve sonra görüntüyü bir kapta çalıştırın .

$ docker run iman/ping stackoverflow.com

1
Asla bir kereden fazla manuel olarak yapmak zorunda kalmamak, liman işçisinin amacıdır. Bir dockerfile dosyası oluşturun, ortaya çıkan görüntüyü kaydedin ve yükleyin. Adı geçen görüntüyü ileri doğru çekin.
Brandon Bertelsen

11

Sorunuza çok daha basit bir cevabım var, aşağıdaki iki komutu çalıştırın

sudo docker run -t -d ubuntu --name mycontainername /bin/bash
sudo docker ps -a

Yukarıdaki ps -a komutu tüm kapsayıcıların bir listesini döndürür. 'Ubuntu' adlı resim adına başvuran kabın adını alın. docker, kapsayıcılar için otomatik olarak adlar oluşturur - örneğin 'lightlyxuyzx', --name seçeneğini kullanmazsanız.

-T ve -d seçenekleri önemlidir, oluşturulan kap ayrılır ve -t seçeneği ile aşağıda verildiği şekilde yeniden bağlanabilir.

--Name seçeneğiyle, konteynırımı 'mycontainername' adımda adlandırabilirsiniz.

sudo docker exec -ti mycontainername bash

ve bu yukarıdaki komut, bash kabuğu ile kaba giriş yapmanıza yardımcı olur. Bu noktadan sonra, kapta yaptığınız değişiklikler docker tarafından otomatik olarak kaydedilir. Örneğin - apt-get install curlkonteynerin içinde Konteynerden herhangi bir sorun olmadan çıkabilirsiniz, docker değişiklikleri otomatik olarak kaydeder.

Bir sonraki kullanımda tek yapmanız gereken, bu kapsayıcıyla her çalışmak istediğinizde bu iki komutu çalıştırmaktır.

Aşağıdaki komut durdurulan kapsayıcıyı başlatır:

sudo docker start mycontainername

sudo docker exec -ti mycontainername bash

Bağlantı noktalarına ve aşağıda verilen paylaşılan alana sahip başka bir örnek:

docker run -t -d --name mycontainername -p 5000:5000 -v ~/PROJECTS/SPACE:/PROJECTSPACE 7efe2989e877 /bin/bash

Benim durumumda: 7efe2989e877 - kullanarak elde ettiğim önceki bir konteynerin çalışan kimliği

docker ps -a


4
Ubuntu 18.04'te Docker 18.09.2 ile olduğu gibi çalışmaz. --nameGörüntü adının önüne ve seçeneğini koyarsam çalışır :docker run --name mycontainername -t -d ubuntu /bin/bash
Stéphane Gourichon


3

Benim önerim docker compose ile docker yönetmek için. Projeniz için tüm liman işçilerinin konteynırlarını yönetmenin kolay bir yoludur, sürümleri eşleyebilir ve farklı konteynırları birlikte çalıştırabilirsiniz.

Dokümanların anlaşılması çok basittir, liman işçilerinin dokümanlarından daha iyidir.

Docker-Compose Dokümanları

En iyi


3

Yukarıda sorulan soruya gerçekten harika cevaplar var. Başka bir cevaba gerek olmayabilir ama yine de konuyla ilgili kişisel fikrimi mümkün olan en basit kelimelerle vermek istiyorum.

Sonuç olarak bize yardımcı olacak kapsayıcılar ve resimler hakkında bazı noktalar:

  • Bir liman işçisi görüntüsü :
    1. oluşturulan-a-verilen-kabından
    2. silindi
    3. kullanılan Oluşturulması-bir-dizi-of-the konteyner
  • Bir liman işçisi konteyneri :
    1. oluşturulan-bir-görüntüden
    2. başladı
    3. durduruldu
    4. yeniden
    5. silindi
    6. used-to-create-herhangi-sayı-of-the görüntüleri
  • Docker run komutu bunu yapar :
    1. Bir resmi indirir veya önbelleğe alınmış bir resim kullanır
    2. Yeni bir kap oluşturur
    3. Kapsayıcıyı başlatır
  • Bir görüntü oluşturmak için Dockerfile kullanıldığında :
    1. Görüntünün sonunda bir docker kapsayıcısını çalıştırmak için kullanılacağı zaten bilinmektedir.
    2. Docker build komutunu verdikten sonra, perde arkasındaki docker, temel dosya sistemine sahip çalışan bir kap oluşturur ve Dockerfile içindeki adımları geliştirerek bu kapsayıcıyı geliştiricilerin gereksinimlerine göre yapılandırır.
    3. Kap, Dockerfile özellikleriyle yapılandırıldıktan sonra, bir görüntü olarak işlenecektir.
    4. Görüntü sallanmaya hazırlanıyor!

Sonuç :

Gördüğümüz gibi, bir liman işçisi konteyneri limancı görüntüsünden bağımsızdır.

Bir kap [ docker ps --allo kimliği almak için kullanın ] benzersiz kimliği koşuluyla bir kapsayıcı yeniden başlatılabilir .

Yeni bir dizin oluşturma, dosya oluşturma, yükleme araçları vb. Gibi herhangi bir işlem çalışırken konteyner içinde yapılabilir. Kap durdurulduktan sonra, tüm değişikliklere devam eder. Kapsayıcı durdurma ve yeniden başlatma bir bilgisayar sistemini yeniden başlatmak gibidir.

Önceden oluşturulmuş bir kapsayıcı yeniden başlatma için her zaman kullanılabilir, ancak docker runkomut verdiğimizde , görüntüden yeni bir kapsayıcı oluşturulur ve bu nedenle yeni bir bilgisayar sistemi gibidir. Eski kapsayıcıda yapılan değişiklikler - şimdi anlayabileceğimiz gibi - bu yeni kapsayıcıda mevcut değil.

Son bir not :

Sanırım şimdi neden veriler kaybolmuş gibi görünüyor ama her zaman orada .. ama farklı bir [eski] kapta. Bu yüzden docker start& docker runkomutundaki farkı iyi bir şekilde not edin ve bunlarda asla kafanız karışmasın.


1

benzer bir sorun (ve Dockerfile'ın tek başına çözememesi mümkün değil) beni bu sayfaya getirdi.

Aşama 0: herkes için, Dockerfile'ın bunu düzeltebileceğini ummak: Dockerfile desteğinde --dns ve --dns-search görünene kadar - intranet tabanlı kaynakları birleştirmenin bir yolu yoktur.

Aşama 1: Dockerfile kullanarak görüntü oluşturduktan sonra (bu arada ciddi bir aksaklık Dockerfile geçerli klasörde olmalıdır), docker çalıştırma komut dosyasını çalıştırarak intranet tabanlı olanı dağıtmak için bir görüntüye sahip. misal: docker run -d \ --dns=${DNSLOCAL} \ --dns=${DNSGLOBAL} \ --dns-search=intranet \ -t pack/bsp \ --name packbsp-cont \ bash -c " \ wget -r --no-parent http://intranet/intranet-content.tar.gz \ tar -xvf intranet-content.tar.gz \ sudo -u ${USERNAME} bash --norc"

Aşama 2: Daemon modunda docker çalıştırma betiğinin uygulanması, yerel dns kayıtlarının yerel şeyleri indirme ve dağıtma yeteneğine sahip olmasını sağlar.

önemli nokta: çalıştırma komut dosyası /usr/bin/sudo -u ${USERNAME} bash --norc, yükleme komut dosyaları tamamlandıktan sonra bile kapsayıcıyı çalışır durumda tutmak gibi bir şeyle bitiyor olmalıdır.

hayır , konteynır içinde CTRL-p CTRL-q basılana kadar komut isteminde bulunacağı için tam otomasyon konusu için etkileşimli modda konteyner çalıştırmak mümkün değildir .

hayır , etkileşen bash yükleme komut dosyasının sonunda yürütülmezse, komut dosyası yürütme tamamlandıktan hemen sonra kap tüm sonlandırma sonuçlarını kaybederek sona erer.

Aşama 3: Kapsayıcı hala arka planda çalışıyor ancak kapsayıcı yükleme yordamını sonlandırıp sonlandırmadığı belli değil. yürütme yordamının sonlandığını belirlemek için aşağıdaki bloğu kullanın: while ! docker container top ${CONTNAME} | grep "00[[:space:]]\{12\}bash \--norc" - do echo "." sleep 5 done komut dosyası yalnızca tamamlandıktan sonra devam eder. ve şu an çağrılacak doğru an: command , geçerli kapsayıcı kimliği ve hedef resim adının sağlanması ( oluşturma / çalıştırma yordamıyla aynı olabilir ancak yerel yükleme amaçlı etiketiyle eklenmiş olabilir. örnek: docker commit containerID pack/bsp:toolchainedbu bağlantıya bakın doğru containerID nasıl edinilir

Aşama 4: Kapsayıcı yerel yüklemelerle güncellendi ve yeni atanan görüntüye (amaç etiketi eklenmiş olan) eklendi. artık konteynerin çalışmasını durdurmak güvenli. misal:docker stop packbsp-cont

Aşama 5: Yerel yüklemeleri olan kapsayıcıyı çalıştırmak istediğiniz an, daha önce kaydedilen görüntüyle başlatın. misal:docker run -d -t pack/bsp:toolchained


1

burada parlak bir cevap Kullanıcı kg'larından çıkılan bir liman işçisi nasıl devam edilir

docker start $(docker ps -a -q --filter "status=exited")
(or in this case just docker start $(docker ps -ql) 'cos you don't want to start all of them)

docker exec -it <container-id> /bin/bash

Bu ikinci satır çok önemli. Bu nedenle exec, bir görüntüde değil, bir kapsayıcıda çalışma yerine kullanılır. Ve konteyner başlatıldıktan sonra bunu yaparsınız.


0

Cevapların hiçbiri bu tasarım seçiminin amacına değinmiyor. Docker bu 2 hataları önlemek için bu şekilde çalışır düşünüyorum:

  • Tekrarlanan yeniden başlatma
  • Kısmi hata
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.