Blog

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

Konstantinos Bessas

Aktualisiert Oktober 15, 2025
9 Minuten

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:
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.
Es gibt verschiedene Tools, die man zum Schreiben von IaC verwenden kann. Um ein paar bekannte Optionen zu nennen:
  • YAML
  • Crossplane
  • pulumi
  • Terraform
  • AWS CDK
Was ist also der Unterschied zwischen dem deklarativen und dem imperativen Ansatz und wie passen die oben genannten Optionen dazu? Deklarativer Ansatz Der deklarative Ansatz konzentriert sich auf das "Was" der Infrastruktur. Bei einem deklarativen Ansatz definieren Sie den gewünschten Endzustand der Infrastruktur, ohne festzulegen, wie dieser erreicht werden soll. Das bedeutet, dass Sie nur angeben müssen, welche Ressourcen Sie erstellen, konfigurieren oder löschen möchten. Zu den deklarativen IaC-Tools gehören Sprachen wie YAML, JSON und HCL. Imperativer Ansatz Konzentriert sich auf das "Wie" der Infrastruktur. Bei einem imperativen Ansatz schreiben Sie Schritt-für-Schritt-Anweisungen für die Bereitstellung und Konfiguration von Ressourcen. Das bedeutet, dass Sie jeden Schritt definieren müssen, der zur Erstellung und Konfiguration der Infrastruktur erforderlich ist. Imperative IaC-Tools umfassen Skripte, die in Sprachen wie Bash, PowerShell oder Python geschrieben sind.

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. tf lebenszyklus meta-argument 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. tf provisioner meta-argument

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. aws cdk deklarativ

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: k8s design aws

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 das ec2.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 die eks.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.
Siehe unten für den architektonischen Aufbau des eks.Cluster level 2 construct. eks Cluster

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.txt müssen wir die folgenden 2 Bibliotheken konfigurieren:
    • cdk8s
    • cdk8s-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 Klasse cdk8s.Chart erben.
In diesem Projekt verwendetes Beispieldiagramm:
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_chart der Klasse eks.Cluster, um das Diagramm auf dem EKS Cluster bereitzustellen. Bei der Bereitstellung wird die Lambda-Funktion KubectlHandler für die Ausführung der entsprechenden kubectl-Befehle verwendet.
Beispiel:
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


  1. 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

Contact

Let’s discuss how we can support your journey.