Skip to content

Amazon EKS Storage - Part 3: Monitoring, Troubleshooting, Cost Optimization, and Security ​

Este documento es la tercera y última parte de la serie de almacenamiento de Amazon EKS, y cubre el monitoreo del almacenamiento, la solución de problemas, la optimización de costos y la seguridad.

Table of Contents ​

  1. Storage Monitoring
  2. Storage Troubleshooting
  3. Storage Cost Optimization
  4. Storage Security
  5. Storage Management Best Practices

Storage Monitoring ​

Monitorear eficazmente los recursos de almacenamiento en un cluster de EKS es importante para detectar problemas de rendimiento de forma temprana y establecer la planificación de capacidad.

Monitoring with CloudWatch ​

Puedes usar AWS CloudWatch para monitorear métricas de rendimiento de volúmenes EBS, EFS y FSx for Lustre:

EBS Volume Metrics ​

Métricas clave de EBS:

  • VolumeReadBytes/VolumeWriteBytes: rendimiento de lectura/escritura
  • VolumeReadOps/VolumeWriteOps: número de operaciones de lectura/escritura
  • VolumeTotalReadTime/VolumeTotalWriteTime: latencia de lectura/escritura
  • VolumeQueueLength: número de solicitudes de I/O pendientes
  • BurstBalance: saldo de créditos burst (volúmenes gp2)

Ejemplo de dashboard de CloudWatch:

bash
aws cloudwatch get-dashboard --dashboard-name EBSVolumeMonitoring

EFS File System Metrics ​

Métricas clave de EFS:

  • TotalIOBytes: total de bytes de I/O
  • DataReadIOBytes/DataWriteIOBytes: rendimiento de lectura/escritura
  • ClientConnections: número de clientes conectados
  • PermittedThroughput: rendimiento permitido
  • BurstCreditBalance: saldo de créditos burst

FSx for Lustre Metrics ​

Métricas clave de FSx for Lustre:

  • DataReadBytes/DataWriteBytes: rendimiento de lectura/escritura
  • DataReadOperations/DataWriteOperations: número de operaciones de lectura/escritura
  • FreeDataStorageCapacity: capacidad de almacenamiento disponible
  • NetworkThroughputUtilization: utilización del rendimiento de red

Monitoring with Prometheus and Grafana ​

Puedes usar Prometheus y Grafana para monitorear recursos de almacenamiento a nivel de Kubernetes:

  1. Instala Prometheus y Grafana:
bash
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo update
helm install prometheus prometheus-community/kube-prometheus-stack \
  --namespace monitoring \
  --create-namespace
  1. Configura ServiceMonitor para la recopilación de métricas relacionadas con el almacenamiento:
yaml
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  name: csi-metrics
  namespace: monitoring
spec:
  selector:
    matchLabels:
      app: ebs-csi-controller
  endpoints:
  - port: metrics
    interval: 30s
  1. Configura el dashboard de Grafana:

Crea un dashboard en Grafana que incluya las siguientes métricas:

  • Uso y capacidad de PVC
  • Estado de aprovisionamiento de volúmenes
  • Latencia de operación del driver CSI
  • Operaciones de montaje/desmontaje de volúmenes

Custom Monitoring Solutions ​

Puedes implementar soluciones de monitoreo personalizadas para requisitos específicos:

  1. Pod de monitoreo de uso de volúmenes:
yaml
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: volume-usage-exporter
  namespace: monitoring
spec:
  selector:
    matchLabels:
      app: volume-usage-exporter
  template:
    metadata:
      labels:
        app: volume-usage-exporter
    spec:
      containers:
      - name: exporter
        image: quay.io/prometheus/node-exporter:v1.3.1
        args:
        - --path.procfs=/host/proc
        - --path.sysfs=/host/sys
        - --collector.filesystem
        volumeMounts:
        - name: proc
          mountPath: /host/proc
          readOnly: true
        - name: sys
          mountPath: /host/sys
          readOnly: true
        - name: root
          mountPath: /host/root
          readOnly: true
          mountPropagation: HostToContainer
      volumes:
      - name: proc
        hostPath:
          path: /proc
      - name: sys
        hostPath:
          path: /sys
      - name: root
        hostPath:
          path: /
  1. Configuración de reglas de alerta:
