全部產品
Search
文件中心

Container Service for Kubernetes:使用Terraform建立具備自動調整功能的節點池

更新時間:Dec 04, 2024

ACK的節點池及託管節點池中的節點預設不具備自動調整能力,您也可以通過使用Terraform工具建立開啟自動調整功能的節點池。本文介紹如何通過Terraform建立開啟自動調整功能的節點池。

說明

本教程所含範例程式碼支援一鍵運行,您可以直接運行代碼。一鍵運行

前提條件

  • 自動調整功能依賴Auto Scaling(Auto Scaling,舊稱ESS)服務。啟動節點自動調整前,您需要開通Auto Scaling服務,並完成預設角色授權。具體操作,請參見開通Auto Scaling服務

    說明

    如果您之前已經使用了alicloud_cs_kubernetes_autoscaler組件,預設已開通Auto Scaling服務。

  • 已為CloudOps Orchestration Service (OOS)服務授權。您可以通過建立AliyunOOSLifecycleHook4CSRole角色,為OOS服務授權。

    1. 單擊AliyunOOSLifecycleHook4CSRole

      說明
      • 如果當前帳號是阿里雲帳號,單擊AliyunOOSLifecycleHook4CSRole即可授權。

      • 如果當前帳號是RAM使用者,請先確保對應的阿里雲帳號已授權AliyunOOSLifecycleHook4CSRole,並為RAM使用者授予AliyunRAMReadOnlyAccess系統策略。具體操作,請參見為RAM使用者授權

    2. 雲資源訪問授權頁面,單擊同意授權

  • 準備Terraform運行環境,您可以選擇以下任一方式來使用Terraform。

    • Cloud Shell:阿里雲Cloud Shell中預裝了Terraform的組件,並已配置好身份憑證,您可直接在Cloud Shell中運行Terraform的命令。適用於低成本、快速、便捷地訪問和使用Terraform的情境。

    • 在本地安裝和配置Terraform:適用於網路連接較差或需要自訂開發環境的情境。

背景資訊

Terraform是一種開源工具,通過Provider來支援新的基礎架構,用於安全高效地預覽、配置和管理雲基礎架構和資源。更多資訊,請參見Terraform產品介紹

Alibaba Cloud Provider的老版本中,ACK提供了一個名為alicloud_cs_kubernetes_autoscaler的組件。alicloud_cs_kubernetes_autoscaler組件可以實現節點的Auto Scaling,但是其能力受限:

  • 配置複雜,使用成本高。

  • 伸縮的節點都會被放置到預設節點池,自動調整的節點未單獨維護。

  • 部分配置參數不可更改。

Alibaba Cloud Provider從1.111.0版本開始可通過組件alicloud_cs_kubernetes_node_pool建立開啟自動調整功能的節點池,優勢如下:

  • 配置簡單,您只需要配置伸縮組內節點數的上下限。

  • 針對非必須配置,ACK使用預設值的配置,以防誤操作帶來的基礎環境不一致的問題,例如:作業系統鏡像。

  • 在ACK控制台中可以直觀地觀察節點池內節點的變化。

使用的資源

說明

本教程樣本包含的部分資源會產生一定費用,請在不需要時及時進行釋放或退訂。

使用Terraform建立開啟自動調整功能的節點池

使用過alicloud_cs_kubernetes_autoscaler組件

如果您的叢集之前已經使用alicloud_cs_kubernetes_autoscaler組件,在完成上述為當前叢集添加Auto Scaling服務授權後,您需要執行以下步驟平滑切換alicloud_cs_kubernetes_autoscaler至alicloud_cs_kubernetes_node_pool,以建立開啟自動調整功能的節點池。

  1. 修改叢集的autoscaler-meta配置項。

    1. 登入Container Service管理主控台,在左側導覽列選擇叢集

    2. 叢集列表頁面,單擊目的地組群名稱,然後在左側導覽列,選擇組態管理 > 配置項

    3. 配置項頁面左上方的命名空間下拉框中,選擇kube-system,然後在autoscaler-meta配置項右側操作列下,單擊編輯

    4. 編輯面板中,修改autoscaler-meta配置項的值。

      您需將taints值的String類型改成數群組類型,即在文字框中,修改"taints":"""taints":[]

    5. 單擊確定

  2. 同步節點池。

    1. 在叢集管理頁左側導覽列,選擇節點管理 > 節點池

    2. 節點池頁面右上方,單擊同步節點池

未使用過alicloud_cs_kubernetes_autoscaler組件

您可以使用Terraform建立開啟自動調整功能的節點池。

  1. 建立節點池的設定檔。

    為已有叢集建立開啟自動調整功能的節點池

    在已有叢集中建立開啟自動調整功能的節點池,配置樣本如下。

    provider "alicloud" {
    }
    # 為已有叢集建立開啟自動調整功能的節點池。
    resource "alicloud_cs_kubernetes_node_pool" "at1" {
      # 目的地組群ID。
      cluster_id           = ""
      name                 = "np-test"
      # 節點池內節點使用的vswitch,至少提供一個。
      vswitch_ids          = ["vsw-bp1mdigyhmilu2h4v****"]
      instance_types       = ["ecs.e3.medium"]
      password             = "Hello1234"
     
      scaling_config {
        # 最小節點數。
        min_size     = 1
        # 最大節點數。
        max_size     = 5
      }
    
    }

    建立新的具備自動調整功能的節點池叢集

    建立一個包含自動調整節點池的叢集,配置樣本如下。

    provider "alicloud" {
      region = var.region_id
    }
    
    variable "region_id" {
      type    = string
      default = "cn-shenzhen"
    }
    
    variable "cluster_spec" {
      type        = string
      description = "The cluster specifications of kubernetes cluster,which can be empty. Valid values:ack.standard : Standard managed clusters; ack.pro.small : Professional managed clusters."
      default     = "ack.pro.small"
    }
    
    variable "ack_version" {
      type        = string
      description = "Desired Kubernetes version. "
      default     = "1.28.9-aliyun.1"
    }
    
    # 指定虛擬交換器(vSwitches)的可用性區域。
    variable "availability_zone" {
      description = "The availability zones of vswitches."
      default     = ["cn-shenzhen-c", "cn-shenzhen-e", "cn-shenzhen-f"]
    }
    
    # 用於建立新vSwitches的CIDR地址塊列表。
    variable "node_vswitch_cidrs" {
      type        = list(string)
      default     = ["172.16.0.0/23", "172.16.2.0/23", "172.16.4.0/23"]
    }
    
    # 用於建立Terway使用的vSwitch的CIDR地址塊。
    variable "terway_vswitch_cidrs" {
      type        = list(string)
      default     = ["172.16.208.0/20", "172.16.224.0/20", "172.16.240.0/20"]
    }
    
    # 定義了用於啟動工作節點的ECS執行個體類型。
    variable "worker_instance_types" {
      description = "The ecs instance types used to launch worker nodes."
      default     = ["ecs.g6.2xlarge", "ecs.g6.xlarge"]
    }
    
    # 設定工作階段的密碼
    variable "password" {
      description = "The password of ECS instance."
      default     = "Test123456"
    }
    
    # 指定建立ACK託管叢集名稱的首碼。
    variable "k8s_name_prefix" {
      description = "The name prefix used to create managed kubernetes cluster."
      default     = "tf-ack-shenzhen"
    }
    
    variable "vpc_name" {
      default = "tf-vpc"
    }
    
    variable "autoscale_nodepool_name" {
      default = "autoscale-node-pool"
    }
    
    # 指定ACK叢集安裝的組件。包括Terway(網路組件)、csi-plugin(儲存群組件)、csi-provisioner(儲存群組件)、logtail-ds(日誌組件)、Nginx Ingress Controller、ack-arms-prometheus(監控組件)以及ack-node-problem-detector(節點診斷組件)。
    variable "cluster_addons" {
      type = list(object({
        name   = string
        config = string
      }))
    
      default = [
        {
          "name"   = "terway-eniip",
          "config" = "",
        },
        {
          "name"   = "logtail-ds",
          "config" = "{\"IngressDashboardEnabled\":\"true\"}",
        },
        {
          "name"   = "nginx-ingress-controller",
          "config" = "{\"IngressSlbNetworkType\":\"internet\"}",
        },
        {
          "name"   = "arms-prometheus",
          "config" = "",
        },
        {
          "name"   = "ack-node-problem-detector",
          "config" = "{\"sls_project_name\":\"\"}",
        },
        {
          "name"   = "csi-plugin",
          "config" = "",
        },
        {
          "name"   = "csi-provisioner",
          "config" = "",
        }
      ]
    }
    
    # 預設資源名稱。
    locals {
      k8s_name_terway = substr(join("-", [var.k8s_name_prefix, "terway"]), 0, 63)
    }
    
    # 節點ECS執行個體配置。將查詢滿足CPU、Memory要求的ECS執行個體類型。
    data "alicloud_instance_types" "default" {
      cpu_core_count       = 8
      memory_size          = 32
      availability_zone    = var.availability_zone[0]
      kubernetes_node_role = "Worker"
    }
    
    # 專用網路。
    resource "alicloud_vpc" "default" {
      vpc_name   = var.vpc_name
      cidr_block = "172.16.0.0/12"
    }
    
    # Node交換器。
    resource "alicloud_vswitch" "vswitches" {
      count      = length(var.node_vswitch_cidrs)
      vpc_id     = alicloud_vpc.default.id
      cidr_block = element(var.node_vswitch_cidrs, count.index)
      zone_id    = element(var.availability_zone, count.index)
    }
    
    # Pod交換器。
    resource "alicloud_vswitch" "terway_vswitches" {
      count      = length(var.terway_vswitch_cidrs)
      vpc_id     = alicloud_vpc.default.id
      cidr_block = element(var.terway_vswitch_cidrs, count.index)
      zone_id    = element(var.availability_zone, count.index)
    }
    
    # Kubernetes託管版。
    resource "alicloud_cs_managed_kubernetes" "default" {
      name                         = local.k8s_name_terway # Kubernetes叢集名稱。
      cluster_spec                 = var.cluster_spec      # 建立Pro版叢集。
      version                      = var.ack_version
      worker_vswitch_ids           = split(",", join(",", alicloud_vswitch.vswitches.*.id))        # 節點池所在的vSwitch。指定一個或多個vSwitch的ID,必須在availability_zone指定的地區中。
      pod_vswitch_ids              = split(",", join(",", alicloud_vswitch.terway_vswitches.*.id)) # Pod虛擬交換器。
      new_nat_gateway              = true                                                          # 是否在建立Kubernetes叢集時建立新的NAT Gateway。預設為true。
      service_cidr                 = "10.11.0.0/16"                                                # Pod網路的CIDR塊。當cluster_network_type設定為flannel,你必須設定該參數。它不能與VPC CIDR相同,並且不能與VPC中的Kubernetes叢集使用的CIDR相同,也不能在建立後進行修改。叢集中允許的最大主機數量:256。
      slb_internet_enabled         = true                                                          # 是否為API Server建立Internet負載平衡。預設為false。
      enable_rrsa                  = true
      control_plane_log_components = ["apiserver", "kcm", "scheduler", "ccm"] # 控制平面日誌。
      dynamic "addons" {                                                      # 組件管理。
        for_each = var.cluster_addons
        content {
          name   = lookup(addons.value, "name", var.cluster_addons)
          config = lookup(addons.value, "config", var.cluster_addons)
        }
      }
    }
    
    # 建立自動調整節點池,節點池最多可以擴充到 10 個節點,最少保持 1 個節點。
    resource "alicloud_cs_kubernetes_node_pool" "autoscale_node_pool" {
      cluster_id     = alicloud_cs_managed_kubernetes.default.id
      node_pool_name = var.autoscale_nodepool_name
      vswitch_ids    = split(",", join(",", alicloud_vswitch.vswitches.*.id))
    
      scaling_config {
        min_size = 1
        max_size = 10
      }
    
      instance_types        = var.worker_instance_types
      runtime_name          = "containerd"
      runtime_version       = "1.6.20"
      password              = var.password # SSH登入叢集節點的密碼。
      install_cloud_monitor = true         # 是否為kubernetes的節點安裝CloudMonitor。
      system_disk_category  = "cloud_efficiency"
      system_disk_size      = 100
      image_type            = "AliyunLinux3"
    
      data_disks {              # 節點資料盤配置。
        category = "cloud_essd" # 節點資料盤種類。
        size     = 120          # 節點資料盤大小。
      }
    }
  2. 執行如下命令,初始化Terraform運行環境。

    terraform init

    返回資訊如下,Terraform初始化成功。

    Terraform has been successfully initialized!
    
    You may now begin working with Terraform. Try running "terraform plan" to see
    any changes that are required for your infrastructure. All Terraform commands
    should now work.
    
    If you ever set or change modules or backend configuration for Terraform,
    rerun this command to reinitialize your working directory. If you forget, other
    commands will detect it and remind you to do so if necessary.
  3. 執行terraform apply命令完成建立。

  4. 驗證結果。

    完成建立節點池後,在節點池列表中可以看到建立的節點池,該節點池名稱下會標註已開啟自動調整

清理資源

當您不再需要上述通過Terraform建立或管理的資源時,請運行terraform destroy命令以釋放資源。關於terraform destroy的更多資訊,請參見常用命令

terraform destroy

完整樣本

說明

當前範例程式碼支援一鍵運行,您可以直接運行代碼。一鍵運行

provider "alicloud" {
  region = var.region_id
}

variable "region_id" {
  type    = string
  default = "cn-shenzhen"
}

variable "cluster_spec" {
  type        = string
  description = "The cluster specifications of kubernetes cluster,which can be empty. Valid values:ack.standard : Standard managed clusters; ack.pro.small : Professional managed clusters."
  default     = "ack.pro.small"
}

variable "ack_version" {
  type        = string
  description = "Desired Kubernetes version. "
  default     = "1.28.9-aliyun.1"
}

# 指定虛擬交換器(vSwitches)的可用性區域。
variable "availability_zone" {
  description = "The availability zones of vswitches."
  default     = ["cn-shenzhen-c", "cn-shenzhen-e", "cn-shenzhen-f"]
}

# 用於建立新vSwitches的CIDR地址塊列表。
variable "node_vswitch_cidrs" {
  type        = list(string)
  default     = ["172.16.0.0/23", "172.16.2.0/23", "172.16.4.0/23"]
}

# 用於建立Terway使用的vSwitch的CIDR地址塊。
variable "terway_vswitch_cidrs" {
  type        = list(string)
  default     = ["172.16.208.0/20", "172.16.224.0/20", "172.16.240.0/20"]
}

# 定義了用於啟動工作節點的ECS執行個體類型。
variable "worker_instance_types" {
  description = "The ecs instance types used to launch worker nodes."
  default     = ["ecs.g6.2xlarge", "ecs.g6.xlarge"]
}

# 設定工作階段的密碼
variable "password" {
  description = "The password of ECS instance."
  default     = "Test123456"
}

# 指定建立ACK託管叢集名稱的首碼。
variable "k8s_name_prefix" {
  description = "The name prefix used to create managed kubernetes cluster."
  default     = "tf-ack-shenzhen"
}

variable "vpc_name" {
  default = "tf-vpc"
}

variable "autoscale_nodepool_name" {
  default = "autoscale-node-pool"
}

# 指定ACK叢集安裝的組件。包括Terway(網路組件)、csi-plugin(儲存群組件)、csi-provisioner(儲存群組件)、logtail-ds(日誌組件)、Nginx Ingress Controller、ack-arms-prometheus(監控組件)以及ack-node-problem-detector(節點診斷組件)。
variable "cluster_addons" {
  type = list(object({
    name   = string
    config = string
  }))

  default = [
    {
      "name"   = "terway-eniip",
      "config" = "",
    },
    {
      "name"   = "logtail-ds",
      "config" = "{\"IngressDashboardEnabled\":\"true\"}",
    },
    {
      "name"   = "nginx-ingress-controller",
      "config" = "{\"IngressSlbNetworkType\":\"internet\"}",
    },
    {
      "name"   = "arms-prometheus",
      "config" = "",
    },
    {
      "name"   = "ack-node-problem-detector",
      "config" = "{\"sls_project_name\":\"\"}",
    },
    {
      "name"   = "csi-plugin",
      "config" = "",
    },
    {
      "name"   = "csi-provisioner",
      "config" = "",
    }
  ]
}

# 預設資源名稱。
locals {
  k8s_name_terway = substr(join("-", [var.k8s_name_prefix, "terway"]), 0, 63)
}

# 節點ECS執行個體配置。將查詢滿足CPU、Memory要求的ECS執行個體類型。
data "alicloud_instance_types" "default" {
  cpu_core_count       = 8
  memory_size          = 32
  availability_zone    = var.availability_zone[0]
  kubernetes_node_role = "Worker"
}

# 專用網路。
resource "alicloud_vpc" "default" {
  vpc_name   = var.vpc_name
  cidr_block = "172.16.0.0/12"
}

# Node交換器。
resource "alicloud_vswitch" "vswitches" {
  count      = length(var.node_vswitch_cidrs)
  vpc_id     = alicloud_vpc.default.id
  cidr_block = element(var.node_vswitch_cidrs, count.index)
  zone_id    = element(var.availability_zone, count.index)
}

# Pod交換器。
resource "alicloud_vswitch" "terway_vswitches" {
  count      = length(var.terway_vswitch_cidrs)
  vpc_id     = alicloud_vpc.default.id
  cidr_block = element(var.terway_vswitch_cidrs, count.index)
  zone_id    = element(var.availability_zone, count.index)
}

# Kubernetes託管版。
resource "alicloud_cs_managed_kubernetes" "default" {
  name                         = local.k8s_name_terway # Kubernetes叢集名稱。
  cluster_spec                 = var.cluster_spec      # 建立Pro版叢集。
  version                      = var.ack_version
  worker_vswitch_ids           = split(",", join(",", alicloud_vswitch.vswitches.*.id))        # 節點池所在的vSwitch。指定一個或多個vSwitch的ID,必須在availability_zone指定的地區中。
  pod_vswitch_ids              = split(",", join(",", alicloud_vswitch.terway_vswitches.*.id)) # Pod虛擬交換器。
  new_nat_gateway              = true                                                          # 是否在建立Kubernetes叢集時建立新的NAT Gateway。預設為true。
  service_cidr                 = "10.11.0.0/16"                                                # Pod網路的CIDR塊。當cluster_network_type設定為flannel,你必須設定該參數。它不能與VPC CIDR相同,並且不能與VPC中的Kubernetes叢集使用的CIDR相同,也不能在建立後進行修改。叢集中允許的最大主機數量:256。
  slb_internet_enabled         = true                                                          # 是否為API Server建立Internet負載平衡。預設為false。
  enable_rrsa                  = true
  control_plane_log_components = ["apiserver", "kcm", "scheduler", "ccm"] # 控制平面日誌。
  dynamic "addons" {                                                      # 組件管理。
    for_each = var.cluster_addons
    content {
      name   = lookup(addons.value, "name", var.cluster_addons)
      config = lookup(addons.value, "config", var.cluster_addons)
    }
  }
}

# 建立自動調整節點池,節點池最多可以擴充到 10 個節點,最少保持 1 個節點。
resource "alicloud_cs_kubernetes_node_pool" "autoscale_node_pool" {
  cluster_id     = alicloud_cs_managed_kubernetes.default.id
  node_pool_name = var.autoscale_nodepool_name
  vswitch_ids    = split(",", join(",", alicloud_vswitch.vswitches.*.id))

  scaling_config {
    min_size = 1
    max_size = 10
  }

  instance_types        = var.worker_instance_types
  runtime_name          = "containerd"
  runtime_version       = "1.6.20"
  password              = var.password # SSH登入叢集節點的密碼。
  install_cloud_monitor = true         # 是否為kubernetes的節點安裝CloudMonitor。
  system_disk_category  = "cloud_efficiency"
  system_disk_size      = 100
  image_type            = "AliyunLinux3"

  data_disks {              # 節點資料盤配置。
    category = "cloud_essd" # 節點資料盤種類。
    size     = 120          # 節點資料盤大小。
  }
}