Blog
Verwaltung von K8S-Infrastruktur und -Anwendungen auf AWS: Der Imperative Weg

Dieser Artikel ist das Ergebnis eines Vortrags, den ich kürzlich im Rahmen des Wissensaustauschs (XKE) bei Xebia in den Niederlanden gehalten habe. Die Frage ist ganz einfach:
Das Provisioner-Metaargument in Terraform gilt als zwingend erforderlich, da es Ihnen ermöglicht, Aktionen zu definieren, die mit einer Ressource durchgeführt werden, nachdem sie erstellt oder aktualisiert wurde, typischerweise für Konfigurationsmanagement oder Bootstrapping-Aufgaben.
Wie können wir die Infrastruktur und die Anwendungen von K8s mit einer einzigen Codebasis und Hochsprachen verwalten?In den kommenden Abschnitten werden wir herausfinden, wie wir Infrastructure as Code (IaC) sowie die K8s-Arbeitslastdefinition für eine Anwendung schreiben können, die auf AWS bereitgestellt werden soll. Wir werden die Leistungsfähigkeit von AWS CDK und cdk8s in einer einzigen Codebasis kombinieren, um unsere Infrastruktur und Anwendung bereitzustellen.
Deklarativer vs. Imperativer Ansatz für IaC
Bevor wir fortfahren, lassen Sie uns zunächst die verschiedenen Möglichkeiten aufzeigen, wie Sie Infrastruktur als Code schreiben können, sowie die wichtigsten Unterschiede zwischen der imperativen und der deklarativen Arbeitsweise. Der deklarative und der imperative Ansatz für die Programmierung sind zwei unterschiedliche Konzepte für die Entwicklung und Bereitstellung von Code. Wir werden uns das genauer ansehen:- Die wichtigsten Unterschiede zwischen den beiden Ansätzen, die sich nur auf IaC konzentrieren.
- Machen wir es wirklich richtig?
- Tauchen Sie ein in den speziellen Fall von AWS und sehen Sie die Stärken von Terraform gegenüber AWS CDK und umgekehrt.
- YAML
- Crossplane
- pulumi
- Terraform
- AWS CDK
Terraform VS AWS CDK
Konzentrieren wir uns für einen Moment auf 2 der oben genannten Optionen, die den größten Marktanteil bei der Bereitstellung von Infrastruktur in AWS haben. Was sind also die Unterschiede?Sprache und Syntax
Terraform verwendet eine eigene deklarative Konfigurationssprache (HCL), die Cloud-unabhängig sein soll, während Sie mit AWS CDK die Infrastruktur mit vertrauten Programmiersprachen wie Python, TypeScript, Java, C# und Go definieren können. Das bedeutet, dass Sie mit AWS CDK die volle Leistungsfähigkeit und Ausdruckskraft einer Programmiersprache nutzen können, um Ihre Infrastruktur zu definieren, während Sie mit Terraform eine eigene Konfigurationssprache verwenden.Abstraktionsebene
Terraform bietet eine höhere Abstraktionsebene, die es Ihnen ermöglicht, Infrastrukturressourcen, Anbieter und Module auf eine abstraktere und Cloud-unabhängige Weise zu definieren. Das bedeutet, dass Sie Terraform zur Verwaltung von Ressourcen über mehrere Cloud-Anbieter hinweg verwenden können, nicht nur für AWS. AWS CDK wurde speziell für die Bereitstellung von AWS-Ressourcen entwickelt und bietet einen stärker AWS-zentrierten Ansatz mit AWS-spezifischen Konstrukten, Bibliotheken und APIs, mit denen Sie AWS-Ressourcen auf eine nativere Weise definieren können.Bereitstellungsmodell
Terraform folgt einem deklarativen Modell, bei dem Sie den gewünschten Zustand Ihrer Infrastruktur definieren und Terraform sich um die Details kümmert, wie dieser Zustand erreicht werden soll. Änderungen an der Infrastruktur werden durch Aktualisieren der Terraform-Konfiguration und Anwenden der Änderungen verwaltet. AWS CDK hingegen folgt einem imperativen Modell, bei dem Sie die Infrastruktur mithilfe von Programmiercode definieren und Änderungen durch Aktualisieren des Codes und erneutes Bereitstellen der CDK-Anwendung vorgenommen werden. Das bedeutet, dass Sie mit AWS CDK mehr Flexibilität bei der Definition komplexer Logik und dynamischen Verhaltens haben, aber es kann im Vergleich zu Terraform zusätzliche Kodierung und Tests erfordern.Lernkurve und Vertrautheit
Die HCL-Syntax von Terraform ist so konzipiert, dass sie einfach und leicht zu erlernen ist, mit einem konfigurationsbasierten Ansatz, der vielen Betriebs- und Infrastrukturteams vertraut ist. AWS CDK ist ein programmierbasierter Ansatz und erfordert von den Entwicklern Kenntnisse und Erfahrungen mit Programmiersprachen, was je nach den Fähigkeiten und Vorlieben Ihres Teams ein Vor- oder Nachteil sein kann.Ist Terraform wirklich deklarativ?
Das Lebenszyklus-Metaargument in Terraform gilt als zwingend erforderlich, da Sie damit bestimmte Einstellungen für die Lebenszykluskonfiguration einer Ressource festlegen können, die sich darauf auswirken, wie Terraform die Ressource bei Aktualisierungen oder Löschungen verwaltet.
Das Provisioner-Metaargument in Terraform gilt als zwingend erforderlich, da es Ihnen ermöglicht, Aktionen zu definieren, die mit einer Ressource durchgeführt werden, nachdem sie erstellt oder aktualisiert wurde, typischerweise für Konfigurationsmanagement oder Bootstrapping-Aufgaben.
Ist das AWS CDK wirklich unabdingbar?
Sie können das AWS CDK sogar so verwenden, dass die gesamte Codebasis deklarativ ist, indem Sie imperative Deklarationen vermeiden. In dem folgenden Beispiel kann die Definition des S3-Buckets als deklarativ betrachtet werden.
Terraform VS AWS CDK (wieder)
All diese Punkte sind nur eine Frage der Definition. Die Wahl zwischen Terraform und AWS CDK hängt von Ihren spezifischen Anforderungen, Präferenzen und den Fähigkeiten Ihres Teams ab. Beide Tools sind leistungsstark und in der Branche weit verbreitet. Sie bieten unterschiedliche Ansätze für die Definition und Verwaltung von Cloud-Infrastruktur als Code.Verwalten von K8s-Infra und -Anwendungen auf AWS mit dem AWS CDK und cdk8s
In der Regel gehen Sie bei der Bereitstellung von K8s wie folgt vor: - Erstellen Sie die Infrastruktur mit IaC oder auf andere Weise. - Definieren Sie Ihre K8s-Arbeitslast (Pods, Deployments, Statefulsets usw.) mit Yaml. - Erstellen Sie Ihre Images mit Docker. - Konfigurieren Sie Ihren Cluster mit kubectl und stellen Sie ihn bereit.Die Konfiguration von K8s war schon immer ein deklaratives Paradigma, aber das galt auch für IaC in seiner Anfangsphase.Betrachten wir die folgende Herausforderung. Wir wollen: - Die K8s-Infrastruktur auf AWS mit AWS CDK bereitstellen. - Die K8s-Arbeitslast mit cdk8s definieren. - eine einzige Codebasis verwenden - eine einstufige Bereitstellung für die Infrastruktur und die K8s-Arbeitslast auf AWS EKS für alle oben genannten Punkte verwenden. Der obige Anwendungsfall beschreibt keine bessere oder bevorzugte Methode für die Arbeit mit IaC- und K8s-Workload-Definitionen, sondern zeigt lediglich eine alternative Herangehensweise an dieses Thema.
Ziel Infrastruktur
Die Zielinfrastruktur, die wir bereitstellen wollen, ist im folgenden Diagramm zu sehen:
Erstellen Sie Ihr AWS CDK-Projekt
Wir werden unser AWS CDK-Projekt mit Python erstellen. Die Absicht ist, ein "Vorlagen"-Projekt zu erstellen, das wiederverwendet werden kann, wenn jemand mit K8s in AWS einsteigen möchte. Mit dem gleichen Ansatz können Sie ähnliche "Vorlagen" in den anderen Programmiersprachen erstellen, die von der Familie der CDK-Projekte unterstützt werden.cdk init app --language=python
Weitere Informationen zu den ersten Schritten mit dem AWS CDK finden Sie hier.
Definieren Sie Ihre AWS-Ressourcen
Gemäß dem oben gezeigten Entwurf müssen wir die folgenden Komponenten in AWS erstellen:- Die Netzwerkinfrastruktur
- Ein EKS-Cluster
Netzwerk
Für das Netzwerk werden wir eine VPC und die sie umgebenden Ressourcen erstellen. Wir werden dasec2.Vpc Level 2 Konstrukt verwenden.
Die Umsetzung finden Sie unten.
from aws_cdk import (
NestedStack,
aws_ec2 as ec2,
)
from constructs import Construct
from helper import config
class NetworkingStack(NestedStack):
def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
super().__init__(scope, construct_id, **kwargs)
conf = config.Config(self.node.try_get_context('environment'))
self.vpc = ec2.Vpc(self, "k8s-sample-vpc",
ip_addresses=ec2.IpAddresses.cidr(conf.get('cidr')),
subnet_configuration=[
ec2.SubnetConfiguration(
name = 'public',
subnet_type = ec2.SubnetType.PUBLIC,
cidr_mask = 28
),
ec2.SubnetConfiguration(
name = 'eks',
subnet_type = ec2.SubnetType.PRIVATE_WITH_EGRESS,
cidr_mask = 26
)
],
)
EKS-Cluster
Für den EKS-Cluster werden wir dieeks.Cluster Level 2-Konstrukt.
Die Umsetzung finden Sie unten.
from aws_cdk import (
NestedStack,
aws_eks as eks,
aws_ec2 as ec2,
aws_iam as iam
)
from constructs import Construct
from helper import config
from aws_cdk.lambda_layer_kubectl_v25 import KubectlV25Layer
class EKSStack(NestedStack):
def __init__(self, scope: Construct, construct_id: str, vpc: ec2.IVpc, **kwargs) -> None:
super().__init__(scope, construct_id, **kwargs)
conf = config.Config(self.node.try_get_context('environment'))
self.cluster = eks.Cluster(
self, 'k8s-sample-cluster',
version=eks.KubernetesVersion.V1_25,
kubectl_layer=KubectlV25Layer(self, "kubectl"),
alb_controller=eks.AlbControllerOptions(
version=eks.AlbControllerVersion.V2_4_1
),
default_capacity=0,
vpc=vpc,
vpc_subnets=[
ec2.SubnetSelection(
subnet_group_name='eks'
)
]
)
self.cluster.add_nodegroup_capacity(
'eks-nodegroup',
instance_types=[ec2.InstanceType('t3.large')]
)
# importing an existing user
admin_user = iam.User.from_user_arn(
self, 'imported_user',
user_arn='arn:aws:iam::970059968789:user/iam_user' # change me
)
self.cluster.aws_auth.add_user_mapping(admin_user, groups=["system:masters"])
Das Level 2-Konstrukt zur Erstellung eines EKS-Clusters schafft einige wichtige Ressourcen für die Integration mit cdk8s. Es werden nämlich 2 Lambda-Funktionen zusammen mit dem Cluster bereitgestellt:
- KubectlHandler ist eine Lambda-Funktion zum Aufrufen von kubectl-Befehlen auf dem Cluster.
- ClusterHandler ist eine Lambda-Funktion für die Interaktion mit der EKS-API zur Verwaltung des Lebenszyklus des Clusters.
eks.Cluster level 2 construct.
Integration von cdk8s in das AWS CDK-Projekt
Um cdk8s verwenden zu können, müssen wir die folgenden Änderungen im AWS CDK-Projekt vornehmen.- In der
requirements.txtmüssen wir die folgenden 2 Bibliotheken konfigurieren:cdk8scdk8s-plus-251
- Erstellen Sie einen Ordner (z.B.
k8s_full_stack_charts) auf der Stammebene des Projekts, der Ihre cdk8s-Charts enthalten wird. Erstellen Sie Ihre Zeichen in diesem Ordner als Klassen, die von der Klassecdk8s.Charterben.
import cdk8s as cdk8s
import cdk8s_plus_25 as kplus
from constructs import Construct
class SampleChart(cdk8s.Chart):
def __init__(self, scope: Construct, id: str):
super().__init__(scope, id)
nginx_deployment = kplus.Deployment(
self, 'sampleDeployment',
replicas=1,
containers=[
kplus.ContainerProps(
image='nginx:mainline-alpine',
port=80,
security_context=kplus.ContainerSecurityContextProps(
ensure_non_root=False,
read_only_root_filesystem=False
)
)
],
security_context=kplus.PodSecurityContextProps(
ensure_non_root=False
)
)
nginx_deployment.expose_via_service(
service_type=kplus.ServiceType.LOAD_BALANCER
)
- Verwenden Sie die
add_cdk8s_chartder Klasseeks.Cluster, um das Diagramm auf dem EKS Cluster bereitzustellen. Bei der Bereitstellung wird die Lambda-FunktionKubectlHandlerfür die Ausführung der entsprechenden kubectl-Befehle verwendet.
from aws_cdk import (
NestedStack,
aws_eks as eks
)
import cdk8s as cdk8s
from constructs import Construct
class EKSApplicationStack(NestedStack):
def __init__(self, scope: Construct, construct_id: str, cluster: eks.ICluster, chart: cdk8s.Chart, **kwargs) -> None:
super().__init__(scope, construct_id, **kwargs)
cluster.add_cdk8s_chart(
'sample-chart',
chart,
ingress_alb=True,
ingress_alb_scheme=eks.AlbScheme.INTERNET_FACING,
prune=True
)
Abschließende Gedanken
Diese Art der Bereitstellung von K8s-Clustern zusammen mit der Arbeitslast kann bei ephemeren Clustern sehr nützlich sein. Es könnte auch für Teams nützlich sein, die hohe Programmiersprachen beherrschen, um Infrastruktur und Arbeitslasten unter Verwendung der gleichen hohen Programmiersprache ihrer Wahl zu bündeln. Sie finden die vollständige Lösung für alles, was oben beschrieben wurde, auf GitHub. Sie können sie als Startvorlage für die Bereitstellung von K8s-Clustern auf AWS zusammen mit der Verwaltung der Anwendung in einem Repository verwenden. Die nächsten Schritte wären das Hinzufügen weiterer Vorlagen im oben genannten Repository in den anderen Sprachen, die von der CDK-Frameworks-Familie unterstützt werden.Hauptbild von svstudioart auf Freepik
- Der Name/die Version dieser Bibliothek hängt von der für den EKS-Cluster verwendeten K8s-Version ab. In diesem Fall verwenden wir die K8s-Version
1.25.
Verfasst von
Konstantinos Bessas
Unsere Ideen
Weitere Blogs
Contact
Let’s discuss how we can support your journey.