yaml
apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
  name: storage-alerts
  namespace: monitoring
spec:
  groups:
  - name: storage
    rules:
    - alert: VolumeUsageHigh
      expr: kubelet_volume_stats_used_bytes / kubelet_volume_stats_capacity_bytes > 0.85
      for: 10m
      labels:
        severity: warning
      annotations:
        summary: "Volume usage high ({{ $value | humanizePercentage }})"
        description: "PVC {{ $labels.persistentvolumeclaim }} is using {{ $value | humanizePercentage }} of its capacity."
    - alert: VolumeFullIn24Hours
      expr: predict_linear(kubelet_volume_stats_used_bytes[6h], 24 * 3600) > kubelet_volume_stats_capacity_bytes
      for: 10m
      labels:
        severity: warning
      annotations:
        summary: "Volume will fill in 24 hours"
        description: "PVC {{ $labels.persistentvolumeclaim }} is predicted to fill within 24 hours."

Storage Troubleshooting ​

Exploremos los problemas comunes de almacenamiento que pueden ocurrir en clusters de EKS y sus soluciones.

Volume Provisioning Issues ​

Issue: PVC Remains in Pending State ​

  1. Comprueba el estado del PVC:
bash
kubectl get pvc
kubectl describe pvc <pvc-name>
  1. Comprueba la storage class:
bash
kubectl get sc
kubectl describe sc <storage-class-name>
  1. Comprueba los logs del Pod provisioner:
bash
kubectl -n kube-system get pods | grep csi
kubectl -n kube-system logs <csi-controller-pod-name>
  1. Causas comunes y soluciones:
    • La storage class no existe: crea la storage class correcta
    • El driver CSI no está instalado: instala el driver
    • Permisos de IAM insuficientes: concede los permisos de IAM requeridos
    • Límite de volúmenes excedido: solicita un aumento del límite del servicio

Issue: Volume Not Provisioned with WaitForFirstConsumer Binding Mode ​

  1. Comprueba el estado del Pod:
bash
kubectl get pods
kubectl describe pod <pod-name>
  1. Comprueba las zonas de disponibilidad de los nodes:
bash
kubectl get nodes -L topology.kubernetes.io/zone
  1. Soluciones:
    • Resuelve los problemas de scheduling del Pod
    • Comprueba las reglas de node selector y affinity
    • Asegúrate de que el node pool esté en la misma zona de disponibilidad que el PVC

Volume Mount Issues ​

Issue: Pod Stuck in ContainerCreating State ​

  1. Comprueba los eventos del Pod:
bash
kubectl describe pod <pod-name>
  1. Comprueba los logs de kubelet del node:
bash
kubectl get nodes
ssh ec2-user@<node-ip>
sudo journalctl -u kubelet
  1. Causas comunes y soluciones:
    • ID de volumen no encontrado: verifica la existencia del volumen en la consola de AWS
    • Error de montaje del dispositivo: comprueba la ruta del dispositivo y el file system
    • Problemas de permisos: comprueba los roles de IAM y los security groups

Issue: EFS or FSx Mount Failure ​

  1. Comprueba los security groups:

    • EFS: permite el puerto TCP 2049
    • FSx for Lustre: permite el puerto TCP 988
  2. Comprueba la conectividad de red:

bash
kubectl debug node/<node-name> -it --image=amazon/aws-cli
ping <efs-dns-name>
telnet <efs-dns-name> 2049
  1. Crea un Pod helper de montaje:
yaml
apiVersion: v1
kind: Pod
metadata:
  name: mount-helper
spec:
  containers:
  - name: mount-helper
    image: amazonlinux:2
    command: ["sleep", "infinity"]
    securityContext:
      privileged: true
  1. Prueba el montaje manualmente:
bash
kubectl exec -it mount-helper -- bash
yum install -y nfs-utils
mkdir -p /mnt/efs
mount -t nfs4 <efs-dns-name>:/ /mnt/efs

Performance Issues ​

