

 **Contribuisci a migliorare questa pagina** 

Le traduzioni sono generate tramite traduzione automatica. In caso di conflitto tra il contenuto di una traduzione e la versione originale in Inglese, quest'ultima prevarrà.

Per contribuire a questa guida per l'utente, scegli il GitHub link **Modifica questa pagina** nel riquadro destro di ogni pagina.

Le traduzioni sono generate tramite traduzione automatica. In caso di conflitto tra il contenuto di una traduzione e la versione originale in Inglese, quest'ultima prevarrà.

# Usa l’archiviazione delle app ad alte prestazioni con Amazon FSx per Lustre
<a name="fsx-csi"></a>

Il [driver Container Storage Interface (CSI) per Amazon FSx per Lustre](https://github.com/kubernetes-sigs/aws-fsx-csi-driver) mette a disposizione un’interfaccia CSI che permette ai cluster Amazon EKS di gestire il ciclo di vita dei file system Amazon FSx per Lustre. Per ulteriori informazioni, consulta [Amazon FSx for Lustre User Guide](https://docs.aws.amazon.com/fsx/latest/LustreGuide/what-is.html).

Per informazioni su come implementare il driver CSI per Amazon FSx per Lustre nel cluster Amazon EKS e come verificarne il funzionamento, consulta [Implementa il driver FSx for Lustre](fsx-csi-create.md).

# Implementa il driver FSx for Lustre
<a name="fsx-csi-create"></a>

Questo argomento mostra come distribuire il [driver CSI FSx for Lustre](fsx-csi.md) nel cluster Amazon EKS e verificarne il funzionamento. Ti consigliamo di utilizzare sempre la versione più recente del driver. Per le versioni disponibili, consulta la matrice di compatibilità delle [specifiche CSI su](https://github.com/kubernetes-sigs/aws-fsx-csi-driver/blob/master/docs/README.md#csi-specification-compatibility-matrix). GitHub

**Nota**  
Il driver non è supportato su Fargate.

Per descrizioni dettagliate dei parametri disponibili ed esempi completi che dimostrano le funzionalità del driver, consultate il progetto [driver FSx for Lustre Container Storage Interface (CSI)](https://github.com/kubernetes-sigs/aws-fsx-csi-driver) su. GitHub

## Prerequisiti
<a name="fsx-csi-prereqs"></a>
+ Un cluster esistente.
+ Il componente aggiuntivo Amazon FSx CSI Driver EKS supporta l'autenticazione tramite EKS Pod Identity o IAM Roles for Service Accounts (IRSA). Per utilizzare EKS Pod Identity, installa l'agente Pod Identity prima o dopo la distribuzione del FSx componente aggiuntivo CSI Driver. Per ulteriori informazioni, consulta [Configurazione dell’agente Amazon EKS Pod Identity](pod-id-agent-setup.md). Per utilizzare invece IRSA, consulta. [Per creare un provider di identità IAM OIDC per il cluster](enable-iam-roles-for-service-accounts.md)
+ Versione `2.12.3` o successiva o versione `1.27.160` o successiva dell'interfaccia a riga di AWS comando (AWS CLI) installata e configurata sul dispositivo o. AWS CloudShell Per verificare la versione attuale, usa `aws --version | cut -d / -f2 | cut -d ' ' -f1`. I gestori di pacchetti come `yum``apt-get`, o Homebrew per macOS sono spesso diverse versioni dell'ultima versione della CLI AWS . Per installare la versione più recente, consulta [Installazione](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-install.html) e [configurazione rapida con aws configure](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-quickstart.html#cli-configure-quickstart-config) nella Guida per l'utente dell'*interfaccia a riga di AWS comando*. La versione AWS CLI installata in AWS CloudShell potrebbe anche contenere diverse versioni precedenti alla versione più recente. Per aggiornarlo, consulta [Installazione della AWS CLI nella tua home directory nella Guida per](https://docs.aws.amazon.com/cloudshell/latest/userguide/vm-specs.html#install-cli-software) l'* AWS CloudShell utente*.
+ La versione `0.215.0` o quelle successive dello strumento a riga di comando `eksctl` deve essere installata sul dispositivo o nella AWS CloudShell. Per l’installazione o l’aggiornamento di `eksctl`, consulta la sezione [Installation](https://eksctl.io/installation) nella documentazione di `eksctl`.
+ Lo strumento a riga di comando `kubectl` è installato sul dispositivo o AWS CloudShell. La versione può essere uguale oppure immediatamente precedente o successiva alla versione di Kubernetes del cluster. Ad esempio, se la versione del cluster è `1.29`, puoi usare `kubectl` versione `1.28`, `1.29` o `1.30`. Per installare o aggiornare `kubectl`, consulta [Impostazione di `kubectl` e `eksctl`](install-kubectl.md):

## Passaggio 1: Creazione di un ruolo IAM
<a name="fsx-create-iam-role"></a>

Il plug-in Amazon FSx CSI richiede le autorizzazioni IAM per effettuare chiamate per tuo AWS APIs conto.

**Nota**  
I pod avranno accesso alle autorizzazioni assegnate al ruolo IAM, a meno che non si blocchi l’accesso a IMDS. Per ulteriori informazioni, consulta [Protezione dei cluster Amazon EKS con le best practice](security-best-practices.md).

La procedura seguente mostra come creare un ruolo IAM e allegare ad esso la policy AWS gestita.

1. Crea un ruolo IAM e collega la policy AWS gestita con il seguente comando. Sostituisci `my-cluster` con il nome del cluster che desideri utilizzare. Il comando distribuisce uno AWS CloudFormation stack che crea un ruolo IAM e vi allega la policy IAM.

   ```
   eksctl create iamserviceaccount \
       --name fsx-csi-controller-sa \
       --namespace kube-system \
       --cluster my-cluster \
       --role-name AmazonEKS_FSx_CSI_DriverRole \
       --role-only \
       --attach-policy-arn arn:aws: iam::aws:policy/AmazonFSxFullAccess \
       --approve
   ```

   Visualizzerai diverse righe di output quando l’account del servizio viene creato. Le ultime righe dell’output sono simili a quelle riportate di seguito.

   ```
   [ℹ]  1 task: {
       2 sequential sub-tasks: {
           create IAM role for serviceaccount "kube-system/fsx-csi-controller-sa",
           create serviceaccount "kube-system/fsx-csi-controller-sa",
       } }
   [ℹ]  building iamserviceaccount stack "eksctl-my-cluster-addon-iamserviceaccount-kube-system-fsx-csi-controller-sa"
   [ℹ]  deploying stack "eksctl-my-cluster-addon-iamserviceaccount-kube-system-fsx-csi-controller-sa"
   [ℹ]  waiting for CloudFormation stack "eksctl-my-cluster-addon-iamserviceaccount-kube-system-fsx-csi-controller-sa"
   [ℹ]  created serviceaccount "kube-system/fsx-csi-controller-sa"
   ```

   Annota il nome dello AWS CloudFormation stack che è stato distribuito. Nell’output di esempio precedente, lo stack è denominato `eksctl-my-cluster-addon-iamserviceaccount-kube-system-fsx-csi-controller-sa`.

Ora che hai creato il ruolo IAM del driver Amazon FSx CSI, puoi passare alla sezione successiva. Quando si implementa il componente aggiuntivo con il ruolo IAM, questo crea e viene configurato per utilizzare un account di servizio denominato `fsx-csi-controller-sa`. L’account di servizio è associato a un `clusterrole` Kubernetes a cui sono assegnate le autorizzazioni Kubernetes richieste.

## Fase 2: Installare il driver Amazon FSx CSI
<a name="fsx-csi-deploy-driver"></a>

Ti consigliamo di installare il driver Amazon FSx CSI tramite il componente aggiuntivo Amazon EKS per migliorare la sicurezza e ridurre la quantità di lavoro. Per aggiungere un componente aggiuntivo di Amazon EKS al cluster, consulta [Creare un componente aggiuntivo Amazon EKS](creating-an-add-on.md). Per ulteriori informazioni sui componenti aggiuntivi, consulta [Componenti aggiuntivi Amazon EKS](eks-add-ons.md).

**Importante**  
Le installazioni preesistenti di driver Amazon FSx CSI nel cluster possono causare errori di installazione dei componenti aggiuntivi. Quando tenti di installare la versione del componente aggiuntivo Amazon EKS mentre esiste un driver FSx CSI non EKS, l'installazione avrà esito negativo a causa di conflitti di risorse. Usa il flag `OVERWRITE` durante l’installazione per risolvere il problema.  

```
aws eks create-addon --addon-name aws-fsx-csi-driver --cluster-name my-cluster --resolve-conflicts OVERWRITE
```

In alternativa, se desideri un'installazione autogestita del driver Amazon FSx CSI, consulta [Installation](https://github.com/kubernetes-sigs/aws-fsx-csi-driver/blob/master/docs/install.md) on. GitHub

## Passaggio 3: implementazione di una classe di archiviazione, una dichiarazione di volume persistente e un’app di esempio
<a name="fsx-csi-deploy-storage-class"></a>

Questa procedura utilizza il GitHub repository di [driver FSx for Lustre Container Storage Interface (CSI)](https://github.com/kubernetes-sigs/aws-fsx-csi-driver) per utilizzare un volume Lustre con provisioning dinamico. FSx 

1. Annota il gruppo di sicurezza per il cluster. Puoi vederlo nella Console di gestione AWS sezione **Rete** o utilizzando il seguente comando AWS CLI. Sostituisci `my-cluster` con il nome del cluster che desideri utilizzare.

   ```
   aws eks describe-cluster --name my-cluster --query cluster.resourcesVpcConfig.clusterSecurityGroupId
   ```

1. Crea un gruppo di sicurezza per il tuo FSx file system Amazon in base ai criteri indicati in [Amazon VPC Security Groups](https://docs.aws.amazon.com/fsx/latest/LustreGuide/limit-access-security-groups.html#fsx-vpc-security-groups) nella Amazon FSx for Lustre User Guide. Per il **VPC**, seleziona il VPC del cluster come mostrato nella sezione **Reti**. Per i "gruppi di sicurezza associati ai client Lustre", usa il gruppo di sicurezza del cluster. Non specificare alcun valore nelle regole in uscita per consentire **Tutto il traffico**.

1. Scarica il manifesto della classe di storage con il comando seguente.

   ```
   curl -O https://raw.githubusercontent.com/kubernetes-sigs/aws-fsx-csi-driver/master/examples/kubernetes/dynamic_provisioning/specs/storageclass.yaml
   ```

1. Modifica la sezione dei parametri del file `storageclass.yaml`. Sostituisci ogni valore esemplificativo con i tuoi valori.

   ```
   parameters:
     subnetId: subnet-0eabfaa81fb22bcaf
     securityGroupIds: sg-068000ccf82dfba88
     deploymentType: PERSISTENT_1
     automaticBackupRetentionDays: "1"
     dailyAutomaticBackupStartTime: "00:00"
     copyTagsToBackups: "true"
     perUnitStorageThroughput: "200"
     dataCompressionType: "NONE"
     weeklyMaintenanceStartTime: "7:09:00"
     fileSystemTypeVersion: "2.12"
   ```
   +  **`subnetId`**— L'ID di sottorete in cui deve essere creato il file system Amazon FSx for Lustre. Amazon FSx for Lustre non è supportato in tutte le zone di disponibilità. Apri la console Amazon FSx for Lustre all'indirizzo per https://console.aws.amazon.com/fsx/ confermare che la sottorete che desideri utilizzare si trova in una zona di disponibilità supportata. La sottorete può includere i nodi oppure può essere una sottorete o un VPC differente:
     + **Puoi verificare la presenza di sottoreti di nodi in Console di gestione AWS selezionando il gruppo di nodi nella sezione Elaborazione.**
     + Se la sottorete specificata non è la stessa sottorete in cui sono presenti i nodi, è VPCs necessario essere [connessi](https://docs.aws.amazon.com/whitepapers/latest/aws-vpc-connectivity-options/amazon-vpc-to-amazon-vpc-connectivity-options.html) e assicurarsi di avere le porte necessarie aperte nei gruppi di sicurezza.
   +  ** `securityGroupIds` ** – l’ID del gruppo di sicurezza creato per il file system.
   +  **`deploymentType` (facoltativo)**: il tipo di implementazione del file system. I valori validi sono `SCRATCH_1`, `SCRATCH_2`, `PERSISTENT_1` e `PERSISTENT_2`. Per ulteriori informazioni sui tipi di distribuzione, consulta [Create your Amazon FSx for Lustre file system](https://docs.aws.amazon.com/fsx/latest/LustreGuide/getting-started-step1.html).
   +  **altri parametri (facoltativo)**: per informazioni sugli altri parametri, consulta [Modifica StorageClass](https://github.com/kubernetes-sigs/aws-fsx-csi-driver/tree/master/examples/kubernetes/dynamic_provisioning#edit-storageclass) su GitHub.

1. Crea il manifesto della classe di storage.

   ```
   kubectl apply -f storageclass.yaml
   ```

   Di seguito viene riportato un output di esempio:

   ```
   storageclass.storage.k8s.io/fsx-sc created
   ```

1. Scaricare il manifesto della dichiarazione di volume persistente.

   ```
   curl -O https://raw.githubusercontent.com/kubernetes-sigs/aws-fsx-csi-driver/master/examples/kubernetes/dynamic_provisioning/specs/claim.yaml
   ```

1. (Facoltativo) Modificare il file `claim.yaml`. Cambia `1200Gi` in uno dei valori di incremento riportati di seguito in base ai tuoi requisiti di archiviazione e al `deploymentType` selezionato in un passaggio precedente.

   ```
   storage: 1200Gi
   ```
   +  `SCRATCH_2` e `PERSISTENT` – `1.2 TiB`, `2.4 TiB` o incrementi di 2,4 TiB su 2,4 TiB.
   +  `SCRATCH_1` – `1.2 TiB`, `2.4 TiB`, `3.6 TiB` o incrementi di 3,6 TiB su 3,6 TiB.

1. Creare la dichiarazione di volume persistente.

   ```
   kubectl apply -f claim.yaml
   ```

   Di seguito viene riportato un output di esempio:

   ```
   persistentvolumeclaim/fsx-claim created
   ```

1. Verificare che il file system sia stato sottoposto a provisioning.

   ```
   kubectl describe pvc
   ```

   Di seguito viene riportato un output di esempio:

   ```
   Name:          fsx-claim
   Namespace:     default
   StorageClass:  fsx-sc
   Status:        Bound
   [...]
   ```
**Nota**  
`Status` può apparire `Pending` per 5-10 minuti, prima di passare a `Bound`. Non continuare con il passo successivo fino a quando `Status` non è `Bound`. Se nel campo `Status` viene visualizzato `Pending` per più di 10 minuti, utilizza i messaggi di avviso negli `Events` come riferimento per risolvere eventuali problemi.

1. Implementare un’applicazione di esempio.

   ```
   kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/aws-fsx-csi-driver/master/examples/kubernetes/dynamic_provisioning/specs/pod.yaml
   ```

1. Verificare che l’applicazione di esempio sia in esecuzione.

   ```
   kubectl get pods
   ```

   Di seguito viene riportato un output di esempio:

   ```
   NAME      READY   STATUS              RESTARTS   AGE
   fsx-app   1/1     Running             0          8s
   ```

1. Verifica che l’applicazione abbia montato correttamente il file system.

   ```
   kubectl exec -ti fsx-app -- df -h
   ```

   Di seguito viene riportato un output di esempio.

   ```
   Filesystem                   Size  Used Avail Use% Mounted on
   overlay                       80G  4.0G   77G   5% /
   tmpfs                         64M     0   64M   0% /dev
   tmpfs                        3.8G     0  3.8G   0% /sys/fs/cgroup
   192.0.2.0@tcp:/abcdef01      1.1T  7.8M  1.1T   1% /data
   /dev/nvme0n1p1                80G  4.0G   77G   5% /etc/hosts
   shm                           64M     0   64M   0% /dev/shm
   tmpfs                        6.9G   12K  6.9G   1% /run/secrets/kubernetes.io/serviceaccount
   tmpfs                        3.8G     0  3.8G   0% /proc/acpi
   tmpfs                        3.8G     0  3.8G   0% /sys/firmware
   ```

1. Verifica che i dati siano stati scritti nel file system FSx for Lustre dall'app di esempio.

   ```
   kubectl exec -it fsx-app -- ls /data
   ```

   Di seguito viene riportato un output di esempio.

   ```
   out.txt
   ```

   Questo output esemplificativo mostra che l’app di esempio ha eseguito correttamente la scrittura del file `out.txt` nel file system.

**Nota**  
Prima di eliminare il cluster, assicuratevi di eliminare il file system FSx for Lustre. Per ulteriori informazioni, consultate [Clean up resources nella Guida FSx ](https://docs.aws.amazon.com/fsx/latest/LustreGuide/getting-started-step4.html) *per l'utente di for Lustre*.

## Ottimizzazione delle prestazioni per for FSx Lustre
<a name="_performance_tuning_for_fsx_for_lustre"></a>

Quando si utilizza FSx per Lustre con Amazon EKS, è possibile ottimizzare le prestazioni applicando le ottimizzazioni Lustre durante l'inizializzazione del nodo. L’approccio consigliato consiste nell’utilizzare i dati utente del modello di avvio per garantire una configurazione coerente su tutti i nodi.

Queste ottimizzazioni includono:
+ Ottimizzazioni di rete e RPC
+ Gestione del modulo Lustre
+ Ottimizzazioni LRU (Lock Resource Unit)
+ Impostazioni di controllo della cache del client
+ Controlli RPC per OST e MDC

Per istruzioni dettagliate sull’implementazione di queste ottimizzazioni delle prestazioni:
+ Per ottimizzare le prestazioni per i nodi standard (non EFA), consulta [Ottimizza le prestazioni di Amazon FSx for Lustre sui nodi (non EFA)](fsx-csi-tuning-non-efa.md) per uno script completo che può essere aggiunto ai dati utente del modello di avvio.
+ Per ottimizzare le prestazioni per i nodi abilitati all’EFA, consulta [Ottimizza le prestazioni di Amazon FSx for Lustre sui nodi (EFA)](fsx-csi-tuning-efa.md).

# Ottimizza le prestazioni di Amazon FSx for Lustre sui nodi (EFA)
<a name="fsx-csi-tuning-efa"></a>

Questo argomento descrive come configurare l'ottimizzazione di Elastic Fabric Adapter (EFA) con Amazon EKS e Amazon for Lustre. FSx 

**Nota**  
Per informazioni sulla creazione e la distribuzione del driver CSI FSx for Lustre, consulta. [Implementa il driver FSx for Lustre](fsx-csi-create.md)
Per ottimizzare i nodi standard senza EFA, consultare [Ottimizza le prestazioni di Amazon FSx for Lustre sui nodi (non EFA)](fsx-csi-tuning-non-efa.md).

## Passaggio 1. Crea un cluster EKS
<a name="create-eks-cluster"></a>

Crea un cluster utilizzando il file di configurazione fornito:

```
# Create cluster using efa-cluster.yaml
eksctl create cluster -f efa-cluster.yaml
```

Esempio: `efa-cluster.yaml`

```
#efa-cluster.yaml

apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig

metadata:
  name: csi-fsx
  region: us-east-1
  version: "1.30"

iam:
  withOIDC: true

availabilityZones: ["us-east-1a", "us-east-1d"]

managedNodeGroups:
  - name: my-efa-ng
    instanceType: c6gn.16xlarge
    minSize: 1
    desiredCapacity: 1
    maxSize: 1
    availabilityZones: ["us-east-1b"]
    volumeSize: 300
    privateNetworking: true
    amiFamily: Ubuntu2204
    efaEnabled: true
    preBootstrapCommands:
      - |
        #!/bin/bash
        eth_intf="$(/sbin/ip -br -4 a sh | grep $(hostname -i)/ | awk '{print $1}')"
        efa_version=$(modinfo efa | awk '/^version:/ {print $2}' | sed 's/[^0-9.]//g')
        min_efa_version="2.12.1"

        if [[ "$(printf '%s\n' "$min_efa_version" "$efa_version" | sort -V | head -n1)" != "$min_efa_version" ]]; then
            sudo curl -O https://efa-installer.amazonaws.com/aws-efa-installer-1.37.0.tar.gz
            tar -xf aws-efa-installer-1.37.0.tar.gz && cd aws-efa-installer
            echo "Installing EFA driver"
            sudo apt-get update && apt-get upgrade -y
            sudo apt install -y pciutils environment-modules libnl-3-dev libnl-route-3-200 libnl-route-3-dev dkms
            sudo ./efa_installer.sh -y
            modinfo efa
        else
            echo "Using EFA driver version $efa_version"
        fi

        echo "Installing Lustre client"
        sudo wget -O - https://fsx-lustre-client-repo-public-keys.s3.amazonaws.com/fsx-ubuntu-public-key.asc | gpg --dearmor | sudo tee /usr/share/keyrings/fsx-ubuntu-public-key.gpg > /dev/null
        sudo echo "deb [signed-by=/usr/share/keyrings/fsx-ubuntu-public-key.gpg] https://fsx-lustre-client-repo.s3.amazonaws.com/ubuntu jammy main" > /etc/apt/sources.list.d/fsxlustreclientrepo.list
        sudo apt update | tail
        sudo apt install -y lustre-client-modules-$(uname -r) amazon-ec2-utils | tail
        modinfo lustre

        echo "Loading Lustre/EFA modules..."
        sudo /sbin/modprobe lnet
        sudo /sbin/modprobe kefalnd ipif_name="$eth_intf"
        sudo /sbin/modprobe ksocklnd
        sudo lnetctl lnet configure

        echo "Configuring TCP interface..."
        sudo lnetctl net del --net tcp 2> /dev/null
        sudo lnetctl net add --net tcp --if $eth_intf

        # For P5 instance type which supports 32 network cards,
        # by default add 8 EFA interfaces selecting every 4th device (1 per PCI bus)
        echo "Configuring EFA interface(s)..."
        instance_type="$(ec2-metadata --instance-type | awk '{ print $2 }')"
        num_efa_devices="$(ls -1 /sys/class/infiniband | wc -l)"
        echo "Found $num_efa_devices available EFA device(s)"

        if [[ "$instance_type" == "p5.48xlarge" || "$instance_type" == "p5e.48xlarge" ]]; then
           for intf in $(ls -1 /sys/class/infiniband | awk 'NR % 4 == 1'); do
               sudo lnetctl net add --net efa --if $intf --peer-credits 32
          done
        else
        # Other instances: Configure 2 EFA interfaces by default if the instance supports multiple network cards,
        # or 1 interface for single network card instances
        # Can be modified to add more interfaces if instance type supports it
            sudo lnetctl net add --net efa --if $(ls -1 /sys/class/infiniband | head -n1) --peer-credits 32
            if [[ $num_efa_devices -gt 1 ]]; then
               sudo lnetctl net add --net efa --if $(ls -1 /sys/class/infiniband | tail -n1) --peer-credits 32
            fi
        fi

        echo "Setting discovery and UDSP rule"
        sudo lnetctl set discovery 1
        sudo lnetctl udsp add --src efa --priority 0
        sudo /sbin/modprobe lustre

        sudo lnetctl net show
        echo "Added $(sudo lnetctl net show | grep -c '@efa') EFA interface(s)"
```

## Passaggio 2. Creazione di un gruppo di nodi
<a name="create-node-group"></a>

Creazione di un gruppo di nodi abilitato per EFA:

```
# Create node group using efa-ng.yaml
eksctl create nodegroup -f efa-ng.yaml
```

**Importante**  
=== Modifica questi valori per il tuo ambiente nella sezione `# 5. Mount FSx filesystem`.

```
FSX_DNS="<your-fsx-filesystem-dns>" # Needs to be adjusted.
MOUNT_NAME="<your-mount-name>" # Needs to be adjusted.
MOUNT_POINT="</your/mount/point>" # Needs to be adjusted.
```

===

Esempio`efa-ng.yaml`:

```
apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig

metadata:
  name: final-efa
  region: us-east-1

managedNodeGroups:
  - name: ng-1
    instanceType: c6gn.16xlarge
    minSize: 1
    desiredCapacity: 1
    maxSize: 1
    availabilityZones: ["us-east-1a"]
    volumeSize: 300
    privateNetworking: true
    amiFamily: Ubuntu2204
    efaEnabled: true
    preBootstrapCommands:
      - |
        #!/bin/bash
        exec 1> >(logger -s -t $(basename $0)) 2>&1

        #########################################################################################
        #                                    Configuration Section                              #
        #########################################################################################

        # File System Configuration
        FSX_DNS="<your-fsx-filesystem-dns>" # Needs to be adjusted.
        MOUNT_NAME="<your-mount-name>" # Needs to be adjusted.
        MOUNT_POINT="</your/mount/point>" # Needs to be adjusted.

        # Lustre Tuning Parameters
        LUSTRE_LRU_MAX_AGE=600000
        LUSTRE_MAX_CACHED_MB=64
        LUSTRE_OST_MAX_RPC=32
        LUSTRE_MDC_MAX_RPC=64
        LUSTRE_MDC_MOD_RPC=50

        # File paths
        FUNCTIONS_SCRIPT="/usr/local/bin/lustre_functions.sh"
        TUNINGS_SCRIPT="/usr/local/bin/apply_lustre_tunings.sh"
        SERVICE_FILE="/etc/systemd/system/lustre-tunings.service"

        #EFA
        MIN_EFA_VERSION="2.12.1"

        # Function to check if a command was successful
        check_success() {
            if [ $? -eq 0 ]; then
                echo "SUCCESS: $1"
            else
                echo "FAILED: $1"
                return 1
            fi
        }

        echo "********Starting FSx for Lustre configuration********"

        # 1. Install Lustre client
        if grep -q '^ID=ubuntu' /etc/os-release; then
            echo "Detected Ubuntu, proceeding with Lustre setup..."
            # Add Lustre repository
            sudo wget -O - https://fsx-lustre-client-repo-public-keys.s3.amazonaws.com/fsx-ubuntu-public-key.asc | sudo gpg --dearmor | sudo tee /usr/share/keyrings/fsx-ubuntu-public-key.gpg > /dev/null

            echo "deb [signed-by=/usr/share/keyrings/fsx-ubuntu-public-key.gpg] https://fsx-lustre-client-repo.s3.amazonaws.com/ubuntu jammy main" | sudo tee /etc/apt/sources.list.d/fsxlustreclientrepo.list

            sudo apt-get update
            sudo apt-get install -y lustre-client-modules-$(uname -r)
            sudo apt-get install -y lustre-client
        else
            echo "Not Ubuntu, exiting"
            exit 1
        fi

        check_success "Install Lustre client"

        # Ensure Lustre tools are in the PATH
        export PATH=$PATH:/usr/sbin

        # 2. Apply network and RPC tunings
        echo "********Applying network and RPC tunings********"
        if ! grep -q "options ptlrpc ptlrpcd_per_cpt_max" /etc/modprobe.d/modprobe.conf; then
            echo "options ptlrpc ptlrpcd_per_cpt_max=64" | sudo tee -a /etc/modprobe.d/modprobe.conf
            check_success "Set ptlrpcd_per_cpt_max"
        else
            echo "ptlrpcd_per_cpt_max already set in modprobe.conf"
        fi

        if ! grep -q "options ksocklnd credits" /etc/modprobe.d/modprobe.conf; then
            echo "options ksocklnd credits=2560" | sudo tee -a /etc/modprobe.d/modprobe.conf
            check_success "Set ksocklnd credits"
        else
            echo "ksocklnd credits already set in modprobe.conf"
        fi

        # 3. Load Lustre modules
        manage_lustre_modules() {
            echo "Checking for existing Lustre modules..."
            if lsmod | grep -q lustre; then
                echo "Existing Lustre modules found."

                # Check for mounted Lustre filesystems
                echo "Checking for mounted Lustre filesystems..."
                if mount | grep -q "type lustre"; then
                    echo "Found mounted Lustre filesystems. Attempting to unmount..."
                    mounted_fs=$(mount | grep "type lustre" | awk '{print $3}')
                    for fs in $mounted_fs; do
                        echo "Unmounting $fs"
                        sudo umount $fs
                        check_success "Unmount filesystem $fs"
                    done
                else
                    echo "No Lustre filesystems mounted."
                fi

                # After unmounting, try to remove modules
                echo "Attempting to remove Lustre modules..."
                sudo lustre_rmmod
                if [ $? -eq 0 ]; then
                    echo "SUCCESS: Removed existing Lustre modules"
                else
                    echo "WARNING: Could not remove Lustre modules. They may still be in use."
                    echo "Please check for any remaining Lustre processes or mounts."
                    return 1
                fi
            else
                echo "No existing Lustre modules found."
            fi

            echo "Loading Lustre modules..."
            sudo modprobe lustre
            check_success "Load Lustre modules" || exit 1

            echo "Checking loaded Lustre modules:"
            lsmod | grep lustre
        }

        # Managing Lustre kernel modules
        echo "********Managing Lustre kernel modules********"
        manage_lustre_modules

        # 4. Initializing Lustre networking
        echo "********Initializing Lustre networking********"
        sudo lctl network up
        check_success "Initialize Lustre networking" || exit 1

        # 4.5 EFA Setup and Configuration
        setup_efa() {
            echo "********Starting EFA Setup********"

            # Get interface and version information
            eth_intf="$(/sbin/ip -br -4 a sh | grep $(hostname -i)/ | awk '{print $1}')"
            efa_version=$(modinfo efa | awk '/^version:/ {print $2}' | sed 's/[^0-9.]//g')
            min_efa_version=$MIN_EFA_VERSION

            # Install or verify EFA driver
            if [[ "$(printf '%s\n' "$min_efa_version" "$efa_version" | sort -V | head -n1)" != "$min_efa_version" ]]; then
                echo "Installing EFA driver..."
                sudo curl -O https://efa-installer.amazonaws.com/aws-efa-installer-1.37.0.tar.gz
                tar -xf aws-efa-installer-1.37.0.tar.gz && cd aws-efa-installer

                # Install dependencies
                sudo apt-get update && apt-get upgrade -y
                sudo apt install -y pciutils environment-modules libnl-3-dev libnl-route-3-200 libnl-route-3-dev dkms

                # Install EFA
                sudo ./efa_installer.sh -y
                modinfo efa
            else
                echo "Using existing EFA driver version $efa_version"
            fi
        }

        configure_efa_network() {
            echo "********Configuring EFA Network********"

            # Load required modules
            echo "Loading network modules..."
            sudo /sbin/modprobe lnet
            sudo /sbin/modprobe kefalnd ipif_name="$eth_intf"
            sudo /sbin/modprobe ksocklnd

            # Initialize LNet
            echo "Initializing LNet..."
            sudo lnetctl lnet configure

            # Configure TCP interface
            echo "Configuring TCP interface..."
            sudo lnetctl net del --net tcp 2> /dev/null
            sudo lnetctl net add --net tcp --if $eth_intf

            # For P5 instance type which supports 32 network cards,
            # by default add 8 EFA interfaces selecting every 4th device (1 per PCI bus)
            echo "Configuring EFA interface(s)..."
            instance_type="$(ec2-metadata --instance-type | awk '{ print $2 }')"
            num_efa_devices="$(ls -1 /sys/class/infiniband | wc -l)"
            echo "Found $num_efa_devices available EFA device(s)"

            if [[ "$instance_type" == "p5.48xlarge" || "$instance_type" == "p5e.48xlarge" ]]; then
                # P5 instance configuration
                for intf in $(ls -1 /sys/class/infiniband | awk 'NR % 4 == 1'); do
                    sudo lnetctl net add --net efa --if $intf --peer-credits 32
                done
            else
                # Standard configuration
                # Other instances: Configure 2 EFA interfaces by default if the instance supports multiple network cards,
                # or 1 interface for single network card instances
                # Can be modified to add more interfaces if instance type supports it
                sudo lnetctl net add --net efa --if $(ls -1 /sys/class/infiniband | head -n1) --peer-credits 32
                if [[ $num_efa_devices -gt 1 ]]; then
                    sudo lnetctl net add --net efa --if $(ls -1 /sys/class/infiniband | tail -n1) --peer-credits 32
                fi
            fi

            # Configure discovery and UDSP
            echo "Setting up discovery and UDSP rules..."
            sudo lnetctl set discovery 1
            sudo lnetctl udsp add --src efa --priority 0
            sudo /sbin/modprobe lustre

            # Verify configuration
            echo "Verifying EFA network configuration..."
            sudo lnetctl net show
            echo "Added $(sudo lnetctl net show | grep -c '@efa') EFA interface(s)"
        }

        # Main execution
        setup_efa
        configure_efa_network

        # 5. Mount FSx filesystem
        if [ ! -z "$FSX_DNS" ] && [ ! -z "$MOUNT_NAME" ]; then
            echo "********Creating mount point********"
            sudo mkdir -p $MOUNT_POINT
            check_success "Create mount point"

            echo "Mounting FSx filesystem..."
            sudo mount -t lustre ${FSX_DNS}@tcp:/${MOUNT_NAME} ${MOUNT_POINT}
            check_success "Mount FSx filesystem"
        else
            echo "Skipping FSx mount as DNS or mount name is not provided"
        fi

        # 6. Applying Lustre performance tunings
        echo "********Applying Lustre performance tunings********"

        # Get number of CPUs
        NUM_CPUS=$(nproc)

        # Calculate LRU size (100 * number of CPUs)
        LRU_SIZE=$((100 * NUM_CPUS))

        #Apply LRU tunings
        echo "Apply LRU tunings"
        sudo lctl set_param ldlm.namespaces.*.lru_max_age=${LUSTRE_LRU_MAX_AGE}
        check_success "Set lru_max_age"
        sudo lctl set_param ldlm.namespaces.*.lru_size=$LRU_SIZE
        check_success "Set lru_size"

        # Client Cache Control
        sudo lctl set_param llite.*.max_cached_mb=${LUSTRE_MAX_CACHED_MB}
        check_success "Set max_cached_mb"

        # RPC Controls
        sudo lctl set_param osc.*OST*.max_rpcs_in_flight=${LUSTRE_OST_MAX_RPC}
        check_success "Set OST max_rpcs_in_flight"

        sudo lctl set_param mdc.*.max_rpcs_in_flight=${LUSTRE_MDC_MAX_RPC}
        check_success "Set MDC max_rpcs_in_flight"

        sudo lctl set_param mdc.*.max_mod_rpcs_in_flight=${LUSTRE_MDC_MOD_RPC}
        check_success "Set MDC max_mod_rpcs_in_flight"

        # 7. Verify all tunings
        echo "********Verifying all tunings********"

        # Function to verify parameter value
        verify_param() {
            local param=$1
            local expected=$2
            local actual=$3

            if [ "$actual" == "$expected" ]; then
                echo "SUCCESS: $param is correctly set to $expected"
            else
                echo "WARNING: $param is set to $actual (expected $expected)"
            fi
        }

        echo "Verifying all parameters:"

        # LRU tunings
        actual_lru_max_age=$(lctl get_param -n ldlm.namespaces.*.lru_max_age | head -1)
        verify_param "lru_max_age" "600000" "$actual_lru_max_age"

        actual_lru_size=$(lctl get_param -n ldlm.namespaces.*.lru_size | head -1)
        verify_param "lru_size" "$LRU_SIZE" "$actual_lru_size"

        # Client Cache
        actual_max_cached_mb=$(lctl get_param -n llite.*.max_cached_mb | grep "max_cached_mb:" | awk '{print $2}')
        verify_param "max_cached_mb" "64" "$actual_max_cached_mb"

        # RPC Controls
        actual_ost_rpcs=$(lctl get_param -n osc.*OST*.max_rpcs_in_flight | head -1)
        verify_param "OST max_rpcs_in_flight" "32" "$actual_ost_rpcs"

        actual_mdc_rpcs=$(lctl get_param -n mdc.*.max_rpcs_in_flight | head -1)
        verify_param "MDC max_rpcs_in_flight" "64" "$actual_mdc_rpcs"

        actual_mdc_mod_rpcs=$(lctl get_param -n mdc.*.max_mod_rpcs_in_flight | head -1)
        verify_param "MDC max_mod_rpcs_in_flight" "50" "$actual_mdc_mod_rpcs"

        # Network and RPC configurations from modprobe.conf
        actual_ptlrpc=$(grep "ptlrpc ptlrpcd_per_cpt_max" /etc/modprobe.d/modprobe.conf | awk '{print $3}')
        verify_param "ptlrpcd_per_cpt_max" "ptlrpcd_per_cpt_max=64" "$actual_ptlrpc"

        actual_ksocklnd=$(grep "ksocklnd credits" /etc/modprobe.d/modprobe.conf | awk '{print $3}')
        verify_param "ksocklnd credits" "credits=2560" "$actual_ksocklnd"

        # 8. Setup persistence
        setup_persistence() {
            # Create functions file
            cat << EOF > $FUNCTIONS_SCRIPT
        #!/bin/bash

        apply_lustre_tunings() {
            local NUM_CPUS=\$(nproc)
            local LRU_SIZE=\$((100 * NUM_CPUS))

            echo "Applying Lustre performance tunings..."
            lctl set_param ldlm.namespaces.*.lru_max_age=$LUSTRE_LRU_MAX_AGE
            lctl set_param ldlm.namespaces.*.lru_size=\$LRU_SIZE
            lctl set_param llite.*.max_cached_mb=$LUSTRE_MAX_CACHED_MB
            lctl set_param osc.*OST*.max_rpcs_in_flight=$LUSTRE_OST_MAX_RPC
            lctl set_param mdc.*.max_rpcs_in_flight=$LUSTRE_MDC_MAX_RPC
            lctl set_param mdc.*.max_mod_rpcs_in_flight=$LUSTRE_MDC_MOD_RPC
        }
        EOF

            # Create tuning script
            cat << EOF > $TUNINGS_SCRIPT
        #!/bin/bash
        exec 1> >(logger -s -t \$(basename \$0)) 2>&1

        source $FUNCTIONS_SCRIPT

        # Function to check if Lustre is mounted
        is_lustre_mounted() {
            mount | grep -q "type lustre"
        }

        # Function to mount Lustre
        mount_lustre() {
            echo "Mounting Lustre filesystem..."
            mkdir -p $MOUNT_POINT
            mount -t lustre ${FSX_DNS}@tcp:/${MOUNT_NAME} $MOUNT_POINT
            return \$?
        }

        # Main execution
        # Try to mount if not already mounted
        if ! is_lustre_mounted; then
            echo "Lustre filesystem not mounted, attempting to mount..."
            mount_lustre
        fi

        # Wait for successful mount (up to 5 minutes)
        for i in {1..30}; do
            if is_lustre_mounted; then
                echo "Lustre filesystem mounted, applying tunings..."
                apply_lustre_tunings
                exit 0
            fi
            echo "Waiting for Lustre filesystem to be mounted... (attempt $i/30)"
            sleep 10
        done

        echo "Timeout waiting for Lustre filesystem mount"
        exit 1
        EOF

        # Create systemd service

        # Create systemd directory if it doesn't exist
        sudo mkdir -p /etc/systemd/system/

            # Create service file directly for Ubuntu
            cat << EOF > $SERVICE_FILE
        [Unit]
        Description=Apply Lustre Performance Tunings
        After=network.target remote-fs.target

        [Service]
        Type=oneshot
        ExecStart=/bin/bash -c 'source $FUNCTIONS_SCRIPT && $TUNINGS_SCRIPT'
        RemainAfterExit=yes

        [Install]
        WantedBy=multi-user.target
        EOF


            # Make scripts executable and enable service
            sudo chmod +x $FUNCTIONS_SCRIPT
            sudo chmod +x $TUNINGS_SCRIPT
            systemctl enable lustre-tunings.service
            systemctl start lustre-tunings.service
        }

        echo "********Setting up persistent tuning********"
        setup_persistence

        echo "FSx for Lustre configuration completed."
```

## (Facoltativo) Passaggio 3. Verifica della configurazione EFA
<a name="verify-efa-setup"></a>

SSH nel nodo:

```
# Get instance ID from EKS console or {aws} CLI
ssh -i /path/to/your-key.pem ec2-user@<node-internal-ip>
```

Verifica della configurazione EFA:

```
sudo lnetctl net show
```

Controlla i registri di configurazione:

```
sudo cat /var/log/cloud-init-output.log
```

Ecco un esempio di output previsto per `lnetctl net show`:

```
net:
    - net type: tcp
      ...
    - net type: efa
      local NI(s):
        - nid: xxx.xxx.xxx.xxx@efa
          status: up
```

## Esempio di implementazioni
<a name="example-deployments"></a>

### a. Creazione di claim.yaml
<a name="_a_create_claim_yaml"></a>

```
#claim.yaml

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: fsx-claim-efa
spec:
  accessModes:
    - ReadWriteMany
  storageClassName: ""
  resources:
    requests:
      storage: 4800Gi
  volumeName: fsx-pv
```

Applica la richiesta:

```
kubectl apply -f claim.yaml
```

### b. Creazione di pv.yaml
<a name="_b_create_pv_yaml"></a>

Aggiorna`<replaceable-placeholders>`:

```
#pv.yaml

apiVersion: v1
kind: PersistentVolume
metadata:
  name: fsx-pv
spec:
  capacity:
    storage: 4800Gi
  volumeMode: Filesystem
  accessModes:
    - ReadWriteMany
  mountOptions:
    - flock
  persistentVolumeReclaimPolicy: Recycle
  csi:
    driver: fsx.csi.aws.com
    volumeHandle: fs-<1234567890abcdef0>
    volumeAttributes:
      dnsname: fs-<1234567890abcdef0>.fsx.us-east-1.amazonaws.com
      mountname: <abcdef01>
```

Applica il volume persistente:

```
kubectl apply -f pv.yaml
```

### c. Creazione di pod.yaml
<a name="_c_create_pod_yaml"></a>

```
#pod.yaml

apiVersion: v1
kind: Pod
metadata:
  name: fsx-efa-app
spec:
  containers:
  - name: app
    image: amazonlinux:2
    command: ["/bin/sh"]
    args: ["-c", "while true; do dd if=/dev/urandom bs=100M count=20 > data/test_file; sleep 10; done"]
    resources:
      requests:
        vpc.amazonaws.com/efa: 1
      limits:
        vpc.amazonaws.com/efa: 1
    volumeMounts:
    - name: persistent-storage
      mountPath: /data
  volumes:
  - name: persistent-storage
    persistentVolumeClaim:
      claimName: fsx-claim-efa
```

Applica il pod:

```
kubectl apply -f pod.yaml
```

## Comandi di verifica aggiuntivi
<a name="verification-commands"></a>

Verifica i montaggi del pod e scrive sul filesystem:

```
kubectl exec -ti fsx-efa-app -- df -h | grep data
# Expected output:
# <192.0.2.0>@tcp:/<abcdef01>  4.5T  1.2G  4.5T   1% /data

kubectl exec -ti fsx-efa-app -- ls /data
# Expected output:
# test_file
```

SSH sul nodo per verificare che il traffico stia passando attraverso EFA:

```
sudo lnetctl net show -v
```

L’output previsto mostrerà le interfacce EFA con le statistiche sul traffico.

## Informazioni correlate
<a name="_related_information"></a>
+  [Implementa il driver FSx for Lustre](fsx-csi-create.md) 
+  [Ottimizza le prestazioni di Amazon FSx for Lustre sui nodi (non EFA)](fsx-csi-tuning-non-efa.md) 
+  [Prestazioni Amazon FSx for Lustre](https://docs.aws.amazon.com/fsx/latest/LustreGuide/performance.html) 
+  [Elastic Fabric Adapter](https://docs.aws.amazon.com/ec2/latest/userguide/efa.html) 

# Ottimizza le prestazioni di Amazon FSx for Lustre sui nodi (non EFA)
<a name="fsx-csi-tuning-non-efa"></a>

Puoi ottimizzare le prestazioni di Amazon FSx for Lustre applicando i parametri di ottimizzazione durante l'inizializzazione del nodo utilizzando i dati utente del modello di lancio.

**Nota**  
Per informazioni sulla creazione e la distribuzione del driver CSI FSx for Lustre, consulta. [Implementa il driver FSx for Lustre](fsx-csi-create.md) Per ottimizzare le prestazioni con i nodi abilitati all’EFA, consultare [Ottimizza le prestazioni di Amazon FSx for Lustre sui nodi (EFA)](fsx-csi-tuning-efa.md).

## Perché utilizzare i dati utente del modello di avvio?
<a name="_why_use_launch_template_user_data"></a>
+ Applica automaticamente le ottimizzazioni durante l’inizializzazione del nodo.
+ Garantisce una configurazione coerente su tutti i nodi.
+ Elimina la necessità di configurare manualmente il nodo.

## Panoramica degli script di esempio
<a name="_example_script_overview"></a>

Lo script di esempio definito in questo argomento esegue le seguenti operazioni:

### `# 1. Install Lustre client`
<a name="_1_install_lustre_client"></a>
+ Rileva automaticamente la versione del tuo sistema operativo Amazon Linux (AL).
+ Installa il pacchetto client Lustre appropriato.

### `# 2. Apply network and RPC tunings`
<a name="_2_apply_network_and_rpc_tunings"></a>
+ Imposta `ptlrpcd_per_cpt_max=64` per l’elaborazione RPC parallela.
+ Configura `ksocklnd credits=2560` per ottimizzare i buffer di rete.

### `# 3. Load Lustre modules`
<a name="_3_load_lustre_modules"></a>
+ Rimuove in modo sicuro i moduli Lustre esistenti, se presenti.
+ Gestisce lo smontaggio dei filesystem esistenti.
+ Carica nuovi moduli Lustre.

### `# 4. Lustre Network Initialization`
<a name="_4_lustre_network_initialization"></a>
+ Inizializza la configurazione di rete Lustre.
+ Imposta i parametri di rete richiesti.

### `# 5. Mount FSx filesystem`
<a name="_5_mount_fsx_filesystem"></a>
+ È necessario modificare i valori per il tuo ambiente in questa sezione.

### `# 6. Apply tunings`
<a name="_6_apply_tunings"></a>
+ Ottimizzazioni LRU (Lock Resource Unit):
  +  `lru_max_age=600000` 
  +  `lru_size` calcolato in base al numero di CPU
+ Controllo della cache del client: `max_cached_mb=64` 
+ Controlli RPC:
  + OST `max_rpcs_in_flight=32` 
  + MDC `max_rpcs_in_flight=64` 
  + MDC `max_mod_rpcs_in_flight=50` 

### `# 7. Verify tunings`
<a name="_7_verify_tunings"></a>
+ Verifica tutte le ottimizzazioni applicate.
+ Segnala il successo o l’avviso per ogni parametro.

### `# 8. Setup persistence`
<a name="_8_setup_persistence"></a>
+ È necessario modificare i valori per il tuo ambiente anche in questa sezione.
+ Rileva automaticamente la versione del sistema operativo (AL2023) per determinare quale `Systemd` servizio applicare.
+ Il sistema si avvia.
+  `Systemd` avvia il servizio `lustre-tunings` (a causa di `WantedBy=multi-user.target`).
+ Il servizio esegue `apply_lustre_tunings.sh` che:
  + Verifica se il filesystem è montato.
  + Monta il filesystem se non è montato.
  + Attende che il montaggio venga eseguito con successo (fino a cinque minuti).
  + Applica i parametri di ottimizzazione dopo il montaggio riuscito.
+ Le impostazioni rimangono attive fino al riavvio.
+ Il servizio si chiude dopo il completamento dello script.
  + Systemd contrassegna il servizio come “attivo (terminato)”.
+ Il processo si ripete al successivo riavvio.

## Creazione di un modello di avvio
<a name="_create_a_launch_template"></a>

1. Apri la EC2 console Amazon all'indirizzo https://console.aws.amazon.com/ec2/.

1. Scegli **Modelli di avvio**.

1. Scegli **Crea modello di avvio**.

1. In **Dettagli avanzati**, individua la sezione **Dati utente**.

1. Incolla lo script qui di seguito, aggiornando tutto ciò che è necessario.
**Importante**  
Regola questi valori per il tuo ambiente sia nella sezione `# 5. Mount FSx filesystem` che nella funzione `setup_persistence()` di `apply_lustre_tunings.sh` nella sezione `# 8. Setup persistence`:  

   ```
   FSX_DNS="<your-fsx-filesystem-dns>" # Needs to be adjusted.
   MOUNT_NAME="<your-mount-name>" # Needs to be adjusted.
   MOUNT_POINT="</your/mount/point>" # Needs to be adjusted.
   ```

   ```
   MIME-Version: 1.0
   Content-Type: multipart/mixed; boundary="==MYBOUNDARY=="
   --==MYBOUNDARY==
   Content-Type: text/x-shellscript; charset="us-ascii"
   #!/bin/bash
   exec 1> >(logger -s -t $(basename $0)) 2>&1
   # Function definitions
   check_success() {
       if [ $? -eq 0 ]; then
           echo "SUCCESS: $1"
       else
           echo "FAILED: $1"
           return 1
       fi
   }
   apply_tunings() {
       local NUM_CPUS=$(nproc)
       local LRU_SIZE=$((100 * NUM_CPUS))
       local params=(
           "ldlm.namespaces.*.lru_max_age=600000"
           "ldlm.namespaces.*.lru_size=$LRU_SIZE"
           "llite.*.max_cached_mb=64"
           "osc.*OST*.max_rpcs_in_flight=32"
           "mdc.*.max_rpcs_in_flight=64"
           "mdc.*.max_mod_rpcs_in_flight=50"
       )
       for param in "${params[@]}"; do
           lctl set_param $param
           check_success "Set ${param%%=*}"
       done
   }
   verify_param() {
       local param=$1
       local expected=$2
       local actual=$3
   
       if [ "$actual" == "$expected" ]; then
           echo "SUCCESS: $param is correctly set to $expected"
       else
           echo "WARNING: $param is set to $actual (expected $expected)"
       fi
   }
   verify_tunings() {
       local NUM_CPUS=$(nproc)
       local LRU_SIZE=$((100 * NUM_CPUS))
       local params=(
           "ldlm.namespaces.*.lru_max_age:600000"
           "ldlm.namespaces.*.lru_size:$LRU_SIZE"
           "llite.*.max_cached_mb:64"
           "osc.*OST*.max_rpcs_in_flight:32"
           "mdc.*.max_rpcs_in_flight:64"
           "mdc.*.max_mod_rpcs_in_flight:50"
       )
       echo "Verifying all parameters:"
       for param in "${params[@]}"; do
           name="${param%%:*}"
           expected="${param#*:}"
           actual=$(lctl get_param -n $name | head -1)
           verify_param "${name##*.}" "$expected" "$actual"
       done
   }
   setup_persistence() {
       # Create functions file
       cat << 'EOF' > /usr/local/bin/lustre_functions.sh
   #!/bin/bash
   apply_lustre_tunings() {
       local NUM_CPUS=$(nproc)
       local LRU_SIZE=$((100 * NUM_CPUS))
   
       echo "Applying Lustre performance tunings..."
       lctl set_param ldlm.namespaces.*.lru_max_age=600000
       lctl set_param ldlm.namespaces.*.lru_size=$LRU_SIZE
       lctl set_param llite.*.max_cached_mb=64
       lctl set_param osc.*OST*.max_rpcs_in_flight=32
       lctl set_param mdc.*.max_rpcs_in_flight=64
       lctl set_param mdc.*.max_mod_rpcs_in_flight=50
   }
   EOF
       # Create tuning script
       cat << 'EOF' > /usr/local/bin/apply_lustre_tunings.sh
   #!/bin/bash
   exec 1> >(logger -s -t $(basename $0)) 2>&1
   # Source the functions
   source /usr/local/bin/lustre_functions.sh
   # FSx details
   FSX_DNS="<your-fsx-filesystem-dns>" # Needs to be adjusted.
   MOUNT_NAME="<your-mount-name>" # Needs to be adjusted.
   MOUNT_POINT="</your/mount/point>" # Needs to be adjusted.
   # Function to check if Lustre is mounted
   is_lustre_mounted() {
       mount | grep -q "type lustre"
   }
   # Function to mount Lustre
   mount_lustre() {
       echo "Mounting Lustre filesystem..."
       mkdir -p ${MOUNT_POINT}
       mount -t lustre ${FSX_DNS}@tcp:/${MOUNT_NAME} ${MOUNT_POINT}
       return $?
   }
   # Main execution
   # Try to mount if not already mounted
   if ! is_lustre_mounted; then
       echo "Lustre filesystem not mounted, attempting to mount..."
       mount_lustre
   fi
   # Wait for successful mount (up to 5 minutes)
   for i in {1..30}; do
       if is_lustre_mounted; then
           echo "Lustre filesystem mounted, applying tunings..."
           apply_lustre_tunings
           exit 0
       fi
       echo "Waiting for Lustre filesystem to be mounted... (attempt $i/30)"
       sleep 10
   done
   echo "Timeout waiting for Lustre filesystem mount"
   exit 1
   EOF
       # Create systemd service
       cat << 'EOF' > /etc/systemd/system/lustre-tunings.service
   [Unit]
   Description=Apply Lustre Performance Tunings
   After=network.target remote-fs.target
   StartLimitIntervalSec=0
   [Service]
   Type=oneshot
   ExecStart=/usr/local/bin/apply_lustre_tunings.sh
   RemainAfterExit=yes
   Restart=on-failure
   RestartSec=30
   [Install]
   WantedBy=multi-user.target
   EOF
       chmod +x /usr/local/bin/lustre_functions.sh
       chmod +x /usr/local/bin/apply_lustre_tunings.sh
       systemctl enable lustre-tunings.service
       systemctl start lustre-tunings.service
   }
   echo "Starting FSx for Lustre configuration..."
   # 1. Install Lustre client
   if grep -q 'VERSION="2"' /etc/os-release; then
       amazon-linux-extras install -y lustre
   elif grep -q 'VERSION="2023"' /etc/os-release; then
       dnf install -y lustre-client
   fi
   check_success "Install Lustre client"
   # 2. Apply network and RPC tunings
   export PATH=$PATH:/usr/sbin
   echo "Applying network and RPC tunings..."
   if ! grep -q "options ptlrpc ptlrpcd_per_cpt_max" /etc/modprobe.d/modprobe.conf; then
       echo "options ptlrpc ptlrpcd_per_cpt_max=64" | tee -a /etc/modprobe.d/modprobe.conf
       echo "options ksocklnd credits=2560" | tee -a /etc/modprobe.d/modprobe.conf
   fi
   # 3. Load Lustre modules
   modprobe lustre
   check_success "Load Lustre modules" || exit 1
   # 4. Lustre Network Initialization
   lctl network up
   check_success "Initialize Lustre networking" || exit 1
   # 5. Mount FSx filesystem
   FSX_DNS="<your-fsx-filesystem-dns>" # Needs to be adjusted.
   MOUNT_NAME="<your-mount-name>" # Needs to be adjusted.
   MOUNT_POINT="</your/mount/point>" # Needs to be adjusted.
   if [ ! -z "$FSX_DNS" ] && [ ! -z "$MOUNT_NAME" ]; then
       mkdir -p $MOUNT_POINT
       mount -t lustre ${FSX_DNS}@tcp:/${MOUNT_NAME} ${MOUNT_POINT}
       check_success "Mount FSx filesystem"
   fi
   # 6. Apply tunings
   apply_tunings
   # 7. Verify tunings
   verify_tunings
   # 8. Setup persistence
   setup_persistence
   echo "FSx for Lustre configuration completed."
   --==MYBOUNDARY==--
   ```

1. Quando crei gruppi di nodi Amazon EKS, seleziona questo modello di avvio. Per ulteriori informazioni, consulta [Creare un gruppo di nodi gestiti per il cluster](create-managed-node-group.md).

## Informazioni correlate
<a name="_related_information"></a>
+  [Implementa il driver FSx for Lustre](fsx-csi-create.md) 
+  [Ottimizza le prestazioni di Amazon FSx for Lustre sui nodi (EFA)](fsx-csi-tuning-efa.md) 
+  [Prestazioni Amazon FSx for Lustre](https://docs.aws.amazon.com/fsx/latest/LustreGuide/performance.html) 