如何扩大 Terraformed EKS 节点的体积

tec*_*242 5 amazon-ec2 kubernetes terraform terraform-provider-aws amazon-eks

我们使用 Terraform 来管理 AWS 上的各种资源(从堡垒主机到 VPC、RDS 以及 EKS)已经快一年了。

有时我们真的对 EKS 模块感到困惑。然而,这可能是由于缺乏理解(和文档),所以这里是:

问题:扩容磁盘(卷)


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

  cluster_name    = local.cluster_name
  cluster_version = "1.19"
  subnets         = module.vpc.private_subnets

  #...

  node_groups = {
    first = {
      desired_capacity = 1
      max_capacity     = 5
      min_capacity     = 1

      instance_type = "m5.large"
    }
  }
Run Code Online (Sandbox Code Playgroud)

我认为这个(开发)k8s 集群节点的默认值很容易是默认的 20GB,但它很快就填满了,所以我知道想要更改disk_size为 40GB。

=> 我想我可以添加类似disk_size=40和完成的东西。

terraform plan告诉我需要更换节点。这是一个 1 节点集群,所以不好。即使是这样,我也不想耗尽节点。这就是为什么我认为我们正在使用像 EKS 这样的托管 k8。

预期行为:由于这些是弹性卷,我应该能够扩大但不能缩小规模,为什么这是不可能的?我可以定义。从 AWS UI 执行此操作。

当然有一个有点可怕的警告:

您确定要修改卷 vol-xx 吗?性能更改可能需要一些时间才能完全生效。您可能需要扩展卷上的操作系统文件系统以使用任何新分配的空间

但我可以使用提供的文档:https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/recognize-expanded-volume-linux.html ?icmpid=docs_ec2_console

有关如何增加存储空间的任何指南吗?如果我使用 UI 执行此操作但不触摸 Terraform,那么我的 EKS 状态将被取消/不同步。

Luk*_*ler 5

据我所知,目前无法在不使用 Terraform 重新创建节点的情况下调整 EKS 节点卷的大小。

幸运的是,有一个解决方法:正如您还发现的那样,您可以通过 AWS UI 或 API 直接更改节点大小。要稍后更新状态文件,您可以运行terraform apply -refresh-only下载最新数据(例如,增加的节点卷大小)。之后,您可以更改 Terraform 计划中的节点大小,以保持计划和状态同步。

对于未来,您可能希望考虑迁移到临时节点,因为(至少我的)经验表明,您会不时对集群和节点进行不可预见的更改。已经考虑到可更换节点的规划将使这些更改变得更加容易。


jai*_*iks 2

通过使用 terraform-aws-eks terraform 模块,您实际上遵循了“临时节点”范例,因为对于创建实例的两种方式(自我管理的工作节点托管节点组),该模块正在创建自动扩展组,从而创建 EC2 实例启动模板。

ASG 和启动模板经过专门设计,让您不再关心特定节点,而只关心节点数量。这意味着,要更新节点,您只需将它们替换为新节点,这将使用新更新的启动模板(例如,具有更多 GB,或具有新更新的 AMI,或新实例类型)。

这称为“滚动更新”,可以使用脚本手动完成(添加新实例,然后耗尽节点,然后删除旧节点)(请参阅:Hellofresh 的 github 中的 eks-rolling-update),或者也可以如果您使用 AWS 托管节点(指定“node_groups”时实际使用的节点,这就是为什么如果您添加更多 GB,它会在您运行 apply 时自动替换节点),则会自动完成。

这种范例在云中运行 Kubernetes 时最常见(在使用虚拟化时也非常常见的本地数据中心)。

选项 1) 自我管理员工

对于自管理节点,当您更改磁盘大小或实例类型等参数时,它将更改启动模板。它将更新 $latest version 标记,这通常是 ASG 指向的位置(尽管可以更改)。这意味着旧实例不会看到任何更改,但新实例将具有更新的配置。

如果您想更改现有实例,您实际上想用新实例替换它们。这就是这个短暂节点范例。

您可以一一耗尽旧实例,同时增加 ASG 上的desired_instances 数量,或者让集群自动缩放程序来完成这项工作。或者,您可以使用自动脚本为每个 ASG 执行此操作: https: //github.com/hellofresh/eks-rolling-update

在 terraform_aws_eks 模块中,您可以使用worker_groups或worker_groups_launch_template(推荐)字段创建自我管理的工作人员

选项 2) 受管节点

受管节点是 EKS 特定的功能。您对它们的配置非常相似,但实际上,它是一个抽象,AWS 将创建实际的底层 ASG。

您可以指定 ASG 使用的启动模板及其版本。可以在受管节点级别(即 AMI 和 instance_types)和启动模板(如果前者未指定)指定某些配置。

节点组级别配置或启动模板版本的任何更改都将触发自动滚动更新,这将替换所有旧实例。

您可以通过不指向 $latest 版本(或指向 $default,并且在更改 LT 时不更新 $default 标记)来延迟滚动更新。

在 terraform_aws_eks 模块中,您可以使用node_groups字段创建自我管理工作人员。您还可以使用以下设置:create_launch_template=true 和 set_instance_types_on_lt=true 如果您希望模块为您创建 LT(或者您可以不使用它,或者传递对它的引用);并在上述 LT 上设置 instance_type。

但行为与工人群体相似。在任何情况下,您都不会更改现有实例。您只能手动更改它们。

但是,还有另一种选择:手动方式

您可以使用 EKS 模块创建控制平面,然后使用 terraform 中的常规 EC2 资源 ( https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/instance ) 创建一个矿石多个(使用 count 或 for_each)实例。

如果您使用 aws_instance 资源创建实例,则当允许进行任何更改(即增加根卷 GB 或实例类型;而更改 AMI 将强制替换)时,terraform 将修补这些实例(就地更新)。

唯一棘手的部分是,您需要配置 cloud-init 脚本以使实例加入集群(使用自/托管节点组时,EKS 模块会自动完成此操作)。

但是,这是很有可能的,您可以从模块借用脚本并将其插入 aws_instance 的 user_data 字段(https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/instance#user_data

然而,在这种情况下(当谈论 disk_size 时),您仍然需要手动(通过 SSH 或使用 terraform 运行 hacky exec)来修补 XFS 文件系统,以便它看到增加的磁盘空间。

另一种选择:考虑 Kubernetes 存储

也就是说,对于某些用例还有另一种选择。如果您由于某个应用程序使用了 hostPath 而想要增加这些实例的磁盘空间,那么您可能可以使用带有 EBS CSI 驱动程序的 kubernetes 内置存储解决方案。

例如,我在 Kubernetes 中管理一个 ElasticSearch 集群(并使用 helm 模块从 terraform 部署它),它使用动态存储配置来请求 EBS 卷(请注意,性能是相同的,因为根卷和另一个卷都是 EBS)卷)。EBS CSI 驱动程序支持卷扩展,因此我可以通过更改 terraform 变量来增加该磁盘。


总而言之,我不会推荐 aws_instance 方式,除非您理解它并且确定您确实想要它。在某些情况下可能有意义,但绝对不常见