Cyfroteka.pl

klikaj i czytaj online

Cyfro
Czytomierz
00306 007478 18994605 na godz. na dobę w sumie
Kubernetes. Tworzenie niezawodnych systemów rozproszonych - książka
Kubernetes. Tworzenie niezawodnych systemów rozproszonych - książka
Autor: , , Liczba stron: 224
Wydawca: Helion Język publikacji: polski
ISBN: 978-83-283-5235-3 Data wydania:
Lektor:
Kategoria: ebooki >> komputery i informatyka >> hardware >> raspberry pi
Porównaj ceny (książka, ebook, audiobook).

Systemy rozproszone miały być odpowiedzią na zwiększone wymagania wobec systemów informatycznych. Chodziło o takie cechy jak łatwe współużytkowanie zasobów, odporność na awarie, prostota rozbudowy czy skalowalność. Z czasem okazało się, że możliwości systemów rozproszonych mogą być jeszcze bardziej atrakcyjne. Równocześnie jednak architekci, programiści i w końcu również administratorzy systemów doświadczali na własnej skórze, że projektowanie, budowa i utrzymywanie systemu rozproszonego niesie ze sobą wyzwania, o jakich nie mieli pojęcia twórcy systemów wcześniejszych generacji. Wyjściem z tej trudnej sytuacji mogą być rozwijane w ostatnich latach kontenery i interfejsy API orkiestracji kontenerów, takie jak Kubernetes.

Ta książka jest znakomitym wprowadzeniem do Kubernetesa - udostępnionego na licencji open source orkiestratora klastrów (ang. orchestrator). Kontenery i orkiestratory są bardzo młodą technologią, jednak już teraz umożliwiają programistom budowanie i wdrażanie aplikacji z nieosiągalną dotychczas szybkością i niezawodnością. Dzięki tej książce dowiesz się, jaką rolę odgrywa Kubernetes w cyklu życia aplikacji rozproszonej. Nauczysz się wykorzystywać narzędzia i interfejsy API do automatyzacji skalowalnych systemów rozproszonych, niezależnie od tego, czy są to usługi internetowe, aplikacje do uczenia maszynowego, czy klastry komputerów Raspberry Pi. Przekonasz się, że Kubernetes i technologia kontenerowa mogą pomóc w osiągnięciu nowych poziomów prędkości, zwinności, niezawodności i wydajności.

W książce między innymi:

Niezawodny system rozproszony? Kubernetes, koniecznie!

Znajdź podobne książki Ostatnio czytane w tej kategorii

Darmowy fragment publikacji:

