Stałe dostarczanie klastrów Amazon EKS przy użyciu AWS CDK i CDK Pipelines
Klienci zawsze szukają sposobów na zautomatyzowanie wdrażania swoich klastrów Amazon EKS w różnych wersjach, środowiskach, kontach i regionach. Wdrażanie tych klastrów obejmuje takie zadania, jak tworzenie klastrów z pożądaną konfiguracją sieci i rejestrowania, wybieranie wersji dodatków Amazon EKS i gdy są gotowe, wdrażanie innych komponentów infrastruktury.
Ten post obrazuje użycie AWS CDK i CDK Pipelines do wdrażania klastrów Amazon EKS.
Ogólny zarys
Za pomocą tego artykułu autorzy przedstawią przykładowy potok przy użyciu CDK Pipelines, biblioteki konstrukcji wysokiego poziomu, która ułatwia konfigurowanie ciągłego potoku wdrażania dla aplikacji CDK, obsługiwanego przez AWS CodePipeline.
Ten potok tworzy dwa różne klastry Amazon EKS, jeden w wersji 1.20, a drugi w wersji 1.21, z zarządzaną grupą węzłów dla każdego z nich. Wdraża również kontrolery i operatory, takie jak AWS Load Balancer Controller, Calico for Network Policies, ExternalDNS, Cluster Autoscaler, Metrics Server, and Container Insights.
Obejmuje również etap wymiany użytkowników przykładowej aplikacji przy użyciu strategii niebiesko-zielonej w różnych klastrach. Wykorzystuje istniejącą domenę Amazon Route 53 i dwie subdomeny zarządzane przez zewnętrzny DNS każdego klastra do kierowania użytkowników.
Etapy potoku:
- Źródło: Ten etap pobiera źródło aplikacji CDK z rozwidlonego repozytorium GitHub i uruchamia potok za każdym razem, gdy wysyłasz do niego nowe zatwierdzenia.
- Kompilacja: Ten etap kompiluje kod (jeśli to konieczne) i wykonuje syntezator CDK. Wynikiem tego kroku jest zestaw w chmurze, który jest używany do wykonywania wszystkich działań w pozostałej części potoku.
- UpdatePipeline: Ten etap w razie potrzeby zmienia potok. Na przykład, jeśli zaktualizujesz kod, aby dodać nowy etap wdrażania do potoku lub dodać nowy zasób do aplikacji, automatycznie aktualizuje potok, aby odzwierciedlić wprowadzone zmiany.
- PublishAssets: Ten etap przygotowuje i publikuje wszystkie zasoby plików, których używasz w swojej aplikacji do Amazon Simple Storage Service (Amazon S3) i wszystkie obrazy Docker w Amazon Elastic Container Registry (Amazon ECR) na każdym koncie i regionie, z którego są używane, aby mogły być używane podczas kolejnych wdrożeń.
- Wdrażanie (DeployEKSClusters): na tym etapie wdrażane są aplikacje CDK w dwóch różnych stosach, które opisują klastry Amazon EKS, ich konfigurację i składniki.
- Sprawdź poprawność: na tym etapie sprawdza się, czy obciążenia wdrożone na poprzednim etapie działają.
- Wydanie (PromoteEnvironment): Ten etap aktualizuje rekord Route 53, aby wskazywał klaster określony jako środowisko produkcyjne w kodzie. Do wykonania wymagane jest ręczne zatwierdzenie.
Kolejne kroki w celu wdrożenia powyższej infrastruktury:
- Rozdziel repozytorium próbek.
- Utwórz parametry i sekrety specyficzne dla środowiska.
- Utwórz subdomeny dla każdego klastra (np. blue.my.domain i green.my.domain) w Amazon Route 53.
- Zmień rozwidlenie i wprowadzaj zmiany.
- Wdróż swoje stosy CDK.
Warunki wstępne:
- Konto AWS;
- Konto GitHub;
- Istniejąca publiczna strefa hostowana w Amazon Route 53 lub – możesz zarejestrować nową domenę w Amazon Route 53 lub użyć jej dla istniejącej domeny;
- AWS CDK w wersji 1.121.0 lub nowszej;
- Dla uproszczenia używamy AWS CLI.
Rozpoczynanie
- Aby rozpocząć, rozdziel przykładowe repozytorium (https://github.com/aws-samples/aws-cdk-pipelines-eks-cluster) i sklonuj je.
BASH
$ git clone https://github.com/YOUR-USERNAME/aws-cdk-pipelines-eks-cluster
- Utwórz osobisty token dostępu GitHub z repozytorium zakresów i admin:repo_hook, korzystając z poniższego łącza lub krok po kroku.
- Przechowuj token utworzony w poprzednim kroku w AWS Secrets Manager za pomocą:
BASH
$ aws secretsmanager create-secret --name github-oauth-token --description "Secret for GitHub" --secret-string TOKEN-GENERATED-PREVIOUS-STEP
- Przechowuj identyfikator strefy hostowanej i nazwę domeny w magazynie parametrów AWS Systems Manager przy użyciu:
BASH
$ aws ssm put-parameter --name '/eks-cdk-pipelines/hostZoneId' --type String --value YOUR-HOSTED-ZONE-ID $ aws ssm put-parameter --name '/eks-cdk-pipelines/zoneName' --type String --value YOUR-ZONE-NAME
Przejdź do Route 53 przez konsolę AWS, aby uzyskać dostęp do hostowanych stref, użyj nazwy domeny jako zoneName i hostowanej strefy ID jako hostZoneId.
Możesz użyć parameters.sh w swoim rozwidleniu, aby interaktywnie zapewnić powyższą konfigurację:
BASH
$ chmod +x parameters.sh; ./parameters.sh
- Utwórz subdomenę dla każdego klastra (np. blue.my.domain i green.my.domain) w Twoim DNS:
Utworzysz subdomenę na klaster, więc każda aplikacja klastra będzie posiadać własną nazwę domeny i będziesz mófł wymieniać ruch za pomocą potoku. W tym przykładzie utworzysz niebieskie i zielone subdomeny dla nazwy domeny, której użyłeś w poprzednim kroku.
W przypadku Amazon Route 53 możesz wykonać następujące czynności:
1.Najpierw tworzysz strefę hostowaną, która ma taką samą nazwę jak subdomena, dla której chcesz kierować ruch, na przykład blue.example.org (zastąp example.org własną domeną).
2.Otrzymasz serwery nazw, które Route 53 przypisała do nowej strefy hostowanej podczas jej tworzenia.
3.Powtórz kroki 1–3, korzystając z green.example.com.
Ostatecznie Twoja domena nadrzędna powinna wyglądać tak:
Zmień rozwidlenie
Jest tylko jedna obowiązkowa zmiana w Twoim kodzie:
- Zaktualizuj definicję potoku w lib/eks-pipeline-stack.ts, aby wskazywała na własne repozytorium rozwidlone, zastępując aws-samples swoją nazwą użytkownika GitHub.
const pipeline = new CodePipeline(this, "Pipeline", {
synth: new ShellStep("Synth", {
input: CodePipelineSource.gitHub(
"aws-samples/aws-cdk-pipelines-eks-cluster",
"main",
{
authentication:
cdk.SecretValue.secretsManager("github-oauth-token"),
}
),
commands: ["npm ci", "npm run build", "npx cdk synth"],
}),
pipelineName: "EKSClusterBlueGreen",
});
Uwaga: Upewnij się, że zatwierdziłeś i wypchnąłeś kod po jego zmianie, w przeciwnym razie potok zmieni się na ostatnio wypchnięty na etapie SelfMutate.
Powyższy kod utworzy etap Source, Build, UpdatePipeline i PublishAssets przez co wystarczy zdefiniować kolejne etapy. W przykładowym kodzie istnieją dwa etapy, po jednym dla każdego klastra EKS (niebieski i zielony), które działają równolegle przy użyciu fali:
const clusterANameSuffix = "blue";
const clusterBNameSuffix = "green";
const eksClusterStageA = new EksClusterStage(this, "EKSClusterA", {
clusterVersion: eks.KubernetesVersion.V1_20,
nameSuffix: clusterANameSuffix,
});
const eksClusterStageB = new EksClusterStage(this, "EKSClusterB", {
clusterVersion: eks.KubernetesVersion.V1_21,
nameSuffix: clusterBNameSuffix,
});
const eksClusterWave = pipeline.addWave("DeployEKSClusters");
Autorzy ponownie używają EksClusterStage z dwoma parametrami: clusterVersion i nameSuffix, który jest również używany jako subdomena do zarządzania DNS z klastra Kubernetes przy użyciu ExternalDNS. Ten etap wdraża stos, który zawiera definicję Twojego klastra i jego głównych komponentów:
const cluster = new eks.Cluster(this, `acme-${props.nameSuffix}`, {
clusterName: `acme-${props.nameSuffix}`,
version: props.clusterVersion,
defaultCapacity: 0,
vpc,
vpcSubnets: [{ subnetType: ec2.SubnetType.PRIVATE }],
});
new EksManagedNodeGroup(this, "EksManagedNodeGroup", {
cluster: cluster,
nameSuffix: props.nameSuffix,
});
new AWSLoadBalancerController(this, "AWSLoadBalancerController", {
cluster: cluster,
});
new ExternalDNS(this, "ExternalDNS", {
cluster: cluster,
hostZoneId: hostZoneId,
domainFilters: [`${props.nameSuffix}.${zoneName}`],
});
new ClusterAutoscaler(this, "ClusterAutoscaler", {
cluster: cluster,
});
new ContainerInsights(this, "ContainerInsights", {
cluster: cluster,
});new Calico(this, "Calico", {
cluster: cluster,
});
new Prometheus(this, "Prometheus", {
cluster: cluster,
});
new Echoserver(this, "EchoServer", {
cluster: cluster,
nameSuffix: props.nameSuffix,
domainName: zoneName,
});
Możesz badać każdy kod konstrukcji w lib/infrastructure i lib/app; są to podstawowe bloki konstrukcyjne aplikacji AWS CDK. Konstrukt reprezentuje „komponent chmury” i zawiera wszystko, czego potrzebuje AWS CloudFormation do utworzenia komponentu. Poniżej znajdziesz wyczerpujący opis roli każdego zbudowanego przez konstruktu:
- EksManagedNodeGroup: opisuje zarządzaną grupę węzłów przy użyciu niestandardowego szablonu uruchamiania, określając typ wystąpienia jako t3a.medium, tagi dla nazwy i środowiska. Definiuje również AMI (Amazon Linux 2) i rolę węzła z wymaganymi zarządzanymi zasadami, a także AmazonSSMManagedInstanceCore, dzięki czemu można łączyć się z węzłami za pomocą Menedżera sesji AWS Systems Manager.
- AWSLoadBalancerController: Instalacja kontrolera równoważenia obciążenia AWS z repozytorium eks-charts przy użyciu Helm v3, konfiguracja wymaganej polityki IAM, roli IAM dla konta usługi i niestandardowych CRD.
- ExternalDNS: Instalacja ExternalDNS zintegrowanego z Amazon Route 53 przy użyciu Helm v3, w tym konfiguracja wymaganych zasad IAM w celu aktualizacji rekordów Route 53 i roli IAM dla konta usługi.
- ClusterAutoscaler: instalacja narzędzia Kubernetes Cluster Autoscaler przy użyciu Helm v3, w tym konfiguracja wymaganych zasad uprawnień i roli uprawnień dla konta usługi.
- ContainerInsights: Konfiguracja Container Insights przy użyciu metryk aws-for-fluent-bit i aws-cloudwatch z repozytorium eks-charts przy użyciu Helm v3 oraz niezbędnych uprawnień z rolą IAM dla konta usługi.
- Calico: Instalacja operatora przy użyciu Helm v3 do segmentacji sieci i izolacji najemców.
- EchoServer: Instalacja przykładowej aplikacji w celu sprawdzenia poprawności działania innych składników, takich jak kontroler równoważenia obciążenia AWS i zewnętrzny DNS.
Gdy skończysz zmieniać kod, powinieneś uruchomić swoje środowisko:
npm install
cdk bootstrap
Po zakończeniu zatwierdź i wypchnij zmiany do swojego repozytorium za pomocą:
git add .
git commit -m "Update cluster configuration."
git push
Pierwsze wdrażanie
Za pierwszym razem będziesz musiał wdrożyć potok ręcznie, używając narzędzia cdk deploy. Następnie każda zmiana, którą wypchniesz do repozytorium, uruchomi potok, który zaktualizuje się i wykona.
Twoja pierwsza realizacja zajmie trochę czasu, ponieważ niektóre zasoby, takie jak klastry EKS i zarządzane grupy węzłów, mogą potrwać kilka minut, zanim będą gotowe. Możesz śledzić postęp, uzyskując dostęp do potoku przez AWS CodePipeline
Jeśli sprawdzisz stosy AWS CloudFormation, znajdziesz stos dla samego potoku (EksPipelineStack) i jeden stos (ze stosami zagnieżdżonymi) dla każdego klastra EKS.
W danych wyjściowych stosów EKSCluster znajdują się polecenia umożliwiające skonfigurowanie kubeconfig w celu uzyskania dostępu do klastra, skopiowanie go i wykonanie:
Następnie możesz wykonać zwykłe polecenia kubectl:
Możesz uzyskać dostęp do aplikacji bezpośrednio z przeglądarki używając echoserver.subdomain.my.domain lub używając curl:
curl -H “Host: app.my.domain” elb.<AWS_REGION>.elb.amazonaws.com
Ostateczna infrastruktura udostępniona dla tego potoku będzie wyglądać tak:
Definicja potoku używa zmiennej prodEnv do zdefiniowania klastra docelowego, innymi słowy, do którego użytkownicy będą mieli dostęp. Po ustawieniu i przejściu do rozwidlenia będziesz musiał ręcznie zatwierdzić tę zmianę w CodePipeline:
Po zakończeniu aktualizacji rekordu DNS i jego propagowaniu możesz sprawdzić, na co wskazuje rekord app.my.domain.
Sprzątanie
Aby posprzątać po tym tutorialu, zaloguj się do konsoli AWS na różne używane przez Ciebie konta, przejdź do konsoli AWS CloudFormation regionów, w których wybrałeś wdrożenie, a następnie wybierz i kliknij Usuń na następujących stosach: EksPipelineStack, EKSClusterA-EKSCluster, EKSClusterB-EKSCluster, UpdateDNS-AppDns, CDKToolkit.
Stos potoku (EksPipelineStack) i stos ładowania początkowego (CDKToolkit) zawierają klucz usługi zarządzania kluczami AWS, za który zostanie naliczona opłata w wysokości 1 USD miesięcznie, jeśli ich nie usuniesz.
Aby usunąć ten przykład za pomocą wiersza poleceń, możesz użyć:
$ cdk destroy -y
$ aws cloudformation delete-stack —stack-name EksPipelineStack
$ aws cloudformation delete-stack —stack-name EKSClusterA-EKSCluster
$ aws cloudformation delete-stack —stack-name EKSClusterB-EKSCluster
$ aws cloudformation delete-stack —stack-name UpdateDNS-AppDns
$ aws cloudformation delete-stack —stack-name CDKToolkit
Podsumowanie
Za pomocą tego artykułu twórcy przedstawili, jak używać AWS CDK i CDK Pipelines do wdrażania i zarządzania całym cyklem życia klastrów Amazon EKS. Ta infrastruktura jako kod zbliża się do zmian dostarczania poprzez zautomatyzowany i ustandaryzowany potok, który jest również zdefiniowany w AWS CDK, co pozwala na spójne wdrażanie i uaktualnianie klastrów w różnych wersjach, środowiskach, kontach i regionach, jednocześnie śledząc zmiany klastra i potoku za pośrednictwem Git. Przykładowy kod zawiera kilka przykładów składników często instalowanych w klastrach EKS, takich jak AWS Load Balancer Controller, Calico for Network Policies, ExternalDNS, Cluster Autoscaler, Metrics Server i Container Insights.
Ten przykładowy projekt można wykorzystać jako punkt wyjścia do zbudowania własnego rozwiązania do automatyzacji wdrażania własnych klastrów Amazon EKS. Odwiedź dokumentację AWS CDK Pipelines i dokumentację biblioteki Amazon EKS Construct, aby uzyskać więcej informacji na temat korzystania z tych bibliotek.
źródło: AWS