Issue: Slow I/O Performance ​

  1. Comprueba las métricas de rendimiento del volumen:
bash
aws cloudwatch get-metric-statistics \
  --namespace AWS/EBS \
  --metric-name VolumeReadOps \
  --dimensions Name=VolumeId,Value=vol-1234567890abcdef0 \
  --start-time $(date -u -v-1H +%Y-%m-%dT%H:%M:%SZ) \
  --end-time $(date -u +%Y-%m-%dT%H:%M:%SZ) \
  --period 300 \
  --statistics Average
  1. Prueba el rendimiento del file system:
bash
kubectl exec -it <pod-name> -- bash
dd if=/dev/zero of=/data/test bs=1M count=1000 oflag=direct
dd if=/data/test of=/dev/null bs=1M count=1000 iflag=direct
  1. Causas comunes y soluciones:
    • Tipo de volumen inadecuado: selecciona un tipo de volumen adecuado para la workload (por ejemplo, gp3, io2)
    • Límites de IOPS o throughput: ajusta los parámetros de rendimiento del volumen
    • Limitaciones de la instance: usa instances optimizadas para EBS
    • Fragmentación del file system: optimiza o recrea el file system

Issue: EFS Performance Degradation ​

  1. Comprueba el modo de rendimiento y el modo de throughput de EFS
  2. Optimiza las opciones de montaje del cliente:
yaml
mountOptions:
  - nfsvers=4.1
  - rsize=1048576
  - wsize=1048576
  - timeo=600
  - retrans=2
  - noresvport
  1. Optimiza los patrones de acceso:
    • Usa archivos grandes en lugar de archivos pequeños
    • Usa patrones de acceso secuencial
    • Minimiza las operaciones de metadatos

Storage Cost Optimization ​

Exploremos estrategias para optimizar los costos de almacenamiento en clusters de EKS.

Volume Type and Size Optimization ​

  1. Selecciona el tipo de volumen adecuado:

    • Workloads generales: gp3 (más rentable que gp2)
    • Workloads intensivas en throughput: st1
    • Datos con acceso poco frecuente: sc1
  2. Optimiza el tamaño del volumen:

    • Aprovisiona volúmenes ligeramente mayores de lo necesario
    • Monitorea el uso del volumen y amplíalo según sea necesario
    • Limpia o archiva datos innecesarios
  3. Migra a volúmenes gp3:

yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: ebs-gp3
  annotations:
    storageclass.kubernetes.io/is-default-class: "true"
provisioner: ebs.csi.aws.com
parameters:
  type: gp3
  encrypted: "true"
allowVolumeExpansion: true

Storage Lifecycle Management ​

  1. Data tiering:

    • Datos de acceso frecuente: EBS o EFS
    • Datos de acceso poco frecuente: S3 o S3 Glacier
  2. Política automatizada de snapshots:

    • Crea snapshots regulares
    • Elimina automáticamente los snapshots antiguos
yaml
apiVersion: snapshot.storage.k8s.io/v1
kind: VolumeSnapshotClass
metadata:
  name: ebs-snapshot-class
driver: ebs.csi.aws.com
deletionPolicy: Delete
  1. Política de reclamación de PV:
    • Usa la política Delete para datos temporales
    • Usa la política Retain para datos importantes

EFS Cost Optimization ​

  1. Selecciona el modo de throughput adecuado:

    • Workloads predecibles: throughput aprovisionado
    • Workloads variables: modo bursting
  2. Gestión del lifecycle:

    • Mueve automáticamente los archivos de acceso poco frecuente a la storage class IA (Infrequent Access)
    • Configura la política de lifecycle:
bash
aws efs put-lifecycle-configuration \
  --file-system-id fs-1234567890abcdef0 \
  --lifecycle-policies '[{"TransitionToIA":"AFTER_30_DAYS"}]'
  1. Usa access points:
    • Comparte el file system usando access points específicos de la aplicación

