Korzystanie z kontenerów i orkiestratorów
Napiwek
Ta zawartość jest fragmentem książki eBook, Architekting Cloud Native .NET Applications for Azure, dostępnej na platformie .NET Docs lub jako bezpłatny plik PDF do pobrania, który można odczytać w trybie offline.
Kontenery i orkiestratory są przeznaczone do rozwiązywania problemów typowych dla monolitycznych podejść wdrażania.
Wyzwania związane z wdrożeniami monolitycznymi
Tradycyjnie większość aplikacji została wdrożona jako pojedyncza jednostka. Takie aplikacje są określane jako monolityczne. To ogólne podejście do wdrażania aplikacji jako pojedynczych jednostek, nawet jeśli składają się z wielu modułów lub zestawów, jest nazywane architekturą monolityczną, jak pokazano na rysunku 3–1.
Rysunek 3–1. Architektura monolityczna.
Mimo że mają one zalety prostoty, architektury monolityczne stoją przed wieloma wyzwaniami:
Wdrożenie
Ponadto wymagają ponownego uruchomienia aplikacji, co może tymczasowo wpłynąć na dostępność, jeśli techniki bez przestojów nie są stosowane podczas wdrażania.
Skalowanie
Aplikacja monolityczna jest hostowana w całości na pojedynczym wystąpieniu maszyny, często wymagającym sprzętu o wysokiej możliwości. Jeśli jakakolwiek część monolitu wymaga skalowania, na innej maszynie musi zostać wdrożona inna kopia całej aplikacji. Dzięki monolicie nie można pojedynczo skalować składników aplikacji — to wszystko lub nic. Skalowanie składników, które nie wymagają skalowania, powoduje nieefektywne i kosztowne użycie zasobów.
Środowisko
Aplikacje monolityczne są zwykle wdrażane w środowisku hostingu ze wstępnie zainstalowanym systemem operacyjnym, środowiskiem uruchomieniowym i zależnościami biblioteki. To środowisko może nie odpowiadać temu, na którym aplikacja została opracowana lub przetestowana. Niespójności w środowiskach aplikacji są typowym źródłem problemów z wdrożeniami monolitycznymi.
Sprzęgła
Aplikacja monolityczna może mieć duże sprzężenie między składnikami funkcjonalnymi. Bez trudnych granic zmiany systemowe często powodują niezamierzone i kosztowne skutki uboczne. Nowe funkcje/poprawki stają się trudne, czasochłonne i kosztowne do zaimplementowania. Aktualizacje wymagają rozbudowanego testowania. Sprzęganie utrudnia również refaktoryzację składników lub zamianę w implementacjach alternatywnych. Nawet w przypadku ścisłego rozdzielenia obaw erozja architektury ustawia się w miarę pogarszania się bazy kodu monolitycznego z niekończącymi się "przypadkami specjalnymi".
Blokada platformy
Aplikacja monolityczna jest tworzona przy użyciu pojedynczego stosu technologicznego. Oferując jednolitość, to zobowiązanie może stać się barierą dla innowacji. Nowe funkcje i składniki zostaną utworzone przy użyciu bieżącego stosu aplikacji — nawet wtedy, gdy bardziej nowoczesne technologie mogą być lepszym wyborem. Długoterminowe ryzyko polega na tym, że twój stos technologiczny staje się przestarzały i przestarzały. Zmiana architektury całej aplikacji na nową, bardziej nowoczesną platformę jest najbardziej kosztowna i ryzykowna.
Jakie są zalety kontenerów i koordynatorów?
Wprowadziliśmy kontenery w rozdziale 1. Podkreśliliśmy, jak platforma Cloud Native Computing Foundation (CNCF) plasuje konteneryzację jako pierwszy krok w mapie szlaków natywnych dla chmury — wskazówki dla przedsiębiorstw rozpoczynających swoją podróż natywną dla chmury. W tej sekcji omówiono zalety kontenerów.
Platforma Docker jest najpopularniejszą platformą do zarządzania kontenerami. Działa z kontenerami zarówno w systemie Linux, jak i Windows. Kontenery zapewniają oddzielne, ale powtarzalne środowiska aplikacji, które działają w taki sam sposób w dowolnym systemie. Ten aspekt sprawia, że doskonale nadają się do tworzenia i hostowania usług natywnych dla chmury. Kontenery są odizolowane od siebie. Dwa kontenery na tym samym sprzęcie hosta mogą mieć różne wersje oprogramowania bez powodowania konfliktów.
Kontenery są definiowane przez proste pliki tekstowe, które stają się artefaktami projektu i są sprawdzane w kontroli źródła. Chociaż pełne serwery i maszyny wirtualne wymagają ręcznej aktualizacji, kontenery są łatwo kontrolowane w wersji. Aplikacje utworzone do uruchamiania w kontenerach można opracowywać, testować i wdrażać przy użyciu zautomatyzowanych narzędzi w ramach potoku kompilacji.
Kontenery są niezmienne. Po zdefiniowaniu kontenera można go ponownie utworzyć i uruchomić w taki sam sposób. Ta niezmienność nadaje się do projektowania opartego na składnikach. Jeśli niektóre części aplikacji ewoluują inaczej niż inne, dlaczego ponownie wdrożysz całą aplikację, gdy możesz po prostu wdrożyć części, które zmieniają się najczęściej? Różne funkcje i kwestie związane z tworzeniem krzyżowym aplikacji można podzielić na oddzielne jednostki. Rysunek 3–2 pokazuje, jak aplikacja monolityczna może korzystać z kontenerów i mikrousług przez delegowanie niektórych funkcji lub funkcji. Pozostałe funkcje w samej aplikacji również zostały skoeneryzowane.
Rysunek 3–2. Dekompozycja aplikacji monolitycznej w celu objęcia mikrousług.
Każda usługa natywna dla chmury jest kompilowana i wdrażana w osobnym kontenerze. Każda z nich może być aktualizowana zgodnie z potrzebami. Poszczególne usługi mogą być hostowane w węzłach z zasobami odpowiednimi dla każdej usługi. Środowisko, w których działa każda usługa, jest niezmienne, współużytkowane w środowiskach deweloperskich, testowych i produkcyjnych oraz łatwe wersjonowane. Sprzężenie między różnymi obszarami aplikacji odbywa się jawnie jako wywołania lub komunikaty między usługami, a nie zależności czasu kompilacji w monolicie. Możesz również wybrać technologię, która najlepiej ustawia daną możliwość bez konieczności wprowadzania zmian w pozostałej części aplikacji.
Usługi konteneryzowane wymagają zautomatyzowanego zarządzania. Nie byłoby możliwe ręczne administrowanie dużym zestawem niezależnych wdrożonych kontenerów. Rozważmy na przykład następujące zadania:
- W jaki sposób wystąpienia kontenerów będą aprowizowane w klastrze wielu maszyn?
- Jak kontenery odnajdują się i komunikują się ze sobą po wdrożeniu?
- Jak kontenery mogą być skalowane na żądanie lub w poziomie?
- Jak monitorować kondycję każdego kontenera?
- Jak chronić kontener przed awariami sprzętu i oprogramowania?
- Jak uaktualnić kontenery dla aplikacji na żywo z zerowym przestojem?
Koordynatorzy kontenerów adresują i automatyzują te i inne problemy.
W natywnym dla chmury systemie ekologicznym platforma Kubernetes stała się de facto orkiestratorem kontenerów. Jest to platforma typu open source zarządzana przez Cloud Native Computing Foundation (CNCF). Platforma Kubernetes automatyzuje wdrażanie, skalowanie i problemy operacyjne związane z konteneryzowanymi obciążeniami w klastrze maszynowym. Jednak instalowanie platformy Kubernetes i zarządzanie nią jest notorycznie złożone.
Znacznie lepszym podejściem jest wykorzystanie platformy Kubernetes jako usługi zarządzanej od dostawcy chmury. Chmura platformy Azure oferuje w pełni zarządzaną platformę Kubernetes zatytułowaną Azure Kubernetes Service (AKS). Usługa AKS abstrahuje od złożoności i obciążeń operacyjnych związanych z zarządzaniem platformą Kubernetes. Używasz platformy Kubernetes jako usługi w chmurze; Firma Microsoft ponosi odpowiedzialność za zarządzanie nim i wspieranie go. Usługa AKS ściśle integruje się również z innymi usługami platformy Azure i narzędziami deweloperskimi.
Usługa AKS to technologia oparta na klastrze. Pula federacyjnych maszyn wirtualnych lub węzłów jest wdrażana w chmurze platformy Azure. Razem tworzą środowisko o wysokiej dostępności lub klaster. Klaster jest wyświetlany jako bezproblemowa, pojedyncza jednostka w aplikacji natywnej dla chmury. Usługa AKS wdraża konteneryzowane usługi w tych węzłach zgodnie ze wstępnie zdefiniowaną strategią równomierną rozłożenia obciążenia.
Jakie są korzyści ze skalowania?
Usługi oparte na kontenerach mogą korzystać ze skalowania korzyści zapewnianych przez narzędzia orkiestracji, takie jak Kubernetes. Kontenery projektu wiedzą tylko o sobie. Po utworzeniu wielu kontenerów, które muszą współpracować, należy zorganizować je na wyższym poziomie. Organizowanie dużej liczby kontenerów i ich współużytkowanych zależności, takich jak konfiguracja sieci, to miejsce, w którym narzędzia orkiestracji są zapisywane w ciągu dnia! Platforma Kubernetes tworzy warstwę abstrakcji na grupach kontenerów i organizuje je w zasobniki. Zasobniki są uruchamiane na maszynach roboczych nazywanych węzłami. Ta zorganizowana struktura jest określana jako klaster. Rysunek 3–3 przedstawia różne składniki klastra Kubernetes.
Rysunek 3–3. Składniki klastra Kubernetes.
Skalowanie konteneryzowanych obciążeń to kluczowa funkcja orkiestratorów kontenerów. Usługa AKS obsługuje automatyczne skalowanie w dwóch wymiarach: wystąpienia kontenerów i węzły obliczeniowe. Razem zapewniają usłudze AKS możliwość szybkiego i wydajnego reagowania na wzrost zapotrzebowania i dodawania dodatkowych zasobów. W dalszej części tego rozdziału omówimy skalowanie w usłudze AKS.
Deklaratywne a imperatywne
Platforma Kubernetes obsługuje zarówno konfigurację deklaratywną, jak i imperatywne. Podejście imperatywne polega na uruchomieniu różnych poleceń, które informują platformę Kubernetes o tym, co należy zrobić w każdym kroku. Uruchom ten obraz. Usuń ten zasobnik. Uwidocznij ten port. W przypadku podejścia deklaratywnego należy utworzyć plik konfiguracji nazywany manifestem, aby opisać, co chcesz zrobić, zamiast tego, co należy zrobić. Platforma Kubernetes odczytuje manifest i przekształca żądany stan końcowy na rzeczywisty stan zakończenia.
Polecenia imperatywne doskonale nadają się do uczenia się i interakcyjnego eksperymentowania. Jednak należy deklaratywnie utworzyć pliki manifestu kubernetes, aby objąć infrastrukturę jako podejście kodu, zapewniając niezawodne i powtarzalne wdrożenia. Plik manifestu staje się artefaktem projektu i jest używany w potoku ciągłej integracji/ciągłego wdrażania do automatyzacji wdrożeń kubernetes.
Jeśli klaster został już skonfigurowany przy użyciu poleceń imperatywnych, możesz wyeksportować manifest deklaratywny przy użyciu polecenia kubectl get svc SERVICENAME -o yaml > service.yaml
. To polecenie tworzy manifest podobny do przedstawionego poniżej:
apiVersion: v1
kind: Service
metadata:
creationTimestamp: "2019-09-13T13:58:47Z"
labels:
component: apiserver
provider: kubernetes
name: kubernetes
namespace: default
resourceVersion: "153"
selfLink: /api/v1/namespaces/default/services/kubernetes
uid: 9b1fac62-d62e-11e9-8968-00155d38010d
spec:
clusterIP: 10.96.0.1
ports:
- name: https
port: 443
protocol: TCP
targetPort: 6443
sessionAffinity: None
type: ClusterIP
status:
loadBalancer: {}
W przypadku korzystania z konfiguracji deklaratywnej można wyświetlić podgląd zmian, które zostaną wprowadzone przed ich zatwierdzeniem przy użyciu kubectl diff -f FOLDERNAME
folderu, w którym znajdują się pliki konfiguracji. Gdy na pewno chcesz zastosować zmiany, uruchom polecenie kubectl apply -f FOLDERNAME
. Dodaj -R
element , aby rekursywnie przetwarzać hierarchię folderów.
Można również użyć konfiguracji deklaratywnej z innymi funkcjami platformy Kubernetes, z których jednym z nich są wdrożenia. Wdrożenia deklaratywne ułatwiają zarządzanie wydaniami, aktualizacjami i skalowaniem. Instruują kontroler wdrażania platformy Kubernetes o sposobie wdrażania nowych zmian, skalowania obciążenia w poziomie lub wycofywania do poprzedniej poprawki. Jeśli klaster jest niestabilny, wdrożenie deklaratywne automatycznie zwróci klaster z powrotem do żądanego stanu. Jeśli na przykład węzeł powinien ulec awarii, mechanizm wdrażania ponownie wdroży zastąpienie w celu osiągnięcia żądanego stanu
Użycie konfiguracji deklaratywnej umożliwia reprezentowanie infrastruktury jako kodu, który można zaewidencjonować i wersjonować wraz z kodem aplikacji. Zapewnia lepszą kontrolę zmian i lepszą obsługę ciągłego wdrażania przy użyciu potoku kompilacji i wdrażania.
Jakie scenariusze są idealne dla kontenerów i koordynatorów?
Poniższe scenariusze są idealne do używania kontenerów i koordynatorów.
Aplikacje wymagające wysokiej dostępności i skalowalności
Poszczególne aplikacje, które mają wymagania dotyczące wysokiej dostępności i skalowalności, są idealnymi kandydatami do architektur natywnych dla chmury przy użyciu mikrousług, kontenerów i orkiestratorów. Można je opracowywać w kontenerach, testować w różnych środowiskach w wersji i wdrażać w środowisku produkcyjnym z zerowym przestojem. Użycie klastrów Kubernetes zapewnia, że takie aplikacje mogą być również skalowane na żądanie i automatycznie odzyskiwane po awariach węzłów.
Duża liczba aplikacji
Organizacje, które wdrażają i utrzymują dużą liczbę aplikacji, korzystają z kontenerów i koordynatorów. Nakład pracy z góry podczas konfigurowania konteneryzowanych środowisk i klastrów Kubernetes jest przede wszystkim kosztem stałym. Wdrażanie, konserwowanie i aktualizowanie poszczególnych aplikacji ma koszt, który różni się w zależności od liczby aplikacji. Poza kilkoma aplikacjami złożoność obsługi niestandardowych aplikacji ręcznie przekracza koszt implementacji rozwiązania przy użyciu kontenerów i koordynatorów.
Kiedy należy unikać używania kontenerów i koordynatorów?
Jeśli nie możesz skompilować aplikacji zgodnie z zasadami Dwunastoskładnikowa aplikacja, rozważ uniknięcie kontenerów i koordynatorów. W takich przypadkach należy rozważyć platformę hostingu opartą na maszynie wirtualnej lub ewentualnie jakiś system hybrydowy. Za jego pomocą zawsze można odkręcić niektóre elementy funkcjonalności do oddzielnych kontenerów, a nawet funkcji bezserwerowych.
Zasoby programistyczne
W tej sekcji przedstawiono krótką listę zasobów programistycznych, które mogą ułatwić rozpoczęcie korzystania z kontenerów i koordynatorów dla następnej aplikacji. Jeśli szukasz wskazówek dotyczących projektowania aplikacji architektury mikrousług natywnych dla chmury, przeczytaj towarzysza tej książki , .NET Microservices: Architecture for Containerized .NET Applications (Architektura konteneryzowanych aplikacji platformy .NET).
Tworzenie lokalnego rozwiązania Kubernetes
Wdrożenia platformy Kubernetes zapewniają dużą wartość w środowiskach produkcyjnych, ale mogą być również uruchamiane lokalnie na maszynie deweloperów. Mimo że poszczególne mikrousługi mogą działać niezależnie, czasami konieczne będzie uruchomienie całego systemu lokalnie — tak samo jak po wdrożeniu w środowisku produkcyjnym. Istnieje kilka narzędzi, które mogą pomóc: Minikube i Docker Desktop. Program Visual Studio udostępnia również narzędzia do programowania na platformie Docker.
Minikube
Co to jest Minikube? Projekt Minikube mówi: "Minikube implementuje lokalny klaster Kubernetes w systemach macOS, Linux i Windows". Jego głównymi celami są "najlepsze narzędzie do tworzenia lokalnych aplikacji Kubernetes i obsługa wszystkich funkcji platformy Kubernetes pasujących do tych potrzeb". Instalowanie aplikacji Minikube jest oddzielone od platformy Docker, ale aplikacja Minikube obsługuje różne funkcje hypervisor niż obsługuje program Docker Desktop. Następujące funkcje platformy Kubernetes są obecnie obsługiwane przez firmę Minikube:
- DNS
- NodePorts
- Konfiguracja Mapy i wpisy tajne
- Pulpity nawigacyjne
- Środowiska uruchomieniowe kontenerów: Docker, rkt, CRI-O i containerd
- Włączanie interfejsu sieciowego kontenera (CNI)
- Ruch przychodzący
Po zainstalowaniu aplikacji Minikube możesz szybko rozpocząć korzystanie z niego, uruchamiając minikube start
polecenie , które pobiera obraz i uruchamia lokalny klaster Kubernetes. Po uruchomieniu klastra będziesz z nim korzystać przy użyciu standardowych poleceń platformy Kubernetes kubectl
.
Docker Desktop
Możesz również pracować z platformą Kubernetes bezpośrednio z poziomu programu Docker Desktop w systemie Windows. Jest to jedyna opcja, jeśli używasz kontenerów systemu Windows i jest doskonałym wyborem dla kontenerów innych niż Windows. Rysunek 3–4 przedstawia sposób włączania obsługi lokalnej platformy Kubernetes podczas uruchamiania programu Docker Desktop.
Rysunek 3–4. Konfigurowanie platformy Kubernetes w programie Docker Desktop.
Docker Desktop jest najpopularniejszym narzędziem do konfigurowania i uruchamiania aplikacji konteneryzowanych lokalnie. Podczas pracy z usługą Docker Desktop można opracowywać lokalnie na dokładnie tym samym zestawie obrazów kontenerów platformy Docker, które zostaną wdrożone w środowisku produkcyjnym. Program Docker Desktop jest przeznaczony do lokalnego tworzenia, testowania i dostarczania konteneryzowanych aplikacji. Obsługuje zarówno kontenery systemu Linux, jak i Windows. Po wypchnięciu obrazów do rejestru obrazów, takiego jak Usługa Azure Container Registry lub Docker Hub, usługa AKS może ściągnąć i wdrożyć je w środowisku produkcyjnym.
Narzędzia platformy Docker programu Visual Studio
Program Visual Studio obsługuje tworzenie aplikacji internetowych na platformie Docker. Podczas tworzenia nowej aplikacji ASP.NET Core możesz ją skonfigurować przy użyciu obsługi platformy Docker, jak pokazano na rysunku 3–5.
Rysunek 3–5. Obsługa platformy Docker w programie Visual Studio
Po wybraniu tej opcji projekt zostanie utworzony za pomocą elementu Dockerfile
w katalogu głównym, który może służyć do kompilowania i hostowania aplikacji w kontenerze platformy Docker. Przykładowy plik Dockerfile jest wyświetlany na rysunku 3–6.
FROM mcr.microsoft.com/dotnet/aspnet:7.0 AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443
FROM mcr.microsoft.com/dotnet/sdk:7.0 AS build
WORKDIR /src
COPY ["eShopWeb/eShopWeb.csproj", "eShopWeb/"]
RUN dotnet restore "eShopWeb/eShopWeb.csproj"
COPY . .
WORKDIR "/src/eShopWeb"
RUN dotnet build "eShopWeb.csproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "eShopWeb.csproj" -c Release -o /app/publish
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "eShopWeb.dll"]
Rysunek 3–6. Plik Dockerfile wygenerowany w programie Visual Studio
Po dodaniu obsługi możesz uruchomić aplikację w kontenerze platformy Docker w programie Visual Studio. Rysunek 3–7 przedstawia różne opcje uruchamiania dostępne w nowym projekcie ASP.NET Core utworzonym przy użyciu dodanej obsługi platformy Docker.
Rysunek 3–7. Opcje uruchamiania platformy Docker programu Visual Studio
Ponadto w dowolnym momencie możesz dodać obsługę platformy Docker do istniejącej aplikacji ASP.NET Core. W programie Visual Studio Eksplorator rozwiązań kliknij prawym przyciskiem myszy projekt i wybierz polecenie Dodaj>obsługę platformy Docker, jak pokazano na rysunku 3-8.
Rysunek 3–8. Dodawanie obsługi platformy Docker do programu Visual Studio
Narzędzia platformy Docker programu Visual Studio Code
Istnieje wiele rozszerzeń dostępnych dla programu Visual Studio Code, które obsługują programowanie na platformie Docker.
Firma Microsoft udostępnia rozszerzenie Docker for Visual Studio Code. To rozszerzenie upraszcza proces dodawania obsługi kontenerów do aplikacji. Tworzy szkielet wymaganych plików, kompiluje obrazy platformy Docker i umożliwia debugowanie aplikacji wewnątrz kontenera. Rozszerzenie zawiera eksploratora wizualizacji, który ułatwia wykonywanie akcji dotyczących kontenerów i obrazów, takich jak uruchamianie, zatrzymywanie, inspekcja, usuwanie i nie tylko. Rozszerzenie obsługuje również platformę Docker Compose, umożliwiając zarządzanie wieloma uruchomionymi kontenerami jako pojedynczą jednostką.