1. Omówienie
Mikronauty
Micronaut to oparta na JVM nowoczesna platforma typu full stack do tworzenia modułowych, łatwych do przetestowania mikroserwisów i aplikacji bezserwerowych. Firma Micronaut stara się zapewnić krótki czas uruchamiania, wysoką przepustowość przy minimalnym zużyciu pamięci. Programiści mogą programować przy użyciu oprogramowania Micronaut w języku Java oraz Groovy lub Kotlin.
Mikronaut zapewnia:
- Szybkie uruchamianie małe wykorzystanie pamięci – platformy IoC oparte na odbiciach wczytują i buforują dane odbicia w pamięci podręcznej dla każdego pola, metody i konstruktora w kodzie, podczas gdy w przypadku Micronaut czas uruchamiania aplikacji i wykorzystanie pamięci nie są powiązane z rozmiarem bazy kodu.
- Deklaratywny, reaktywny, kompilowany klient HTTP w czasie kompilowania – deklaratywne tworzenie reaktywnych klientów HTTP, które są wdrażane podczas kompilacji, co zmniejsza wykorzystanie pamięci.
- Nieblokujący serwer HTTP oparty na Netty – dzięki płynnej krzywej uczenia się serwer HTTP firmy Micronaut ułatwia udostępnianie interfejsów API do wykorzystania przez klienty HTTP.
- Szybkie i łatwe testowanie – łatwo uruchamiaj serwery i klienty w testach jednostkowych i od razu je uruchamiaj.
- Efektywne wstrzykiwanie zależności podczas kompilacji oraz AOP – Micronaut zapewnia prosty, zorientowany na aspekt interfejs API do programowania w czasie kompilacji, który nie wymaga odbicia.
- Tworzenie w pełni reaktywnych i nieblokujących aplikacji – Micronaut obsługuje dowolną platformę wykorzystującą strumienie reaktywne, w tym RxJava i Reactor.
Więcej informacji znajdziesz na stronie Micronaut.
Kubernetes
Kubernetes to projekt open source, który może działać w wielu różnych środowiskach, od laptopów po klastry z wieloma węzłami o wysokiej dostępności, od chmur publicznych po wdrożenia lokalne, od maszyn wirtualnych po usługi Bare Metal.
W tym module wdrożysz w Kubernetes prosty mikroserwis Micronaut oparty na Groovy, który działa w Kubernetes Engine.
Celem tego ćwiczenia w Codelabs jest uruchomienie mikroserwisu jako replikowanej usługi działającej w Kubernetes. W tym celu bierzesz kod na komputerze, zmieniasz go w obraz kontenera Dockera, a następnie uruchamiasz ten obraz w Kubernetes Engine.
Oto schemat poszczególnych części tego ćwiczenia z programowania, które pomogą Ci zrozumieć, jak elementy się ze sobą łączą. Wykorzystaj go jako pomoc podczas wykonywania ćwiczeń z programowania. Zanim dojdziesz do końca, wszystko powinno mieć sens (ale na razie możesz to pominąć).
Na potrzeby tego ćwiczenia z programowania korzystanie z zarządzanego środowiska takiego jak Kubernetes Engine (hostowana przez Google wersja Kubernetes działająca w Compute Engine) pozwala skupić się bardziej na korzystaniu z Kubernetes, a nie na konfiguracji bazowej infrastruktury.
Jeśli zamierzasz uruchomić Kubernetes na swoim komputerze lokalnym (np. na laptopie programistycznym), prawdopodobnie warto zainteresować się usługą Minikube. Umożliwia to prostą konfigurację klastra Kubernetes z 1 węzłem na potrzeby programowania i testowania. Jeśli chcesz, możesz wykonać to ćwiczenia z programowania za pomocą Minikube.
Informacje o Jib
Jib to narzędzie typu open source, które umożliwia tworzenie obrazów Dockera i OCI na potrzeby aplikacji w Javie. Jest dostępna jako wtyczki do Maven i Gradle oraz jako biblioteka Java.
Jib ma na celu:
- Szybkość – szybko wdrażaj zmiany. Jib dzieli aplikację na kilka warstw, dzieląc zależności od klas. Nie musisz już czekać, aż Docker utworzy ponownie Twoją aplikację w języku Java – wystarczy, że wdrożysz zmienione warstwy.
- Łatwa do odtwarzania – ponowne kompilowanie obrazu kontenera z tą samą zawartością zawsze powoduje wygenerowanie tego samego obrazu. Nigdy nie uruchamiaj niepotrzebnej aktualizacji.
- Daemonless – zmniejsz zależności interfejsu wiersza poleceń. Utwórz obraz Dockera w narzędziu Maven lub Gradle i przekaż go do dowolnego rejestru. Koniec z pisaniem Dockerfiles i wywołaniem kompilacji/push w usłudze Docker.
Więcej informacji na temat Jib znajdziesz na stronie projektu w GitHub.
Informacje o tym samouczku
W tym samouczku używamy przykładowego kodu z narzędzia Jib do tworzenia kontenerów dla aplikacji w Javie.
Przykładem jest prosta usługa hello world używająca platformy Micronaut i języka programowania Apache Groovy.
Czego się nauczysz
- Jak spakować prostą aplikację w Javie jako kontener Dockera za pomocą Jib
- Jak utworzyć klaster Kubernetes w Kubernetes Engine.
- Jak wdrożyć usługę Micronaut w Kubernetes w Kubernetes Engine
- Jak skalować usługę i wdrożyć uaktualnienie.
- Jak uzyskać dostęp do graficznego panelu Kubernetes.
Czego potrzebujesz
- Projekt Google Cloud Platform
- przeglądarkę, np. Chrome lub Firefox;
- znajomość standardowych edytorów tekstu systemu Linux, takich jak Vim, EMAC lub Nano;
Jak wykorzystasz ten samouczek?
Jak oceniasz swoje doświadczenie z tworzeniem aplikacji internetowych HTML/CSS?
Jak oceniasz swoje wrażenia z korzystania z usług Google Cloud Platform?
2. Konfiguracja i wymagania
Samodzielne konfigurowanie środowiska
- Zaloguj się w konsoli Google Cloud i utwórz nowy projekt lub wykorzystaj już istniejący. Jeśli nie masz jeszcze konta Gmail lub G Suite, musisz je utworzyć.
Zapamiętaj identyfikator projektu, unikalną nazwę we wszystkich projektach Google Cloud (powyższa nazwa jest już zajęta i nie będzie Ci odpowiadać). W dalszej części tego ćwiczenia w Codelabs będzie ona określana jako PROJECT_ID
.
- Następnie musisz włączyć płatności w Cloud Console, aby korzystać z zasobów Google Cloud.
Ukończenie tego ćwiczenia z programowania nie powinno kosztować zbyt wiele. Postępuj zgodnie z instrukcjami podanymi w sekcji „Czyszczenie” W tym samouczku znajdziesz wskazówki, jak wyłączyć zasoby, aby uniknąć naliczania opłat. Nowi użytkownicy Google Cloud mogą skorzystać z programu bezpłatnego okresu próbnego o wartości 300 USD.
3. Pobierz przykładowy kod źródłowy Micronaut
Po uruchomieniu Cloud Shell możesz za pomocą wiersza poleceń skopiować przykładowy kod źródłowy z katalogu głównego i zapisać go w katalogu zawierającym naszą przykładową usługę:
$ git clone https://github.com/GoogleContainerTools/jib.git
$ cd jib/examples/micronaut/
4. Rzuć okiem na kod
Nasza prosta usługa Micronaut składa się z kontrolera, który generuje złą sławę wiadomość Hello World:
@Controller("/hello") class HelloController { @Get("/") String index() { "Hello World" } }
Kontroler HelloController
odpowiada na żądania w ścieżce /hello
, a metoda index()
akceptuje żądania HTTP GET.
Dostępna jest też klasa testowa Spock do sprawdzenia, czy w danych wyjściowych jest podany właściwy komunikat.
class HelloControllerSpec extends Specification { @Shared @AutoCleanup EmbeddedServer embeddedServer = ApplicationContext.run(EmbeddedServer) @Shared @AutoCleanup RxHttpClient client = embeddedServer.applicationContext.createBean(RxHttpClient, embeddedServer.getURL()) void "test hello world response"() { when: HttpRequest request = HttpRequest.GET('/hello') String rsp = client.toBlocking().retrieve(request) then: rsp == "Hello World" } }
Ten test to coś więcej niż zwykły test jednostkowy, który uruchamia ten sam stos serwera Micronaut (opartego na platformie Netty), który jest uruchamiany w środowisku produkcyjnym. Działanie kodu w usłudze będzie więc takie samo jak w testach.
Aby sprawdzić, czy wszystko jest w porządku, możesz uruchomić to polecenie:
./gradlew test
5. Lokalne uruchamianie aplikacji
Usługę Micronaut możesz uruchomić normalnie za pomocą tego polecenia Gradle:
$ ./gradlew run
Po uruchomieniu aplikacji możesz otworzyć dodatkową instancję Cloud Shell, klikając ikonę +. Następnie za pomocą narzędzia curl możesz sprawdzić, czy otrzymujesz oczekiwane wyniki:
$ curl localhost:8080/hello
Powinien wyświetlić się prosty komunikat „Hello World”.
6. Pakowanie aplikacji jako kontenera Dockera za pomocą Jib
Następnie przygotuj aplikację do uruchomienia w Kubernetes. W tym celu wykorzystamy Jib, aby wykonać dla nas ciężką pracę, dzięki czemu nie będziemy musieli stykać się z Dockerfile
.
Uruchommy polecenie, aby utworzyć kontener:
$ ./gradlew jibDockerBuild
Oto dane wyjściowe, które powinny być widoczne:
Tagging image with generated image reference micronaut-jib:0.1. If you'd like to specify a different tag, you can set the jib.to.image parameter in your build.gradle, or use the --im age=<MY IMAGE> commandline flag. Containerizing application to Docker daemon as micronaut-jib:0.1... warning: Base image 'gcr.io/distroless/java' does not use a specific image digest - build may not be reproducible Getting base image gcr.io/distroless/java... Building dependencies layer... Building resources layer... Building classes layer... Finalizing... Container entrypoint set to [java, -cp, /app/resources:/app/classes:/app/libs/*, example.micronaut.Application] Loading to Docker daemon... Built image to Docker daemon as micronaut-jib:0.1
Skoro obraz jest już skompilowany, sprawdźmy, czy możemy wyświetlić przyjazną wiadomość powitalną, uruchamiając obraz Dockera na pierwszej karcie Cloud Shell:
$ docker run -it -p 8080:8080 micronaut-jib:0.1 16:57:20.255 [main] INFO i.m.context.env.DefaultEnvironment - Established active environments: [cloud, gcp] 16:57:23.203 [main] INFO io.micronaut.runtime.Micronaut - Startup completed in 2926ms. Server Running: http://97b7d76ccf3f:8080
Usługa działa, więc możemy teraz uruchomić polecenie curl na drugiej karcie Cloud Shell, aby sprawdzić, czy działa prawidłowo:
$ curl localhost:8080/hello Hello World
Aby zatrzymać kontener, kliknij Ctrl+C
w Cloud Shell.
7. Przekazywanie naszej usługi skonteneryzowanej do rejestru
Gdy obraz działa zgodnie z oczekiwaniami, możesz go przekazać do Google Container Registry – prywatnego repozytorium obrazów Dockera, które jest dostępne z każdego projektu Google Cloud (ale także spoza Google Cloud Platform).
Zanim będzie można przekazać dane do rejestru, sprawdź, czy Container Registry jest włączony w naszym projekcie. Aby to zrobić, kliknij Narzędzia > Container Registry. Jeśli ta opcja nie jest włączona, powinno wyświetlić się okno. Kliknij „Włącz Container Registry API”. aby ją włączyć:
Gdy rejestr będzie gotowy, prześlij do niego obraz, uruchamiając następujące polecenia:
$ gcloud auth configure-docker $ docker tag micronaut-jib:0.1 \ gcr.io/$GOOGLE_CLOUD_PROJECT/micronaut-jib:0.1 $ docker push gcr.io/$GOOGLE_CLOUD_PROJECT/micronaut-jib:0.1
Powyższe polecenia pozwalają pakietowi gcloud SDK skonfigurować i autoryzować dockera do przekazywania obrazów do Twojej instancji Container Registry, aby oznaczyć obraz tagiem wskazujący jego lokalizację w rejestrze, a następnie przekazać go do rejestru.
Jeśli wszystko pójdzie dobrze, po chwili powinien pojawić się w konsoli obraz kontenera: Narzędzia > Container Registry. W tej chwili dostępny jest obraz Dockera obejmujący cały projekt, do którego Kubernetes może uzyskać dostęp i administrować – jak to będzie widoczne za kilka minut.
8. Tworzenie klastra
Teraz możesz utworzyć klaster Kubernetes Engine, ale wcześniej przejdź do sekcji Google Kubernetes Engine w konsoli internetowej i poczekaj na zainicjowanie systemu (powinno to potrwać tylko kilka sekund).
Klaster składa się z serwera Kubernetes master API zarządzanego przez Google oraz zbioru węzłów roboczych. Węzły robocze to maszyny wirtualne Compute Engine. Użyjmy interfejsu wiersza poleceń gcloud
z sesji CloudShell, aby utworzyć klaster z 2 węzłami n1-standard-1
(wykonanie tego kroku może potrwać kilka minut):
$ gcloud container clusters create hello-cluster \ --num-nodes 2 \ --machine-type n1-standard-1 \ --zone us-central1-c
Na koniec zobaczysz utworzony klaster.
Creating cluster hello-cluster in us-central1-c...done. Created [https://container.googleapis.com/v1/projects/mn-gke-test/zones/us-central1-c/clusters/hello-cluster]. To inspect the contents of your cluster, go to: https://console.cloud.google.com/kubernetes/workload_/gcloud/us-central1-c/hello-cluster?project=mn-gke-test kubeconfig entry generated for hello-cluster. NAME LOCATION MASTER_VERSION MASTER_IP MACHINE_TYPE NODE_VERSION NUM_NODES STATUS hello-cluster us-central1-c 1.9.7-gke.7 35.239.224.115 n1-standard-1 1.9.7-gke.7 2 RUNNING
Teraz w pełni działający klaster Kubernetes obsługiwany przez Google Kubernetes Engine:
Czas wdrożyć własną aplikację skonteneryzowaną w klastrze Kubernetes. Od teraz będziesz używać wiersza poleceń kubectl
(jest on już skonfigurowany w Twoim środowisku Cloud Shell). Pozostała część tego ćwiczenia w Codelabs wymaga, aby klient i serwer Kubernetes były w wersji 1.2 lub nowszej. kubectl version
wyświetli bieżącą wersję polecenia.
9. Wdrażanie aplikacji w Kubernetes
Wdrożenie Kubernetes może tworzyć i skalować wiele instancji Twojej aplikacji oraz zarządzać nimi, korzystając z nowo utworzonego obrazu kontenera. Utwórzmy wdrożenie Twojej aplikacji w Kubernetes za pomocą polecenia kubectl create deployment
:
$ kubectl create deployment hello-micronaut \ --image=gcr.io/$GOOGLE_CLOUD_PROJECT/micronaut-jib:0.1
Aby wyświetlić nowo utworzone wdrożenie, po prostu uruchom polecenie:
$ kubectl get deployments NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE hello-micronaut 1 1 1 1 5m
Aby wyświetlić instancje aplikacji utworzone przez wdrożenie, uruchom to polecenie:
$ kubectl get pods NAME READY STATUS RESTARTS AGE hello-micronaut-5647fb98c5-lh5h7 1/1 Running 0 5m
W tym momencie kontener powinien działać pod kontrolą Kubernetes, ale nadal musisz udostępnić go światu zewnętrznemu.
10. Zezwalaj na ruch zewnętrzny
Domyślnie pod jest dostępny tylko przez jego wewnętrzny adres IP w klastrze. Aby umożliwić dostęp do kontenera hello-micronaut
spoza sieci wirtualnej Kubernetes, musisz udostępnić poda jako usługę Kubernetes.
W Cloud Shell możesz udostępnić poda w internecie publicznym za pomocą polecenia kubectl expose
w połączeniu z flagą --type=LoadBalancer
. Ta flaga jest wymagana do utworzenia dostępnego zewnętrznie adresu IP :
$ kubectl expose deployment hello-micronaut --type=LoadBalancer --port=8080
Flaga użyta w tym poleceniu wskazuje, że będziesz używać systemu równoważenia obciążenia udostępnianego przez bazową infrastrukturę (w tym przypadku system równoważenia obciążenia Compute Engine). Pamiętaj, że udostępniasz wdrożenie, a nie bezpośrednio pod. Spowoduje to równoważenie obciążenia ruchu generowanego przez powstałą usługę we wszystkich podach zarządzanych przez wdrożenie (w tym przypadku tylko 1 pod, ale później dodasz więcej replik).
Master Kubernetes tworzy system równoważenia obciążenia i powiązane reguły przekierowania Compute Engine, pule docelowe i reguły zapory sieciowej, aby zapewnić pełną dostępność usługi spoza Google Cloud Platform.
Aby znaleźć dostępny publicznie adres IP usługi, wyślij żądanie kubectl
do listy wszystkich usług klastra:
$ kubectl get services NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE hello-micronaut LoadBalancer 10.39.243.251 aaa.bbb.ccc.ddd 8080:30354/TCP 1m kubernetes ClusterIP 10.39.240.1 <none> 443/TCP 31m
Zwróć uwagę na 2 adresy IP dotyczące Twojej usługi, które obsługują port 8080
. Pierwszym z nich jest wewnętrzny adres IP, który jest widoczny tylko w sieci wirtualnej w chmurze. a drugi to zewnętrzny adres IP z zrównoważonym obciążeniem. W tym przykładzie zewnętrzny adres IP to aaa.bbb.ccc.ddd
.
Usługa powinna być teraz dostępna po wpisaniu w przeglądarce tego adresu: http://<EXTERNAL_IP>
:8080
/hello
11. Skalowanie usług
Jedną z zaawansowanych funkcji platformy Kubernetes jest łatwość skalowania aplikacji. Załóżmy, że nagle potrzebujesz większej pojemności na aplikację. możesz po prostu zlecić kontrolerowi replikacji zarządzanie nową liczbą replik instancji aplikacji:
$ kubectl scale deployment hello-micronaut --replicas=3 deployment.extensions "hello-micronaut" scaled $ kubectl get deployment NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE hello-micronaut 3 3 3 3 16m
Zwróć uwagę na podejście deklaratywne – zamiast uruchamiać lub zatrzymywać nowe instancje, musisz zadeklarować, ile instancji powinno być działających w danym momencie. Pętle uzgadniania Kubernetes po prostu dbają o to, aby rzeczywistość była zgodna z żądaniami i w razie potrzeby podjęto odpowiednie działania.
12. Wdrażanie uaktualnienia usługi
Aplikacja wdrożona w wersji produkcyjnej będzie czasami wymagała poprawek błędów lub dodatkowych funkcji. Kubernetes pomoże Ci wdrożyć nową wersję w środowisku produkcyjnym bez wpływu na użytkowników.
Najpierw zmodyfikujmy aplikację. Otwórz edytor kodu z Cloud Shell.
Przejdź do pola /jib/examples/micronaut/src/main/groovy/example/micronaut/HelloController.groovy
i zaktualizuj wartość odpowiedzi:
@Controller("/hello") class HelloController { @Get("/") String index() { "Hello Kubernetes World" } }
W /jib/examples/micronaut/build.gradle
uaktualnimy wersję obrazu z 0.1 do 0.2, aktualizując ten wiersz:
version '0.2'
Następnie ponownie skompiluj aplikację i spakuj ją z najnowszymi zmianami:
$ ./gradlew jibDockerBuild
Otaguj obraz i przekaż go do rejestru obrazów kontenerów:
$ docker tag micronaut-jib:0.2 \ gcr.io/$GOOGLE_CLOUD_PROJECT/micronaut-jib:0.2 $ docker push gcr.io/$GOOGLE_CLOUD_PROJECT/micronaut-jib:0.2
Teraz Kubernetes może sprawnie zaktualizować kontroler replikacji do nowej wersji aplikacji. Aby zmienić etykietę obrazu aktywnego kontenera, zmodyfikuj istniejący hello-micronaut deployment
i zmień obraz z gcr.io/PROJECT_ID/micronaut-jib:0.1
na gcr.io/PROJECT_ID/micronaut-jib:0.2
.
Aby poprosić Kubernetes o wdrożenie nowej wersji aplikacji w całym klastrze po jednej instancji, możesz użyć polecenia kubectl set image
z aktualizacją kroczącą:
$ kubectl set image deployment/hello-micronaut \ micronaut-jib=gcr.io/$GOOGLE_CLOUD_PROJECT/micronaut-jib:0.2 deployment.apps "hello-micronaut" image updated
Sprawdź ponownie adres http://EXTERNAL_IP:8080, aby upewnić się, że zwraca nową odpowiedź.
13. Wycofaj zmiany
Ups – czy popełniłeś błąd w nowej wersji aplikacji? Być może nowa wersja zawiera błąd i musisz szybko przywrócić poprzednią wersję. W Kubernetes można łatwo przywrócić poprzedni stan. Przywróćmy aplikację, uruchamiając polecenie:
$ kubectl rollout undo deployment/hello-micronaut
Jeśli spojrzymy na dane wyjściowe usługi, wrócimy do początkowego tekstu „Hello World”. .
14. Podsumowanie
W tym kroku skonfigurujesz prostą usługę Micronaut hello world opartą na Apache Groovy i uruchomisz ją bezpośrednio z poziomu Cloud Shell, spakujesz ją jako kontener z Jib i wdrożysz w Google Kubernetes Engine.
15. Gratulacje!
Wiesz już, jak utworzyć i wdrożyć nowy internetowy mikroserwis Apache Groovy / Mikronaut w Kubernetes w Google Kubernetes Engine.
Więcej informacji
- Dokumentacja i przykłady Jib: https://github.com/GoogleContainerTools/jib/
- Witryna Micronaut: http://micronaut.io/
- Java w Google Cloud Platform: https://cloud.google.com/java/
- Przykłady w Javie: https://cloud.google.com/java/samples.
- Dłuższy i bardziej wyczerpujący samouczek dotyczący Kubernetes znajdziesz na stronie bit.ly/k8s-lab, gdzie dowiesz się, jak wdrożyć aplikację typu full stack.
Licencja
To zadanie jest licencjonowane na podstawie ogólnej licencji Creative Commons Attribution 2.0.