Bir docker kapsayıcısını ve içindekiler dahil ilişkili veri kapsayıcısını nasıl dağıtırım?


18

Docker için oldukça yeni olduğumu itiraf ederek başlayacağım ve bu soruna yanlış varsayımlardan yaklaşıyor olabilirim ... durumun bu olup olmadığını bana bildirin. Docker'ın dağıtım için nasıl yararlı olduğu konusunda birçok tartışma gördüm, ancak bunun gerçekte nasıl yapıldığına dair bir örnek yok.

İşte işe yarayacağını düşündüğüm yol :

  1. A makinesinde bazı kalıcı verileri tutmak için veri kabını oluşturma
  2. veri kapsayıcısından birimler kullanan uygulama kapsayıcısını oluşturma
  3. veri kapsayıcısındaki verileri potansiyel olarak değiştirerek biraz çalışma yapın
  4. uygulama kabını durdur
  5. veri taşıyıcısını taahhüt et ve etiketle
  6. veri kapsayıcısını (özel) bir depoya gönderme
  7. B makinesinde 6. adımdaki görüntüyü çekin ve çalıştırın
  8. B makinesinde kaldığınız yerden devam edin

Buradaki önemli adım, geçerli durumu (dosya sisteminin içeriği dahil) kaydedeceğini düşündüğüm adım 5'tir. Daha sonra bu durumu bir depoya aktarabilir ve başka bir yerden çekerek, orijinaliyle aynı olan yeni bir kap elde edebilirsiniz.

Ancak bu şekilde çalışmıyor gibi görünüyor. Bulduğum şey, ya adım 5'in düşündüğüm şeyi yapmaması ya da adım 7 (görüntüyü çekme ve çalıştırma) kapsayıcıyı ilk durumuna "sıfırlar".

Bunu test etmek için üç Docker görüntüsü ve kapsayıcısını bir araya getirdim: bir veri kabı, her 30 saniyede bir veri kabındaki bir dosyaya rastgele bir dize yazan bir yazar ve sadece echoverilerdeki değeri es olan bir okuyucu konteyner dosyası ve çıkışları.

Veri taşıyıcısı

İle oluşturuldu

docker run \
    --name datatest_data \
    -v /datafolder \
    myrepository:5000/datatest-data:latest

Dockerfile:

FROM ubuntu:trusty

# make the data folder
#
RUN mkdir /datafolder

# write something to the data file
#
RUN echo "no data here!" > /datafolder/data.txt

# expose the data folder
#
VOLUME /datafolder

yazar

İle oluşturuldu

docker run \
    --rm \
    --name datatest_write \
    --volumes-from datatest_data \
    myrepository:5000/datatest-write:latest

Dockerfile:

FROM ubuntu:trusty

