将 Kubernetes 更新从 Terragrunt 和 Terraform 迁移到 Azure Kubernetes Fleet Manager

多群集环境的作员通常使用 Terragrunt 和 Terraform 管理其群集中的 Kubernetes 更新。 群集更新顺序是使用 Git 存储库或配置文件或脚本中的文件夹结构(使用 Terragrunt 作为业务流程工具)定义的。

在较小的环境中,此方法可以管理,但随着群集的数量和大小的增长,群集更新的复杂性也是如此。 长时间运行的更新进程会给运营团队带来负担,因为他们需要使用断开连接的工具和流程监视多个群集中的更新进度。

随着时间的推移,管理更新的开销会导致更新频率较低,导致群集不受支持或面临复杂的多版本 Kubernetes 更新。

Azure Kubernetes Fleet Manager 更新操作 为操作员提供了一种安全的方法,以简化多群集更新的复杂性。 更新运行允许作员定义更新策略,以确保在单个作中跨群集对更新进行安全排序。 更新运行支持具有数百个群集的大型环境,这些环境可能需要数天或数周才能完成。

本文介绍如何从基于 Terragrunt 和 Terraform 的现有 Kubernetes 更新过程迁移到 Azure Kubernetes 机队管理器更新运行。

使用舰队管理器更新运行的好处

使用 Fleet Manager 更新操作来管理群集中的 Kubernetes 更新具有以下优势:

  • 自动更新或手动更新:更新运行可用于随时手动更新群集,也可以使用自动升级自动执行更新过程。 自动升级会在 AKS 发布新的 Kubernetes 版本时自动创建和执行更新运行。
  • 定义更新的顺序:生成可重用的策略,以定义群集更新的顺序。 更新策略可确保先更新较低环境,从而限制意外问题的爆破半径。
  • 轻松添加新群集:可以通过填充群集的更新组,将新群集包含在更新运行中。 如果已在更新策略中定义组,则群集将自动包含在下一次更新运行中。 可以通过随时修改更新组,从更新运行中移动(或删除)群集。
  • 持续数天和数周:更新运行旨在处理长时间运行的更新,使你可以更新数百个可能需要数天甚至数周才能完成的群集。
  • 更新不仅仅是 Kubernetes:更新运行不仅仅可用于更新 Kubernetes,还允许更新群集的节点映像版本。
  • 遵循维护时段:更新运行会自动遵循为每个群集定义的维护时段,确保更新仅在安全的情况下应用。

注释

如果不熟悉 Fleet Manager 更新运行,请在阅读本文之前阅读 更新运行文档

使用 Terragrunt 和 Terraform 的示例多群集环境

为了帮助说明如何迁移到 Fleet Manager,我们提供了一个使用 Terragrunt 和 Terraform 管理 Azure Kubernetes 服务 (AKS) 群集的示例多群集环境。 以下文件夹结构用于保存 Terraform 和 Terragrunt 配置文件。

├── environments/
│   ├── dev/
│   │   └── aks/
│   │       └── terragrunt.hcl
│   └── prod/
│       └── aks/
│           └── terragrunt.hcl
|
└── modules/
    └── aks/
        └── main.tf

首先,我们提供了用于创建 Azure Kubernetes 服务(AKS)群集的 Terraform 定义。

# main.tf
variable "kubernetes_version" {
    type    = string
    default = "1.30.2"
}

resource "azurerm_kubernetes_cluster" "aks" {
    name                = var.cluster_name
    location            = var.location
    resource_group_name = var.resource_group_name
    dns_prefix          = var.cluster_name
    
    default_node_pool {
        name       = "default"
        node_count = 3
        vm_size    = "Standard_DS2_v2"
    }
    
    kubernetes_version = var.kubernetes_version
    
    identity {
        type = "SystemAssigned"
    }
    
    tags = var.tags
}

接下来,我们配置了开发群集 Terragrunt。

# dev/aks/terragrunt.hcl
terraform {
    source = "../../../modules/aks"
}

inputs = {
    cluster_name        = "aks-dev-cluster-01"
    location            = "chinanorth3"
    resource_group_name = "rg-dev-aks"
    tags = {
        environment = "dev"
    }
}

我们的生产 Terragrunt 定义类似,但群集名称、资源组和标记的值不同。

# prod/aks/terragrunt.hcl
terraform {
    source = "../../../modules/aks"
}

inputs = {
    cluster_name        = "aks-prod-cluster-01"
    location            = "chinanorth3"
    resource_group_name = "rg-prod-aks"
    tags = {
        environment = "prod"
    }
}

让我们继续使用 Terragrunt 部署群集。

terragrunt apply-all

部署了两个 AKS 群集,一个命名并标记为 dev 一个 prod,每个群集都设置为 Kubernetes 版本 1.30.2 (默认值)。

使用 Terragrunt 更新 Kubernetes 版本

让我们将这两个群集的 Kubernetes 版本更新为 1.31.1 使用 Terragrunt。

我们希望确保在生产之前将更新应用到开发群集。 此外,我们希望跟踪群集配置的状态,因此,我们将变量 kubernetes_version 添加到 Terragrunt 配置文件,而不是将其作为命令行参数提供。

# dev/aks/terragrunt.hcl
terraform {
    source = "../../../modules/aks"
}

inputs = {
    cluster_name        = "aks-dev-cluster-01"
    location            = "chinanorth3"
    resource_group_name = "rg-dev-aks"
    kubernetes_version  = "1.31.1"  # <-- Updated version
    tags = {
        environment = "dev"
    }
}

我们开始将更新应用到开发集群。

# Navigate to the dev/aks directory
cd environments/dev/aks
# Apply the update to the development cluster
terragrunt apply

开发群集更新并测试为正常工作后,可以使用同一过程更新生产群集。

还可以更新所有单独的 hcl 文件(或 main.tf 文件),然后使用 apply-all Terragrunt dependenciesdependency 块来控制群集的顺序。

但是,多个群集或环境意味着文件夹结构、配置文件和进程可能会变得不方便且容易出错。 与配置文件和 Git 存储库中保留的所需状态相比,很难直观显示群集的实际状态。

迁移到舰队管理器更新运行

让我们看看如何将现有的方法转变为使用 Fleet Manager 进行更新运行,然后启用自动升级。 在本文中,让我们执行刚才相同的更新,但这次通过机队管理器执行,而不是使用 Terragrunt 和 Terraform。

如果想要使用 Azure 门户,可以遵循使用组和阶段更新群集文档。

注释

开始使用 Fleet Manager 更新运行后,应从 Terragrunt 和 Terraform 配置中删除 Kubernetes 版本更新支持。

创建 Fleet Manager 资源并将群集添加为成员

使用 Terraform 定义 Fleet Manager 资源。 只要 Entra ID 租户与要管理的群集相同,队列管理器资源就可以位于任何资源组或 Azure 订阅中。

provider "azurerm" {
  features {}
}

resource "azurerm_kubernetes_fleet_manager" "fleet" {
    location            = "chinanorth3"
    name                = "flt-demo-01"
    resource_group_name = "rg-fleet-01"
}

接下来,我们需要将群集添加为机群管理器的成员,为每个群集创建资源 azurerm_kubernetes_fleet_member 。 我们还在创建成员时分配更新组。 更新组是可选的,但允许将群集包含在使用策略的更新运行中。


# We're assuming all resources are in the same Azure subscription

# Reference existing AKS clusters
resource "azurerm_kubernetes_cluster" "dev_cluster" {
    name                = "aks-dev-cluster-01"
    resource_group_name = "rg-dev-aks"
}

resource "azurerm_kubernetes_cluster" "prod_cluster" {
    name                = "aks-prod-cluster-01"
    resource_group_name = "rg-prod-aks"
}

# Create member clusters and assign update groups
resource "azurerm_kubernetes_fleet_member" "dev_cluster_member" {
    kubernetes_cluster_id = dev_cluster.id
    kubernetes_fleet_id   = fleet_demo_01.id
    name                  = "mbr-dev-cluster-01"
    group                 = "dev"
}

resource "azurerm_kubernetes_fleet_member" "prod_cluster_member" {
    kubernetes_cluster_id = prod_cluster.id
    kubernetes_fleet_id   = fleet_demo_01.id
    name                  = "mbr-prod-cluster-01"
    group                 = "prod"
}

创建更新策略

接下来,我们需要创建一个更新策略,用于定义要更新的群集顺序。 可以在多个更新运行中重复使用更新策略。 例如,可以单独执行 Kubernetes 和节点映像更新,但使用相同的策略。

可以使用 azurerm_kubernetes_fleet_update_strategy 资源定义策略。 阶段按顺序执行,阶段中的组并行执行。 该 after_stage_wait_in_seconds 属性允许在下一阶段开始之前在阶段完成时定义等待时间,这对于在继续下一阶段之前进行测试或验证非常有用。

resource "azurerm_kubernetes_fleet_update_strategy" "tg_migration_strategy" {
    name                        = "tg-migration-strategy"
    kubernetes_fleet_manager_id = azurerm_kubernetes_fleet_manager.fleet.id
    stage {
        name = "stg-pre-prod"
        group {
            name = "dev"
        }
        after_stage_wait_in_seconds = 3600
    }
    stage {
        name = "stg-prod"
        group {
          name = "prod"
        }
    }
}

创建更新任务

现在,我们可以创建一个使用我们定义的策略的更新运行。 资源 azurerm_kubernetes_fleet_update_run 允许我们指定要更新的策略和群集。

resource "azurerm_kubernetes_fleet_update_run" "update_run_tg_migration_131" {
    name                        = "update_run_tg_migration_131"
    kubernetes_fleet_manager_id = azurerm_kubernetes_fleet_manager.fleet.id
    managed_cluster_update {
        upgrade {
            type               = "Full"
            kubernetes_version = "1.31.1"
        }
        node_image_selection {
            type = "Consistent"
        }
    }
    fleet_update_strategy_id = azurerm_kubernetes_fleet_update_strategy.tg_migration_strategy.id
}

执行更新操作

可以使用 Terraform 通过null_resource和一个local-exec预配程序执行更新运行,如下所示。 根据配置,要传递的参数将更改。

resource "null_resource" "trigger_update_run" {
  provisioner "local-exec" {
    command = "az fleet updaterun start --resource-group ${azurerm_kubernetes_fleet_manager.fleet.resource_group_name} --fleet-name ${azurerm_kubernetes_fleet_manager.fleet.name} --name ${azurerm_kubernetes_fleet_update_run.update_run_tg_migration_131.name}"
  }

  depends_on = [azurerm_kubernetes_fleet_update_run.update_run_tg_migration_131]
}

还可以使用 Azure 门户或 Azure CLI 启动更新运行。 有关详细信息,请参阅 管理更新运行

启用自动升级

熟悉更新运行后,可以为群集 启用自动升级 。 当 AKS 发布新的 Kubernetes 版本时,自动升级会自动创建和执行更新运行。 这意味着不再需要监视新的 Kubernetes 版本并手动创建更新运行。

注释

自动升级目前支持稳定且快速的 Kubernetes 发布通道,并在发布新的次要版本时自动递增 Kubernetes 次要版本。 如果想要保留在特定的 Kubernetes 次要服务器上,则目前不应使用自动升级。 支持目标 Kubernetes 版本的自动升级功能正在开发中。 在 Fleet Manager 路线图上跟踪目标次要版本支持。