FSx for Lustre Cost Optimization ​

  1. Selecciona el tipo de deployment adecuado:

    • Workloads temporales: SCRATCH_2
    • Workloads a largo plazo: PERSISTENT_1 o PERSISTENT_2
  2. Habilita la compresión de datos:

    • Usa compresión de datos LZ4 para reducir los costos de almacenamiento
  3. Integración con S3:

    • Conecta el bucket de S3 a FSx for Lustre para data tiering

Cost Monitoring and Analysis ​

  1. Usa AWS Cost Explorer:

    • Analiza las tendencias de costos de almacenamiento
    • Analiza los costos por recurso
  2. Asignación de costos de Kubernetes:

    • Asigna costos usando namespaces y labels
    • Usa herramientas como Kubecost
  3. Detección de anomalías de costos:

    • Configura AWS Budgets y alertas
    • Configura alertas para aumentos de costos anormales

Storage Security ​

Exploremos las mejores prácticas de seguridad para proteger los recursos de almacenamiento en clusters de EKS.

Data Encryption ​

  1. Cifrado de datos en reposo:
    • Cifrado de volúmenes EBS:
yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: ebs-encrypted
provisioner: ebs.csi.aws.com
parameters:
  type: gp3
  encrypted: "true"
  kmsKeyId: arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab
  • Cifrado de file system EFS:
bash
aws efs create-file-system \
  --encrypted \
  --kms-key-id arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab
  • Cifrado de FSx for Lustre:
bash
aws fsx create-file-system \
  --file-system-type LUSTRE \
  --storage-capacity 1200 \
  --subnet-ids subnet-1234567890abcdef0 \
  --lustre-configuration DeploymentType=SCRATCH_2 \
  --security-group-ids sg-1234567890abcdef0 \
  --kms-key-id arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab
  1. Cifrado de datos en tránsito:
    • Cifrado en tránsito de EFS:
yaml
mountOptions:
  - tls
  • Cifrado en tránsito de S3:
bash
aws s3 cp --sse AES256 file.txt s3://my-bucket/

Access Control ​

  1. Roles y políticas de IAM:
    • Aplica el principio de privilegio mínimo
    • Usa roles de IAM para service accounts
bash
eksctl create iamserviceaccount \
  --name ebs-csi-controller-sa \
  --namespace kube-system \
  --cluster my-cluster \
  --attach-policy-arn arn:aws:iam::aws:policy/service-role/AmazonEBSCSIDriverPolicy \
  --approve
  1. Security groups:
    • Permite solo los puertos requeridos
    • Restringe las IPs de origen
bash
aws ec2 authorize-security-group-ingress \
  --group-id sg-1234567890abcdef0 \
  --protocol tcp \
  --port 2049 \
  --source-group sg-0987654321fedcba0
  1. Kubernetes RBAC:
    • Restringe el acceso a PVs y PVCs
yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: app-namespace
  name: pvc-manager
rules:
- apiGroups: [""]
  resources: ["persistentvolumeclaims"]
  verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: pvc-manager-binding
  namespace: app-namespace
subjects:
- kind: ServiceAccount
  name: app-service-account
  namespace: app-namespace
roleRef:
  kind: Role
  name: pvc-manager
  apiGroup: rbac.authorization.k8s.io

Pod Security Context ​

  1. Root filesystem de solo lectura:
yaml
apiVersion: v1
kind: Pod
metadata:
  name: secure-pod
spec:
  containers:
  - name: app
    image: nginx
    securityContext:
      readOnlyRootFilesystem: true
    volumeMounts:
    - name: data-volume
      mountPath: /data
      readOnly: false
  1. Privilegios limitados:
yaml
securityContext:
  runAsUser: 1000
  runAsGroup: 3000
  fsGroup: 2000
  allowPrivilegeEscalation: false
  1. Perfiles SELinux, AppArmor o seccomp:
yaml
securityContext:
  seLinuxOptions:
    level: "s0:c123,c456"
  seccompProfile:
    type: RuntimeDefault

Security Policy Enforcement ​

  1. OPA Gatekeeper o Kyverno:
    • Permite solo volúmenes cifrados