# Add script
#
ADD run.sh /usr/local/sbin/run.sh
RUN chmod 755 /usr/local/sbin/*.sh

CMD ["/usr/local/sbin/run.sh"]

run.sh

#!/bin/bash

while :
do
    sleep 30s

    NEW_STRING=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 32 | head -n 1)

    echo "$NEW_STRING" >> /datafolder/data.txt

    date >> /datafolder/data.txt

    echo "wrote '$NEW_STRING' to file"
done

Bu komut dosyası /datafolder/data.txt, veri taşıyıcısına rastgele bir dize ve tarih / saat yazar .

Okuyucu

İle oluşturuldu

docker run \
    --rm \
    --name datatest_read \
    --volumes-from datatest_data \
    myrepository:5000/datatest-read:latest

Dockerfile:

FROM ubuntu:trusty

# Add scripts
ADD run.sh /run.sh
RUN chmod 0777 /run.sh

CMD ["/run.sh"]

run.sh:

#!/bin/bash

echo "reading..."

echo "-----"

cat /datafolder/data.txt

echo "-----"

Bu kapları oluşturup çalıştırdığımda, iyi çalışıyorlar ve beklediğim gibi çalışıyorlar:

Geliştirme makinesinde Durdur ve Başlat:

  1. veri kabını oluştur
  2. yazarı çalıştır
  3. okuyucuyu hemen çalıştırın, "burada veri yok!" İleti
  4. Bir süre bekleyin
  5. okuyucuyu çalıştırın, rastgele dizeye bakın
  6. yazarı durdur
  7. yazarı yeniden başlat
  8. okuyucuyu çalıştırın, aynı rastgele dizeye bakın

Ama taahhüt ve itme beklediğim şeyi yapmaz:

  1. veri kabını oluştur
  2. yazarı çalıştır
  3. okuyucuyu hemen çalıştırın, "burada veri yok!" İleti
  4. Bir süre bekleyin
  5. okuyucuyu çalıştırın, rastgele dizeye bakın
  6. yazarı durdur
  7. veri kapsayıcısını taahhüt ve etiketle docker commit datatest_data myrepository:5000/datatest-data:latest
  8. depoya zorla
  9. tüm kapları sil ve yeniden oluştur

Bu noktada, veri kabı işlendiğinden, havuza itildiğinden ve daha sonra havuzdaki aynı görüntüden yeniden oluşturulduğundan okuyucuyu çalıştırmayı ve aynı rastgele dizeyi görmeyi beklerdim. Ancak, aslında gördüğüm "burada veri yok!" İleti.

Birisi nerede yanlış gittiğimi açıklayabilir mi? Ya da, alternatif olarak, beni Docker ile dağıtımın nasıl yapıldığına dair bir örneğe yönlendirin?

Yanıtlar:


22

Liman işçisinde hacimlerin nasıl çalıştığı hakkında yanlış bir varsayım var. Birimlerin liman işçileri konteynırları ve liman işçileri görüntüleri ile nasıl ilişkilendiğini açıklamaya çalışacağım ve umarım veri birimleri ve veri birimleri arasındaki farklar netleşecektir.

İlk önce birkaç tanımı hatırlayalım

Docker görüntüleri

Docker görüntüleri temelde birleşim dosya sistemi + meta verileridir. Docker görüntü birliği dosya sisteminin içeriğini docker exportkomutla inceleyebilir ve docker görüntü meta verilerini docker inspectkomutla inceleyebilirsiniz.

Veri hacimleri

dan Docker kullanıcı kılavuzunda :

Veri birimi, bir veya daha fazla kapsayıcı içinde, kalıcı veya paylaşılan veriler için birkaç yararlı özellik sağlamak üzere Birlik Dosya Sistemini atlayan özel olarak belirlenmiş bir dizindir.

Burada, belirli bir birimin (veri içeren dizin veya dosya olarak) yalnızca, onu kullanan en az bir docker kapsayıcısı varsa yeniden kullanılabileceğini belirtmek önemlidir. Docker görüntülerinin birimleri yok, yalnızca birimlerin dosya sistemine nereye birleştirileceğini söyleyen meta veriler var. Veri birimleri docker kapsayıcıları sendika dosya sisteminin bir parçası değildir, bu yüzden neredeler? altında /var/lib/docker/volumes(konteynerler saklanırken /var/lib/docker/containers).

Veri hacmi kapları

Bu özel konteyner türünün özel bir şeyi yoktur. Bunlar, yalnızca ve bu veri hacmini kullanan en az bir konteynere sahip olma amacını taşıyan bir veri hacmi kullanan kapsayıcılardır. Belirli bir veri hacmini kullanan son kapsayıcı (çalışıyor veya durdurulur) silinir silinmez, docker çalışma --volumes-from seçeneği aracılığıyla bu birime erişilemeyeceğini unutmayın .

Veri hacmi kaplarıyla çalışma

Veri hacmi kapsayıcısı oluşturma

Bir veri hacmi kabı oluşturmak için kullanılan görüntünün önemi yoktur, çünkü böyle bir kap durmaya devam edebilir ve yine de amacını doldurabilir. Bu nedenle, datatest_databir birimde adlandırılmış bir veri taşıyıcısı oluşturmak için /datafolderyalnızca çalıştırmanız gerekir:

docker run --name datatest_data --volume /datafolder busybox true

İşte basegörüntü adı (uygun şekilde küçük olanı) ve truedocker daemon'un eksik bir komuttan şikayet etmesini önlemek için sağladığımız bir komut. Her neyse datatest_data, yalnızca komut --volumes-fromseçeneğiyle bu birime ulaşmanıza izin vermek amacıyla adlandırılmış bir kapsayıcı bulunduktan sonra docker run.

Veri hacmi kapsayıcısından okuma

Veri hacmini okumanın iki yolunu biliyorum: ilki bir kapsayıcıdan. Bu veri hacmine erişmek için mevcut bir kapsayıcıya kabuğunuz yoksa --volumes-from, yalnızca bu verileri okumak amacıyla yeni bir kapsayıcı çalıştırabilirsiniz .

Örneğin:

docker run --rm --volumes-from datatest_data busybox cat /datafolder/data.txt

Diğer yol, birimi /var/lib/docker/volumesklasörden kopyalamaktır . Birimi kullanarak kaptan birinin meta verilerini denetleyerek o klasördeki birimin adını keşfedebilirsiniz. Ayrıntılar için bu cevaba bakınız.

Birimlerle çalışma (Docker 1.9.0'dan beri)

Birim nasıl oluşturulur (Docker 1.9.0'dan beri)

Docker 1.9.0, docker volumebirimler oluşturmanıza izin veren yeni bir komut sundu :

docker volume create --name hello

Ciltten okuma (Docker 1.9.0'dan beri)

Adlı bir hacmi yarattı diyelim helloile docker volume create --name hellosize bir kap içinde monte edebilirsiniz, -vopsiyon:

docker run -v hello:/data busybox ls /data

Kapları işleme ve itme hakkında

Artık, veri hacimleri bir kapsayıcının (birleşim dosya sistemi) bir parçası olmadığından, yeni bir liman işçisi görüntüsü üretmek için kapsayıcı işlemenin veri biriminde olacak hiçbir veriyi sürdürmeyeceği açıktır.

Veri birimlerinin yedeklerini alma

Docker kullanım kılavuzunda veri birimlerinin yedeklerini alma hakkında güzel bir makale bulunmaktadır .


Hacimleri dikkate alan iyi makale: http://container42.com/2014/11/03/docker-indepth-volumes/


Görünüşe göre "Veri hacmi kabı oluşturmak için kullanılan görüntünün önemi yok" tam olarak doğru değil. Sadece "exec:" true "verecek bir" karalama "görüntüsü ile deneyin: yürütülebilir dosya bulunamadı"
tcurdt

Bu hataya rağmen, konteynırınız bir hacim sahibi olarak rolünü yerine
getirecek

1
Hm - belki de bunun için bir sorun açmaya değer.
tcurdt

hayır, bu davranış, sıfırdan görüntü /bin/truezaten ikili (veya başka herhangi bir) bulunamayan boş bir görüntü olduğu için bekleniyor
Thomasleveil

1
Sadece bir şey. "Belirli bir veri birimini kullanan son kapsayıcı (çalışıyor veya durdurulur) silinir silinmez, docker bu veri hacmini / var / lib / docker / volumes'tan yok edecektir.", Ancak bu aslında doğru değil: sadece bakın: docs.docker.com/userguide/dockervolumes (Kabın kendisi silinmiş olsa bile veri hacimleri devam eder. docker rm -v
Birimi

1

Kodu dağıtmak için bir docker veri taşıyıcısı da kullanabilirsiniz

İyi bir uygulama olup olmadığını bilmiyorum, ama böyle yapıyorum:

FROM ubuntu:trusty

# make the data folder
#
RUN mkdir /data-image

# in my case, I have a 
# ADD dest.tar /data-image/
#
# but to follow your example :
# write something to the data file
RUN echo "no data here!" > /data-image/data.txt

# expose the data folder 
#
VOLUME /datafolder

ENTRYPOINT cp -r /data-image/* /datafolder/

Artık resminizi itebilir ve birimlerden vb. Kullanabilirsiniz ...


Aradığım şey bu, ancak kabul edilen cevap açıkça yapılamadığından bahsediyor. Şimdi deneyeceğim.
andho

1
İkinci bakışta, kabul edilen cevap, birimlerin (veya içindeki verilerin) işlenmeyeceğini söylüyor, ancak COPYveya öğesini kullanarak verileri kaba ekleyebilir ve Dockerfile'da ADDkullanarak birimi oluşturabilirsiniz VOLUME.
andho
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.