Skip to content

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

本文档是 Amazon EKS 存储系列的第三部分,也是最后一部分,涵盖存储监控、故障排查、成本优化和安全。

Table of Contents ​

  1. 存储监控
  2. 存储故障排查
  3. 存储成本优化
  4. 存储安全
  5. 存储管理最佳实践

Storage Monitoring ​

有效监控 EKS 集群中的存储资源,对于及早发现性能问题并建立容量规划非常重要。

Monitoring with CloudWatch ​

你可以使用 AWS CloudWatch 监控 EBS、EFS 和 FSx for Lustre 卷的性能指标:

EBS Volume Metrics ​

关键 EBS 指标:

  • VolumeReadBytes/VolumeWriteBytes:读/写吞吐量
  • VolumeReadOps/VolumeWriteOps:读/写操作数量
  • VolumeTotalReadTime/VolumeTotalWriteTime:读/写延迟
  • VolumeQueueLength:待处理 I/O 请求数量
  • BurstBalance:突发积分余额(gp2 卷)

CloudWatch dashboard 示例:

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

EFS File System Metrics ​

关键 EFS 指标:

  • TotalIOBytes:总 I/O 字节数
  • DataReadIOBytes/DataWriteIOBytes:读/写吞吐量
  • ClientConnections:已连接客户端数量
  • PermittedThroughput:允许的吞吐量
  • BurstCreditBalance:突发积分余额

FSx for Lustre Metrics ​

关键 FSx for Lustre 指标:

  • DataReadBytes/DataWriteBytes:读/写吞吐量
  • DataReadOperations/DataWriteOperations:读/写操作数量
  • FreeDataStorageCapacity:可用存储容量
  • NetworkThroughputUtilization:网络吞吐量利用率

Monitoring with Prometheus and Grafana ​

你可以使用 Prometheus 和 Grafana 在 Kubernetes 层面监控存储资源:

  1. 安装 Prometheus 和 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. 配置用于收集存储相关指标的 ServiceMonitor:
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. 配置 Grafana dashboard:

在 Grafana 中创建包含以下指标的 dashboard:

  • PVC 使用量和容量
  • 卷供应状态
  • CSI driver 操作延迟
  • 卷挂载/卸载操作

Custom Monitoring Solutions ​

你可以针对特定需求实现自定义监控解决方案:

  1. 卷使用量监控 Pod:
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. 告警规则配置:
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 ​

让我们探讨 EKS 集群中可能出现的常见存储问题及其解决方案。

Volume Provisioning Issues ​

Issue: PVC Remains in Pending State ​

  1. 检查 PVC 状态:
bash
kubectl get pvc
kubectl describe pvc <pvc-name>
  1. 检查 StorageClass:
bash
kubectl get sc
kubectl describe sc <storage-class-name>
  1. 检查 provisioner Pod 日志:
bash
kubectl -n kube-system get pods | grep csi
kubectl -n kube-system logs <csi-controller-pod-name>
  1. 常见原因和解决方案:
    • StorageClass 不存在:创建正确的 StorageClass
    • 未安装 CSI driver:安装该 driver
    • IAM 权限不足:授予所需的 IAM 权限
    • 超出卷限制:请求提升服务限制

Issue: Volume Not Provisioned with WaitForFirstConsumer Binding Mode ​

  1. 检查 Pod 状态:
bash
kubectl get pods
kubectl describe pod <pod-name>
  1. 检查节点可用区:
bash
kubectl get nodes -L topology.kubernetes.io/zone
  1. 解决方案:
    • 解决 Pod 调度问题
    • 检查 node selector 和 affinity 规则
    • 确保 node pool 与 PVC 位于同一可用区

Volume Mount Issues ​

Issue: Pod Stuck in ContainerCreating State ​

  1. 检查 Pod 事件:
bash
kubectl describe pod <pod-name>
  1. 检查节点 kubelet 日志:
bash
kubectl get nodes
ssh ec2-user@<node-ip>
sudo journalctl -u kubelet
  1. 常见原因和解决方案:
    • 找不到卷 ID:在 AWS console 中验证卷是否存在
    • 设备挂载失败:检查设备路径和文件系统
    • 权限问题:检查 IAM roles 和 security groups

