Wdróż mnie! Seans z .NET Core, VSTS i Kubernetes w roli głównej

Wdróż mnie! Seans z .NET Core, VSTS i Kubernetes w roli głównej

Continuous… – Od lat znamy to słowo. W szkole Present Continuous, dzisiaj Continuous Integration (CI) i Continuous Delivery. Nie raz musiałeś słyszeć to magiczne zaklęcie od swego szefa bądź mistrza DevOps’u. Nie słyszałeś? To nie dobrze…

W dzisiejszym poście zamierzam zaznajomić Cię z wdrożeniem CI/CD dla aplikacji ASP.NET Core uruchomionej w klastrze Kubernetes w Azure Container Service (ACS).

CI/CD? A na co to komu!

CI/CD nie jest niczym niezwykłym. Jest to proces, polegający na doszlifowywaniu diamentu, jakim jest wytwarzane przez nas oprogramowanie. Pisząc kod każdemu z nas zdarzyła się sytuacja, w której to kod po wrzuceniu do repozytorium nie budował się i nikt o tym nie wiedział. Za eliminację i wykrycie takich sytuacji “odpowiada” Continuous Integration, a dodatkowo zintegrowane z automatycznym procesem wdrażania genialnie komponuje się Continuous Delivery.

https://thecamels.org/continuous-integration-continuous-delivery-oraz-continuous-deployment

Procesy te są jednymi z lepszych funkcjonalności oferowanych w ramach Visual Studio Team Services. VSTS jest internetową platformą, pomagającą nam zarządzać i przechowywać pisany przez nas i naszych kolegów z pracy kod.

Deliverable

Po wykonaniu wszystkich kroków, na wyjściu uzyskasz aplikację web przechowującą dane w postaci klucz-wartość, która jest budowana, testowana i wdrażana w sposób automatyczny. Aplikacja będzie wdrażana jako nowy kontener w Azure Container Registry, a następnie pobierana i uruchamiana w Kubernetes. Cały flow w przybliżeniu prezentuje poniższy diagram:

Konfiguracja środowiska

Kubernetes – Azure Container Service

Zgodnie z instrukcją na stronie Microsoftu tworzymy nową Resource Group’ę bądź wybieramy istniejącą (musi być pusta!), przy użyciu polecenia Azure CLI,

az group create --name vstsDeployRg --location eastus

Po czym tworzymy instancję ACS z Kubernetes. Całość operacji powinna potrwać około kilkanaście minut.

az acs create --orchestrator-type=kubernetes --resource-group vstsDeployRg --name=myK8SCluster --generate-ssh-keys 

Gdy nasz klaster się stworzy, instalujemy na swoim komputerze klienta Kubernetes kolejnym poleceniem CLI  i po zainstalowaniu przechodzimy do katalogu C:\Program Files (x86)\

az acs kubernetes install-cli

Ostatnim krokiem jest podłączenie do master-noda klastra, co wykonujemy również z poziomu wiersza poleceń.

az acs kubernetes get-credentials --resource-group=vstsDeployRg --name=myK8SCluster

W tym momencie mamy stworzony i uruchomiony w pełni działający klaster Kubernetes, jednak najlepsze dopiero przed nami 🙂

Azure Container Registry

ACR jest usługą, która przechowuje stworzone przez nas obrazy kontenerów, czyli konkretne wersje build’ów aplikacji. Dodajemy go poleceniem:

az acr create --resource-group vstsDeployRg --name vstsDeployAcr --sku Basic --admin-enabled true

Wdrożenie

Zanim wdrożymy, chciałbym przedstawić Ci strukturę pliku deploy.yaml, który zawiera strukturę aplikacji w Kubernetes. Składa się ona z Deploymentu appki ASP.NET Core, Pod‘a z kontenerem z Redis oraz deklaracji dwoch serwisów (Service) – jeden dla Redisa (bez load balancera) i drugi dla apkikacji Web (z Azure Load Balancerem).

Wdrożenie kodu solucji do VSTS

Zachęcam Cię do pobrania startowej solucji z mojego GitHuba. Uruchom ją i potestuj, po czym wrzuć do nowego projektu w VSTS.

Definicja procesu Build’a

Zanim zaczniemy definiować Build’a, doinstalujmy do VSTS rozszerzenie Kubernetes. Link TUTAJ. Klikamy na kartę Build & Release oraz New definition.

Zanim zaczniemy, kliknijmy na Process  i jaki agenta wybierzmy Hosted Linux.

Pierwszym krokiem każdego procesu Build’a jest pobranie kodu, dlatego wskazujemy lokalizację repozytorium.

Wybieramy task typu Command Line i przekazujemy parametry. MUSIMY jako Working folder ustawić katalog z aplikacją ASP.NET Core.

Dodajemy task typu Docker i wskazujemy subskrypcję, z której korzystamy. Może się pojawić potrzeba sparowania jej z projektem. Z listy klikamy na utworzone ACR, przechodzimy do folderu z aplikacją i zaznaczamy tag latest.

Ponownie dodajemy task Dockera. Tym razem już nie budujemy kontenera, tylko go wrzucamy do ACR.

Przetwarzamy plik deploy.yml przy użyciu CMD. W przedostatnim już tasku typu Command Line uruchamiamy bash z argumentem

-c "sed -i 's/$BUILD_ID/$(Build.BuildId)/; s/$ACR_DNS/vstsdeployacr.azurecr.io/' deploy.yaml"

gdzie vstsdeployacr jest nazwą ACR.

UWAGA: Nazwa ACR MUSI być podana małymi literami, w przeciwnym razie mogą w późniejszych krokach pojawić się komplikacje!

Ostatnim krokiem jest task Publish Build Artifacts. W Path to publish wpisujemy deploy.yaml, czyli pliku zawierającego instrukcje dla Kubernetes jak wdrożyć/zaktualizować aplikację.

Po wyklikaniu Build’a, przechodzimy do Triggers i uruchamiamy Continuous Integration.

Build zakończyliśmy. Naciskamy Save & queue i czekamy na pozytywny wynik.

Definicja procesu Release’a

Po konfiguracji Build’a dodajemy nową definicję release’a. W tym celu z zakładki Releases tworzymy nową definicję.

Nie będziemy korzystać z gotowych szablonów, dlatego w kolejnym etapie wybieramy pusty szablon i jako źródło oraz trigger operacji ustawiamy zdefiniowany wcześniej build.

Dodajemy task typu Deploy to Kubernetes i dodajemy nowe połączenie do klastra. Nazwa dowolna, URL serwera odnajdziemy wywołując poniższą komendę i odczytująć URL mastera.

kubectl cluster-info

Pole Kubeconfig uzupełniamy zawartością pliku o nazwie zbliżonej do config, znajdującego się w lokalizacji C:\Users\{NazwaUżytkownika}\.kube

W grupie Container Registry Details wyklikujemy z listy wykorzystywane ACR, w grupie Commands jako komendę zaznaczamy apply, a następnie w polu arguments dodajemy

-f $(System.DefaultWorkingDirectory)\VSTSDemo-CI\deploy\deploy.yaml

gdzie VSTSDemo-CI jest nazwą wykorzystywanego builda. Po wykonaniu, zapisujemy.

Całość CI/CD jest już stworzona, zachęcam Cię do przetestowania poprzez wrzucenie nowego commita na sparowany z buildem branch.

Połączenie z aplikacją

Adres API znajdziemy wywołując

kubectl get svc

Zanim się zmieni stan <pending> na adres IP może potrwać kilka minut. W tym czasie Kubernetes tworzy instancję Azure Load Balancer.

Przechodzimy pod 52.170.103.27/swagger i powinniśmy zobaczyć widoczny podczas lokalnego debug’a ekran.

Podsumowanie

Jak widać, Continuous Integration wraz z Continuous Delivery stanowi nierozłączny duet. Znajdą się tacy, którzy będą chcieli wdrażać każdy update ręcznie, jednak z perspektywy czasu będzie to przykład nieoptymalnego wypalania godzin projektowych. Pomimo często sporej ilości czasu poświęconej na zdefiniowanie całego procesu kompilacji i wdrożenia warto jednak zaryzykować, gdyż czasy ręcznego patchowania już dawno minęły 🙂

Leave a Reply

Your email address will not be published. Required fields are marked *