GNU/Linux >> Znalost Linux >  >> Panels >> Docker

Jak upravit obrázky Docker

Předpokládám, že jste trochu obeznámeni s Dockerem a znáte základy, jako je provozování dockerových kontejnerů atd.

V předchozích článcích jsme diskutovali o aktualizaci kontejneru dockeru a psaní souborů dockeru.

Co přesně je úprava obrazu dockeru?

Obrázek kontejneru je vytvořen ve vrstvách (nebo je to kolekce vrstev), každá instrukce Dockerfile vytváří vrstvu obrázku. Zvažte například následující Dockerfile:

FROM alpine:latest

RUN apk add --no-cache python3

ENTRYPOINT ["python3", "-c", "print('Hello World')"]

Protože existují celkem tři příkazy Dockerfile, bude obraz vytvořený z tohoto Dockerfile obsahovat celkem tři vrstvy.

Můžete to potvrdit vytvořením obrázku:

docker image built -t dummy:0.1 .

A poté pomocí příkazu docker image history na vytvořeném obrázku.

articles/Modify a Docker Image on  modify-docker-images [?] took 12s 
❯ docker image history dummy:0.1 
IMAGE          CREATED          CREATED BY                                      SIZE      COMMENT
b997f897c2db   10 seconds ago   /bin/sh -c #(nop)  ENTRYPOINT ["python3" "-c…   0B        
ee217b9fe4f7   10 seconds ago   /bin/sh -c apk add --no-cache python3           43.6MB    
28f6e2705743   35 hours ago     /bin/sh -c #(nop)  CMD ["/bin/sh"]              0B        
<missing>      35 hours ago     /bin/sh -c #(nop) ADD file:80bf8bd014071345b…   5.61MB

Poslední vrstvu „“ ignorujte.

Každá z těchto vrstev je pouze pro čtení. To je výhodné, protože vzhledem k tomu, že tyto vrstvy jsou pouze pro čtení, žádný proces spojený s běžící instancí tohoto obrazu nebude schopen upravit obsah tohoto obrazu, takže tyto vrstvy mohou být sdíleny mnoha kontejnery, aniž by bylo nutné uchovávat kopie pro každou instanci. Aby však procesy kontejnerů mohly provádět r/w, je při vytváření kontejnerů přidána další vrstva k existujícím vrstvám RO. Tato vrstva je zapisovatelná a není sdílena jinými kontejnery.

Nevýhodou této vrstvy r/w je, že změny provedené v této vrstvě nejsou trvalé, ačkoli můžete použít svazky k zachování některých dat, někdy můžete potřebovat/chtit přidat vrstvu před nějakou existující vrstvu nebo odstranit vrstvu z obrázek nebo jednoduše nahradit vrstvu. To jsou důvody, proč by bylo vhodné upravit stávající docker obrázek.

V tomto článku se budu zabývat všemi případy, které jsem zmínil výše, za použití různých metod.

Metody úpravy obrázku dockeru

Existují dva způsoby, jak upravit obrázek dockeru.

  1. Prostřednictvím Dockerfiles.
  2. Pomocí příkazu docker container commit .

Vysvětlím obě metody a na závěr také doplním, který případ použití by byl pro metodu v kontextu lepší.

Metoda 1:Úprava obrazu dockeru prostřednictvím souboru Dockerfile

Úprava obrázku dockeru v podstatě znamená úpravu vrstev obrázku. Nyní, protože každý příkaz Dockerfile představuje jednu vrstvu obrázku, úprava každého řádku souboru Dockerfile změní i příslušný obrázek.

Pokud byste tedy k obrázku přidali vrstvu, můžete k ní jednoduše přidat další instrukci Dockerfile, pro odstranění jedné byste odstranili řádek a pro změnu vrstvy byste řádek podle toho změnili.

Existují dva způsoby, jak můžete pomocí Dockerfile upravit obrázek.

  1. Použití obrázku, který chcete upravit, jako základního obrázku a vytvoření podřízeného obrázku.
  2. Úprava skutečného Dockerfile obrázku, který chcete změnit.