Issue: EFS or FSx Mount Failure ​

  1. 检查 security groups:

    • EFS:允许 TCP 端口 2049
    • FSx for Lustre:允许 TCP 端口 988
  2. 检查网络连接:

bash
kubectl debug node/<node-name> -it --image=amazon/aws-cli
ping <efs-dns-name>
telnet <efs-dns-name> 2049
  1. 创建 mount helper Pod:
yaml
apiVersion: v1
kind: Pod
metadata:
  name: mount-helper
spec:
  containers:
  - name: mount-helper
    image: amazonlinux:2
    command: ["sleep", "infinity"]
    securityContext:
      privileged: true
  1. 手动测试挂载:
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. 检查卷性能指标:
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. 测试文件系统性能:
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. 常见原因和解决方案:
    • 卷类型不合适:选择适合工作负载的卷类型(例如 gp3、io2)
    • IOPS 或吞吐量限制:调整卷性能参数
    • 实例限制:使用 EBS-optimized instances
    • 文件系统碎片:优化或重新创建文件系统

Issue: EFS Performance Degradation ​

  1. 检查 EFS performance mode 和 throughput mode
  2. 优化客户端挂载选项:
yaml
mountOptions:
  - nfsvers=4.1
  - rsize=1048576
  - wsize=1048576
  - timeo=600
  - retrans=2
  - noresvport
  1. 优化访问模式:
    • 使用大文件而不是小文件
    • 使用顺序访问模式
    • 尽量减少元数据操作

Storage Cost Optimization ​

让我们探讨优化 EKS 集群存储成本的策略。

Volume Type and Size Optimization ​

  1. 选择合适的卷类型:

    • 通用工作负载:gp3(比 gp2 更具成本效益)
    • 吞吐密集型工作负载:st1
    • 不常访问的数据:sc1
  2. 优化卷大小:

    • 预置略大于需求的卷
    • 监控卷使用量,并按需扩展
    • 清理或归档不必要的数据
  3. 迁移到 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. 数据分层:

    • 频繁访问的数据:EBS 或 EFS
    • 不常访问的数据:S3 或 S3 Glacier
  2. 自动化 snapshot 策略:

    • 定期创建 snapshot
    • 自动删除旧 snapshot
yaml
apiVersion: snapshot.storage.k8s.io/v1
kind: VolumeSnapshotClass
metadata:
  name: ebs-snapshot-class
driver: ebs.csi.aws.com
deletionPolicy: Delete
  1. PV reclaim policy:
    • 对临时数据使用 Delete policy
    • 对重要数据使用 Retain policy

EFS Cost Optimization ​

  1. 选择合适的 throughput mode:

    • 可预测的工作负载:Provisioned throughput
    • 可变工作负载:Bursting mode
  2. Lifecycle management:

    • 自动将不常访问的文件移动到 IA (Infrequent Access) storage class
    • 配置 lifecycle policy:
bash
aws efs put-lifecycle-configuration \
  --file-system-id fs-1234567890abcdef0 \
  --lifecycle-policies '[{"TransitionToIA":"AFTER_30_DAYS"}]'
  1. 使用 access points:
    • 使用特定于应用程序的 access points 共享文件系统

FSx for Lustre Cost Optimization ​

  1. 选择合适的 deployment type:

    • 临时工作负载:SCRATCH_2
    • 长期工作负载:PERSISTENT_1 或 PERSISTENT_2
  2. 启用数据压缩:

    • 使用 LZ4 数据压缩降低存储成本
  3. 与 S3 集成:

    • 将 S3 bucket 连接到 FSx for Lustre 以进行数据分层

Cost Monitoring and Analysis ​

  1. 使用 AWS Cost Explorer:

    • 分析存储成本趋势
    • 按资源分析成本
  2. Kubernetes 成本分配:

    • 使用 namespaces 和 labels 分配成本
    • 使用 Kubecost 等工具
  3. 成本异常检测:

    • 设置 AWS budgets 和 alerts
    • 为异常成本增长配置 alerts

Storage Security ​

让我们探讨保护 EKS 集群中存储资源的安全最佳实践。

Data Encryption ​

  1. 静态数据加密:
    • 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
  • EFS 文件系统加密:
bash
aws efs create-file-system \
  --encrypted \
  --kms-key-id arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab
  • 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. 传输中数据加密:
    • EFS 传输中加密:
yaml
mountOptions:
  - tls
  • S3 传输中加密:
bash
aws s3 cp --sse AES256 file.txt s3://my-bucket/

Access Control ​

  1. IAM roles and policies:
    • 应用最小权限原则
    • 对 service accounts 使用 IAM roles
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:
    • 仅允许必需端口
    • 限制源 IP
bash
aws ec2 authorize-security-group-ingress \
  --group-id sg-1234567890abcdef0 \
  --protocol tcp \
  --port 2049 \
  --source-group sg-0987654321fedcba0
  1. Kubernetes RBAC:
    • 限制对 PVs 和 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:
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. 有限权限:
yaml
securityContext:
  runAsUser: 1000
  runAsGroup: 3000
  fsGroup: 2000
  allowPrivilegeEscalation: false
  1. SELinux、AppArmor 或 seccomp profiles:
yaml
securityContext:
  seLinuxOptions:
    level: "s0:c123,c456"
  seccompProfile:
    type: RuntimeDefault

Security Policy Enforcement ​

  1. OPA Gatekeeper 或 Kyverno:
    • 仅允许加密卷
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:
    • 将 Pod Security Standards 应用于 namespaces
yaml
apiVersion: v1
kind: Namespace
metadata:
  name: secure-ns
  labels:
    pod-security.kubernetes.io/enforce: restricted

Storage Management Best Practices ​

让我们探讨在 EKS 集群中有效管理存储的最佳实践。

Storage Planning and Design ​

  1. 需求分析:

    • 性能需求(IOPS、吞吐量)
    • 容量需求
    • 访问模式(读/写比例、并发)
    • 可用性和持久性需求
  2. 存储类型选择:

    • Block storage (EBS):数据库、有状态应用程序
    • File storage (EFS):共享文件、web servers、CMS
    • High-performance file storage (FSx for Lustre):HPC、ML training
    • Object storage (S3):备份、归档、静态内容
  3. 容量规划:

    • 当前需求 + 增长余量
    • 实现自动扩展机制
    • 定期容量评审

Backup and Disaster Recovery ​

  1. 定期备份:
    • 自动执行卷 snapshot
    • 定义备份保留策略
bash
# Create snapshot daily at midnight
0 0 * * * kubectl create -f snapshot.yaml
  1. Disaster recovery plan:

    • Multi-AZ 或跨区域复制
    • 定义 Recovery Time Objective (RTO) 和 Recovery Point Objective (RPO)
    • 定期恢复测试
  2. 使用 Velero 进行集群备份:

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

Automation and IaC (Infrastructure as Code) ​

  1. 使用 Terraform 或 CloudFormation:
    • 以声明式方式定义存储资源
    • 版本控制和变更跟踪
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. 使用 Helm charts:
    • 将 storage classes 和 PVCs 模板化
yaml
# values.yaml
storage:
  class: ebs-gp3
  size: 10Gi
  encrypted: true
  1. GitOps workflow:
    • 使用 ArgoCD 或 Flux 管理存储配置

Performance and Cost Optimization ​

  1. 定期性能评审:

    • 识别并解决瓶颈
    • 随着工作负载变化调整存储配置
  2. 成本优化评审:

    • 识别并移除未使用的卷
    • 迁移到具有成本效益的存储类型
    • 考虑 Reserved Instances 或 Savings Plans
  3. Auto scaling:

    • 根据需求自动扩展存储
    • 配置基于使用量的 alerts

Conclusion ​

在本文档中,我们介绍了 Amazon EKS 存储的监控、故障排查、成本优化和安全。有效的存储管理对于确保 EKS 集群的性能、可靠性和成本效益至关重要。

存储需求因应用程序而异,因此了解工作负载的特征并选择合适的存储解决方案非常重要。此外,你还应通过定期监控、故障排查、成本优化和安全评审来有效管理存储资源。

References ​

Quiz ​

要测试你在本章学到的内容,请尝试完成主题测验。

向文档提问

按 Enter 发送,按 Shift+Enter 换行。