2016-07-29 12 views
8

Jestem zdumiony, jak dobrze działa buforowanie warstw przez Dockera, ale zastanawiam się także, w jaki sposób ustala, czy może używać warstwy buforowanej, czy nie.W jaki sposób Docker wie, kiedy używać pamięci podręcznej podczas kompilacji, a kiedy nie?

Weźmy te kroki zbudować na przykład:

Step 4 : RUN npm install -g node-gyp 
---> Using cache 
---> 3fc59f47f6aa 
Step 5 : WORKDIR /src 
---> Using cache 
---> 5c6956ba5856 
Step 6 : COPY package.json . 
---> d82099966d6a 
Removing intermediate container eb7ecb8d3ec7 
Step 7 : RUN npm install 
---> Running in b960cf0fdd0a 

Na przykład jak to wiedzieć może korzystać z pamięci podręcznej warstwy dla npm install -g node-gyp ale tworzy nową warstwę dla npm install?

+3

Czy znasz https://docs.docker.com/engine/userguide/eng-image/dockerfile_best-practices/#build-cache? – Roman

Odpowiedz

3

To dlatego, że plik package.json został zmodyfikowany, patrz Removing intermediate container.

Jest to również zwykle powód, dla którego pliki informacyjne menedżera pakietów (dostawcy/innej firmy) to COPY 'ed first podczas docker build. Następnie uruchom instalację menedżera pakietów, a następnie dodaj resztę aplikacji, tj. src.

Jeśli nie masz żadnych zmian w swoich bibliotekach, te kroki są obsługiwane z pamięci podręcznej kompilacji.

+0

Pamięć podręczna może być również unieważniona przez zmianę instrukcji w 'Dockerfile' – Matt

9

Proces budowania pamięci podręcznej wyjaśniono dość dokładnie w sekcji Dockerfile best practices build cache.

  • Począwszy obrazu bazowego, który jest już w pamięci podręcznej, następna instrukcja jest porównywana wszystkich obrazów dzieci pochodzących z tego bazowej zdjęcie, aby zobaczyć, jeśli jeden z nich został zbudowany przy użyciu dokładnie taką samą dyspozycję . Jeśli nie, pamięć podręczna jest unieważniona.

  • W większości przypadków wystarczy porównać instrukcję pod numerem Dockerfile z jednym z obrazów podrzędnych. Jednak niektóre instrukcje wymagają nieco więcej badań i wyjaśnień.

  • W przypadku instrukcji ADD i COPY zawartość pliku (plików) na obrazie jest sprawdzana, a dla każdego pliku obliczana jest suma kontrolna. Ostatnio zmodyfikowane i ostatnio dostępne czasy pliku (ów) nie są w tych sumach kontrolnych uważane za . Podczas wyszukiwania w pamięci podręcznej suma kontrolna jest porównywana z sumą kontrolną w istniejących obrazach. Jeśli coś się zmieniło w pliku (plikach), takim jak zawartość i metadane, to pamięć podręczna zostanie unieważniona.

  • Oprócz poleceń ADD i COPY, sprawdzanie pamięci podręcznej nie pozwoli na sprawdzenie plików w kontenerze w celu ustalenia zgodności z pamięcią podręczną. W przypadku przykładu podczas przetwarzania komendy zaktualizowane w kontenerze pliki nie będą sprawdzane w celu określenia, czy istnieje trafienie z pamięci podręcznej . W takim przypadku sam łańcuch poleceń zostanie użyty , aby znaleźć dopasowanie.

Gdy bufor jest unieważnione, wszystkie kolejne Dockerfile polecenia wygeneruje nowe obrazy i pamięć podręczna nie zostaną wykorzystane.

Będziesz biegać w sytuacjach, w których pakiety OS, pakiety KMP albo repo Git są uaktualnione do nowszej wersji (powiedzmy ~2.3 semver w package.json) ale jako swój Dockerfile lub package.json nie aktualizowane, doker będą kontynuowane przy użyciu Pamięć podręczna.

Możliwe jest programowe wygenerowanie , które niweluje pamięć podręczną poprzez modyfikowanie linii w niektórych inteligentniejszych kontrolach (np. Pobranie najnowszego shasum gałęzi git z repo do użycia w instrukcji klonowania). Możesz także okresowo uruchamiać kompilację za pomocą --no-cache=true, aby wymusić aktualizacje.

+0

inną opcją złamania pamięci podręcznej jest użycie stałych wersji dla pakietów i aktualizacja ręczna wewnątrz pliku docker – Ohmen

+0

@Ohmen True, możesz zrobić podobne naprawione wersje w 'package.json' też. Nadal można się złapać przez zależności pakietowe. – Matt

+0

Ale jeśli ręcznie zaktualizujesz wersję w swoim pliku dokowanym, to nie jest to już samo polecenie, które spowoduje, że okno dokowane nie będzie używać pamięci podręcznej i ponownie uruchom cmd. – Ohmen