Dovolte mi vysvětlit, která metoda by měla být použita, kdy a jak.

1. Použití obrázku jako základního obrázku

To je, když vezmete obrázek, který chcete upravit, a přidáte k němu vrstvy, abyste vytvořili nový podřízený obrázek. Pokud není obrázek vytvořen od začátku, každý obrázek je modifikací stejného nadřazeného základního obrázku.

Zvažte předchozí soubor Dockerfile. Řekněme, že sestavení obrázku z tohoto obrázku se jmenuje dummy:0.1 . Kdybych si teď myslel, že teď musím použít Perl místo Pythonu3 k tisku "Hello World", ale také nechci odstraňovat Python3, mohl bych použít dummy:0.1 image jako základní obrázek (protože Python3 již existuje) a sestavte z něj následovně

FROM dummy:0.1

RUN apk add --no-cache perl

ENTRYPOINT ["perl", "-e", "print \"Hello World\n\""]

Zde stavím na dummy:0.1 , přidáním dalších vrstev, jak uznám za vhodné.

Tato metoda nebude příliš užitečná, pokud je vaším záměrem změnit nebo odstranit některou existující vrstvu. K tomu musíte postupovat podle následující metody.

2. Úprava Dockerfile obrázku

Vzhledem k tomu, že existující vrstvy obrázku jsou pouze pro čtení, nemůžete je přímo upravovat prostřednictvím nového souboru Dockerfile. Pomocí FROM příkazu v Dockerfile, vezmete nějaký obrázek jako základ a postavíte na nebo k němu přidat vrstvy.

Některé úkoly mohou vyžadovat, abychom změnili existující vrstvu, i když to můžete udělat pomocí předchozí metody s množstvím protichůdných RUN pokyny (jako je mazání souborů, odstranění/nahrazení balíčků přidaných v některé předchozí vrstvě), není to ideální řešení nebo to, co bych doporučil. Protože přidává další vrstvy a značně zvětšuje velikost obrázku.

Lepší metodou by bylo nepoužívat obrázek jako základní obrázek, ale změnit skutečný Dockerfile tohoto obrázku. Zvažte znovu předchozí Dockerfile, co kdybych nemusel ponechat Python3 v tomto obrazu a nahradit balíček Python3 a příkaz těmi z Perlu?

Pokud bych postupoval podle předchozí metody, musel bych vytvořit nový soubor Dockerfile -

FROM dummy:0.1

RUN apk del python3 && apk add --no-cache perl

ENTRYPOINT ["perl", "-e", "print \"Hello World\n\""]

Pokud bude tento obrázek vytvořen, bude mít celkem pět vrstev.

articles/Modify a Docker Image on  modify-docker-images [?] took 3s 
❯ docker image history dummy:0.2
IMAGE          CREATED          CREATED BY                                      SIZE      COMMENT
2792036ddc91   10 seconds ago   /bin/sh -c #(nop)  ENTRYPOINT ["perl" "-e" "…   0B        
b1b2ec1cf869   11 seconds ago   /bin/sh -c apk del python3 && apk add --no-c…   34.6MB    
ecb8694b5294   3 hours ago      /bin/sh -c #(nop)  ENTRYPOINT ["python3" "-c…   0B        
8017025d71f9   3 hours ago      /bin/sh -c apk add --no-cache python3 &&    …   43.6MB    
28f6e2705743   38 hours ago     /bin/sh -c #(nop)  CMD ["/bin/sh"]              0B        
<missing>      38 hours ago     /bin/sh -c #(nop) ADD file:80bf8bd014071345b…   5.61MB

Velikost obrázku je také 83,8 MB.

articles/Modify a Docker Image on  modify-docker-images [?] 
❯ docker images
REPOSITORY   TAG       IMAGE ID       CREATED          SIZE
dummy        0.2       2792036ddc91   19 seconds ago   83.8MB

