Kubernetes w akcji - ebook
Kubernetes w akcji - ebook
Kubernetes w akcji uczy, jak stosować Kubernetes do wdrażania rozproszonych aplikacji opartych na kontenerach. Zanim zbudujemy swój pierwszy klaster, rozpoczniemy od przeglądu technologii Docker i Kubernetes. Następnie stopniowo będziemy rozbudowywać wstępną aplikację, dodając funkcje i pogłębiając swoją wiedzę o architekturze i działaniu Kubernetes. Opanujemy też takie ważne zagadnienia, jak monitorowanie, dostrajanie i skalowanie.
W książce omówiono:
• Wewnętrzne mechanizmy Kubernetes
• Wdrażanie kontenerów w klastrze
• Zabezpieczanie klastrów
• Aktualizowanie aplikacji bez wyłączania
Publikacja jest przeznaczona dla średnio zaawansowanych programistów, nieznających Dockera ani systemów orkiestracji kontenerów.
Kategoria: | Informatyka |
Zabezpieczenie: |
Watermark
|
ISBN: | 978-83-01-21739-6 |
Rozmiar pliku: | 10 MB |
FRAGMENT KSIĄŻKI
Pod koniec roku 2014, po kilku latach pracy w Red Hat, zostałem przydzielony do nowo utworzonego zespołu o nazwie Cloud Enablement. Naszym zadaniem było wprowadzenie całego szeregu produktów oprogramowania pośredniczącego naszej firmy do platformy kontenerów OpenShift, którą właśnie opracowywaliśmy na bazie Kubernetes. W tym czasie Kubernetes był w wieku niemowlęcym – nie wydano jeszcze nawet wersji 1.0.
Nasz zespół musiał szybko poznać tajniki Kubernetes, aby nadać właściwy kierunek naszemu oprogramowaniu i wykorzystać wszystko, co Kubernetes miał do zaoferowania. Gdy napotykaliśmy jakiś problem, trudno było nam stwierdzić, czy to my coś zrobiliśmy źle, czy po prostu trafiliśmy na jeden z wczesnych błędów Kubernetes.
Zarówno Kubernetes, jak i moja wiedza na ten temat pokonały od tego czasu długą drogę. Gdy zaczynałem używać Kubernetes, większość ludzi w ogóle jeszcze o nim nie słyszała. Obecnie niemal każdy inżynier oprogramowania wie, co to jest, i system ten stał się jednym z najszybciej rozwijających się i najszerzej stosowanych sposobów uruchamiania aplikacji, zarówno w chmurze, jak i we własnych centrach danych.
W pierwszym miesiącu zajmowania się Kubernetes napisałem dwuczęściowy post na blogu na temat uruchamiania klastra serwera aplikacji JBoss WildFly w OpenShift/Kubernetes. W tym czasie nie mogłem sobie wyobrazić, że ten prosty post ostatecznie sprawi, że redaktorzy z wydawnictwa Manning zwrócą się do mnie z pytaniem, czy nie zechciałbym napisać książki o Kubernetes. Naturalnie nie mogłem odrzucić takiej oferty, choć byłem pewien, że kontaktowali się również z innymi i ostatecznie mogli wybrać kogoś innego.
A jednak dotarliśmy tutaj. Po ponad półtora roku badań i pisania książka jest gotowa. To była niezwykła podróż. Pisanie o technologii jest zdecydowanie najlepszym sposobem, aby poznać ją znacznie dokładniej, niż moglibyśmy ją opanować po prostu jako użytkownik. W miarę pisania rosła moja wiedza o Kubernetes, ale i sam system ewoluował, zatem musiałem ciągle wracać do wcześniejszych rozdziałów, które już napisałem, i uzupełniać informacje. Jestem perfekcjonistą, zatem nigdy nie będę naprawdę usatysfakcjonowany książką, ale jestem szczęśliwy, słysząc, że wielu Czytelników wersji wstępnej udostępnionej w ramach Manning Early Access Program (MEAP) uznało ją za świetny przewodnik po Kubernetes.
Moim celem jest zapewnienie zrozumienia samej technologii i pokazanie, jak używać dostępnych narzędzi, aby skutecznie i wydajnie tworzyć oraz wdrażać aplikacje w klastrach Kubernetes. W tej książce nie położyłem większego nacisku na to, jak faktycznie zbudować i utrzymywać prawdziwie wysoko dostępny klaster Kubernetes, ale ostatnia część powinna dać Czytelnikom solidną wiedzę, z czego taki klaster się składa, i pomóc w łatwym przyswojeniu dodatkowych źródeł poświęconych tej tematyce.
Mam nadzieję, że lektura sprawi wam przyjemność i pokaże, jak wydobyć jak najwięcej z tak wspaniałego systemu, jakim jest Kubernetes.PODZIĘKOWANIA
Zanim zacząłem pisać tę książkę, nie miałem pojęcia, jak wielu ludzi będzie zaangażowanych w przekształcenie surowego manuskryptu w opublikowane dzieło. Oznacza to, że jest mnóstwo osób, którym należą się podziękowania.
Przede wszystkim dziękuję Erin Twohey za nakłonienie mnie do napisania tej książki oraz Michaelowi Stephensowi z wydawnictwa Manning, który zawsze był w pełni przekonany, że jestem w stanie ją napisać. Jego słowa zachęty zmotywowały mnie od samego początku i podtrzymywały tę motywację przez ostatnie półtora roku.
Chciałbym też podziękować mojemu pierwszemu redaktorowi, Andrew Warrenowi, który pomógł doprowadzić do końca pierwszy rozdział, oraz Elesha Hyde, która przejęła pałeczkę od Andrew i pracowała ze mną aż do ostatniego rozdziału. Dziękuję za to, że mnie znosiłaś, mimo że nie jestem łatwą osobą, jako że mam skłonność do regularnego znikania z pola widzenia.
Podziękować chciałbym również Jeanne Boyarsky, która była pierwszym recenzentem, sczytującym i komentującym moje rozdziały w trakcie ich pisania. To Jeanne i Elesha głównie sprawiły, że książka jest tak dobra, jak – mam nadzieję – jest. Bez ich komentarzy nigdy nie uzyskałaby tak dobrych opinii od zewnętrznych recenzentów i Czytelników.
Chcę też podziękować korektorowi technicznemu, Antonio Magnaghi, i oczywiście wszystkim zewnętrznym recenzentom, w kolejności alfabetycznej byli to: Al Krinker, Alessandro Campeis, Alexander Myltsev, Csaba Sari, David DiMaria, Elias Rangel, Erisk Zelenka, Fabrizio Cucci, Jared Duncan, Keith Donaldson, Michael Bright, Paolo Antinori, Peter Perlepes i Tiklu Ganguly. Ich pozytywne komentarze podtrzymywały mnie w pracy w tych chwilach, gdy zdawało mi się, że moja pisanina jest okropna i zupełnie bezużyteczna. Jednocześnie ich konstruktywny krytycyzm pomógł ulepszyć te części, które w innym przypadku wrzuciłbym razem bez dostatecznej staranności. Dziękuję za wskazywanie trudnych do zrozumienia fragmentów i sugerowanie sposobów ulepszenia książki. Dziękuję też za zadawanie właściwych pytań, które pozwoliły mi zrozumieć, że byłem w błędzie odnośnie do dwóch czy trzech kwestii we wstępnych wersjach manuskryptu.
Pragnę również podziękować Czytelnikom, którzy kupili wczesną wersję książki przez program MEAP i zgłaszali swoje komentarze na forum online lub zwracali się do mnie bezpośrednio. Do osób tych należą zwłaszcza: Vimal Kansal, Paolo Patierno i Roland Huß, którzy zwrócili uwagę na całkiem sporo niespójności i innych pomyłek. Chciałbym też podziękować wszystkim pracownikom Manning, którzy uczestniczyli w doprowadzeniu do wydania tej książki. Zanim zakończę, chcę też podziękować mojemu koledze i przyjacielowi szkolnemu, Aleš Justinowi, który wprowadził mnie do Red Hat, oraz moim wspaniałym kolegom z zespołu Cloud Enablement. Gdybym nie znalazł się w Red Hat i w tym zespole, nie mógłbym być tym, który napisał tę książkę.
Na koniec chcę podziękować mojej żonie i synowi, którzy wykazali aż nazbyt dużo zrozumienia i wsparcia w ostatnich 18 miesiącach, gdy tkwiłem zamknięty w swoim biurze, zamiast spędzać czas z nimi.
Dziękuję wam wszystkim!O KSIĄŻCE
Kubernetes w akcji ma na celu sprawić, by Czytelnik stał się wydajnym użytkownikiem Kubernetes. Przedstawia niemal wszystkie koncepcje, które trzeba poznać, aby skutecznie tworzyć i uruchamiać aplikacje w środowisku Kubernetes.
Przed zanurzeniem się w tematykę Kubernetes książka przedstawia ogólny przegląd technologii kontenerowych, takich jak Docker, włącznie z tym, jak budować kontenery, tak by nawet ci Czytelnicy, którzy wcześniej nigdy nie używali tych rozwiązań, mogli od razu przystąpić do pracy. Następnie powoli prowadzi Czytelnika przez niemal wszystko, co trzeba wiedzieć o Kubernetes – od podstawowych pojęć po kwestie kryjące się pod powierzchnią.
KTO POWINIEN PRZECZYTAĆ TĘ KSIĄŻKĘ
Książka skupia się głównie na twórcach aplikacji, ale udostępnia też przegląd zarządzania aplikacjami z perspektywy operacyjnej. Jest przeznaczona dla każdego zainteresowanego uruchamianiem i zarządzaniem aplikacjami skonteneryzowanymi na więcej niż tylko pojedynczym serwerze.
Zarówno początkujący, jak i zaawansowani inżynierowie oprogramowania, którzy chcieliby się nauczyć czegoś o technologiach kontenerów i orkiestrowaniu wielu powiązanych kontenerów w dużej skali, mogą tu zdobyć wiedzę konieczną do tworzenia, konteneryzowania i uruchamiania swoich aplikacji w środowisku Kubernetes.
Nie jest wymagana wcześniejsza znajomość ani technologii kontenerów, ani Kubernetes. Tematyka jest przedstawiana z narastającą szczegółowością i nie używa żadnego kodu źródłowego, który byłby zbyt trudny do zrozumienia dla programistów niebędących ekspertami.
Niemniej jednak Czytelnicy powinni dysponować przynajmniej podstawową wiedzą na temat programowania, sieci komputerowych i wykonywania podstawowych poleceń w systemie Linux oraz znać dobrze znane protokoły, takie jak HTTP.
ORGANIZACJA KSIĄŻKI: MAPA DROGOWA
Książka składa się z trzech części obejmujących 18 rozdziałów.
Część 1 przedstawia krótkie wprowadzenie do Dockera i Kubernetes, pokazuje, jak skonfigurować klaster Kubernetes i jak uruchomić w nim prostą aplikację. Zawiera dwa rozdziały:
■ Rozdział 1 wyjaśnia, czym jest Kubernetes, skąd się wziął i jak pomaga rozwiązywać dzisiejsze problemy zarządzania aplikacjami w wielkiej skali.
■ Rozdział 2 to praktyczny przewodnik po budowaniu obrazu kontenera i uruchamianiu go w klastrze Kubernetes. Wyjaśnia też, jak uruchomić lokalny jednowęzłowy klaster Kubernetes oraz prawdziwy, wielowęzłowy klaster w chmurze.
Część 2 przedstawia kluczowe koncepcje, które trzeba opanować, aby uruchamiać aplikacje w Kubernetes. Zawiera następujące rozdziały:
■ Rozdział 3 wprowadza podstawowy blok konstrukcyjny Kubernetes – pod – i wyjaśnia, jak porządkować pody i inne obiekty Kubernetes za pomocą etykiet.
■ Rozdział 4 pokazuje, jak Kubernetes utrzymuje dobrą kondycję aplikacji przez automatyczne restartowanie kontenerów. Pokazuje też, jak poprawnie uruchamiać zarządzane pody, skalować je w poziomie, zapewnić im odporność na awarie węzłów klastra i uruchamiać w określonej chwili w przyszłości albo okresowo.
■ Rozdział 5 pokazuje, jak pody mogą eksponować usługę, którą udostępniają klientom działającym zarówno wewnątrz, jak i na zewnątrz klastra. Pokazuje też, jak pody działające w klastrze mogą odkrywać usługi i uzyskiwać do nich dostęp, niezależnie od tego, czy są one zlokalizowane wewnątrz klastra, czy poza nim.
■ Rozdział 6 przedstawia współużytkowanie plików przez wiele kontenerów działających w tym samym podzie i jak można zarządzać trwałą pamięcią masową oraz zapewnić jej dostępność dla podów.
■ Rozdział 7 pokazuje, jak przekazywać do aplikacji działających wewnątrz podów dane konfiguracyjne i informacje poufne, takie jak poświadczenia.
■ Rozdział 8 opisuje, jak aplikacje mogą uzyskiwać informacje o środowisku Kubernetes, w którym działają, i jak mogą komunikować się z Kubernetes w celu zmiany stanu klastra.
■ Rozdział 9 przedstawia koncepcję zasobu Deployment oraz wyjaśnia właściwy sposób uruchamiania i aktualizowania aplikacji w środowisku Kubernetes.
■ Rozdział 10 wprowadza dedykowaną metodę uruchamiania aplikacji stanowych, które zazwyczaj wymagają stabilnej tożsamości i pamięci stanu.
W części 3 zanurzymy się głębiej w wewnętrzne mechanizmy klastra Kubernetes, przedstawimy kilka dodatkowych koncepcji i podsumujemy wszystko, czego nauczyliśmy się w dwóch pierwszych częściach, ale z szerszej perspektywy. Oto ostatnia grupa rozdziałów:
■ Rozdział 11 schodzi poniżej powierzchni Kubernetes i przedstawia wszystkie komponenty budujące klaster oraz to, co robi każdy z nich. Wyjaśnia też, jak pody komunikują się ze sobą przez sieć i jak usługi realizują równoważenie obciążeń między wieloma podami.
■ Rozdział 12 wyjaśnia, jak zabezpieczyć serwer API Kubernetes, a w konsekwencji cały klaster, przy użyciu uwierzytelnienia i autoryzacji.
■ Rozdział 13 pokazuje, jak pody mogą uzyskiwać dostęp do zasobów węzła i jak administrator klastra może im to uniemożliwić.
■ W rozdziale 14 zagłębimy się w ograniczanie zasobów obliczeniowych, jakiego może zużyć każda aplikacja przez skonfigurowanie jej gwarancji jakości usługi (Quality of Service), a także w monitorowanie zużycia zasobów przez indywidualne aplikacje. Pokazuje też, jak powstrzymać użytkowników przed konsumowaniem zbyt wielu zasobów.
■ Rozdział 15 zawiera omówienie konfigurowania Kubernetes w celu automatycznego skalowania liczby działających replik aplikacji, a także powiększania rozmiarów klastra, gdy bieżąca liczba węzłów nie może zaakceptować żadnych dodatkowych aplikacji.
■ Rozdział 16 pokazuje, jak zagwarantować, że pody będą rozmieszczane tylko na wybranych węzłach lub jak powstrzymać ich umieszczanie na innych. Pokazuje też, jak zagwarantować, że pewne pody będą rozmieszczane razem albo jak sprawić, aby tak się nie stało.
■ Rozdział 17 przedstawia najlepsze praktyki tworzenia aplikacji, aby stały się dobrymi obywatelami klastra. Zawiera również kilka wskazówek, jak skonfigurować swoje przepływy pracy programowania i testowania, aby zredukować opory podczas wytwarzania oprogramowania.
■ Rozdział 18 pokazuje sposoby rozszerzania Kubernetes przy użyciu własnych, niestandardowych obiektów, a także jak zrobili to inni, tworząc platformy aplikacji klasy przedsiębiorstwa.
W miarę postępów lektury Czytelnik pozna nie tylko indywidualne bloki konstrukcyjne Kubernetes, ale będzie również poszerzał swoją wiedzę na temat posługiwania się narzędziem wiersza polecenia kubectl.
KOD ZAWARTY W KSIĄŻCE
Choć ta książka nie zawiera zbyt dużo rzeczywistego kodu źródłowego, znalazło się w niej wiele manifestów zasobów Kubernetes w formacie YAML oraz poleceń powłoki wraz z ich wyjściem. Wszystkie one są sformatowane przy użyciu czcionki o stałej szerokości, jak w tym miejscu w celu odróżnienia od zwykłego tekstu.
Polecenia powłoki są głównie przedstawiane z wytłuszczeniem, aby jednoznacznie oddzielić je od danych wyjściowych, ale niekiedy dla wyróżnienia wytłuszczone są tylko najważniejsze części poleceń lub ich wyjścia. W większości przypadków wyjście poleceń zostało przeformatowane, aby mieściło się na ograniczonej powierzchni dostępnej w książce. Dodatkowo ze względu na fakt, że narzędzie CLI Kubernetes kubectl stale ewoluuje, nowsze wersje mogą zwracać więcej informacji, niż pokazano w książce. Trzeba to mieć na uwadze i nie zdziwić się, jeśli uzyskiwane wyniki nie będą dokładnie pasować.
Listingi niekiedy zawierają znacznik kontynuacji wiersza () pokazujący, że dany wiersz tekstu został zawinięty do kolejnej linii. Zawierają też odnośniki wyróżniające i objaśniające najważniejsze części.
W akapitach treściowych niektóre bardzo typowe elementy, takie jak Pod, ReplicationController, ReplicaSet, DaemonSet i tak dalej są złożone zwykłą czcionką, aby uniknąć rozpanoszenia się czcionki dla kodu i poprawić czytelność. W niektórych miejscach słowo „Pod” pisane jest wielką literą, gdy odnosimy się do zasobu Pod, natomiast małą literą, gdy odwołujemy się do rzeczywistej grupy uruchomionych kontenerów.
Wszystkie przykłady zamieszczone w książce zostały przetestowane w Kubernetes w wersji 1.8, działającym w Google Kubernetes Engine oraz w lokalnym klastrze uruchamianym przy użyciu Minikube. Pełny kod źródłowy i manifesty YAML można znaleźć w repozytorium https://github.com/luksa/kubernetesin-action albo pobrać z witryny wydawcy pod adresem www.manning.com/books/kubernetes-in-action.
FORUM KSIĄŻKI
Zakup książki Kubernetes w akcji zapewnia darmowy dostęp do prywatnego forum WWW utrzymywanego przez Manning Publications, w którym można zamieszczać komentarze na temat książki, zadawać pytania techniczne i uzyskiwać pomoc od autora oraz od innych użytkowników. W celu uzyskania dostępu do forum należy przejść do strony https://forums.manning.com/forums/kubernetes-in-action. Więcej informacji na temat różnych forów firmy Manning i obowiązujących reguł można znaleźć pod adresem https://forums.manning.com/forums/about.
Zobowiązanie firmy Manning względem Czytelników to zapewnienie miejsca, w którym może się toczyć istotny dialog między indywidualnymi Czytelnikami i między Czytelnikami a autorem. Nie gwarantuje żadnego określonego poziomu udziału ze strony autora, którego wkład w forum pozostaje ochotniczy (i nieopłacony). Sugerujemy, aby zadawać autorowi prawdziwie trudne pytania, by przyciągnąć jego uwagę! Forum oraz archiwa wcześniejszych dyskusji będą dostępne w witrynie wydawcy, jak długo książka będzie obecna na rynku.
INNE ŹRÓDŁA ONLINE
Czytelnik może znaleźć szeroki wybór dodatkowych źródeł na temat Kubernetes w następujących lokalizacjach:
■ Witryna Kubernetes: https://kubernetes.io
■ Blog Kubernetes, na którym regularnie publikowane są interesujące informacje (http://blog.kubernetes.io)
■ Kanał Slack społeczności Kubernetes: http://slack.k8s.io
■ Kanały Kubernetes oraz Cloud Native Computing Foundation na YouTube:
https://www.youtube.com/channel/UCZ2bu0qutTOM0tHYa_jkIwg
https://www.youtube.com/channel/UCvqbFHwN-nwalWPjPUKpvTA
Aby uzyskać pogłębioną wiedzę o indywidualnych zagadnieniach lub nawet wnieść wkład w Kubernetes, można również sprawdzić jedną z Kubernetes Special Interest Groups (SIGs), dostępnych pod adresem https://github.com/kubernetes/community.
Na koniec, jako że Kubernetes jest oprogramowaniem open source, bogactwo informacji dostępne jest w samym kodzie źródłowym Kubernetes. Można go znaleźć w repozytorium https://github.com/kubernetes/kubernetes i innych powiązanych repozytoriach.O AUTORZE
Marko Lukša jest inżynierem oprogramowania z ponad dwudziestoletnim doświadczeniem przy tworzeniu wszystkiego, od prostych aplikacji WWW po pełne systemy ERP, platformy i oprogramowanie pośredniczące. Pierwsze kroki w programowaniu poczynił już w roku 1985, w wieku sześciu lat, na używanym komputerze ZX Spectrum, który kupił mu ojciec. W szkole podstawowej został zwycięzcą krajowych zawodów w programowaniu Logo i uczestniczył w letnich obozach kodowania, gdzie nauczył się programowania w Pascalu. Od tego czasu tworzył oprogramowanie w szerokiej gamie języków programowania.
W szkole średniej zaczął tworzyć dynamiczne witryny WWW, gdy sieć WWW była jeszcze względnie młoda. Następnie przeszedł do tworzenia oprogramowania dla branży opieki zdrowotnej i telekomunikacji w lokalnej firmy, podczas gdy studiował informatykę na Uniwersytecie Ljubljana w Słowenii. Ostatecznie trafił do pracy w Red Hat, początkowo tworząc implementację open source Google App Engine API, wykorzystującą opracowane przez Red Hat oprogramowanie pośredniczące JBoss. Pracował także lub wniósł wkład w takie projekty, jak CDI/Weld, Infinispan/JBoss DataGrid i inne.
Począwszy od końca roku 2014, jest członkiem zespołu Cloud Enablement w firmie Red Hat, gdzie do jego obowiązków należy śledzenie najnowszych osiągnięć w Kubernetes i powiązanych technologiach oraz zagwarantowanie, że firmowe oprogramowanie pośredniczące w najlepszy sposób wykorzystuje funkcjonalności Kubernetes i OpenShift.O ILUSTRACJI NA OKŁADCE
Obraz na okładce Kubernetes w akcji to „Członek Dywanu”, tureckiej rady stanu czy też rządu. Ilustracja pochodzi ze zbioru strojów imperium otomańskiego, opublikowanego 1 stycznia 1802 roku przez Williama Millera z Old Bond Street w Londynie. Zbiór ten utracił stronę tytułową i nie byliśmy w stanie prześledzić jego dziejów do tej pory. Spis treści książki identyfikuje ilustracje po angielsku oraz francusku i każda opatrzona jest nazwiskami dwóch artystów, którzy nad nią pracowali. Obydwaj byliby niewątpliwie zaskoczeni, gdyby dowiedzieli się, że ich dzieło zdobi frontową okładkę książki o programowaniu komputerów… 200 lat później.
Zbiór ten został zakupiony przez redaktora wydawnictwa Manning na pchlim targu w „Garage” na West 26th Street na Manhattanie. Sprzedawcą był Amerykanin mieszkający w Ankarze w Turcji, a do transakcji doszło w chwili, gdy właśnie pakował swoje stoisko. Redaktor nie miał przy sobie dostatecznej ilości gotówki na ten zakup, a propozycja użycia karty kredytowej lub czeku została uprzejmie odrzucona. Jako że sprzedawca odlatywał tego wieczora z powrotem do Ankary, sytuacja wydawała się beznadziejna. Rozwiązanie? Jak się okazało, nie było potrzebne nic więcej, jak staromodna ustna umowa przypieczętowana uściskiem dłoni. Sprzedawca zaproponował, aby przelać mu pieniądze, i redaktor odszedł z informacją o banku na świstku papieru oraz zbiorem obrazów pod pachą. Nie trzeba dodawać, że pieniądze przesłał następnego dnia i nadal jesteśmy wdzięczni i pod wrażeniem zaufania, jakie ten nieznany człowiek okazał jednemu z nas. Przypomina to coś, co mogło wydarzyć się dawno temu.
Wydawnictwo Manning celebruje innowacyjność, inicjatywę i – tak – frajdę związaną z branżą komputerową, używając okładek opartych na bogatej różnorodności regionalnych strojów sprzed dwóch stuleci, przywróconych do życia dzięki ilustracjom z tej kolekcji.2
Pierwsze kroki z Dockerem i Kubernetes
W tym rozdziale:
■ Tworzenie, uruchamianie i udostępnianie obrazu kontenera przy użyciu Dockera
■ Uruchamianie lokalnego, jednowęzłowego klastra Kubernetes
■ Konfigurowanie klastra Kubernetes w Google
■ Kubernetes Engine
■ Konfigurowanie i używanie klienta wiersza poleceń kubectl
■ Wdrażanie aplikacji w Kubernetes i skalowanie jej w poziomie
Zanim zaczniemy szczegółowo poznawać koncepcje Kubernetes, przyjrzyjmy się, jak utworzyć prostą aplikację, opakować ją w obraz kontenera i uruchomić w zarządzanym klastrze Kubernetes (w Google Kubernetes Engine) albo w lokalnym jednowęzłowym klastrze. Powinno to dać Czytelnikowi nieco lepszy obraz całego systemu Kubernetes i ułatwi lekturę kilku następnych rozdziałów, w których zajmiemy się podstawowymi blokami konstrukcyjnymi i koncepcjami używanymi w Kubernetes.
2.1 Tworzenie, uruchamianie i udostępnianie obrazu kontenera
Jak wiemy z poprzedniego rozdziału, uruchamianie aplikacji w Kubernetes wymaga ich zapakowania w obrazy kontenerów. Pokażemy teraz podstawowe wprowadzenie do korzystania z Dockera na wypadek, gdyby Czytelnik jeszcze go nie używał. W kolejnych kilku podrozdziałach wykonamy następujące działania:
1 Zainstalujemy Dockera i uruchomimy swój pierwszy powitalny kontener „Hello world”.
2 Utworzymy trywialną aplikację Node.js, którą później wdrożymy w Kubernetes.
3 Opakujemy aplikację w obraz kontenera, tak by mogła zostać uruchomiona jako izolowany kontener.
4 Uruchomimy kontener oparty na tym obrazie.
5 Wypchniemy obraz do Docker Hub, tak by każdy mógł go uruchomić gdziekolwiek.
2.1.1 Instalowanie Dockera i uruchamianie powitalnego kontenera
Najpierw musimy zainstalować Dockera w swoim komputerze systemu Linux. Jeśli ktoś nie używa Linuksa, może uruchomić linuksową maszynę wirtualną (VM) i uruchomić Dockera wewnątrz tej maszyny wirtualnej. Jeśli ktoś używa Maca lub Windowsów i zainstaluje Dockera zgodnie z instrukcją, Docker skonfiguruje potrzebną maszynę wirtualną i uruchomi demona Docker wewnątrz tej maszyny wirtualnej. W macierzystym systemie operacyjnym dostępny będzie wykonywalny klient Dockera, który może komunikować się z demonem wewnątrz maszyny wirtualnej.
W celu zainstalowania Dockera należy postępować zgodnie z instrukcjami dla konkretnego systemu operacyjnego, dostępnymi pod adresem http://docs.docker.com/engine/install/. Po ukończeniu instalacji będzie można użyć wykonywalnego programu klienckiego w celu uruchamiania różnych poleceń Dockera. Możemy na przykład próbować pobrać i uruchomić istniejący obraz z Docker Hub, publicznego rejestru Dockera, który zawiera gotowe do użycia obrazy kontenerów dla wielu dobrze znanych pakietów oprogramowania. Jednym z nich jest obraz busybox, którego użyjemy do wykonania prostego polecenia echo „Hello world”.
URUCHAMIANIE POWITALNEGO KONTENERA
Dla osób, które nie znają narzędzia busybox – jest to pojedynczy plik wykonywalny, który łączy w sobie wiele standardowych uniksowych narzędzi wiersza poleceń, takich jak echo, ls, gzip i tak dalej. Zamiast obrazu busybox moglibyśmy użyć również innych w pełni wyposażonych kontenerów systemu operacyjnego, takich jak Fedora, Ubuntu lub inne podobne, jeśli tylko będą one zawierać plik wykonywalny echo.
Jak uruchomić obraz busybox? Nie trzeba pobierać ani instalować czegokolwiek. Wystarczy użyć polecenia docker run i wskazać, jaki obraz ma zostać pobrany i uruchomiony oraz (opcjonalnie), jakie polecenie ma być wykonane, co widać w poniższym listingu.
Listing 2.1 Uruchamianie powitalnego kontenera przy użyciu Dockera
$ docker run busybox echo „Hello world"
Unable to find image ‘busybox:latest' locally
latest: Pulling from docker.io/busybox
9a163e0b8d13: Pull complete
fef924a0204a: Pull complete
Digest: sha256:97473e34e311e6c1b3f61f2a721d038d1e5eef17d98d1353a513007cf46ca6bd
Status: Downloaded newer image for docker.io/busybox:latest
Hello world
Nie robi to może szczególnego wrażenia, ale jeśli uwzględnimy, że cała „aplikacja” została pobrana i uruchomiona jednym poleceniem, bez konieczności jej instalowania ani czegokolwiek innego, zgodzimy się, że jest to zadziwiające. W tym przypadku aplikacja była pojedynczym plikiem wykonywalnym (busybox), ale mogłaby równie dobrze być niebywale złożoną aplikacją z mnóstwem zależności. Cały proces konfigurowania i uruchamiania aplikacji byłby dokładnie taki sam. Równie ważny jest fakt, że aplikacja została wykonana wewnątrz kontenera, w całkowitej izolacji od wszystkich innych procesów działających na naszej maszynie.
CO SIĘ DZIEJE W TLE
Rysunek 2.1 pokazuje, co dokładnie się wydarzyło po wykonaniu polecenia docker run. Najpierw Docker sprawdził, czy obraz busybox:latest jest obecny już na lokalnym komputerze. Nie był, zatem Docker ściągnął go z rejestru Docker Hub, dostępnego pod adresem https://www.docker.com/. Po pobraniu obrazu Docker utworzył kontener z tego obrazu i wykonał w nim polecenie. Polecenie echo wypisało tekst na STDOUT, po czym proces się zakończył, a kontener został zatrzymany.
Rysunek 2.1 Uruchamianie echo „Hello world” w kontenerze opartym na obrazie kontenera busybox
URUCHAMIANIE INNYCH OBRAZÓW
Uruchamianie innych istniejących obrazów kontenerów odbywa się zasadniczo tak samo jak w przypadku obrazu busybox. W istocie jest to często jeszcze prostsze, gdyż zazwyczaj nie potrzebujemy specyfikować polecenia do wykonania, jak w tym przykładzie (echo "Hello world"). Polecenie, które powinno zostać wykonane, zazwyczaj jest zaszyte w samym obrazie, ale można to zastąpić w razie potrzeby. Po wyszukaniu lub przejrzeniu obrazów publicznie dostępnych w witrynie http://hub.docker.com lub innym publicznym rejestrze możemy nakazać Dockerowi uruchomić obraz jak poniżej:
$ docker run
WERSJONOWANIE OBRAZÓW KONTENERÓW
Wszystkie pakiety oprogramowania są aktualizowane, zatem zazwyczaj istnieje więcej niż jedna wersja pakietu. Docker wspiera posługiwanie się wieloma wersjami lub wariantami tego samego obrazu pod tą samą nazwą. Każdy wariant musi mieć unikatowy znacznik (tag). Przy odwoływaniu się do obrazu bez jawnego wyspecyfikowania znacznika Docker przyjmie, że odwołujemy się do tak zwanego znacznika latest (najświeższy). Aby uruchomić inną wersję obrazu, możemy wyspecyfikować znacznik wraz z nazwą obrazu, jak poniżej:
$ docker run
2.1.2 Tworzenie trywialnej aplikacji Node.js
Teraz, gdy mamy już działającą konfigurację Dockera, utworzymy aplikację. Zbudujemy trywialną aplikację sieciową Node.js i spakujemy ją w obraz kontenera. Aplikacja będzie przyjmować żądania HTTP i odpowiadać nazwą hosta maszyny, na której jest uruchomiona. W ten sposób będziemy mogli zobaczyć, że aplikacja działająca w kontenerze widzi swoją własną nazwę hosta, a nie tę komputera macierzystego, mimo że działa w nim jak każdy inny proces. Przyda się to później, gdy wdrożymy aplikację w Kubernetes i przeskalujemy ją wszerz (przeskalujemy w poziomie, czyli uruchomimy wiele wystąpień aplikacji). Będziemy mogli zobaczyć, że nasze żądania HTTP docierają do różnych wystąpień aplikacji.
Nasza aplikacja będzie składać się z pojedynczego pliku o nazwie app.js, którego zawartość pokazana jest w poniższym listingu.
Listing 2.2 Prosta aplikacja Node.js: app.js
const http = require('http');
const os = require('os');
console.log("Kubia server starting...");
var handler = function(request, response) {
console.log("Received request from " + request.connection.remoteAddress);
response.writeHead(200);
response.end("You've hit " + os.hostname() + "\n");
};
var www = http.createServer(handler);
www.listen(8080);
Powinno być jasne, co ten kod robi. Uruchamia on serwer HTTP na porcie 8080. Serwer odpowiada na każde żądanie kodem statusu HTTP 200 OK oraz tekstem "You've hit
UWAGA Zwrócona nazwa hosta jest rzeczywistą nazwą hosta serwera, a nie nazwą, którą klient wysyła w nagłówku Host żądania HTTP.
Możemy następnie pobrać i zainstalować Node.js, aby bezpośrednio przetestować naszą aplikację, ale nie jest to konieczne, gdyż użyjemy Dockera do spakowania aplikacji w obraz kontenera i umożliwimy jego uruchomienie w dowolnym miejscu, bez konieczności pobierania ani instalowania czegokolwiek (z wyjątkiem Dockera, który musi być zainstalowany na komputerze, na którym chcemy uruchomić obraz).
2.1.3 Tworzenie Dockerfile dla obrazu
Aby spakować aplikację w obraz, musimy najpierw utworzyć plik o nazwie Dockerfile, zawierający listę instrukcji, które Docker będzie wykonywać podczas budowania obrazu. Dockerfile musi znajdować się w tym samym katalogu co plik app.js i powinien zawierać polecenia pokazane w poniższym listingu.
Listing 2.3 Plik Dockerfile dla budowania obrazu kontenera dla naszej aplikacji
FROM node:7
ADD app.js /app.js
ENTRYPOINT
Wiersz FROM definiuje obraz kontenera, którego użyjemy jako punktu wyjścia (obrazu, na którym zbudujemy nasz obraz). W tym przypadku używamy obrazu kontenera node ze znacznikiem 7. W drugim wierszu dodajemy plik app.js z katalogu lokalnego do głównego katalogu w obrazie, pod tą samą nazwą (app.js). Na koniec w trzecim wierszu definiujemy, jakie polecenie powinno zostać wykonane, gdy ktoś uruchomi obraz. W tym przypadku polecenie to node app.js.
Wybieranie obrazu bazowego
Ktoś mógłby się zastanawiać, dlaczego wybraliśmy ten konkretny obraz jako punkt wyjścia. Ponieważ nasza aplikacja jest aplikacją Node.js, potrzebujemy, aby nasz obraz zawierał binarny plik wykonywalny node, aby móc ją uruchomić. Moglibyśmy użyć dowolnego obrazu zawierającego ten plik binarny, a nawet moglibyśmy użyć bazowego obrazu dystrybucji Linuksa, takiego jak fedora lub ubuntu, i zainstalować Node.js w tym kontenerze podczas budowania obrazu. Jednak ponieważ obraz node został sporządzony specjalnie w celu uruchamiania aplikacji Node.js i zawiera wszystko, czego potrzebujemy do uruchomienia aplikacji, użyliśmy jej jako obrazu bazowego.
2.1.4 Budowanie obrazu kontenera
Teraz, gdy mamy już pliki Dockerfile i app.js, mamy wszystko, czego potrzebujemy do zbudowania obrazu. Aby to zrobić, należy wykonać poniższe polecenie Dockera:
$ docker build -t kubia .
Rysunek 2.2 pokazuje, co się dzieje w trakcie procesu budowania. Nakazaliśmy Dockerowi zbudować obraz o nazwie kubia, oparty na zawartości bieżącego katalogu (zwróćmy uwagę na kropkę na końcu polecenia build). Docker wyszuka w tym katalogu plik Dockerfile i zbuduje obraz na podstawie instrukcji zawartych w tym pliku.
Rysunek 2.2 Budowanie nowego obrazu kontenera na podstawie Dockerfile
JAK OBRAZ JEST BUDOWANY
Proces budowania nie jest wykonywany przez klienta Dockera. Zamiast tego zawartość całego katalogu jest ładowana do demona Docker i tam budowany jest obraz. Klient i demon nie muszą nawet działać na tej samej maszynie. Jeśli używamy Dockera w systemie operacyjnym innym niż Linux, klient działa w systemie operacyjnym hosta, ale demon jest uruchomiony wewnątrz maszyny wirtualnej. Ponieważ wszystkie pliki z katalogu budowania są ładowane do demona, jeśli katalog ten zawiera wiele dużych plików, a demon nie jest uruchomiony lokalnie, ładowanie to może potrwać dłużej.
WSKAZÓWKA Nie należy dołączać żadnych niepotrzebnych plików do katalogu budowania, gdyż spowolni to proces budowania – szczególnie w przypadku, gdy demon Dockera jest zlokalizowany na komputerze zdalnym.
W trakcie procesu budowania Docker najpierw ściąga obraz bazowy (node:7) z publicznego repozytorium obrazów (Docker Hub), chyba że obraz został już wcześniej ściągnięty i jest przechowywany na komputerze lokalnym.
WARSTWY OBRAZÓW
Obraz nie jest pojedynczym, wielkim plikiem binarnym, ale składa się z wielu warstw, co już mogliśmy zauważyć przy uruchamianiu przykładu busybox (było tam kilka wierszy Pull complete – po jednym dla każdej warstwy). Różne obrazy mogą współużytkować wiele warstw, co znacznie zwiększa wydajność przechowywania i transferowania obrazów. Jeśli na przykład utworzymy wiele obrazów opartych na tym samym obrazie bazowym (takim jak node:7 w naszym przykładzie), wszystkie warstwy tworzące obraz bazowy będą przechowywane tylko raz. Również podczas ściągania obrazu Docker będzie pobierać indywidualnie każdą warstwę. Wiele warstw może być już przechowywanych na naszym komputerze, zatem Docker będzie pobierać tylko te, których jeszcze nie ma.
Można sądzić, że każdy plik Dockerfile tworzy tylko jedną nową warstwę, jednak tak nie jest. Przy budowaniu obrazu tworzona jest nowa warstwa dla każdego indywidualnego polecenia w Dockerfile. W trakcie budowania obrazu, po ściągnięciu wszystkich warstw obrazu bazowego Docker utworzy nową warstwę nad nimi i doda do niej plik app.js. Następnie utworzy jeszcze jedną warstwę, która będzie specyfikować polecenie do wykonania przy uruchamianiu obrazu. Ta ostatnia warstwa zostanie oznakowana jako kubia:latest. Widać to na rysunku 2.3, który pokazuje również, jak inny obraz o nazwie other:latest będzie używać tych samych warstw obrazu Node.js, z których korzysta nasz obraz.
Rysunek 2.3 Obrazy kontenerów składają się z warstw, które mogą być współużytkowane przez różne obrazy
Po ukończeniu procesu budowania mamy nowy, lokalnie przechowywany obraz. Możemy go zobaczyć, nakazując Dockerowi wylistowanie wszystkich lokalnie przechowywanych obrazów, co pokazuje poniższy listing.
Listing 2.4 Wyliczanie obrazów przechowywanych lokalnie
$ docker images
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
kubia latest d30ecc7419e7 1 minute ago 637.1 MB ...
PORÓWNYWANIE BUDOWANIA OBRAZÓW PRZY UŻYCIU DOCKERFILE Z RĘCZNYM TWORZENIEM
Pliki Dockerfile to typowy sposób budowania obrazów kontenerów przy użyciu Dockera, ale można również zbudować obraz ręcznie, uruchamiając kontener z istniejącego obrazu, wykonując polecenia w tym kontenerze, zamykając kontener i zatwierdzając jego stan finalny jako nowy obraz. Dokładnie to następuje, gdy budujemy obraz przy użyciu Dockerfile, ale jest wykonywane automatycznie i jest powtarzalne, co pozwala na dokonanie zmian w Dockerfile i odbudowanie obrazu w dowolnej chwili bez konieczności ponownego ręcznego wpisywania wszystkich poleceń.
2.1.5 Uruchamianie obrazu kontenera
Możemy teraz uruchomić nasz obraz poniższym poleceniem:
$ docker run --name kubia-container -p 8080:8080 -d kubia
Nakazuje ono Dockerowi uruchomienie nowego kontenera o nazwie kubia-container na podstawie obrazu kubia. Kontener ten zostanie odłączony (detached) od konsoli (flaga -d), co oznacza, że będzie działać w tle. Port 8080 lokalnego komputera zostanie zamapowany na port 8080 wewnątrz kontenera (opcja -p 8080:8080), zatem będziemy mogli uzyskać dostęp do aplikacji przez http://localhost:8080.
Jeśli demon Docker nie działa na komputerze lokalnym (jeśli używamy komputera Mac lub Windows, demon uruchomiony jest wewnątrz maszyny wirtualnej), trzeba użyć nazwy hosta lub adresu IP maszyny wirtualnej z działającym demonem zamiast localhost. Można ją ustalić przy użyciu zmiennej środowiskowej DOCKER_HOST.
UZYSKIWANIE DOSTĘPU DO NASZEJ APLIKACJI
Spróbujmy teraz odwołać się do aplikacji pod adresem http://localhost:8080.(trzeba pamiętać, aby zastąpić localhost nazwą hosta lub adresem IP hosta Docker, jeśli to konieczne):
$ curl localhost:8080
You've hit 44d76963e8e1
Taka jest odpowiedź naszej aplikacji. Nasza malutka aplikacja działa teraz wewnątrz kontenera, izolowana od wszystkiego innego. Jak widzimy, zwraca ona 44d76963e8e1 jako nazwę hosta, a nie rzeczywistą nazwę macierzystej maszyny. Ta szesnastkowa liczba jest identyfikatorem kontenera Docker.
WYLICZANIE WSZYSTKICH DZIAŁAJĄCYCH KONTENERÓW
Wyliczmy teraz wszystkie działające kontenery w poniższym listingu, aby móc zbadać tę listę (przeedytowałem wyjście, aby było bardziej czytelne – należy sobie wyobrazić, że dwa ostatnie wiersze są kontynuacją dwóch pierwszych).
Listing 2.5 Wyliczanie działających kontenerów
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED ...
44d76963e8e1 kubia:latest "/bin/sh -c 'node ap 6 minutes ago ...
... STATUS PORTS NAMES
... Up 6 minutes 0.0.0.0:8080->8080/tcp kubia-container
Uruchomiony jest pojedynczy kontener. Dla każdego kontenera Docker wypisuje jego ID oraz nazwę, obraz użyty do uruchomienia oraz polecenie wykonywane wewnątrz kontenera.
UZYSKIWANIE DODATKOWYCH INFORMACJI O KONTENERZE
Polecenie docker ps pokazuje tylko najbardziej podstawowe informacje o kontenerach. Aby zobaczyć informacje dodatkowe, możemy użyć docker inspect:
$ docker inspect kubia-container
Docker wypisze długi plik JSON zawierający niskopoziomowe informacje o kontenerze.
2.1.6 Badanie wnętrza uruchomionego kontenera
Co jednak, jeśli chcielibyśmy zobaczyć, jak wygląda środowisko wewnątrz kontenera? Jako że wiele procesów może działać wewnątrz tego samego kontenera, możemy zawsze uruchomić dodatkowy proces, aby zobaczyć, co się dzieje wewnątrz. Można nawet uruchomić powłokę, jeśli binarny plik wykonywalny powłoki jest dostępny w obrazie.
URUCHAMIANIE POWŁOKI WEWNĄTRZ ISTNIEJĄCEGO KONTENERA
Obraz Node.js, na którym oparliśmy nasz obraz, zawiera powłokę bash, zatem możemy uruchomić powłokę wewnątrz kontenera jak poniżej:
$ docker exec -it kubia-container bash
Spowoduje to uruchomienie bash wewnątrz istniejącego kontenera kubia-container. Proces bash będzie używać tych samych przestrzeni nazw Linuksa co główny proces kontenera. Umożliwia to zbadanie kontenera od środka i zobaczenie, jak Node.js i nasza aplikacja postrzega system, gdy działa wewnątrz kontenera. Opcja -it jest skrótem dwóch opcji:
■ -i, który zapewnia, że STDIN jest otwarte. Będziemy go potrzebować, aby wpisywać polecenia do powłoki.
■ -t, który alokuje pseudo terminal (TTY).
Potrzebujemy obydwu, jeśli chcemy użyć powłoki zgodnie z naszymi przyzwyczajeniami. (Jeśli pominiemy pierwszą opcję, nie będziemy mogli wpisać żadnych poleceń, a jeśli pominiemy drugą, nie pojawi się znak zachęty i niektóre polecenia zgłoszą brak ustawionej zmiennej TERM).
BADANIE KONTENERA OD ŚRODKA
Przyjrzyjmy się teraz, jak użyć powłoki w poniższym listingu, aby zobaczyć procesy uruchomione w kontenerze.
Listing 2.6 Wyliczanie procesów z wnętrza kontenera
root@44d76963e8e1:/# ps aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.1 676380 16504 ? Sl 12:31 0:00 node app.js
root 10 0.0 0.0 20216 1924 ? Ss 12:31 0:00 bash
root 19 0.0 0.0 17492 1136 ? R+ 12:38 0:00 ps aux
Widzimy tu tylko trzy procesy. Nie widzimy żadnych innych procesów należących do macierzystego systemu operacyjnego.
PROCESY W KONTENERZE DZIAŁAJĄ W MACIERZYSTYM SYSTEMIE OPERACYJNYM
Jeśli teraz otworzymy inny terminal i wyliczymy procesy w samym macierzystym systemie operacyjnym, wśród innych procesów hosta ujrzymy również procesy działające w kontenerze, co pokazuje listing 2.7.
UWAGA Jeśli ktoś używa Maca lub Windows, musi zalogować się do maszyny wirtualnej, w której działa demon Docker, aby zobaczyć te procesy.