Prawidłowe porównanie Kubernetes Apply, Zamień i Popraw

Kubernetes ma kilka opcji aktualizacji zasobów: zastosuj, edytuj, łataj i zastępuj. Istnieje zamieszanie co do tego, co każdy z nich robi i kiedy ich używać. Rozwiążmy to.

Prawidłowe porównanie Kubernetes Apply, Zamień i Popraw

jeśli Wyszukaj w google znajduje się fraza „kubernetes zastosuj vs zamień”. odpowiedź na StackOverflow, co nie jest prawidłowe. podczas wyszukiwania „kubernetes Apply vs patch”, pierwszy link to dokumentacja kubectl patch, co nie obejmuje porównania apply и patch. W tym artykule przyjrzymy się różnym opcjom, a także właściwemu wykorzystaniu każdej z nich.

Podczas cyklu życia zasobu Kubernetes (usługa, wdrożenie, ruch przychodzący itp.) czasami trzeba zmienić, dodać lub usunąć niektóre właściwości tego zasobu. Na przykład dodaj notatkę, zwiększ lub zmniejsz liczbę replik.

Interfejs wiersza polecenia Kubernetesa

Jeśli już pracujesz z klastrami Kubernetes za pośrednictwem interfejsu CLI, jest to już Ci znane apply и edit. Zespół apply odczytuje specyfikację zasobu z pliku i dokonuje „upsert” do klastra Kubernetes, czyli tzw. tworzy zasób, jeśli nie istnieje i aktualizuje go, jeśli istnieje. Zespół edit odczytuje zasób poprzez API, następnie zapisuje specyfikację zasobu do pliku lokalnego, który następnie jest otwierany w edytorze tekstu. Po edycji i zapisaniu pliku, kubectl wyśle ​​wprowadzone zmiany z powrotem przez API, które ostrożnie zastosuje te zmiany do zasobu.

Nie każdy zna polecenia patch и replace. Zespół patch umożliwia zmianę części specyfikacji zasobu, udostępniając w wierszu poleceń tylko zmienioną część. Zespół replace działa tak samo jak edit, ale wszystko trzeba zrobić ręcznie: trzeba pobrać aktualną wersję specyfikacji zasobu, na przykład za pomocą kubectl get -o yaml, edytuj go, a następnie użyj replace zaktualizować zasób zgodnie ze zmienioną specyfikacją. Zespół replace nie będzie działać, jeśli między odczytaniem a zastąpieniem zasobu nastąpiły jakiekolwiek zmiany.

API Kubernetesa

Prawdopodobnie znasz te metody CoreV1().Pods().Update(), replaceNamespacedService lub patch_namespaced_deployment, jeśli pracujesz z klastrami za pośrednictwem biblioteka klienta dla Kubernetes API używając jakiegoś języka programowania. Biblioteka obsługuje te metody poprzez żądania HTTP przy użyciu metod PUT и PATCH... W którym update и replace posługiwać się PUTI patch, bez względu na to, jak trywialne może to być, używa PATCH.

Należy zauważyć, że kubectl współpracuje również z klastrami poprzez API. Innymi słowy, kubectlto opakowanie na bibliotekę klienta dla języka Go, które w dużej mierze zapewnia możliwość dostarczania podpoleceń w bardziej zwartej i czytelnej formie, oprócz standardowych możliwości API. Na przykład, jak być może już zauważyłeś, metoda apply nie zostało wspomniane powyżej w poprzednim akapicie. Obecnie (maj 2020, około. tłumacz) cała logika kubectl apply, tj. tworzenie nieistniejących zasobów i aktualizacja istniejących, działa całkowicie po stronie kodu kubectl. Podejmowane są wysiłki na transferze logicznym apply po stronie API, ale nadal jest w fazie beta. Poniżej napiszę szerzej.

Domyślnie łatka

Najlepiej używany patch, jeśli chcesz zaktualizować zasób. W ten sposób obie biblioteki klienckie działają na interfejsie Kubernetes API i kubectl (nic dziwnego, ponieważ jest to opakowanie biblioteki klienta, około. tłumacz).

Pracuj strategicznie

