# Einrichten von Amazon EKS mit S3

Bevor Sie Dynamic Engine und ihre Umgebungen bereitstellen, richten Sie einen Amazon EKS-Cluster mit Amazon S3 als freigegebenes Speicher-Backend ein.

## Vorbereitungen

* Ein AWS-Konto mit den erforderlichen IAM-Berechtigungen. Die vollständige Liste der Voraussetzungen finden Sie unter [Konfigurieren von Amazon EKS für die Dynamic Engine-Bereitstellung](https://help.qlik.com/talend/de-DE/dynamic-engine-configuration-guide/Cloud/deploying-dynamic-engine-on-aws-eks "Dynamic Engine kann auf Amazon Elastic Kubernetes Service (EKS) mit nativen EKS-Speichersystemen bereitgestellt werden.").

## Warum und wann dieser Vorgang ausgeführt wird

Mit diesem Verfahren wird ein neuer EKS-Cluster in einer dedizierten Virtual Private Cloud (Amazon VPC) erstellt, der S3 CSI-Treiber (Container Storage Interface) als AWS-verwaltetes EKS-Add-On installiert, ein S3-Bucket zum Unterstützen von persistenten Volumes erstellt und statische PersistentVolumes und PersistentVolumeClaims für Dynamic Engine und ihre Umgebungen bereitgestellt.

* Anders als die Amazon EFS-Einrichtung verwendet S3 statische Bereitstellung: Es ist keine StorageClass-Ressource vorhanden. Sie müssen PersistentVolumes manuell erstellen und an benannte PersistentVolumeClaims binden, bevor Sie Dynamic Engine bereitstellen.

## Prozedur

1. Legen Sie die Umgebungsvariablen für Ihre Amazon EKS- und S3-Bereitstellung fest:
   ```
   export AWS_REGION=<your-aws-region>
   export EKS_CLUSTER_NAME=<your-eks-cluster-name>
   export S3_BUCKET_NAME=<your-s3-bucket-name>
   ```
2. Erstellen Sie den S3-Bucket, um die persistenten Volumes zu unterstützen. Wählen Sie den Bucket-Typ aus, der Ihren Anforderungen entspricht.

   Der zu erstellende Bucket und die Amazon VPC müssen sich in der gleichen AWS-Region befinden.
   * Allgemeiner Bucket: Verwenden Sie einen S3-Standard-Bucket, der in allen AWS-Regionen verfügbar ist. Ein Bucket dient für alle Dynamic Engine-Volumes, die Pfadpräfixe verwenden.

     ```
     cat <<EOF > $S3_BUCKET_NAME-classic-input.yaml
     Bucket: $S3_BUCKET_NAME
     CreateBucketConfiguration:
       LocationConstraint: ${AWS_REGION}
       Tags:
         - Key: owner
           Value: dyn-engine
         - Key: creator
           Value: ${USER}
         - Key: eks/cluster
           Value: ${EKS_CLUSTER_NAME}
     EOF

     S3_BUCKET_ARN=$(aws s3api create-bucket \
       --cli-input-yaml file://$S3_BUCKET_NAME-classic-input.yaml \
       --region $AWS_REGION \
       --output text \
       --query BucketArn)

     echo "S3 bucket created: $S3_BUCKET_ARN"
     ```

     Die drei Blöcke generieren eine Konfigurationsdatei für den neuen S3-Bucket mit Eigentümer-Tags, erstellen den Bucket über die AWS CLI und drucken eine Bestätigungsmeldung mit der eindeutigen Kennung des Buckets.

   * Verzeichnis-Bucket: Verwenden Sie einen Verzeichnis-Bucket (auch als S3 Express One Zone-Bucket bezeichnet) für reduzierte Latenz innerhalb einer einzelnen Verfügbarkeitszone. Verzeichnis-Buckets erfordern ein spezifisches Benennungsformat: bucket-base-name--zone-id--x-s3, wobei zone-id eine Verfügbarkeitszonen-ID oder eine lokale Zonen-ID ist. Dieser Bucket-Typ ist nur in bestimmten AWS-Regionen und Verfügbarkeitszonen verfügbar.

     InformationshinweisAnmerkung: Legen Sie AWS\_AZ\_ZONE\_ID auf die Zonen-ID für Ihre Ziel-Verfügbarkeitszone fest, bevor Sie dieses Skript ausführen. Beispielsweise gilt euw1-az1 für die Region eu-west-1.

     ```
     AWS_AZ_ZONE_ID=<your-az-zone-id>
     S3_BUCKET_NAME="${EKS_CLUSTER_NAME}--$AWS_AZ_ZONE_ID--x-s3"

     cat <<EOF > $S3_BUCKET_NAME-directory-input.yaml
     Bucket: $S3_BUCKET_NAME
     CreateBucketConfiguration:
       Location:
         Type: AvailabilityZone
         Name: $AWS_AZ_ZONE_ID
       Bucket:
         DataRedundancy: SingleAvailabilityZone
         Type: Directory
       Tags:
         - Key: owner
           Value: dyn-engine
         - Key: creator
           Value: ${USER}
         - Key: eks/cluster
           Value: ${EKS_CLUSTER_NAME}
     EOF

     S3_BUCKET_ARN=$(aws s3api create-bucket \
       --cli-input-yaml file://$S3_BUCKET_NAME-directory-input.yaml \
       --region $AWS_REGION \
       --output text \
       --query BucketArn)

     echo "S3 bucket created: $S3_BUCKET_ARN"
     ```

     Diese vier Blöcke richten einen S3 Express One Zone (Verzeichnis-)Bucket ein und erstellen ihn, der an eine spezifische Verfügbarkeitszone angeheftet ist und für AWS erforderliche Benennungskonventionen und Konfigurationen verwendet. Dann wird eine Bestätigungsmeldung gedruckt.
3. Erstellen Sie die EKS-Cluster-Konfigurationsdatei.

   IAM-Berechtigungen unterscheiden sich zwischen allgemeinen und Verzeichnis-Buckets. Verwenden Sie die Konfiguration, die dem im vorigen Schritt erstellten Bucket-Typ entspricht:
   * Allgemeiner Bucket: Gewähren Sie s3:ListBucket, s3:GetObject, s3:PutObject und s3:DeleteObject für den Bucket und seine Objekte:

     ```
     cat <<EOF > eks-config.yaml
     apiVersion: eksctl.io/v1alpha5
     kind: ClusterConfig

     metadata:
       name: ${EKS_CLUSTER_NAME}
       region: ${AWS_REGION}
       version: "1.34"

     autoModeConfig:
       enabled: false

     addonsConfig:
       autoApplyPodIdentityAssociations: true

     addons:
       - name: eks-pod-identity-agent
       - name: aws-mountpoint-s3-csi-driver
         namespaceConfig:
           namespace: aws-mountpoint-s3
         podIdentityAssociations:
           - namespace: aws-mountpoint-s3
             serviceAccountName: s3-csi-driver-sa
             permissionPolicy:
               Statement:
                 - Effect: Allow
                   Action:
                     - s3:ListBucket
                   Resource: $S3_BUCKET_ARN
                 - Effect: Allow
                   Action:
                     - s3:GetObject
                     - s3:PutObject
                     - s3:DeleteObject
                   Resource: "$S3_BUCKET_ARN/*"

     vpc:
       cidr: 10.10.0.0/16
       autoAllocateIPv6: false
       hostnameType: resource-name
       clusterEndpoints:
         publicAccess: true
         privateAccess: true
       nat:
         gateway: HighlyAvailable

     managedNodeGroups:
       - name: ng-amd64
         amiFamily: AmazonLinux2023 # (default) or Bottlerocket
         minSize: 2
         maxSize: 4
         desiredCapacity: 2
         instanceSelector:
           vCPUs: 4
           memory: 16GiB
           cpuArchitecture: amd64
         privateNetworking: true

     EOF
     ```

   * Verzeichnis-Bucket: Gewähren Sie s3express:CreateSession für den Bucket (S3 Express One Zone-sitzungsbasierte Autorisierung):

     ```
     cat <<EOF > eks-config.yaml
     apiVersion: eksctl.io/v1alpha5
     kind: ClusterConfig

     metadata:
       name: ${EKS_CLUSTER_NAME}
       region: ${AWS_REGION}
       version: "1.34"

     autoModeConfig:
       enabled: false

     addonsConfig:
       autoApplyPodIdentityAssociations: true

     addons:
       - name: eks-pod-identity-agent
       - name: aws-mountpoint-s3-csi-driver
         namespaceConfig:
           namespace: aws-mountpoint-s3
         podIdentityAssociations:
           - namespace: aws-mountpoint-s3
             serviceAccountName: s3-csi-driver-sa
             permissionPolicy:
               Statement:
                 - Effect: Allow
                   Action:
                     - s3express:CreateSession
                   Resource: $S3_BUCKET_ARN

     vpc:
       cidr: 10.10.0.0/16
       autoAllocateIPv6: false
       hostnameType: resource-name
       clusterEndpoints:
         publicAccess: true
         privateAccess: true
       nat:
         gateway: HighlyAvailable

     managedNodeGroups:
       - name: ng-amd64
         amiFamily: AmazonLinux2023 # (default) or Bottlerocket
         minSize: 2
         maxSize: 4
         desiredCapacity: 2
         instanceSelector:
           vCPUs: 4
           memory: 16GiB
           cpuArchitecture: amd64
         privateNetworking: true

     EOF
     ```

   InformationshinweisAnmerkung: Die folgenden Konfigurationshinweise gelten sowohl für allgemeine als auch für Verzeichnis-Bucket-Varianten. Der einzige Unterschied zwischen ihnen besteht in der IAM-Berechtigungsrichtlinie, die dem S3 CSI-Treiber gewährt wird.

   Diese Konfiguration:
   * Legt die Kubernetes-Version auf 1.34 fest. Dies ist die Beispielversion, die in diesem Verfahren verwendet wird. Aktualisieren Sie sie, damit sie Ihrer Ziel-Cluster-Version entspricht. Informationen zu unterstützten Versionen finden Sie unter [Voraussetzungen für die Verwendung von Dynamic Engine](https://help.qlik.com/talend/de-DE/dynamic-engine-configuration-guide/Cloud/prerequisits-to-use-dynamic-engines "Zu den Anforderungen für die Verwendung von Dynamic Engine zählen das Einschließen von DNS-URLs, die Ihrer Proxy- und Firewall-Allowlist hinzugefügt werden, Kubernetes-Spezifikationen und Zugriffsberechtigungen auf Talend Management Console und Dynamic Engines.").
   * Deaktiviert den automatischen EKS-Modus (autoModeConfig: enabled: false), um Standard-Knotengruppenverwaltung sicherzustellen.
   * Installiert das aws-mountpoint-s3-csi-driver-Add-On im aws-mountpoint-s3-Namespace, wobe IAM-Berechtigungen automatisch mit Pod-Identitätszuordnungen konfiguriert werden. Dies gewährt dem S3 CSI-Treiber die Berechtigungen, die er benötigt, um S3-Objekte als VOlumes ohne hartcodierte Anmeldedaten zu mounten. Anders als EFS, das eine EKS-verwaltete Richtlinie verwendet, erfordert der S3 CSI-Treiber eine ausdrückliche IAM-Richtlinie, deren Umfang dem spezifischen S3-Bucket-ARN entspricht ($S3\_BUCKET\_ARN). Diese Richtlinie wird automatisch von eksctl an das Add-On gebunden; es sind keine weiteren AWS CLI-Schritte erforderlich.
   * Erstellt eine VPC und platziert alle Knoten in privaten Subnetzen (privateNetworking: true). Die Knoten erreichen das Internet nur über NAT-Gateways. Der Cluster-Endpunkt bleibt sowohl von der lokalen Maschine als auch innerhalb der VPC erreichbar.
   * Stellt Knoten in der passenden Größe für Dynamic Engine-Arbeitslasten bereit. Jeder Knoten hat 4 vCPUs und 16 GiB RAM. Die Knotengruppen skalieren zwischen 2 und 4 Knoten (minSize: 2, maxSize: 4). Die AMD64-Architektur (cpuArchitecture: amd64) ist erforderlich, weil Dynamic Engine-Container-Images nur für AMD64 erstellt werden.
4. Erstellen Sie den EKS-Cluster, verknüpfen Sie das lokale kubectl-Tool mit dem Cluster und überprüfen Sie die Erreichbarkeit:
   ```
   eksctl create cluster -f eks-config.yaml
   aws eks update-kubeconfig --region "$AWS_REGION" --name "$EKS_CLUSTER_NAME"
   kubectl get nodes
   ```

   Warten Sie vor dem Fortfahren, bis alle Knoten den Status Bereit erreicht haben.
5. Legen Sie Umgebungsvariablen für den Dynamic Engine-Umgebungs-Namespace fest und erstellen Sie die drei PersistentVolumes und PersistentVolumeClaims, die von den Dynamic Engine-Diensten und von Ihren Talend Management Console-Tasks verwendet werden sollen:
   ```
   ENV_ID=67f7d562ffd7c3525a902542
   DYNAMIC_ENGINE_ENV_NAMESPACE=qlik-processing-env-$ENV_ID
   # Ensure the target namespace exists before creating PVs/PVCs
   kubectl get namespace "$DYNAMIC_ENGINE_ENV_NAMESPACE" >/dev/null 2>&1 || kubectl create namespace "$DYNAMIC_ENGINE_ENV_NAMESPACE"
   declare -a pvcs=("archive" "job-data" "custom-resources")

   for pvc in "${pvcs[@]}"
   do
     echo "Creating PV/PVC for $pvc"
   cat <<EOF | kubectl apply -f -
   ---
   apiVersion: v1
   kind: PersistentVolume
   metadata:
     name: $pvc
   spec:
     capacity:
       storage: 1200Gi # Ignored for S3 volumes but required by Kubernetes API
     accessModes:
       - ReadWriteMany # Supported options: ReadWriteMany / ReadOnlyMany
     storageClassName: "" # Required for static provisioning
     claimRef: # To ensure no other PVCs can claim this PV
       namespace: $DYNAMIC_ENGINE_ENV_NAMESPACE # Namespace is required even though it's in "default" namespace.
       name: $pvc # Name of your PVC
     mountOptions:
       - allow-delete
       - allow-overwrite
       - region $AWS_REGION
       - prefix $pvc/
     csi:
       driver: s3.csi.aws.com # Required
       volumeHandle: $pvc # Must be unique
       volumeAttributes:
         bucketName: $S3_BUCKET_NAME
   ---
   apiVersion: v1
   kind: PersistentVolumeClaim
   metadata:
     name: $pvc
     namespace: $DYNAMIC_ENGINE_ENV_NAMESPACE
   spec:
     accessModes:
       - ReadWriteMany # Supported options: ReadWriteMany / ReadOnlyMany
     storageClassName: "" # Required for static provisioning
     resources:
       requests:
         storage: 1200Gi # Ignored, required
     volumeName: $pvc # Name of your PV
   EOF
   ```
   * storageClassName: "": Muss für statische Bereitstellung leer sein.
   * claimRef: Bindet dieses PersistentVolume ausschließlich an den benannten PersistentVolumeClaim im angegebenen Namespace. Erforderlich, um einen unbeabsichtigten Claim durch andere Arbeitslasten zu verhindern.
   * mountOptions: allow-delete und allow-overwrite. Diese ermöglichen Schreibvorgänge auf S3-unterstützten Volumes. Ohne diese Flags können Pods das Volume mounten, aber Schreibvorgänge schlagen fehl.
   * prefix: $pvc/: Legt den Umfang jedes Volumes auf ein getrenntes Pfadpräfix innerhalb des gemeinsamen S3-Buckets fest, wodurch die Daten für jedes Volume isoliert werden.
   * volumeHandle: Muss für alle PersistentVolumes im Cluster eindeutig sein.
6. Erstellen Sie ein Test-Pod, das alle drei PersistentVolumeClaims mountet:
   ```
   cat <<EOF | kubectl apply -f -
   apiVersion: v1
   kind: Pod
   metadata:
     name: test-pod-pvc
     namespace: $DYNAMIC_ENGINE_ENV_NAMESPACE
   spec:
     securityContext:
       fsGroup: 61000
       runAsUser: 61000
       runAsGroup: 61000
       runAsNonRoot: true
     containers:
       - name: app
         image: ghcr.io/talend/kube-base:5.3.0
         command: ["cat"]
         tty: true
         volumeMounts:
           - name: archive
             mountPath: /opt/talend/archive
           - name: job-data
             mountPath: /opt/talend/data
           - name: custom-resources
             mountPath: /opt/talend/custom-resources
     volumes:
       - name: archive
         persistentVolumeClaim:
           claimName: archive
       - name: job-data
         persistentVolumeClaim:
           claimName: job-data
       - name: custom-resources
         persistentVolumeClaim:
           claimName: custom-resources
   EOF
   ```

   Das Test-Pod verwendet runAsUser: 61000, runAsGroup: 61000 und fsGroup: 61000. Diese Werte entsprechen der Dynamic Engine-Laufzeit-UID/GID und sind für eine korrekte Dateieigentümerschaft auf den gemounteten Volumes erforderlich.
7. Validieren Sie, dass der Pod Daten auf den gemounteten Volumes lesen und schreiben kann:
   ```
   kubectl exec -n $DYNAMIC_ENGINE_ENV_NAMESPACE test-pod-pvc -- \
     sh -c "echo 'Hello world' > /opt/talend/archive/test.txt \
     && cat /opt/talend/archive/test.txt \
     && rm -f /opt/talend/archive/test.txt"
   ```

   Wenn der Befehl ohne Fehler abgeschlossen wird, ist das S3-unterstützte Volume zugänglich und beschreibbar.

## Ergebnisse

Ihr EKS-Cluster wird mit dem installierten S3 CSI-Treiber ausgeführt, und die drei PersistentVolumes (archive, job-data, custom-resources) sind erstellt und an ihre PersistentVolumeClaims im qlik-processing-env-&lt;env-id&gt;-Namespace gebunden. Der Cluster ist für die Dynamic Engine-Bereitstellung bereit.

InformationshinweisTipp: Der eingebettete docker-registry-Dienst von Dynamic Engine führt zufällige Schreibvorgänge durch, was der S3 CSI-Treiber (Mountpunkt for Amazon S3) nicht unterstützt. Infolgedessen kann das docker-registry-Volume keinen S3-unterstützten PersistentVolumeClaim verwenden. Verwenden Sie EFS oder andere externe Systeme, die POSIX (Portable Operating System Interface) unterstützen, um persistente Volumes (dynamisch oder statisch) für docker-registry bereitzustellen.

* Einzelheiten zum Konfigurieren von docker-registry finden Sie unter [Konfigurieren einer benutzerdefinierten Docker-Registrierung für Datenservices und Routen](https://help.qlik.com/talend/de-DE/dynamic-engine-configuration-guide/Cloud/configure-docker-registry "Konfigurieren Sie eine interne oder externe Docker-Registrierung für Datenservices und Routen in einer Dynamic Engine-Umgebung.").
* Anweisungen zum Verwenden von vorhandenen statischen persistenten Volumes finden Sie unter [Bereitstellen von Dynamic Engine mit vorhandenen PersistentVolumeClaims](https://help.qlik.com/talend/de-DE/dynamic-engine-configuration-guide/Cloud/deploy-dynamic-engine-with-static-pvc "Konfigurieren Sie die Dynamic Engine Helm Charts, um vorhandene PersistentVolumeClaims nach Namen zu referenzieren, statt dynamische StorageClass-Bereitstellung zu verwenden.").
* Anweisungen zum Verwenden von dynamischen persistenten Volumes (StorageClass) finden Sie unter [Bereitstellung einer Speicherklasse, die auf Dynamic Engine-Umgebungsdienste spezialisiert ist](https://help.qlik.com/talend/de-DE/dynamic-engine-configuration-guide/Cloud/deploy-dynamic-engine-with-specific-storageclass "Konfigurieren Sie eine spezifische Speicherklasse für Dynamic Engine-Umgebungsdienste, anstatt die Standard-Kubernetes-Speicherklasse zu verwenden.").

## Nächste Maßnahme

Konfigurieren Sie die Dynamic Engine Helm Charts und stellen Sie sie bereit, damit sie die PersistentVolumeClaims referenzieren, die Sie in diesem Verfahren erstellt haben. Detaillierte Anweisungen zum Verwenden von vorhandenen PVCs finden Sie unter [Bereitstellen von Dynamic Engine mit vorhandenen PersistentVolumeClaims](https://help.qlik.com/talend/de-DE/dynamic-engine-configuration-guide/Cloud/deploy-dynamic-engine-with-static-pvc "Konfigurieren Sie die Dynamic Engine Helm Charts, um vorhandene PersistentVolumeClaims nach Namen zu referenzieren, statt dynamische StorageClass-Bereitstellung zu verwenden.").

### In diesem Abschnitt

* [Bereitstellen von Dynamic Engine mit vorhandenen PersistentVolumeClaims](https://help.qlik.com/talend/de-DE/dynamic-engine-configuration-guide/Cloud/deploy-dynamic-engine-with-static-pvc)