Nyní místo toho vezměte počáteční soubor Dockerfile a změňte soubory Python3 na Perl takto

FROM alpine:latest

RUN apk add --no-cache perl

ENTRYPOINT ["perl", "-e", "print \"Hello World\n\""]

Počet vrstev se snížil na 3 a velikost je nyní 40,2 MB.

articles/Modify a Docker Image on  modify-docker-images [?] took 3s 
❯ docker image history dummy:0.3
IMAGE          CREATED         CREATED BY                                      SIZE      COMMENT
f35cd94c92bd   9 seconds ago   /bin/sh -c #(nop)  ENTRYPOINT ["perl" "-e" "…   0B        
053a6a6ba221   9 seconds ago   /bin/sh -c apk add --no-cache perl              34.6MB    
28f6e2705743   38 hours ago    /bin/sh -c #(nop)  CMD ["/bin/sh"]              0B        
<missing>      38 hours ago    /bin/sh -c #(nop) ADD file:80bf8bd014071345b…   5.61MB    

articles/Modify a Docker Image on  modify-docker-images [?] 
❯ docker images
REPOSITORY   TAG       IMAGE ID       CREATED          SIZE
dummy        0.3       f35cd94c92bd   29 seconds ago   40.2MB

Obrázek byl úspěšně změněn.

Předchozí metoda je užitečnější, když se chystáte pouze přidat vrstvy na stávající vrstvy, ale není příliš užitečná, když se pokoušíte upravit existující vrstvy, jako je odstranění jedné, nahrazení jedné, změna pořadí stávajících a již brzy. To je místo, kde tato metoda září.

Metoda 2:Úprava obrazu pomocí docker commit

Existuje další metoda, kdy můžete pořídit snímek běžícího kontejneru a přeměnit jej na vlastní obrázek.

Pojďme vytvořit dummy:0.1 identický obrázek, ale tentokrát bez použití Dockerfile. Protože jsem použil alpine:latest jako dummy:0.1 's base, roztočte kontejner tohoto obrázku.

docker run --rm --name alpine -ti alpine ash

Nyní do kontejneru přidejte balíček Python3, apk add --no-cache python3 . Po dokončení otevřete nové okno terminálu a spusťte následující příkaz (nebo něco podobného)

docker container commit --change='ENTRYPOINT ["python3", "-c", "print(\"Hello World\")"]' alpine dummy:0.4

Pomocí --change flag Přidávám instrukci Dockerfile do nového dummy:04 obrázek (v tomto případě ENTRYPOINT instrukce).

Pomocí docker container commit V podstatě převedete nejvzdálenější r/w vrstvu na r/o vrstvu, přidáte ji k vrstvám stávajícího obrázku a vytvoříte nový obrázek. Tato metoda je intuitivnější/interaktivnější, takže ji možná budete chtít použít místo Dockerfiles, ale uvědomte si, že to není příliš reprodukovatelné. Stejná pravidla platí také pro odstranění nebo změnu jakýchkoli existujících vrstev, přidání vrstvy jen za účelem odstranění něčeho nebo změny něčeho provedeného v předchozí vrstvě není nejlepší nápad, alespoň ve většině případů.

Tím tento článek končí. Doufám, že vám to pomohlo, pokud máte nějaké dotazy, napište níže.


Docker
  1. Jak přesunout obrazy Dockeru mezi hostiteli

  2. Jak použít Dockerfile k vytvoření Docker Image

  3. Jak potvrdit změny v obrazu Dockeru

  1. Jak zmenšit velikost obrázku Docker:6 metod optimalizace

  2. Jak zabalit a přenést obrazy Dockeru z jednoho serveru na druhý

  3. Jak sdílet obrázky Docker s ostatními

  1. Docker:Jak jej používat v praxi - Část 3

  2. Začínáme s předpřipravenými obrázky Docker

  3. Jak analyzovat a prozkoumat obsah obrázků Docker