yaml
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: require-ebs-encryption
spec:
  validationFailureAction: enforce
  rules:
  - name: check-ebs-encryption
    match:
      resources:
        kinds:
        - PersistentVolumeClaim
    validate:
      message: "EBS volumes must be encrypted"
      pattern:
        spec:
          storageClassName: "ebs-*"
          +(storageClassName): "ebs-encrypted"
  1. Pod Security Standards:
    • Aplica Pod Security Standards a los namespaces
yaml
apiVersion: v1
kind: Namespace
metadata:
  name: secure-ns
  labels:
    pod-security.kubernetes.io/enforce: restricted

Storage Management Best Practices ​

Exploremos las mejores prácticas para gestionar eficazmente el almacenamiento en clusters de EKS.

Storage Planning and Design ​

  1. Análisis de requisitos:

    • Requisitos de rendimiento (IOPS, throughput)
    • Requisitos de capacidad
    • Patrones de acceso (relación lectura/escritura, concurrencia)
    • Requisitos de disponibilidad y durabilidad
  2. Selección del tipo de almacenamiento:

    • Block storage (EBS): bases de datos, aplicaciones stateful
    • File storage (EFS): archivos compartidos, servidores web, CMS
    • File storage de alto rendimiento (FSx for Lustre): HPC, entrenamiento de ML
    • Object storage (S3): backups, archivos, contenido estático
  3. Planificación de capacidad:

    • Requisitos actuales + margen de crecimiento
    • Implementa mecanismos de auto-scaling
    • Revisiones regulares de capacidad

Backup and Disaster Recovery ​

  1. Backups regulares:
    • Automatiza snapshots de volúmenes
    • Define políticas de retención de backups
bash
# Create snapshot daily at midnight
0 0 * * * kubectl create -f snapshot.yaml
  1. Plan de disaster recovery:

    • Replicación Multi-AZ o cross-region
    • Define Recovery Time Objective (RTO) y Recovery Point Objective (RPO)
    • Pruebas regulares de recuperación
  2. Backup del cluster con Velero:

bash
velero backup create daily-backup --include-namespaces=default,app-namespace

Automation and IaC (Infrastructure as Code) ​

  1. Usa Terraform o CloudFormation:
    • Definición declarativa de recursos de almacenamiento
    • Control de versiones y seguimiento de cambios
hcl
resource "aws_efs_file_system" "example" {
  creation_token = "example"
  performance_mode = "generalPurpose"
  throughput_mode = "bursting"
  encrypted = true

  lifecycle_policy {
    transition_to_ia = "AFTER_30_DAYS"
  }

  tags = {
    Name = "ExampleFileSystem"
  }
}
  1. Usa Helm charts:
    • Templatiza storage classes y PVCs
yaml
# values.yaml
storage:
  class: ebs-gp3
  size: 10Gi
  encrypted: true
  1. Workflow GitOps:
    • Gestiona la configuración de almacenamiento con ArgoCD o Flux

Performance and Cost Optimization ​

  1. Revisión regular del rendimiento:

    • Identifica y resuelve cuellos de botella
    • Ajusta la configuración de almacenamiento a medida que cambian las workloads
  2. Revisión de optimización de costos:

    • Identifica y elimina volúmenes no utilizados
    • Migra a tipos de almacenamiento rentables
    • Considera Reserved Instances o Savings Plans
  3. Auto scaling:

    • Escala automáticamente el almacenamiento según la demanda
    • Configura alertas basadas en uso

Conclusion ​

En este documento, cubrimos el monitoreo, la solución de problemas, la optimización de costos y la seguridad para el almacenamiento de Amazon EKS. La gestión eficaz del almacenamiento es fundamental para garantizar el rendimiento, la confiabilidad y la rentabilidad de tu cluster de EKS.

Los requisitos de almacenamiento varían según la aplicación, por lo que es importante comprender las características de tu workload y seleccionar la solución de almacenamiento adecuada. Además, debes gestionar eficazmente los recursos de almacenamiento mediante monitoreo regular, solución de problemas, optimización de costos y revisiones de seguridad.

References ​

Quiz ​

Para comprobar lo que aprendiste en este capítulo, intenta el cuestionario del tema.

Pregunta a la documentación

Enter envía, Shift+Enter añade una línea.