Úvod
Docker je oblíbený kontejnerizační nástroj používaný k poskytování softwarových aplikací se souborovým systémem, který obsahuje vše, co potřebují ke spuštění. Použití kontejnerů Docker zajišťuje, že se software bude chovat stejně bez ohledu na to, kde je nasazen, protože jeho běhové prostředí je konzistentní.
Obecně platí, že kontejnery Docker jsou pomíjivé a běží tak dlouho, dokud se dokončí příkaz vydaný v kontejneru. Někdy však aplikace potřebují sdílet přístup k datům nebo uchovávat data po odstranění kontejneru. Databáze, uživatelsky generovaný obsah pro webovou stránku a soubory protokolů jsou jen některé příklady dat, která je nepraktické nebo nemožné zahrnout do obrazu Dockeru, ale ke kterým aplikace potřebují přístup. Trvalý přístup k datům je poskytován pomocí Docker Volumes.
Svazky Dockeru lze vytvořit a připojit stejným příkazem, který vytváří kontejner, nebo je lze vytvořit nezávisle na jakýchkoli kontejnerech a připojit později. V tomto článku se podíváte na čtyři různé způsoby sdílení dat mezi kontejnery.
Předpoklady
Abyste mohli postupovat podle tohoto článku, budete potřebovat server Ubuntu 22.04 s následujícím:
- Uživatel bez oprávnění root s právy sudo. Průvodce počátečním nastavením serveru s Ubuntu 22.04 vysvětluje, jak to nastavit.
- Docker byl nainstalován podle pokynů z Kroku 1 a Krok 2 o tom, jak nainstalovat a používat Docker na Ubuntu 22.04
Poznámka: Přestože Předpoklady poskytují pokyny pro instalaci Dockeru na Ubuntu 22.04, docker
příkazy pro objemy dat Dockeru v tomto článku by měly fungovat na jiných operačních systémech, pokud je nainstalován Docker a uživatel sudo byl přidán do docker
skupina.
Krok 1 – Vytvoření nezávislého svazku
docker volume create
, který byl představen ve verzi Dockeru 1.9 umožňuje vytvořit svazek, aniž by byl spojen s jakýmkoli konkrétním kontejnerem. Tento příkaz použijete k přidání svazku s názvem DataVolume1
:
- docker volume create --name DataVolume1
Zobrazí se název označující, že příkaz byl úspěšný:
OutputDataVolume1
Chcete-li svazek využít, vytvořte nový kontejner z obrazu Ubuntu pomocí --rm
příznak, aby se automaticky odstranil při ukončení. Budete také používat -v
pro připojení nového svazku. -v
vyžaduje název svazku, dvojtečku a pak absolutní cestu k místu, kde by se měl svazek uvnitř kontejneru objevit. Pokud adresáře v cestě neexistují jako součást obrazu, budou vytvořeny při spuštění příkazu. Pokud dělají existovat, připojený svazek skryje stávající obsah:
- docker run -ti --rm -v DataVolume1:/datavolume1 ubuntu
V kontejneru zapište některá data do svazku:
- echo "Example1" > /datavolume1/Example1.txt
Protože jste použili --rm
příznak, váš kontejner bude automaticky odstraněn, když opustíte. Váš svazek však bude stále přístupný.
- exit
Přítomnost svazku ve vašem systému můžete ověřit pomocí docker volume inspect
:
- docker volume inspect DataVolume1
Output[
{
"CreatedAt": "2018-07-11T16:57:54Z",
"Driver": "local",
"Labels": {},
"Mountpoint": "/var/lib/docker/volumes/DataVolume1/_data",
"Name": "DataVolume1",
"Options": {},
"Scope": "local"
}
]
Poznámka: Můžete se dokonce podívat na data na hostiteli na cestě uvedené jako Mountpoint
. Měli byste se však vyhnout jeho změnám, protože může způsobit poškození dat, pokud aplikace nebo kontejnery o změnách nevědí.
Dále spusťte nový kontejner a připojte DataVolume1
:
- docker run --rm -ti -v DataVolume1:/datavolume1 ubuntu
Ověřte obsah:
- cat /datavolume1/Example1.txt
OutputExample1
Opusťte kontejner:
- exit
V tomto příkladu jste vytvořili svazek, připojili jej ke kontejneru a ověřili jeho stálost.
Krok 2 — Vytvoření svazku, který přetrvá, když je kontejner odstraněn
V dalším příkladu vytvoříte svazek současně s kontejnerem, odstraníte kontejner a poté jej připojíte k novému kontejneru.
Použijete docker run
příkaz k vytvoření nového kontejneru pomocí základního obrazu Ubuntu. -t
nám poskytne terminál a -i
umožní nám s ním komunikovat. Pro přehlednost použijete --name
k identifikaci kontejneru.
-v
flag nám umožní vytvořit nový svazek, který nazvete DataVolume2
. K oddělení tohoto názvu od cesty, kam by měl být svazek v kontejneru připojen, použijete dvojtečku. Nakonec určíte základní obrázek Ubuntu a budete se spoléhat na výchozí příkaz v souboru Docker základního obrázku Ubuntu, bash
, aby nás pustil do ulity:
- docker run -ti --name=Container2 -v DataVolume2:/datavolume2 ubuntu
Poznámka: -v
vlajka je velmi flexibilní. Může bindmount nebo pojmenovat svazek pouze s mírnou úpravou syntaxe. Pokud první argument začíná /
nebo ~/
vytváříte bindmount. Odstraňte to a pojmenujete svazek. Například:
-v /path:/path/in/container
připojí hostitelský adresář/path
v/path/in/container
-v path:/path/in/container
vytvoří svazek s názvempath
bez vztahu k hostiteli.
Další informace o připojení adresáře z hostitele najdete v tématu Jak sdílet data mezi kontejnerem Docker a hostitelem
V kontejneru zapíšete některá data do svazku:
- echo "Example2" > /datavolume2/Example2.txt
- cat /datavolume2/Example2.txt
OutputExample2
Opusťte kontejner:
- exit
Když kontejner restartujete, svazek se automaticky připojí:
- docker start -ai Container2
Ověřte, že se svazek skutečně připojil a vaše data jsou stále na svém místě:
- cat /datavolume2/Example2.txt
OutputExample2
Nakonec ukončete a vyčistěte:
- exit
Docker nám nedovolí odebrat svazek, pokud na něj odkazuje kontejner. Chcete-li zjistit, co se stane, zkuste:
- docker volume rm DataVolume2
Zpráva nám říká, že svazek se stále používá a poskytuje dlouhou verzi ID kontejneru:
OutputError response from daemon: unable to remove volume: remove DataVolume2: volume is in use - [d0d2233b668eddad4986313c7a4a1bc0d2edaf0c7e1c02a6a6256de27db17a63]
K odstranění kontejneru můžete použít ID ve výše uvedené chybové zprávě:
- docker rm d0d2233b668eddad4986313c7a4a1bc0d2edaf0c7e1c02a6a6256de27db17a63
Outputd0d2233b668eddad4986313c7a4a1bc0d2edaf0c7e1c02a6a6256de27db17a63
Odstranění nádoby neovlivní objem. Můžete vidět, že je stále přítomen v systému, když vypíšete svazky pomocí docker volume ls
:
- docker volume ls
OutputDRIVER VOLUME NAME
local DataVolume2
A můžete použít docker volume rm
pro jeho odstranění:
- docker volume rm DataVolume2
V tomto příkladu jste vytvořili prázdný datový svazek ve stejnou dobu, kdy jste vytvořili kontejner. V dalším příkladu prozkoumáte, co se stane, když vytvoříte svazek s adresářem kontejneru, který již obsahuje data.
Krok 3 — Vytvoření svazku ze stávajícího adresáře s daty
Obecně platí, že vytvoření svazku nezávisle pomocí docker volume create
a vytvoření jednoho při vytváření kontejneru jsou ekvivalentní, s jednou výjimkou. Pokud vytvoříte svazek současně s vytvořením kontejneru a zadáte cestu k adresáři, který obsahuje data v základním obrazu, tato data budou zkopírována do svazku.
Jako příklad vytvoříte kontejner a přidáte objem dat na /var
, adresář, který obsahuje data v základním obrazu:
- docker run -ti --rm -v DataVolume3:/var ubuntu
Veškerý obsah ze základního obrázku /var
adresář se zkopíruje do svazku a tento svazek můžete připojit do nového kontejneru.
Ukončete aktuální kontejner:
- exit
Tentokrát raději než se spoléhat na výchozí bash
základního obrázku příkazem, vydáte svůj vlastní ls
příkaz, který zobrazí obsah svazku bez zadání shellu:
- docker run --rm -v DataVolume3:/datavolume3 ubuntu ls datavolume3
Adresář datavolume3
nyní má kopii obsahu /var
základního obrázku adresář:
Outputbackups
cache
lib
local
lock
log
mail
opt
run
spool
tmp
Je nepravděpodobné, že byste chtěli připojit /var/
tímto způsobem, ale může to být užitečné, pokud jste si vytvořili vlastní obrázek a chcete snadný způsob, jak zachovat data. V dalším příkladu si ukážete, jak lze svazek sdílet mezi více kontejnery.
Krok 4 – Sdílení dat mezi více kontejnery dockeru
Dosud jste svazek připojovali k jednomu kontejneru najednou. Často budete chtít, aby se ke stejnému objemu dat připojilo několik kontejnerů. Toho lze dosáhnout poměrně snadno, ale je tu jedno zásadní upozornění:v tuto chvíli Docker nezvládá zamykání souborů. Pokud potřebujete více kontejnerů zapisovat do svazku, aplikace spuštěné v těchto kontejnerech musí být navržen tak, aby zapisoval do sdílených datových úložišť, aby se zabránilo poškození dat.
Vytvořit kontejner4 a DataVolume4
Použijte docker run
vytvořit nový kontejner s názvem Container4
s připojeným objemem dat:
- docker run -ti --name=Container4 -v DataVolume4:/datavolume4 ubuntu
Dále vytvoříte soubor a přidáte nějaký text:
- echo "This file is shared between containers" > /datavolume4/Example4.txt
Poté kontejner opustíte:
- exit
Tím se vrátíme do příkazového řádku hostitele, kde vytvoříte nový kontejner, který připojí objem dat z Container4
.
Vytvoření kontejneru5 a připojení svazků z kontejneru4
Chystáte se vytvořit Container5
a připojte svazky z Container4
:
- docker run -ti --name=Container5 --volumes-from Container4 ubuntu
Zkontrolujte stálost dat:
- cat /datavolume4/Example4.txt
OutputThis file is shared between containers
Nyní připojte nějaký text z Container5
:
- echo "Both containers can write to DataVolume4" >> /datavolume4/Example4.txt
Nakonec opustíte kontejner:
- exit
Dále zkontrolujete, zda jsou vaše data stále přítomna v Container4
.
Zobrazit změny provedené v kontejneru5
Nyní zkontrolujte změny, které do datového objemu zapsal Container5
restartováním Container4
:
- docker start -ai Container4
Zkontrolujte změny:
- cat /datavolume4/Example4.txt
OutputThis file is shared between containers
Both containers can write to DataVolume4
Nyní, když jste ověřili, že oba kontejnery byly schopny číst a zapisovat z datového objemu, opustíte kontejner:
- exit
Docker opět nezvládá žádné zamykání souborů, takže aplikace musí zohledňují samotné zamykání souborů. Je možné připojit svazek Docker jako pouze pro čtení, aby se zajistilo, že nedojde k náhodnému poškození dat, když kontejner vyžaduje přístup pouze pro čtení, přidáním :ro
. Nyní se podíváte, jak to funguje.
Spustit kontejner 6 a připojit svazek pouze pro čtení
Jakmile je svazek připojen do kontejneru, namísto jeho odpojování, jako byste to dělali s typickým souborovým systémem Linux, můžete místo toho vytvořit nový kontejner připojený tak, jak chcete, a v případě potřeby odstranit předchozí kontejner. Chcete-li, aby byl svazek pouze pro čtení, připojte :ro
na konec názvu kontejneru:
- docker run -ti --name=Container6 --volumes-from Container4:ro ubuntu
Stav pouze pro čtení zkontrolujete pokusem o odebrání vzorového souboru:
- rm /datavolume4/Example4.txt
Outputrm: cannot remove '/datavolume4/Example4.txt': Read-only file system
Nakonec opustíte nádobu a vyčistíte testovací nádoby a objemy:
- exit
Nyní, když jste hotovi, vyčistěte nádoby a objem:
- docker rm Container4 Container5 Container6
- docker volume rm DataVolume4
V tomto příkladu jste ukázali, jak sdílet data mezi dvěma kontejnery pomocí datového svazku a jak připojit datový svazek jako pouze pro čtení.
Závěr
V tomto kurzu jste vytvořili datový svazek, který umožňoval zachování dat po odstranění kontejneru. Sdíleli jste objemy dat mezi kontejnery s upozorněním, že aplikace budou muset být navrženy tak, aby zvládaly zamykání souborů, aby se zabránilo poškození dat. Nakonec jste ukázali, jak připojit sdílený svazek v režimu pouze pro čtení. Pokud se chcete dozvědět o sdílení dat mezi kontejnery a hostitelským systémem, přečtěte si článek Jak sdílet data mezi kontejnerem Docker a hostitelem.