You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在销毁EKS集群时自动删除关联存储卷?

问题描述

用Terraform脚本创建EKS集群后,执行terraform destroy销毁集群时,集群生成的EBS存储卷不会自动删除,得手动去AWS控制台清理,想通过脚本实现存储卷的自动删除。

现有eks.tf代码如下:

# Copyright (c) HashiCorp, Inc.
# SPDX-License-Identifier: MPL-2.0

provider "aws" {
  region  = var.region
  profile = var.profile
  default_tags {
    tags = {
      Name          = "Example Eks cluster"
      
    }
  }
}

# Filter out local zones, which are not currently supported 
# with managed node groups
data "aws_availability_zones" "available" {
  filter {
    name   = "opt-in-status"
    values = ["opt-in-not-required"]
  }
}

locals {
  cluster_name              = "test-eks-cluster"
  cluster_enabled_log_types = []
}



module "eks" {
  source  = "terraform-aws-modules/eks/aws"
  version = "19.15.3"

  cluster_name    = local.cluster_name
  cluster_version = "1.27"

  cluster_endpoint_public_access  = true
  cluster_endpoint_private_access = true

  vpc_id     = "id"
  subnet_ids = ["subnet-0354234234329e", "subnet-2343243"]

  cluster_enabled_log_types = local.cluster_enabled_log_types

  create_cloudwatch_log_group = false

  tags = var.tags


  eks_managed_node_group_defaults = {
    #ami_type = "ami-06d7aa002b2e3009b"
    ami_type = "AL2_x86_64"
    tags     = var.tags


  }

  eks_managed_node_groups = {
    one = {
      name = "node-group-1"

      instance_types = ["t3.large"]

      min_size     = 1
      max_size     = 3
      desired_size = 2
      tags         = var.tags
    }
  }
  # access_entries = {

  #}
}

data "aws_iam_policy" "ebs_csi_policy" {
  arn = "arn:aws:iam::aws:policy/service-role/AmazonEBSCSIDriverPolicy"
}

module "irsa-ebs-csi" {
  source  = "terraform-aws-modules/iam/aws//modules/iam-assumable-role-with-oidc"
  version = "4.7.0"

  create_role                   = true
  role_name                     = "AmazonEKSTFEBSCSIRole-${module.eks.cluster_name}"
  provider_url                  = module.eks.oidc_provider
  role_policy_arns              = [data.aws_iam_policy.ebs_csi_policy.arn]
  oidc_fully_qualified_subjects = ["system:serviceaccount:kube-system:ebs-csi-controller-sa"]
  tags                          = var.tags
}

resource "aws_eks_addon" "ebs-csi" {
  cluster_name             = module.eks.cluster_name
  addon_name               = "aws-ebs-csi-driver"
  addon_version            = "v1.30.0-eksbuild.1"
  service_account_role_arn = module.irsa-ebs-csi.iam_role_arn
  configuration_values = jsonencode({
    controller = {
      extraVolumeTags = {
        Name          = "Example Eks cluster"
     
      }
    }
  })
}
解决方案

可以通过以下几种方式组合实现EBS卷自动删除,适配你的现有配置:

1. 配置EBS CSI驱动的默认存储类回收策略

K8s默认的PV回收策略是Retain(保留卷),改成Delete后,PVC删除时会自动清理对应的EBS卷。直接修改你现有aws_eks_addon.ebs-csi的配置:

resource "aws_eks_addon" "ebs-csi" {
  cluster_name             = module.eks.cluster_name
  addon_name               = "aws-ebs-csi-driver"
  addon_version            = "v1.30.0-eksbuild.1"
  service_account_role_arn = module.irsa-ebs-csi.iam_role_arn
  configuration_values = jsonencode({
    controller = {
      extraVolumeTags = {
        Name          = "Example Eks cluster"
      }
      # 添加默认存储类的回收策略配置
      storageClass = {
        default = true
        reclaimPolicy = "Delete"
      }
    }
  })
}

2. Terraform销毁前自动清理K8s中的PVC

用null_resource配合本地命令,在销毁集群前先删除所有PVC,触发PV的回收逻辑。把这段代码加到eks.tf里:

resource "null_resource" "cleanup_k8s_pvc" {
  depends_on = [module.eks, aws_eks_addon.ebs-csi]

  provisioner "local-exec" {
    command = <<EOT
      # 配置kubectl连接EKS集群
      aws eks update-kubeconfig --name ${local.cluster_name} --region ${var.region} --profile ${var.profile}
      # 删除所有命名空间下的PVC
      kubectl delete pvc --all --all-namespaces
      # 等待K8s完成卷回收
      sleep 30
    EOT
    # 只在销毁阶段执行
    when = destroy
  }
}

注意:执行terraform destroy的环境要提前装aws-cli和kubectl,并且有操作EKS集群和K8s资源的权限。

3. 兜底:用Terraform匹配标签删除遗留EBS卷

如果上面的步骤有遗漏,可以通过标签筛选所有属于这个集群的EBS卷,让Terraform接管并销毁。添加以下代码:

# 筛选带有指定标签的EBS卷
data "aws_volumes" "eks_cluster_volumes" {
  filter {
    name   = "tag:Name"
    values = ["Example Eks cluster"]
  }

  filter {
    name   = "status"
    values = ["available", "in-use"]
  }
}

# 导入并管理这些卷,销毁时自动删除
resource "aws_ebs_volume" "managed_eks_volumes" {
  count             = length(data.aws_volumes.eks_cluster_volumes.ids)
  availability_zone = element(data.aws_volumes.eks_cluster_volumes.availability_zones, count.index)
  size              = element(data.aws_volumes.eks_cluster_volumes.sizes, count.index)
  tags              = var.tags

  lifecycle {
    # 忽略卷的可用区和大小变更,只管理删除
    ignore_changes = [availability_zone, size]
    create_before_destroy = false
  }
}

第一次应用时,需要先把现有卷导入Terraform状态,执行命令:terraform import aws_ebs_volume.managed_eks_volumes[0] <卷ID>,按卷的数量依次导入。

验证步骤
  1. 执行terraform apply应用修改后的配置
  2. 创建测试PVC,确认删除PVC时EBS卷会被自动清理
  3. 执行terraform destroy,检查AWS控制台中对应的EBS卷是否被自动删除

内容的提问来源于stack exchange,提问作者user23627827

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 03:44:56