Wszystkie drużyny kubectl apply, edit и patch użyj metody PATCH w żądaniach HTTP w celu aktualizacji istniejącego zasobu. Jeśli bardziej szczegółowo zagłębisz się w implementację poleceń, wszystkie z nich zastosują to podejście Łatanie polegające na łączeniu strategicznym aby zaktualizować zasoby, chociaż polecenie patch może zastosować inne podejścia (więcej na ten temat poniżej). Podejście polegające na łataniu strategicznego łączenia ma na celu „zrobienie tego dobrze” poprzez połączenie dostarczonej specyfikacji z istniejącą specyfikacją. Mówiąc dokładniej, próbuje połączyć zarówno obiekty, jak i tablice, co oznacza, że ​​zmiany mają charakter addytywny. Na przykład uruchomienie polecenia patch z nową zmienną środowiskową w specyfikacji kontenera pod, powoduje, że ta zmienna środowiskowa zostanie dodana do istniejących zmiennych środowiskowych, zamiast je zastępować. Aby usunąć przy użyciu tego podejścia, należy wymusić wartość parametru na null w podanej specyfikacji. Która z drużyn kubectl Czy najlepiej używać go do aktualizacji?

Jeśli tworzysz i zarządzasz swoimi zasobami za pomocą kubectl apply, podczas aktualizacji lepiej zawsze używać kubectl applyDo kubectl może zarządzać konfiguracją i właściwie śledzić żądane zmiany w poszczególnych aplikacjach. Zaleta zawsze używana apply polega na tym, że śledzi wcześniej zastosowaną specyfikację, dzięki czemu wie, kiedy właściwości specyfikacji i elementy tablicy są jawnie usuwane. Dzięki temu możesz korzystać apply aby usunąć właściwości i elementy tablicy, podczas gdy normalne scalanie strategiczne nie będzie działać. Zespoły edit и patch nie aktualizuj tego kubectl apply używa do śledzenia swoich zmian, więc wszelkie zmiany, które są śledzone i wprowadzane za pośrednictwem interfejsu API Kubernetes, ale wprowadzane za pomocą poleceń edit и patch, niewidoczny dla kolejnych poleceń applyOznacza to, że apply nie usuwa ich, nawet jeśli nie pojawiają się w specyfikacji wejściowej dla apply (Dokumentacja tak mówi edit и patch dokonaj aktualizacji używanych notatek apply, ale w praktyce - nie).

Jeśli nie użyjesz polecenia apply, może być używany jako editI patch, wybierając polecenie, które najlepiej pasuje do wprowadzanej zmiany. Podczas dodawania i zmiany właściwości BOM oba podejścia są mniej więcej takie same. Podczas usuwania właściwości specyfikacji lub elementów tablicy edit zachowuje się jak jednorazowe uruchomienie apply, w tym śledzenie, jak wyglądała specyfikacja przed i po edycji, dzięki czemu można jawnie usuwać właściwości i elementy tablicy z zasobu. Należy jawnie ustawić wartość właściwości na null w specyfikacji patchaby usunąć go z zasobu. Usuwanie elementu tablicy za pomocą łatki polegającej na łączeniu strategicznym jest bardziej złożone, ponieważ wymaga użycia dyrektyw scalających. Zobacz inne metody aktualizacji poniżej, aby uzyskać bardziej opłacalne alternatywy.

Aby zaimplementować metody aktualizacji w bibliotece klienta, które zachowują się podobnie do powyższych poleceń kubectl, należy ustawić w żądaniach content-type в application/strategic-merge-patch+json. Jeśli chcesz usunąć właściwości w specyfikacji, musisz jawnie ustawić ich wartości na null w podobny sposób kubectl patch. Jeśli chcesz usunąć elementy tablicy, powinieneś uwzględnić dyrektywy scalające w specyfikacji aktualizacji lub zastosować inne podejście do aktualizacji.

Inne podejścia do aktualizacji

Kubernetes obsługuje dwa inne podejścia do aktualizacji: Poprawka scalająca JSON и Łatka JSON. Metoda łączenia poprawek JSON przyjmuje jako dane wejściowe częściową specyfikację Kubernetes i obsługuje scalanie obiektów podobnie do podejścia polegającego na łataniu strategicznego scalania. Różnica między nimi polega na tym, że obsługuje tylko wymianę tablicy, w tym tablicę kontenerów w specyfikacji pod. Oznacza to, że korzystając z łatki scalającej JSON, należy podać pełne specyfikacje dla wszystkich kontenerów na wypadek zmiany jakiejkolwiek właściwości dowolnego kontenera. Zatem to podejście jest przydatne do usuwania elementów z tablicy w zestawieniu komponentów. W wierszu poleceń możesz wybrać łatkę scalającą JSON za pomocą kubectl patch --type=merge. Pracując z API Kubernetes warto skorzystać z metody request PATCH i instalacja content-type в application/merge-patch+json.

Metoda łatek JSON zamiast dostarczać częściową specyfikację zasobu, wykorzystuje dostarczanie zmian, które chcesz wprowadzić w zasobie, w postaci tablicy, w której każdy element tablicy reprezentuje opis zmiany wprowadzanej w zasobie. Takie podejście jest bardziej elastycznym i wydajnym sposobem wyrażania wprowadzanych zmian, ale kosztem wyszczególnienia wprowadzanych zmian w osobnym formacie innym niż Kubernetes, zamiast wysyłania częściowej specyfikacji zasobów. W kubectl możesz wybrać łatkę JSON za pomocą kubectl patch --type=json. W przypadku korzystania z interfejsu API Kubernetes to podejście działa przy użyciu metody żądania PATCH i instalacja content-type в application/json-patch+json.

Potrzebujemy zaufania - użyj zamiany

W niektórych przypadkach należy się upewnić, że między odczytaniem zasobu a jego aktualizacją nie wprowadzono żadnych zmian w zasobie. Innymi słowy, powinieneś upewnić się, że wszystkie zmiany zostaną atomowy. W takim przypadku do aktualizacji zasobów należy użyć replace. Na przykład, jeśli masz ConfigMap z licznikiem aktualizowanym przez wiele źródeł, powinieneś upewnić się, że dwa źródła nie aktualizują licznika w tym samym czasie, co spowoduje utratę aktualizacji. Aby to zademonstrować, wyobraź sobie sekwencję zdarzeń, stosując to podejście patch:

  • A i B pobierają bieżący stan zasobu z interfejsu API
  • Każdy z nich lokalnie aktualizuje specyfikację, zwiększając licznik o jeden, a także dodając odpowiednio „A” lub „B” do notatki „zaktualizowany przez”
  • I aktualizuje zasób nieco szybciej
  • B aktualizuje zasób

W rezultacie aktualizacja A zostanie utracona. Ostatnia operacja patch wygrywa, licznik jest zwiększany o jeden zamiast o dwa, a wartość notatki „zaktualizowany przez” kończy się na „B” i nie zawiera „A”. Porównajmy powyższe z tym, co dzieje się, gdy aktualizacje są wykonywane przy użyciu tego podejścia replace:

  • A i B pobierają bieżący stan zasobu z interfejsu API
  • Każdy z nich lokalnie aktualizuje specyfikację, zwiększając licznik o jeden, a także dodając odpowiednio „A” lub „B” do notatki „zaktualizowany przez”
  • I aktualizuje zasób nieco szybciej
  • B próbuje zaktualizować zasób, ale aktualizacja zostaje odrzucona przez API, ponieważ wersja zasobu jest podana w specyfikacji replace nie pasuje do bieżącej wersji zasobu w Kubernetesie, ponieważ wersja zasobu została zwiększona w wyniku operacji zamiany A.

W powyższym przypadku B będzie musiał ponownie pobrać zasób, wprowadzić zmiany w nowym stanie i spróbować ponownie replace. Spowoduje to zwiększenie licznika o dwa i notatkę „zaktualizowany przez” zawierającą „AB” na końcu.

Powyższy przykład sugeruje, że podczas wykonywania replace Cały zasób zostaje całkowicie zastąpiony. Specyfikacja używana do replace, nie może być częściowe lub w częściach jak w apply, ale kompletne, łącznie z dodatkiem resourceVersion w metadanych specyfikacji. Jeśli nie włączyłeś resourceVersion lub podana przez Ciebie wersja jest nieaktualna, zamiennik zostanie odrzucony. Najlepszym podejściem jest więc użycie replace – przeczytaj zasób, zaktualizuj go i natychmiast zastąp. Za pomocą kubectl, może to wyglądać tak:

$ kubectl get deployment my-deployment -o json 
    | jq '.spec.template.spec.containers[0].env[1].value = "new value"' 
    | kubectl replace -f -

Warto zauważyć, że następujące dwa polecenia, wykonane sekwencyjnie, zostaną wykonane pomyślnie, ponieważ deployment.yaml nie zawiera własności .metadata.resourceVersion

$ kubectl create -f deployment.yaml
$ kubectl replace -f deployment.yaml

Wydawałoby się to sprzeczne z tym, co zostało powiedziane powyżej, tj. „dodawanie resourceVersion w metadane specyfikacji.” Czy to niewłaściwe stwierdzenie? Nie, nie jest, ponieważ if kubectl uwagi, których nie określiłeś resourceVersion, odczyta go z zasobu i doda do określonej specyfikacji, a dopiero potem wykona replace. Ponieważ jest to potencjalnie niebezpieczne, jeśli polegasz na atomowości, magia działa całkowicie na boku kubectl, nie należy na nim polegać podczas korzystania z bibliotek klienckich współpracujących z interfejsem API. W takim przypadku będziesz musiał przeczytać aktualną specyfikację zasobu, zaktualizować ją, a następnie wykonać PUT żądanie.

Nie możesz zrobić łatki – my dokonujemy wymiany

Czasami trzeba wprowadzić pewne zmiany, których API nie może obsłużyć. W takich przypadkach można wymusić wymianę zasobu, usuwając go i tworząc ponownie. Odbywa się to za pomocą kubectl replace --force. Uruchomienie polecenia natychmiast usuwa zasoby, a następnie odtwarza je na podstawie dostarczonej specyfikacji. W API nie ma procedury obsługi „wymuszonej zamiany” i aby to zrobić poprzez API, należy wykonać dwie operacje. Najpierw musisz usunąć zasób, ustawiając go gracePeriodSeconds do zera (0) i propagationPolicy w „Tło”, a następnie utwórz ponownie ten zasób z żądaną specyfikacją.

Ostrzeżenie: takie podejście jest potencjalnie niebezpieczne i może prowadzić do nieokreślonego stanu.

Zastosuj po stronie serwera

Jak wspomniano powyżej, programiści Kubernetes pracują nad wdrożeniem logiki apply z kubectl w API Kubernetesa. Logika apply dostępne w Kubernetes 1.18 poprzez kubectl apply --server-side lub poprzez API przy użyciu metody PATCH с content-type application/apply-patch+YAML.

Uwaga: JSON jest również prawidłowym YAML, więc możesz wysłać specyfikację jako JSON, nawet jeśli content-type wola application/apply-patch+yaml.

Poza tą logiką kubectl staje się dostępny dla każdego poprzez API, apply po stronie serwera śledzi, kto jest odpowiedzialny za pola w specyfikacji, umożliwiając w ten sposób bezpieczny wielokrotny dostęp w celu bezkonfliktowej edycji. Innymi słowy, jeśli apply po stronie serwera staną się bardziej powszechne, pojawi się uniwersalny, bezpieczny interfejs do zarządzania zasobami dla różnych klientów, na przykład kubectl, Pulumi czy Terraform, GitOps, a także samodzielnie napisane skrypty korzystające z bibliotek klienckich.

Wyniki

Mam nadzieję, że ten krótki przegląd różnych sposobów aktualizacji zasobów w klastrach był dla Ciebie pomocny. Warto wiedzieć, że nie chodzi tylko o zastosowanie i zamianę, ale także o aktualizację zasobu poprzez zastosowanie, edycję, łatanie lub zamianę. Przecież w zasadzie każde podejście ma swój własny obszar zastosowania. W przypadku zmian atomowych preferowana jest zamiana; w przeciwnym razie powinieneś użyć łatki scalającej strategicznie poprzez zastosowanie. Przynajmniej oczekuję, że zrozumiesz, że nie możesz ufać Google ani StackOerflow, gdy szukasz „kubernetes zastosuj vs zamień”. Przynajmniej do czasu, gdy ten artykuł zastąpi obecną odpowiedź.

Prawidłowe porównanie Kubernetes Apply, Zamień i Popraw

Źródło: www.habr.com

Dodaj komentarz