Tytuł oryginału: Kubernetes: Up and Running: Dive into the Future of Infrastructure Tłumaczenie: Lech Lachowski ISBN: 978-83-283-5235-3 © 2019 Helion S.A. Authorized Polish translation of the English edition of Kubernetes: Up and Running ISBN 9781491935675 © 2017 Kelsey Hightower, Brendan Burns, and Joe Beda. This translation is published and sold by permission of O’Reilly Media, Inc., which owns or controls all rights to publish and sell the same. All rights reserved. No part of this book may be reproduced or transmitted in any form or by any means, electronic or mechanical, including photocopying, recording or by any information storage retrieval system, without permission from the Publisher. Wszelkie prawa zastrzeżone. Nieautoryzowane rozpowszechnianie całości lub fragmentu niniejszej publikacji w jakiejkolwiek postaci jest zabronione. Wykonywanie kopii metodą kserograficzną, fotograficzną, a także kopiowanie książki na nośniku filmowym, magnetycznym lub innym powoduje naruszenie praw autorskich niniejszej publikacji. Wszystkie znaki występujące w tekście są zastrzeżonymi znakami firmowymi bądź towarowymi ich właścicieli. Autor oraz Helion SA dołożyli wszelkich starań, by zawarte w tej książce informacje były kompletne i rzetelne. Nie biorą jednak żadnej odpowiedzialności ani za ich wykorzystanie, ani za związane z tym ewentualne naruszenie praw patentowych lub autorskich. Autor oraz Helion SA nie ponoszą również żadnej odpowiedzialności za ewentualne szkody wynikłe z wykorzystania informacji zawartych w książce. Helion SA ul. Kościuszki 1c, 44-100 Gliwice tel. 32 231 22 19, 32 230 98 63 e-mail: helion@helion.pl WWW: http://helion.pl (księgarnia internetowa, katalog książek) Pliki z przykładami omawianymi w książce można znaleźć pod adresem: ftp://ftp.helion.pl/przyklady/kubern.zip Drogi Czytelniku! Jeżeli chcesz ocenić tę książkę, zajrzyj pod adres http://helion.pl/user/opinie/kubern Możesz tam wpisać swoje uwagi, spostrzeżenia, recenzję. Printed in Poland. • Kup książkę • Poleć książkę • Oceń książkę • Księgarnia internetowa • Lubię to! » Nasza społeczność Spis treści Przedmowa ...................................................................................... 13 Prędkość Wartość niemutowalności Deklaratywna konfiguracja Systemy samonaprawiające się 1. Wprowadzenie ................................................................................. 19 20 21 22 23 24 24 25 Rozłączność Łatwe skalowanie aplikacji i klastrów Skalowanie zespołów programistycznych za pomocą mikrousług Separacja zagadnień dla zapewnienia spójności i skalowania Skalowanie usługi i zespołów programistycznych Zapewnianie abstrakcji infrastruktury Wydajność Podsumowanie 26 27 29 30 31 Obrazy kontenerów Format obrazu Dockera 2. Tworzenie i uruchamianie kontenerów ............................................. 33 34 35 37 37 37 38 Pliki Dockerfile Bezpieczeństwo obrazu Optymalizacja rozmiarów obrazu Budowanie obrazów aplikacji za pomocą Dockera 5 Poleć książkęKup książkę Przechowywanie obrazów w zdalnym rejestrze Środowisko wykonawcze kontenera Dockera Uruchamianie kontenerów za pomocą Dockera Odkrywanie aplikacji kuard Ograniczanie wykorzystania zasobów Czyszczenie Podsumowanie 39 40 41 41 41 42 43 Instalowanie Kubernetes w usłudze dostawcy publicznej chmury Google Container Service Instalowanie Kubernetes w Azure Container Service Instalowanie Kubernetes w Amazon Web Services Lokalna instalacja Kubernetes za pomocą minikube Uruchamianie Kubernetes na Raspberry Pi Klient Kubernetes 3. Wdrażanie klastra Kubernetes ..........................................................45 46 46 46 47 48 49 49 49 50 52 53 53 53 54 Sprawdzanie statusu klastra Wyświetlanie węzłów roboczych klastra Kubernetes Komponenty klastra Serwer proxy Kubernetes Serwer DNS Kubernetes Interfejs użytkownika Kubernetes Podsumowanie 4. Typowe polecenia kubectl .................................................................55 55 55 56 57 58 58 59 Przestrzenie nazw Konteksty Przeglądanie obiektów interfejsu API Kubernetes Tworzenie, aktualizacja i niszczenie obiektów Kubernetes Dodawanie etykiet i adnotacji do obiektów Polecenia debugowania Podsumowanie 6  Spis treści Poleć książkęKup książkę Tworzenie kapsuły Tworzenie manifestu kapsuły Wyświetlanie listy kapsuł Szczegółowe informacje o kapsule Usuwanie kapsuły Uzyskiwanie dostępu do kapsuły Kapsuły w Kubernetes Myślenie w kategoriach kapsuł Manifest kapsuły 5. Kapsuły ............................................................................................ 61 62 63 63 64 65 66 66 67 68 69 Korzystanie z przekierowania portów 69 Uzyskiwanie większej ilości informacji za pomocą dzienników 70 Uruchamianie poleceń w kontenerze przy użyciu exec 70 71 Kopiowanie plików do i z kontenerów 71 72 73 74 74 75 77 77 78 79 80 80 82 Używanie woluminów z kapsułami Różne sposoby używania woluminów z kapsułami Utrwalanie danych przy użyciu dysków zdalnych Żądania zasobów: minimalne wymagane zasoby Ograniczanie wykorzystania zasobów za pomocą limitów Wszystko razem Podsumowanie Uruchamianie kapsuł Kontrole działania Sonda żywotności Sonda gotowości Rodzaje kontroli działania Zarządzanie zasobami Utrwalanie danych za pomocą woluminów Etykiety 6. Etykiety i adnotacje .......................................................................... 83 83 85 86 Stosowanie etykiet Modyfikowanie etykiet Spis treści  7 Poleć książkęKup książkę Selektory etykiet Selektory etykiet w obiektach API Adnotacje Definiowanie adnotacji Czyszczenie Podsumowanie 87 89 89 91 91 91 Udostępnianie usługi poza klastrem Integracja z chmurą Szczegóły dla zaawansowanych Co to jest wykrywanie usług? Obiekt Service DNS usługi Kontrole gotowości 7. Wykrywanie usług ............................................................................93 93 94 95 96 98 99 101 101 102 103 104 105 105 Punkty końcowe Ręczne wykrywanie usług kube-proxy i adresy IP klastra Zmienne środowiskowe adresu IP klastra Czyszczenie Podsumowanie Pętle uzgadniania Relacje między kapsułami i obiektami ReplicaSet 8. Obiekt ReplicaSet ............................................................................ 107 108 109 109 110 110 110 111 111 112 Adaptowanie istniejących kontenerów Poddawanie kontenerów kwarantannie Projektowanie z wykorzystaniem ReplicaSet Specyfikacja ReplicaSet Szablony kapsuł Etykiety Tworzenie obiektu ReplicaSet 8  Spis treści Poleć książkęKup książkę Inspekcja obiektu ReplicaSet Znajdowanie ReplicaSet z poziomu kapsuły Znajdowanie zestawu kapsuł dla ReplicaSet Skalowanie kontrolerów ReplicaSet Skalowanie imperatywne za pomocą polecenia kubectl scale Skalowanie deklaratywne za pomocą kubectl apply Automatyczne skalowanie kontrolera ReplicaSet Usuwanie obiektów ReplicaSet Podsumowanie 112 113 113 114 114 115 115 117 118 9. Obiekt DaemonSet .......................................................................... 119 120 121 Planista DaemonSet Tworzenie obiektów DaemonSet Ograniczanie użycia kontrolerów DaemonSet do określonych węzłów Dodawanie etykiet do węzłów Selektory węzłów Aktualizowanie obiektu DaemonSet Aktualizowanie obiektów DaemonSet poprzez usuwanie poszczególnych kapsuł Ciągła aktualizacja obiektu DaemonSet Usuwanie obiektu DaemonSet Podsumowanie 123 123 124 125 125 126 127 127 Obiekt Job Wzorce obiektu Job 10. Obiekt Job ...................................................................................... 129 129 130 131 136 138 142 Zadania jednorazowe Równoległość Kolejki robocze Podsumowanie Spis treści  9 Poleć książkęKup książkę Tajne dane Obiekty ConfigMap Tworzenie obiektów ConfigMap Używanie obiektów ConfigMap Tworzenie tajnych danych Korzystanie z tajnych danych Prywatne rejestry Dockera 11. Obiekty ConfigMap i tajne dane ...................................................... 143 143 144 145 147 149 150 151 152 153 153 154 155 157 Ograniczenia dotyczące nazewnictwa Zarządzanie obiektami ConfigMap i tajnymi danymi Wyświetlanie obiektów Tworzenie obiektów Aktualizowanie obiektów Usuwanie wdrożenia Podsumowanie 10  Spis treści Podsumowanie Twoje pierwsze wdrożenie Wewnętrzne mechanizmy działania obiektu Deployment Tworzenie obiektów Deployment Zarządzanie obiektami Deployment Aktualizowanie obiektów Deployment 12. Obiekt Deployment ......................................................................... 159 160 160 162 163 164 164 165 166 169 169 170 Skalowanie obiektu Deployment Aktualizowanie obrazu kontenera Historia wersji Strategie wdrażania Strategia Recreate Strategia RollingUpdate Spowalnianie wdrażania w celu zapewnienia poprawnego działania usługi 174 175 176 Poleć książkęKup książkę 13. Integracja rozwiązań do przechowywania danych i Kubernetes ....... 177 178 Importowanie usług zewnętrznych 180 182 182 183 187 188 188 189 192 195 196 196 Usługi bez selektorów Ograniczenia usług zewnętrznych: sprawdzanie poprawności działania Uruchamianie niezawodnych singletonów Uruchamianie singletona MySQL Dynamiczne przydzielanie woluminów Natywne magazyny danych Kubernetes z wykorzystaniem obiektów StatefulSet Właściwości obiektów StatefulSet Ręcznie zreplikowany klaster MongoDB z wykorzystaniem obiektów StatefulSet Automatyzacja tworzenia klastra MongoDB Trwałe woluminy i obiekty StatefulSet Ostatnia rzecz: sondy gotowości Podsumowanie Parse Ghost Redis Wymagania wstępne Budowanie serwera parse-server Wdrażanie serwera parse-server Testowanie Parse 14. Wdrażanie rzeczywistych aplikacji .................................................. 197 197 198 198 198 199 200 200 203 204 206 206 208 208 Konfigurowanie instalacji Redis Tworzenie usługi Redis Wdrażanie klastra Redis Zabawa z klastrem Redis Konfigurowanie serwera Ghost Podsumowanie Spis treści  11 Poleć książkęKup książkę Lista części Flashowanie obrazów Pierwsze uruchomienie: węzeł główny A Budowanie klastra Raspberry Pi Kubernetes .................................... 211 211 212 213 213 216 216 218 Konfigurowanie sieci Instalowanie Kubernetes Konfigurowanie klastra Podsumowanie Skorowidz ...................................................................................... 219 12  Spis treści Poleć książkęKup książkę ROZDZIAŁ 5. Kapsuły W poprzednich rozdziałach omawialiśmy, jak można zabrać się za konteneryzo- wanie aplikacji, ale w rzeczywistych wdrożeniach kontenerowych aplikacji często trzeba kolokować wiele aplikacji w jednej niepodzielnej jednostce rozplanowanej na pojedynczej maszynie. Na rysunku 5.1 przedstawiono kanoniczny przykład takiego wdrożenia; widać na nim kontener obsługujący żądania WWW i kontener synchronizujący system plików ze zdalnym repozytorium Git. Rysunek 5.1. Przykładowa kapsuła z dwoma kontenerami i współdzielonym systemem plików Na początku może wydawać się kuszące opakowanie zarówno serwera WWW, jak i synchronizatora Git w jeden kontener. Jednak po bliższej analizie jasne 61 Poleć książkęKup książkę stają się powody ich rozdzielenia. Po pierwsze, te dwa różne kontenery mają całkowicie odmienne wymagania dotyczące wykorzystania zasobów. Weźmy na przykład pamięć. Ponieważ serwer WWW obsługuje żądania użytkowników, chcemy zagwarantować, żeby zawsze był dostępny i responsywny. Z kolei syn- chronizator Git nie jest tak naprawdę skierowany do użytkownika i charaktery- zuje się jakością usług typu best effort. Załóżmy, że nasz synchronizator Git ma wyciek pamięci. Musimy zagwaranto- wać, żeby synchronizator Git nie wykorzystywał pamięci, której chcemy używać dla serwera WWW, ponieważ mogłoby to wpłynąć na wydajność tego serwera, a nawet spowodować jego awarię. Ten rodzaj izolacji zasobów jest dokładnie tym, w czym najlepiej sprawdzają się kontenery. Rozdzielając dwie aplikacje na dwa osobne kontenery, możemy za- pewnić niezawodne działanie serwera WWW. Oczywiście te dwa kontenery są symbiotyczne; nie ma sensu rozplanowywać serwera WWW na jednej maszynie, a synchronizatora Git na drugiej. Dlatego Kubernetes grupuje wiele kontenerów w pojedynczą niepodzielną jednostkę zwaną kapsułą (ang. pod). Kapsuły w Kubernetes Kapsuła to zbiór kontenerów aplikacji i woluminów działających w tym samym środowisku wykonawczym. Najmniejszymi możliwymi do wdrożenia w klastrze Kubernetes artefaktami są właśnie kapsuły, a nie kontenery. Oznacza to, że wszyst- kie kontenery w kapsule zawsze lądują na tej samej maszynie. Poszczególne kontenery w ramach kapsuły działają we własnych grupach kon- trolnych (cgroups), ale współdzielą wiele przestrzeni nazw Linuksa. Aplikacje działające w tej samej kapsule współdzielą ten sam adres IP i przestrzeń portów (sieciową przestrzeń nazw), mają tę samą nazwę hosta (przestrzeń nazw UTS) i mogą komunikować się za pomocą natywnych kanałów komuni- kacji międzyprocesowej poprzez kolejki komunikatów System V IPC lub POSIX (przestrzeń nazw IPC). Aplikacje w różnych kapsułach są od siebie odizolowane; mają różne adresy IP, różne nazwy hostów itd. Kontenery w różnych kapsułach działających na tym samym węźle mogą równie dobrze znajdować się na róż- nych serwerach. 62  Rozdział 5. Kapsuły Poleć książkęKup książkę Myślenie w kategoriach kapsuł Jednym z najczęstszych pytań, które pojawiają się przy adaptowaniu Kubernetes, jest: „Co należy umieścić w kapsule?”. Czasami ludzie widzą kapsuły i myślą: „Aha! Kontener WordPress i kontener bazy danych MySQL powinny znajdować się w tej samej kapsule”. Jednak taki rodzaj kapsuły jest w rzeczywistości przykładem antywzorca dla budowy kapsuł. Istnieją ku temu dwa powody. Po pierwsze, WordPress i jego baza danych nie są tak naprawdę symbiotyczne. Jeżeli kontener WordPress i kontener bazy da- nych trafią na różne maszyny, nadal mogą ze sobą całkiem skutecznie współpra- cować, ponieważ komunikują się przez połączenie sieciowe. Po drugie, nieko- niecznie powinieneś skalować WordPressa i bazę danych jako jednostkę. Sam WordPress jest głównie bezstanowy, w odpowiedzi na obciążenie frontendu możesz więc chcieć skalować frontendy WordPressa, tworząc kolejne kapsuły WordPressa. Skalowanie bazy danych MySQL jest znacznie trudniejsze i praw- dopodobnie należałoby raczej zwiększyć ilość zasobów przypisanych do poje- dynczej kapsuły MySQL. Jeśli zgrupujesz kontenery WordPress i MySQL w jednej kapsule, będziesz musiał użyć tej samej strategii skalowania dla obu kontene- rów, co nie jest zbyt dobrym rozwiązaniem. Ogólnie rzecz biorąc, pytanie, które należy zadać sobie przy projektowaniu kapsuł, jest następujące: „Czy te kontenery będą działać poprawnie, jeżeli wylą- dują na różnych maszynach?”. Jeśli odpowiedź brzmi „nie”, wtedy właściwym sposobem pogrupowania tych kontenerów jest kapsuła. Jeżeli odpowiedź brzmi „tak”, to prawdopodobnie prawidłowym rozwiązaniem jest wiele kapsuł. W przykładzie przywołanym na początku tego rozdziału dwa kontenery współ- działają poprzez lokalny system plików. Nie mogłyby działać poprawnie, gdyby zostały rozplanowane na różnych maszynach. W pozostałej części tego rozdziału opiszemy, jak tworzyć, analizować i usuwać kapsuły w Kubernetes oraz zarządzać nimi. Manifest kapsuły Kapsuły są opisane w manifeście kapsuły. Manifest kapsuły jest po prostu plikiem tekstowym reprezentującym obiekt API Kubernetes. Twórcy Kubernetes mocno wierzą w konfigurację deklaratywną. Deklaratywna konfiguracja oznacza zapisywanie żądanego stanu świata w pliku konfiguracyjnym, a następnie Manifest kapsuły  63 Poleć książkęKup książkę przesyłanie tej konfiguracji do usługi, która podejmuje działania mające zapew- nić, że pożądany stan stanie się stanem rzeczywistym. Konfiguracja deklaratywna różni się od konfiguracji impera- tywnej, w której po prostu wykonuje się serię czynności (na przy- kład apt-get install foo), aby zmodyfikować świat. Lata doświadczeń w środowisku produkcyjnym nauczyły nas, że utrzy- mywanie pisemnego zapisu żądanego stanu systemu prowadzi do uzyskania łatwiejszego w zarządzaniu, niezawodnego systemu. Konfiguracja deklaratywna zapewnia wiele korzyści, w tym moż- liwość przeglądania kodu pod kątem konfiguracji i dokumento- wania aktualnego stanu świata dla rozproszonych zespołów. Dodatkowo jest podstawą wszystkich zachowań samonapra- wiania się w Kubernetes, które pozwalają aplikacji działać bez podejmowania działań przez użytkownika. Serwer interfejsu API Kubernetes akceptuje i przetwarza manifesty kapsuł przed ich zapisaniem w pamięci trwałej (etcd). Planista również wykorzystuje API Kubernetes do znajdowania kapsuł, które nie zostały rozplanowane dla jakiegoś węzła. Następnie planista umieszcza te kapsuły na węzłach w zależności od zasobów i innych ograniczeń wyrażonych w manifestach kapsuł. Na tej samej maszynie można umieścić wiele kapsuł, o ile dostępne są wystarczające zasoby. Jednak rozplanowywanie wielu replik tej samej aplikacji na tę samą maszynę jest gorsze pod kątem niezawodności, ponieważ taka maszyna jest pojedynczą domeną awarii. W związku z tym planista Kubernetes próbuje sprawić, żeby kapsuły z tej samej aplikacji były rozmieszczane na różnych maszynach w celu zapewnienia niezawodności w przypadku wystąpienia awarii. Po rozplanowaniu na węzeł kapsuły nie przemieszczają się i aby je przenieść, trzeba je bezpośrednio zniszczyć i ponownie rozplanować. Wiele instancji kapsuły można wdrożyć, powtarzając opisany tutaj przepływ pracy. Jednak do uruchamiania wielu instancji kapsuły lepiej nadają się obiekty ReplicaSet (zobacz rozdział 8.). (Okazuje się, że są one również lepsze przy uruchamianiu pojedynczej kapsuły, ale do tego dojdziemy później). Tworzenie kapsuły Najprostszym sposobem na utworzenie kapsuły jest wykonanie imperatywnego polecenia kubectl run. Aby uruchomić na przykład nasz serwer kuard, użyj na- stępującego polecenia: 64  Rozdział 5. Kapsuły Poleć książkęKup książkę $ kubectl run kuard --image=gcr.io/kuar-demo/kuard-amd64:1 W ten sposób możesz sprawdzić status tej kapsuły: $ kubectl get pods Początkowo możesz zobaczyć kontener jako oczekujący (Pending), ale ostatecznie przekonasz się, że jego status zmieni się na działający (Running), co oznacza, że kapsuła i jej kontenery zostały pomyślnie utworzone. Nie przejmuj się zanadto losowymi łańcuchami znaków dołączonymi na końcach nazw kapsuł. W tej metodzie kapsuły są tak naprawdę tworzone za pomocą obiektów Deployment i ReplicaSet, które omówimy w kolejnych rozdziałach. Na razie możesz usunąć tę kapsułę, uruchamiając następujące polecenie: $ kubectl delete deployments/kuard Przejdziemy teraz do ręcznego napisania pełnego manifestu kapsuły. Tworzenie manifestu kapsuły Manifesty kapsuł można pisać przy użyciu formatów YAML lub JSON, ale zasad- niczo preferowany jest YAML, ponieważ daje nieco większe możliwości edycji i oferuje opcję dodawanie komentarzy. Manifesty kapsuł (i inne obiekty API Kubernetes) należy tak naprawdę traktować w ten sam sposób, w jaki traktuje się kod źródłowy, a elementy takie jak komentarze pomagają objaśnić kapsułę nowym członkom zespołu, którzy stykają się z nią po raz pierwszy. Manifesty kapsuł zawierają kilka kluczowych pól i atrybutów, między innymi: sekcję metadata do opisania kapsuły i jej etykiet, sekcję spec opisującą woluminy oraz listę kontenerów, które będą działały w kapsule. W rozdziale 2. wdrożyliśmy kuard za pomocą następującego polecenia Dockera: $ docker run -d --name kuard \ --publish 8080:8080 \ gcr.io/kuar-demo/kuard-amd64:1 Podobny rezultat można osiągnąć, wpisując kod z listingu 5.1 do pliku o nazwie kuard-pod.yaml, a następnie używając poleceń kubectl w celu załadowania tego manifestu do Kubernetes. Listing 5.1. kuard-pod.yaml apiVersion: v1 kind: Pod Manifest kapsuły  65 Poleć książkęKup książkę metadata: name: kuard spec: containers: - image: gcr.io/kuar-demo/kuard-amd64:1 name: kuard ports: - containerPort: 8080 name: http protocol: TCP Uruchamianie kapsuł W poprzednim podrozdziale utworzyliśmy manifest kapsuły, który może być użyty do zainicjowania kapsuły uruchamiającej kuard. Aby uruchomić pojedyn- czą instancję kuard, skorzystaj z polecenia kubectl apply: $ kubectl apply -f kuard-pod.yaml Manifest kapsuły zostanie przesłany na serwer API Kubernetes. Następnie system Kubernetes rozplanuje tę kapsułę, aby została uruchomiona na zdrowym węźle w klastrze, gdzie będzie monitorowana przez proces demona kubelet. Nie przejmuj się, jeśli na razie nie rozumiesz tych wszystkich ruchomych części Kubernetes; w miarę lektury tej książki będziesz poznawał coraz więcej szczegółów. Wyświetlanie listy kapsuł Skoro mamy już uruchomioną kapsułę, dowiedzmy się o niej czegoś więcej. Używając narzędzia wiersza poleceń kubectl, możemy wyświetlić wszystkie kap- suły działające w klastrze. Na razie powinna w nim być tylko jedna kapsuła, którą utworzyliśmy w poprzednim kroku: $ kubectl get pods NAME READY STATUS RESTARTS AGE kuard 1/1 Running 0 44s Możesz zobaczyć nazwę kapsuły (kuard), którą nadaliśmy jej w poprzednim pliku YAML. Oprócz liczby gotowych kontenerów (1/1) dane wyjściowe poka- zują również status, liczbę ponownych uruchomień kapsuły oraz wiek kapsuły. Jeśli uruchomiłeś to polecenie natychmiast po utworzeniu kapsuły, możesz zoba- czyć następujące dane wyjściowe: NAME READY STATUS RESTARTS AGE kuard 0/1 Pending 0 1s 66  Rozdział 5. Kapsuły Poleć książkęKup książkę Stan oczekujący (Pending) wskazuje, że kapsuła została przesłana, ale nie została jeszcze rozplanowana. Jeżeli wystąpi jakiś bardziej znaczący błąd (na przykład próba utworzenia kapsuły z obrazem kontenera, który nie istnieje), również zostanie wyświetlony w polu statusu. Domyślnie narzędzie wiersza poleceń kubectl zwraca zwięzłe informacje, ale możesz uzyskać ich więcej, stosując odpowiednią flagę wiersza poleceń. Dodanie flagi -o wide do jakiegokolwiek polecenia kubectl spowoduje wydrukowanie nieco większej ilości danych wyjściowych (nadal mieszczących się w pojedynczej linii). Dodanie flagi -o json lub -o yaml spowoduje wydruko- wanie kompletnych obiektów odpowiednio w formacie JSON lub YAML. Szczegółowe informacje o kapsule Czasami jednoliniowy wydruk jest niewystarczający, ponieważ jest zbyt lapi- darny. Kubernetes przechowuje dodatkowo różne zdarzenia związane z kapsu- łami, które są obecne w strumieniu zdarzeń, ale nie są dołączone do obiektu kapsuły. W celu uzyskania większej ilości informacji na temat kapsuły (lub dowolnego obiektu Kubernetes) możesz użyć polecenia kubectl describe. Aby opisać na przykład kapsułę, którą wcześniej utworzyliśmy, możemy uruchomić następu- jące polecenie: $ kubectl describe pods kuard Te dane wyjściowe dostarczają wiele informacji o kapsule w różnych sekcjach. Na początku znajdują się informacje podstawowe: Name: kuard Namespace: default Node: node1/10.0.15.185 Start Time: Sun, 02 Jul 2017 15:00:38 -0700 Labels: none Annotations: none Status: Running IP: 192.168.199.238 Controllers: none Uruchamianie kapsuł  67 Poleć książkęKup książkę Następnie mamy informacje o kontenerach działających w kapsule: Containers: kuard: Container ID: docker://055095… Image: gcr.io/kuar-demo/kuard-amd64:1 Image ID: docker-pullable://gcr.io/kuar-demo/ kuard-amd64@sha256:a580… Port: 8080/TCP State: Running Started: Sun, 02 Jul 2017 15:00:41 -0700 Ready: True Restart Count: 0 Environment: none Mounts: /var/run/secrets/kubernetes.io/serviceaccount from default-token-cg5f5 (ro) Na koniec podawane są zdarzenia związane z kapsułą, takie jak czas jej rozplano- wania, czas pobrania obrazu oraz informacje, czy i kiedy kapsuła musiała zostać ponownie uruchomiona z powodu niepowodzenia kontroli poprawności działania: Events: Seen From SubObjectPath Type Reason Message ---- ---- ------------- -------- ------ ------- 50s default-scheduler Normal Scheduled Success… 49s kubelet, node1 spec.containers{kuard} Normal Pulling pulling… 47s kubelet, node1 spec.containers{kuard} Normal Pulled Success… 47s kubelet, node1 spec.containers{kuard} Normal Created Created… 47s kubelet, node1 spec.containers{kuard} Normal Started Started… Usuwanie kapsuły Gdy nadejdzie czas usunięcia kapsuły, możesz ją usunąć na podstawie nazwy: $ kubectl delete pods/kuard Możesz również użyć tego samego pliku, który został wykorzystany do jej utwo- rzenia: $ kubectl delete -f kuard-pod.yaml 68  Rozdział 5. Kapsuły Poleć książkęKup książkę Po usunięciu kapsuła nie jest natychmiast niszczona. Jeżeli uruchomisz w tym momencie polecenie kubectl get pods, zobaczysz, że kapsuła jest w stanie koń- czenia działania (Terminating). Wszystkie kapsuły mają okres karencji związany z kończeniem działania. Domyślnie jest to 30 sekund. Po wejściu kapsuły w stan Terminating nie otrzymuje już ona żadnych nowych żądań. W scenariuszu ser- wowania okres karencji jest ważny dla niezawodności, ponieważ pozwala kapsule przed usunięciem zakończyć wszelkie aktywne żądania, które mogą być w trakcie przetwarzania. Należy zwrócić uwagę, że po usunięciu kapsuły wszelkie dane przechowywane w kontenerach związanych z tą kapsułą również zostaną usunięte. Jeśli chcesz zachować dane na wielu instancjach kapsuły, musisz użyć obiektu Persistent Volumes opisanego na końcu tego rozdziału. Uzyskiwanie dostępu do kapsuły Gdy kapsuła jest już uruchomiona, możesz chcieć z różnych powodów uzyskać do niej dostęp. Na przykład by załadować usługę internetową, która działa w kapsule. Możesz chcieć przejrzeć jej dzienniki w celu debugowania napotka- nego problemu lub nawet wykonać inne polecenia w kontekście kapsuły, które pomogą w debugowaniu. Poniższe punkty rozdziału opisują szczegółowo różne sposoby interakcji z kodem i danymi działającymi wewnątrz kapsuły. Korzystanie z przekierowania portów W dalszej części książki pokażemy, jak udostępnić usługę światu lub innym kon- tenerom korzystającym z mechanizmu równoważenia obciążenia, ale często chcemy po prostu uzyskać dostęp do konkretnej kapsuły, nawet jeśli nie obsłu- guje ona ruchu w internecie. W tym celu możesz użyć funkcji przekierowania portów wbudowanej w API Kubernetes oraz narzędzia wiersza poleceń. Gdy uruchomisz poniższe polecenie, zostanie utworzony bezpieczny tunel z Twojego lokalnego komputera, przez węzeł główny Kubernetes, do instancji kapsuły działającej na jednym z węzłów roboczych: $ kubectl port-forward kuard 8080:8080 Uzyskiwanie dostępu do kapsuły  69 Poleć książkęKup książkę Dopóki polecenie przekierowania portów jest uruchomione, możesz uzyskać dostęp do kapsuły (w tym przypadku do interfejsu WWW kontenera kuard), wpisując w przeglądarce adres http://localhost:8080. Uzyskiwanie większej ilości informacji za pomocą dzienników Gdy aplikacja wymaga debugowania, pomocne jest pozyskanie większej ilości informacji, niż zapewnia describe, aby zrozumieć, co robi aplikacja. Kubernetes oferuje dwa polecenia do debugowania uruchomionych kontenerów. Polecenie kubectl logs pozwala pobrać bieżące dzienniki z działającej instancji: $ kubectl logs kuard Dodanie flagi -f pozwoli na ciągłe przesyłanie dzienników. Użycie polecenia kubectl logs zawsze powoduje próbę uzyskania dzienników z aktualnie uruchomionego kontenera. Po dodaniu flagi --previous pobrane zostaną dzienniki z poprzedniej instancji kontenera. Jest to użyteczne na przykład wtedy, gdy kontenery są ciągle restartowane z powodu problemu z rozruchem kontenera. Chociaż polecenie kubectl logs jest użyteczne w przypadku jednorazowego debugowania kontenerów w środowiskach pro- dukcyjnych, zasadniczo bardziej przydaje się usługa agregacji dzienników. Istnieje kilka open source’owych narzędzi agregacji dzienników, takich jak fluentd i elasticsearch, a także wielu chmurowych dostawców rejestrowania dzienników. Usługi agre- gacji dzienników zapewniają więcej pojemności do przechowy- wania dzienników z dłuższego przedziału czasu oraz wszech- stronne funkcje wyszukiwania i filtrowania dzienników. Ponadto oferują one możliwość agregowania dzienników z wielu kapsuł w jeden widok. Uruchamianie poleceń w kontenerze przy użyciu exec Czasami dzienniki są niewystarczające i żeby naprawdę określić, co się dzieje, musisz wykonywać polecenia w kontekście samego kontenera. W tym celu mo- żesz użyć poniższego polecenia: $ kubectl exec kuard date 70  Rozdział 5. Kapsuły Poleć książkęKup książkę Możesz również uzyskać interaktywną sesję, dodając flagi -it: $ kubectl exec -it kuard ash Kopiowanie plików do i z kontenerów Czasami konieczne może być skopiowanie plików ze zdalnego kontenera na lokalny komputer w celu przeprowadzenia bardziej dogłębnej eksploracji. Do wizualizacji przechwytywania pakietów tcpdump możesz użyć na przykład narzę- dzia takiego jak Wireshark. Załóżmy, że wewnątrz kontenera w kapsule masz plik o nazwie /captures/capture3.txt. Możesz bezpiecznie skopiować ten plik na lokalną maszynę, uruchamiając następujące polecenia: $ kubectl cp nazwa_kapsuły :/captures/capture3.txt ./capture3.txt Innym razem możesz potrzebować skopiować pliki z komputera lokalnego do kontenera. Powiedzmy, że chcesz skopiować plik $HOME/config.txt do zdalnego kontenera. W tym przypadku możesz uruchomić takie polecenie: $ kubectl cp $HOME/config.txt nazwa_kapsuły :/config.txt Ogólnie rzecz biorąc, kopiowanie plików do kontenera jest antywzorcem. Na- prawdę powinieneś traktować zawartość kontenera jako niemutowalną. Jednak czasami jest to sposób na natychmiastowe powstrzymanie krwawienia i przywró- cenie usługi do zdrowia, ponieważ jest szybszy niż zbudowanie, przesłanie do rejestru i wdrożenie nowego obrazu. Gdy krwawienie zostanie już zatrzymane, zawsze bardzo ważne jest, abyś od razu przystąpił do tworzenia i wdrażania obrazu, ponieważ w przeciwnym razie na pewno zapomnisz o lokalnej zmianie, którą wprowadziłeś do swojego kontenera, i nadpiszesz ją podczas późniejszego regularnego wprowadzania kolejnej wersji. Kontrole działania Po uruchomieniu aplikacji jako kontenera w Kubernetes aplikacja ta jest auto- matycznie utrzymywana przy życiu za pomocą kontroli działania procesu (ang. process health check). Ta kontrola po prostu zapewnia, że główny proces aplikacji będzie zawsze uruchomiony. Jeśli proces zostanie wyłączony, Kuberne- tes uruchomi go ponownie. Jednak w większości przypadków prosta kontrola działania procesu jest niewy- starczająca. Jeżeli proces ulegnie na przykład zakleszczeniu i nie będzie mógł Kontrole działania  71 Poleć książkęKup książkę obsługiwać żądań, system sprawdzania działania nadal będzie traktował aplikację jako zdrową, ponieważ jej proces będzie wciąż uruchomiony. Aby rozwiązać ten problem, Kubernetes wprowadził kontrole działania pod ką- tem żywotności aplikacji. Kontrole żywotności uruchamiają logikę charakte- rystyczną dla danej aplikacji (na przykład ładowanie strony internetowej), by zweryfikować, czy aplikacja nie tylko nadal działa, ale także czy działa popraw- nie. Ponieważ kontrole żywotności są charakterystyczne dla danej aplikacji, należy je zdefiniować w manifeście kapsuły. Sonda żywotności Po uruchomieniu procesu kuard potrzebujemy sposobu weryfikacji, czy pro- ces ten naprawdę działa poprawnie i nie powinien zostać zrestartowany. Sondy żywotności są definiowane dla poszczególnych kontenerów, co oznacza, że każdy kontener wewnątrz kapsuły jest sprawdzany osobno. W kodzie z listingu 5.2 dodajemy do naszego kontenera kuard sondę żywotności, która uruchamia zażądanie HTTP dla ścieżki /healthy w kontenerze. Listing 5.2. kuard-pod-health.yaml apiVersion: v1 kind: Pod metadata: name: kuard spec: containers: - image: gcr.io/kuar-demo/kuard-amd64:1 name: kuard livenessProbe: httpGet: path: /healthy port: 8080 initialDelaySeconds: 5 timeoutSeconds: 1 periodSeconds: 10 failureThreshold: 3 ports: - containerPort: 8080 name: http protocol: TCP Powyższy manifest kapsuły używa sondy httpGet do wykonania żądania GET HTTP dla punktu końcowego /healthy na porcie 8080 kontenera kuard. Sonda ustawia początkowe opóźnienie initialDelaySeconds na 5, a zatem wywoływanie 72  Rozdział 5. Kapsuły Poleć książkęKup książkę zostanie wykonane po upływie pięciu sekund od momentu utworzenia wszyst- kich kontenerów w kapsule. Sonda musi odpowiedzieć w ciągu jednosekun- dowego limitu czasu, a kod statusu HTTP musi być równy lub większy niż 200 i mniejszy niż 400, aby wykonanie żądania zostało uznane za udane. Kubernetes będzie wywoływał tę sondę co 10 sekund. Jeżeli zawiodą więcej niż trzy sondy, kontener ulegnie awarii i zostanie uruchomiony ponownie. Możesz zobaczyć to w akcji, otwierając stronę statusu kontenera kuard. Utwórz kapsułę przy użyciu tego manifestu, a następnie przekieruj port do tej kapsuły: $ kubectl apply -f kuard-pod-health.yaml $ kubectl port-forward kuard 8080:8080 Wpisz w przeglądarce adres http://localhost:8080. Kliknij zakładkę Liveness Probe (sonda żywotności). Powinna wyświetlić się tabela zawierającą listę wszystkich sond, które otrzymała ta instancja kuard. Jeżeli klikniesz link fail na tej stronie, kuard zacznie „oblewać” kontrole poprawności działania. Poczekaj, aż Kubernetes zrestartuje kontener. W tym momencie wyświetlacz zostanie zresetowany i zaini- cjowany od nowa. Szczegółowe informacje na temat restartu można uzyskać za pomocą polecenia kubectl describe kuard. Sekcja Events (zdarzenia) będzie za- wierała dane wyjściowe podobne do tych: Killing container with id docker://2ac946...:pod kuard_default(9ee84...) container kuard is unhealthy, it will be killed and re-created. Sonda gotowości Oczywiście sonda żywotności nie jest jedynym rodzajem kontroli działania, który chcemy wykorzystać. Kubernetes dokonuje rozróżnienia pomiędzy żywotnością a gotowością. Żywotność określa, czy aplikacja działa poprawnie. Kontenery, które nie przejdą kontroli żywotności, są restartowane. Gotowość opisuje, kiedy kontener jest gotowy do obsługi żądań użytkownika. Kontenery, które nie przejdą kontroli gotowości, są usuwane z mechanizmów równoważenia obciążenia usług. Sondy gotowości są konfigurowane podobnie do sond żywotności. Szczegółowo zbadamy usługi Kubernetes w rozdziale 7. Połączenie sond gotowości i żywotności pomaga zagwarantować, że w klastrze będą działały tylko zdrowe kontenery. Kontrole działania  73 Poleć książkęKup książkę Rodzaje kontroli działania Oprócz kontroli HTTP Kubernetes obsługuje także kontrole działania tcpSocket, które otwierają gniazdo TCP; jeśli połączenie się powiedzie, kontrola się powie- dzie. Ten styl sondowania jest przydatny dla aplikacji innych niż HTTP, na przykład baz danych lub interfejsów API innych niż oparte na HTTP. Ponadto Kubernetes umożliwia przeprowadzanie sond exec. Wykonują one jakiś skrypt lub program w kontekście kontenera. Zgodnie z powszechnie przyjętą konwencją, jeżeli skrypt zwróci zerowy kod wyjścia, kontrola została wykonana z powodzeniem. W przeciwnym razie wykonanie sondy nie powiedzie się. Skrypty exec są często przydatne dla niestandardowych logik walidacji aplikacji, których nie można zweryfikować za pomocą wywołania HTTP. Zarządzanie zasobami Większość programistów przechodzi na kontenery i orkiestratory takie jak Ku- bernetes z powodu zapewnianych przez nie znacznych usprawnień w zakresie pakowania obrazów i niezawodnego wdrażania. Oprócz podstawowych elemen- tów ukierunkowanych na aplikacje, które upraszczają tworzenie systemów roz- proszonych, równie ważna jest możliwość zwiększenia ogólnego wykorzystania węzłów obliczeniowych, które tworzą klaster. Podstawowe koszty eksploatacji maszyny, wirtualnej lub fizycznej, są zasadniczo stałe niezależnie od tego, czy jest ona bezczynna, czy w pełni obciążona. Dlatego zapewnienie maksymalnej aktyw- ności maszyn zwiększa efektywność każdego dolara wydanego na infrastrukturę. Ogólnie rzecz biorąc, tę efektywność mierzy się za pomocą wskaźnika wykorzy- stania. Wykorzystanie jest definiowane jako ilość aktywnie używanych zaso- bów podzielona przez ilość zakupionych zasobów. Jeśli zakupisz na przykład maszynę jednordzeniową, a Twoja aplikacja będzie używać jedną dziesiątą rdze- nia, wskaźnik wykorzystania wyniesie 10 . Dzięki systemom planowania, takim jak Kubernetes, które zarządzają pakowa- niem zasobów, można zwiększyć poziom wykorzystania do ponad 50 . W tym celu musisz dostarczyć systemowi Kubernetes informacje o zasobach wymaganych przez aplikację, aby mógł ustalić optymalny sposób spakowania kontenerów na zakupionych maszynach. 74  Rozdział 5. Kapsuły Poleć książkęKup książkę Kubernetes umożliwia użytkownikom określenie dwóch różnych metryk zaso- bów. Żądania zasobów określają minimalną ilość zasobu wymaganą do uru- chomienia aplikacji. Limity zasobów określają maksymalną ilość zasobów, które aplikacja może wykorzystywać. Obie te definicje zasobów są opisane bar- dziej szczegółowo w kolejnych punktach rozdziału. Żądania zasobów: minimalne wymagane zasoby W Kubernetes kapsuła żąda zasobów wymaganych do uruchomienia swoich kontenerów. Kubernetes gwarantuje, że te zasoby będą dostępne dla kapsuły. Najczęściej żądanymi zasobami są CPU i pamięć, ale Kubernetes obsługuje rów- nież inne typy zasobów, między innymi GPU. Aby na przykład zażądać, żeby kontener kuard wylądował na maszynie z wolną połową zasobów procesora i otrzymał przydział 128 MB pamięci, definiujemy kapsułę tak, jak pokazano w listingu 5.3. Listing 5.3. kuard-pod-resreq.yaml apiVersion: v1 kind: Pod metadata: name: kuard spec: containers: - image: gcr.io/kuar-demo/kuard-amd64:1 name: kuard resources: requests: cpu: 500m memory: 128Mi ports: - containerPort: 8080 name: http protocol: TCP Zasoby są żądane dla poszczególnych kontenerów, a nie dla kapsuł. Całkowita ilość zasobów zażądanych przez kapsułę jest sumą wszystkich zasobów żądanych przez wszystkie kontenery w kap- sule. Jest tak dlatego, że w wielu przypadkach różne kontenery mają bardzo różne wymagania odnośnie do zasobów procesora. Przykładowo w kapsule serwera WWW i synchronizatora da- nych serwer WWW jest skierowany do użytkownika i prawdo- podobnie wymaga dużej mocy obliczeniowej, a synchronizator danych może obejść się mniejszą ilością zasobów procesora. Zarządzanie zasobami  75 Poleć książkęKup książkę Żądania i limity Żądania są używane podczas rozplanowywania kapsuł na węzły. Planista Kuber- netes gwarantuje, że suma wszystkich żądań wszystkich kapsuł na węźle nie przekroczy pojemności węzła. Dlatego kapsuła działająca na węźle może mieć zagwarantowane posiadanie przynajmniej wymaganych zasobów. Co ważne, „żądanie” określa minimum. Nie określa górnego limitu zasobów, z których może korzystać kapsuła. Aby dowiedzieć się, co to oznacza, spójrz na przykład. Wyobraź sobie, że mamy kontener, którego kod próbuje wykorzystać wszystkie dostępne rdzenie procesora. Załóżmy, że tworzymy kapsułę z tym kontenerem, która żąda połowy procesora. Kubernetes rozplanowuje tę kapsułę na maszynę z dwoma rdzeniami procesora. Dopóki jest to jedyna kapsuła na maszynie, będzie wykorzystywać wszystkie dwa dostępne rdzenie, mimo że zażądała tylko połowy procesora. Jeżeli na tę maszynę trafi druga kapsuła z tym samym kontenerem i tym samym żądaniem 0,5 CPU, wtedy każda kapsuła otrzyma jeden rdzeń. Jeśli rozplanowana zostanie trzecia identyczna kapsuła, każda kapsuła otrzyma 0,66 rdzenia. Wreszcie, jeśli rozplanowana zostanie czwarta identyczna kapsuła, każda kapsuła otrzyma pół rdzenia, którego żąda, a węzeł będzie miał komplet. Żądania CPU są realizowane za pomocą funkcjonalności cpu-share jądra Linuksa. Żądania pamięci są obsługiwane podobnie do żądań procesora, ale istnieje pewna ważna różnica. Jeśli kontener przekracza swoją żądaną pamięć, system operacyjny nie może po prostu usunąć pamięci z procesu, ponieważ została ona przydzielona. Dlatego gdy w systemie zabraknie pamięci, kubelet kończy działanie kontenerów, których użycie pamięci jest większe niż żądana pamięć. Te kontenery są automatycznie restartowane, ale z mniejszą dostępną dla nich pamięcią na komputerze. Ponieważ żądania zasobów gwarantują dostępność zasobów dla kapsuły, są one niezbędne w celu zapewnienia, by kontenery miały wystarczające zasoby w sytu- acjach dużego obciążenia. 76  Rozdział 5. Kapsuły Poleć książkęKup książkę Ograniczanie wykorzystania zasobów za pomocą limitów Oprócz ustawiania zasobów wymaganych przez kapsułę, co ustanawia minimalną ilość zasobów dostępnych dla kapsuły, możesz także definiować maksimum wykorzystania zasobów przez kapsułę, określając limity zasobów. W naszym poprzednim przykładzie utworzyliśmy kapsułę kuard, która zażądała co najmniej pół rdzenia i 128 MB pamięci. W manifeście kapsuły w listingu 5.4 rozszerzamy tę konfigurację, aby dodać limit 1 CPU i 256 MB pamięci. Listing 5.4. kuard-pod-reslim.yaml apiVersion: v1 kind: Pod metadata: name: kuard spec: containers: - image: gcr.io/kuar-demo/kuard-amd64:1 name: kuard resources: requests: cpu: 500m memory: 128Mi limits: cpu: 1000m memory: 256Mi ports: - containerPort: 8080 name: http protocol: TCP Po ustanowieniu ograniczeń dla kontenera jądro jest skonfigurowane w taki spo- sób, aby uniemożliwić wykorzystanie przekraczające te limity. Kontener z limi- tem procesora wynoszącym pół rdzenia będzie otrzymywał tylko pół rdzenia, nawet jeśli procesor będzie bezczynny. Kontener z limitem pamięci 256 MB nie będzie mógł wykorzystywać dodatkowej pamięci (nie powiedzie się na przykład malloc), jeśli jego wykorzystanie pamięci przekroczy 256 MB. Utrwalanie danych za pomocą woluminów Po usunięciu kapsuły lub ponownym uruchomieniu kontenera usuwane są również wszystkie dane z systemu plików kontenera. Często jest to dobre rozwią- zanie, ponieważ raczej nie należy pozostawiać śmieciowego kodu, który akurat Utrwalanie danych za pomocą woluminów  77 Poleć książkęKup książkę zapisała jakaś bezstanowa aplikacja internetowa. W innych przypadkach posia- danie dostępu do trwałego magazynu danych jest ważną cechą zdrowej aplikacji. Kubernetes modeluje takie trwałe magazyny przechowywania danych. Używanie woluminów z kapsułami Aby dodać wolumin do manifestu kapsuły, musimy dodać do naszej konfiguracji dwa nowe fragmenty. Pierwszy to nowa sekcja spec.volumes. Ta tablica definiuje w manifeście kapsuły wszystkie woluminy, do których mogą uzyskiwać dostęp kontenery. Należy zwrócić uwagę, że nie wszystkie kontenery muszą montować wszystkie woluminy zdefiniowane w kapsule. Drugim dodatkiem jest tablica volumeMounts w definicji kontenera. Ta tablica określa woluminy, które są mon- towane w konkretnym kontenerze, oraz ścieżki montowania poszczególnych woluminów. Zauważ, że dwa różne kontenery w kapsule mogą montować ten sam wolumin na różnych ścieżkach. Manifest w listingu 5.5 definiuje pojedynczy nowy wolumin o nazwie kuard-data, który kontener kuard montuje w ścieżce /data. Listing 5.5. kuard-pod-vol.yaml apiVersion: v1 kind: Pod metadata: name: kuard spec: volumes: - name: kuard-data hostPath: path: /var/lib/kuard containers: - image: gcr.io/kuar-demo/kuard-amd64:1 name: kuard volumeMounts: - mountPath: /data name: kuard-data ports: - containerPort: 8080 name: http protocol: TCP 78  Rozdział 5. Kapsuły Poleć książkęKup książkę Różne sposoby używania woluminów z kapsułami Istnieje wiele sposobów wykorzystania danych w aplikacji. Poniżej opisanych zostało kilka zalecanych wzorców dla Kubernetes. Komunikacja/synchronizacja W pierwszym przykładzie kapsuły zobaczyłeś, w jaki sposób dwa kontenery korzystały ze współdzielonego woluminu, aby serwować witrynę, zachowując przy tym synchronizację ze zdalną lokalizacją Git. W tym celu kapsuła używa woluminu emptyDir. Zakresem takiego woluminu jest czas życia kapsuły, ale może on być współdzielony między dwoma kontenerami, tworząc podstawę komuni- kacji między kontenerami synchronizacji Git i serwera WWW. Pamięć podręczna Aplikacja może używać woluminu, który jest istotny pod kątem wydajności, ale nie jest wymagany do poprawnego działania aplikacji. Aplikacja może na przykład przechowywać wstępnie zrenderowane miniatury większych obrazów. Oczywiście można je rekonstruować z oryginalnych obrazów, ale wówczas obsługa miniatur jest bardziej kosztowna. Taka pamięć podręczna powinna przetrwać ponowne uruchomienie kontenera spowodowane niepowodzeniami kontroli po- prawności działania, dlatego również w przypadku użycia pamięci podręcznej dobrze sprawdza się emptyDir. Trwałe dane Czasami będziesz używać woluminu dla prawdziwie trwałych danych, czyli takich, które są niezależne od czasu życia konkretnej kapsuły i powinny być przesuwane między węzłami w klastrze, jeśli jakiś węzeł ulegnie awarii lub kapsuła z jakiegoś powodu zostanie przeniesiona na inną maszynę. W tym celu Kubernetes obsłu- guje wiele różnych zdalnych woluminów sieciowej pamięci masowej, w tym szeroko obsługiwane protokoły, takie jak NFS lub iSCSI, a także sieciowe pamięci masowe dostawców chmury, takie jak Elastic Block Store firmy Amazon, Files and Disk Storage od Azure i Persistent Disk firmy Google. Utrwalanie danych za pomocą woluminów  79 Poleć książkęKup książkę Montowanie systemu plików hosta Inne aplikacje w rzeczywistości nie potrzebują trwałego woluminu, ale niektóre z nich wymagają dostępu do bazowego systemu plików hosta. Mogą na przykład potrzebować dostępu do systemu plików /dev w celu uzyskiwania nieprze- tworzonego dostępu na poziomie bloków do urządzenia w systemie. Dla takich przypadków Kubernetes obsługuje wolumin hostDir, który może montować w kontenerze dowolne lokalizacje w węźle roboczym. W poprzednim przykładzie użyliśmy typu woluminu hostDir. Utworzony wolu- min to /var/lib/kuard na hoście. Utrwalanie danych przy użyciu dysków zdalnych Często wymagane jest, aby dane używane przez kapsułę pozostawały z kapsułą, nawet jeśli zostanie ona ponownie uruchomiona na innej maszynie hosta. Aby to osiągnąć, można zamontować w kapsule zdalny wolumin sieciowy. Podczas korzystania z sieciowej pamięci masowej Kubernetes automatycznie montuje i demontuje odpowiednie woluminy za każdym razem, gdy korzystająca z nich kapsuła zostanie rozplanowana na konkretnej maszynie. Istnieje wiele metod montowania woluminów w sieci. Kubernetes obsługuje standardowe protokoły, takie jak NFS i iSCSI, a także interfejsy API chmurowej pamięci masowej dla głównych dostawców chmury (zarówno publicznej, jak i prywatnej). W wielu przypadkach dostawcy usług w chmurze utworzą dla Ciebie również dysk, jeśli jeszcze go nie masz. Oto przykład użycia serwera NFS: ... # Powyżej reszta definicji kapsuły volumes: - name: kuard-data nfs: server: my.nfs.server.local path: /exports Wszystko razem Wiele aplikacji ma charakter stanowy i jako takie muszą zachowywać wszelkie dane i zapewniać dostęp do bazowej pamięci masowej niezależnie od tego, na jakiej maszynie działa aplikacja. Jak widziałeś wcześniej, można to osiągnąć za 80  Rozdział 5. Kapsuły Poleć książkęKup książkę pomocą trwałego woluminu obsługiwanego przez sieciową pamięć masową. Chcemy również zapewnić, żeby przez cały czas działała zdrowa instancja aplikacji, co oznacza, iż chcemy mieć pewność, że kontener uruchamiający kuard będzie gotowy, zanim udostępnimy go klientom. Poprzez połączenie trwałych woluminów, sond gotowości i żywotności oraz ograniczenia zasobów Kubernetes zapewnia wszystko, co jest potrzebne do nie- zawodnego działania stanowej aplikacji. Listing 5.6 zbiera to wszystko w jeden manifest. Listing 5.6. kuard-pod-full.yaml apiVersion: v1 kind: Pod metadata: name: kuard spec: volumes: - name: kuard-data nfs: server: my.nfs.server.local path: /exports containers: - image: gcr.io/kuar-demo/kuard-amd64:1 name: kuard ports: - containerPort: 8080 name: http protocol: TCP resources: requests: cpu: 500m memory: 128Mi limits: cpu: 1000m memory: 256Mi volumeMounts: - mountPath: /data name: kuard-data livenessProbe: httpGet: path: /healthy port: 8080 initialDelaySeconds: 5 timeoutSeconds: 1 periodSeconds: 10 failureThreshold: 3 readinessProbe: Wszystko razem  81 Poleć książkęKup książkę httpGet: path: /ready port: 8080 initialDelaySeconds: 30 timeoutSeconds: 1 periodSeconds: 10 failureThreshold: 3 Trwałe woluminy to szeroki temat, który obejmuje wiele różnych szczegółowych kwestii, między innymi sposób, w jaki współpracują ze sobą trwałe woluminy, żądania trwałych woluminów i dynamiczne zapewnianie woluminów. Ten temat został omówiony szczegółowo w rozdziale 13. Podsumowanie Kapsuły reprezentują niepodzielną jednostkę pracy w klastrze Kubernetes. Skła- dają się z jednego kontenera lub większej liczby kontenerów współpracujących symbiotycznie. Aby utworzyć kapsułę, należy napisać manifest kapsuły i przesłać go do serwera API Kubernetes za pomocą jakiegoś narzędzia wiersza poleceń lub (rzadziej) poprzez wywołania HTTP i JSON wysyłane bezpośrednio do serwera. Po przesłaniu manifestu do serwera interfejsu API planista Kubernetes znajduje maszynę, na której może zmieścić się kapsuła, i rozplanowuje kapsułę na tę maszynę. Po rozplanowaniu kapsuły demon kubelet na tej maszynie jest odpo- wiedzialny za utworzenie odpowiadających tej kapsule kontenerów oraz prze- prowadzanie kontroli działania określonych w manifeście kapsuły. Gdy kapsuła zostanie rozplanowana na węzeł, nie jest przeprowadzane ponowne rozplanowanie, jeśli ten węzeł ulegnie awarii. W celu uzyskania wielu replik tej samej kapsuły trzeba je utworzyć i nazwać ręcznie. W jednym z kolejnych roz- działów przedstawimy obiekt ReplicaSet i pokażemy, jak może on zautomatyzo- wać tworzenie wielu identycznych kapsuł i pomóc upewnić się, że będą one odtwarzane w przypadku awarii maszyny węzła. 82  Rozdział 5. Kapsuły Poleć książkęKup książkę
Pobierz darmowy fragment (pdf)

Gdzie kupić całą publikację:

Kubernetes. Tworzenie niezawodnych systemów rozproszonych
Autor:
, ,

Opinie na temat publikacji:


Inne popularne pozycje z tej kategorii:


Czytaj również:


Prowadzisz stronę lub blog? Wstaw link do fragmentu tej książki i współpracuj z Cyfroteką: