全部產品
Search
文件中心

Container Service for Kubernetes:使用Terraform建立ACK專有叢集

更新時間:Dec 30, 2025

本文介紹如何使用Terraform建立ACK專有叢集

說明

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

重要

ACK專有叢集已限制建立。請提交工單申請開通。

前提條件

  • 已開通Container Service for KubernetesACK。若需要使用Terraform開通,請參見通過Terraform開通ACK並授權角色

  • 由於阿里雲帳號(主帳號)具有資源的所有許可權,一旦發生泄露將面臨重大風險。建議您使用RAM使用者,並為該RAM使用者建立AccessKey,具體操作方式請參見建立RAM使用者建立AccessKey

  • 為運行Terraform命令的RAM使用者綁定以下最小權限原則,以擷取管理本樣本所涉及資源的許可權。更多資訊,請參見管理RAM使用者的許可權

    該權限原則允許RAM使用者進行VPC、交換器及ACK的建立、查看與刪除操作。

    {
      "Version": "1",
      "Statement": [
        {
          "Effect": "Allow",
          "Action": [
            "vpc:CreateVpc",
            "vpc:CreateVSwitch",
            "vpc:DescribeRouteTableList",
            "vpc:DescribeVpcAttribute",
            "vpc:ListEnhancedNatGatewayAvailableZones",
            "vpc:DescribeVSwitchAttributes",
            "vpc:DescribeNatGateways",
            "cs:CreateCluster",
            "cs:DescribeTaskInfo",
            "cs:DescribeClusterDetail",
            "cs:DescribeClusterCerts",
            "cs:CheckControlPlaneLogEnable",
            "vpc:DeleteVpc",
            "vpc:DeleteVSwitch",
            "cs:DeleteCluster"
          ],
          "Resource": "*"
        }
      ]
    }
  • 準備Terraform運行環境,您可以選擇以下任一方式來使用Terraform。

    • 在Terraform Explorer中使用Terraform:阿里雲提供了Terraform的線上運行環境,您無需安裝Terraform,登入後即可線上使用和體驗Terraform。適用於零成本、快速、便捷地體驗和調試Terraform的情境。

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

    • 在Resource Orchestration Service(ROS)中使用Terraform:Resource Orchestration Service服務(ROS)為Terraform提供了託管的能力,您可以建立Terraform類型的模板,定義阿里雲、AWS或Azure資源,配置資源參數和資源間的依賴關係。

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

    重要

    請確保版本不低於v0.12.28。如需檢查現有版本,請運行terraform --version命令。

使用的資源

說明

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

通過控制台產生Terraform請求參數

如果由於請求參數組合不正確或以下樣本中沒有您需要的配置,您可以通過控制台產生建立叢集所需的請求參數組合。具體操作如下:

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

  2. 叢集列表頁面,單擊叢集模板

  3. 在對話方塊,選擇需要建立的叢集類型,並單擊建立,然後在叢集配置頁面配置叢集資訊。

  4. 配置完成後,在確認配置頁面,單擊右上方的同等代碼

  5. 在側邊欄中單擊Terraform頁簽,將展示您建立叢集時所需的參數組合,您可以複製使用。

使用Terraform建立ACK專有叢集(Terway)

以建立一個使用Terway網路組件的ACK專有叢集為例。

  1. 建立一個工作目錄,並在該工作目錄中建立名為main.tf的設定檔,然後將以下代碼複製到main.tf中。

    provider "alicloud" {
      region = var.region_id
    }
    
    variable "region_id" {
      type    = string
      default = "cn-hangzhou"
    }
    
    variable "zone_ids" {
      type    = list(string)
      default = ["cn-hangzhou-i","cn-hangzhou-j","cn-hangzhou-k"]
    }
    
    # 定義資源的名稱或標籤。
    variable "name" {      
      default = "tf-example"
    }
    
    # 指定現有的vpc_id。如果為空白,則表示建立一個新的VPC。
    variable "vpc_id" {    
      description = "Existing vpc id used to create several vswitches and other resources."
      default     = ""
    }
    
    # 當沒有指定vpc_id時,定義了新VPC的CIDR地址,即IP位址範圍。
    variable "vpc_cidr" {  
      description = "The cidr block used to launch a new vpc when 'vpc_id' is not specified."
      default     = "10.0.0.0/8"
    }
    
    # 指定現有的vSwitch(虛擬交換器)ID。
    variable "vswitch_ids" { 
      description = "List of existing vswitch id."
      type        = list(string)
      default     = []
    }
    
    # 當沒有指定vswitch_ids時,建立新的vSwitch,需要填寫三個且不重疊的CIDR地址塊。
    variable "vswitch_cidrs" { 
      description = "List of cidr blocks used to create several new vswitches when 'vswitch_ids' is not specified."
      type        = list(string)
      default     = ["10.1.0.0/16", "10.2.0.0/16", "10.3.0.0/16"]
    }
    
    # 指定網路組件Terway配置。
    variable "terway_vswitch_ids" {  
      description = "List of existing vswitch ids for terway."
      type        = list(string)
      default     = []
    }
    
    # 當沒有指定terway_vswitch_ids時,用於建立Terway使用的vSwitch的CIDR地址塊。
    variable "terway_vswitch_cidrs" { 
      description = "List of cidr blocks used to create several new vswitches when 'terway_vswitch_cidrs' is not specified."
      type        = list(string)
      default     = ["10.4.0.0/16", "10.5.0.0/16", "10.6.0.0/16"]
    }
    
    # 指定ACK叢集安裝的組件。聲明每個組件的名稱和對應配置。
    variable "cluster_addons" { 
      type = list(object({
        name   = string
        config = string
      }))
    
      default = [
        {
          "name"   = "terway-eniip",
          "config" = "",
        },
        {
          "name"   = "csi-plugin",
          "config" = "",
        },
        {
          "name"   = "csi-provisioner",
          "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\":\"\"}",
        }
      ]
    }
    
    locals {
      all_zone_ids = [for zones in data.alicloud_enhanced_nat_available_zones.enhanced.zones : zones.zone_id]
      common_zone_ids = setintersection(toset(var.zone_ids),toset(local.all_zone_ids))
       
      # 擷取每個可用性區域支援的執行個體類型
      instance_types_per_az = { for az, types in data.alicloud_instance_types.default : az => [for t in types.instance_types : t.id] }
    
      # 擷取所有列出的可用性區域中的執行個體類型列表
      all_instance_types_in_zones = [for zone in local.common_zone_ids : local.instance_types_per_az[zone]]
    
      # 將每個列錶轉換成集合
      sets = [for s in local.all_instance_types_in_zones : toset(s)]
      
      # 計算所有可用性區域間共有的執行個體類型
      common_instance_types = [for element in local.sets[0]: element if length([for set in local.sets: set if contains(set, element)]) == length(local.sets)]
    }
    
    # 查詢用於擷取支援增強型網關NAT的地區。
    data "alicloud_enhanced_nat_available_zones" "enhanced" {
    } 
    
    # 當沒有提供vpc_id變數時,這個資源將建立一個新的專用網路,其CIDR塊由vpc_cidr變數指定。
    resource "alicloud_vpc" "vpc" {  
      count      = var.vpc_id == "" ? 1 : 0
      cidr_block = var.vpc_cidr
    }
    
    # 當沒有提供vswitch_ids變數時,預設會根據填寫的vswitch_cidrs建立新的vSwitch。
    resource "alicloud_vswitch" "vswitches" { 
      count      = length(var.vswitch_ids) > 0 ? 0 : length(var.vswitch_cidrs)
      vpc_id     = var.vpc_id == "" ? join("", alicloud_vpc.vpc.*.id) : var.vpc_id
      cidr_block = element(var.vswitch_cidrs, count.index)
      zone_id    = tolist(local.common_zone_ids)[count.index]
    }
    
    # 當沒有提供terway_vswitch_ids變數時,預設會根據填寫的vswitch_cidrs建立Terway使用的vSwitch。
    resource "alicloud_vswitch" "terway_vswitches" { 
      count      = length(var.terway_vswitch_ids) > 0 ? 0 : length(var.terway_vswitch_cidrs)
      vpc_id     = var.vpc_id == "" ? join("", alicloud_vpc.vpc.*.id) : var.vpc_id
      cidr_block = element(var.terway_vswitch_cidrs, count.index)
      zone_id    = tolist(local.common_zone_ids)[count.index]
    }
    
    # 查詢當前阿里雲使用者的資源群組。
    data "alicloud_resource_manager_resource_groups" "default" { 
      status = "OK"
    }
    
    # 查詢阿里雲的ECS執行個體類型。
    data "alicloud_instance_types" "default" {
      for_each            = toset(local.common_zone_ids )
      availability_zone   = each.key
      cpu_core_count      = 8
      memory_size         = 16
      kubernetes_node_role = "Master"
      system_disk_category = "cloud_essd"
    }
    
     # 建立ACK專有叢集,配置包括控制面虛擬交換器、Pod虛擬交換器、執行個體類型、磁碟、密碼、Service網路位址區段等。
    resource "alicloud_cs_kubernetes" "default" { 
      master_vswitch_ids    = length(var.vswitch_ids) > 0 ? split(",", join(",", var.vswitch_ids)) : length(var.vswitch_cidrs) < 1 ? [] : split(",", join(",", alicloud_vswitch.vswitches.*.id)) # 查詢支援增強型NAT的可用性區域列表。
      pod_vswitch_ids       = length(var.terway_vswitch_ids) > 0 ? split(",", join(",", var.terway_vswitch_ids)) : length(var.terway_vswitch_cidrs) < 1 ? [] : split(",", join(",", alicloud_vswitch.terway_vswitches.*.id)) # 使用Terway時pod網路的vswitch位址區段。
      master_instance_types = [local.common_instance_types[0],local.common_instance_types[0],local.common_instance_types[0]] # 控制面節點的執行個體類型。
      master_disk_category  = "cloud_essd"            # 控制面節點系統硬碟類型。
      password              = "Yourpassword1234"     # SSH登入密碼。
      service_cidr          = "172.18.0.0/16"        # Service網路位址區段。
      load_balancer_spec    = "slb.s1.small"         # 負載平衡規格。
      install_cloud_monitor = "true"                 # 安裝CloudMonitor服務。
      resource_group_id     = data.alicloud_resource_manager_resource_groups.default.groups.0.id # 叢集所屬資源群組ID,實現不同資源的隔離。
      deletion_protection   = "false"                # 叢集刪除保護,防止通過控制台或API誤刪除叢集。
      timezone              = "Asia/Shanghai"        # 叢集使用的時區。
      os_type               = "Linux"                # 作業系統平台類型。
      platform              = "AliyunLinux3"         # 作業系統發行版。
      cluster_domain        = "cluster.local"        # 叢集本地區名。
      proxy_mode            = "ipvs"                 # kube-proxy代理模式。
      custom_san            = "www.terraform.io"     # 自訂認證SAN。
      new_nat_gateway       = "true"                 # 建立一個新的NAT Gateway。
      dynamic "addons" {
        for_each = var.cluster_addons
        content {
          name   = lookup(addons.value, "name", var.cluster_addons)
          config = lookup(addons.value, "config", var.cluster_addons)
        }
      }
    }
  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 plan

    返回以下資訊,表示資源執行計畫已成功產生,您可以查看相關資源資訊。

    Refreshing Terraform state in-memory prior to plan...
    The refreshed state will be used to calculate this plan, but will not be
    persisted to local or remote state storage.
    ...
    Plan: 8 to add, 0 to change, 0 to destroy.
    ...
  4. 執行以下命令,建立ACK專有叢集

    terraform apply

    在執行過程中,根據提示輸入yes並按下Enter鍵,等待命令執行完成,若出現以下資訊,則表示建立ACK專有叢集成功。

    ...
    Do you want to perform these actions?
      Terraform will perform the actions described above.
      Only 'yes' will be accepted to approve.
    
      Enter a value: yes
    ...
    alicloud_cs_managed_kubernetes.default: Creation complete after 8m26s [id=************]
    
    Apply complete! Resources: 8 added, 0 changed, 0 destroyed.
  5. 驗證結果

    執行terraform show命令

    您可以使用以下命令查詢Terraform已建立的資來源詳細資料。

    terraform show

    登入ACK控制台

    登入Container Service管理主控台,查看已建立的叢集。

資源清理

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

重要

執行terraform destroy命令將會銷毀上述所有已建立的資源,請謹慎操作。

terraform destroy

在資源清理過程中,根據提示輸入yes並按下Enter鍵,等待命令執行完成,若出現以下資訊,則表示ACK專有叢集刪除成功。

...
Do you really want to destroy all resources?
  Terraform will destroy all your managed infrastructure, as shown above.
  There is no undo. Only 'yes' will be accepted to confirm.

  Enter a value: yes
...
Destroy complete! Resources: 7 destroyed.

完整樣本

說明

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

provider "alicloud" {
  region = var.region_id
}

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

variable "zone_ids" {
  type    = list(string)
  default = ["cn-hangzhou-i","cn-hangzhou-j","cn-hangzhou-k"]
}

# 定義資源的名稱或標籤。
variable "name" {      
  default = "tf-example"
}

# 指定現有的vpc_id。如果為空白,則表示建立一個新的VPC。
variable "vpc_id" {    
  description = "Existing vpc id used to create several vswitches and other resources."
  default     = ""
}

# 當沒有指定vpc_id時,定義了新VPC的CIDR地址,即IP位址範圍。
variable "vpc_cidr" {  
  description = "The cidr block used to launch a new vpc when 'vpc_id' is not specified."
  default     = "10.0.0.0/8"
}

# 指定現有的vSwitch(虛擬交換器)ID。
variable "vswitch_ids" { 
  description = "List of existing vswitch id."
  type        = list(string)
  default     = []
}

# 當沒有指定vswitch_ids時,建立新的vSwitch,需要填寫三個且不重疊的CIDR地址塊。
variable "vswitch_cidrs" { 
  description = "List of cidr blocks used to create several new vswitches when 'vswitch_ids' is not specified."
  type        = list(string)
  default     = ["10.1.0.0/16", "10.2.0.0/16", "10.3.0.0/16"]
}

# 指定網路組件Terway配置。
variable "terway_vswitch_ids" {  
  description = "List of existing vswitch ids for terway."
  type        = list(string)
  default     = []
}

# 當沒有指定terway_vswitch_ids時,用於建立Terway使用的vSwitch的CIDR地址塊。
variable "terway_vswitch_cidrs" { 
  description = "List of cidr blocks used to create several new vswitches when 'terway_vswitch_cidrs' is not specified."
  type        = list(string)
  default     = ["10.4.0.0/16", "10.5.0.0/16", "10.6.0.0/16"]
}

# 指定ACK叢集安裝的組件。聲明每個組件的名稱和對應配置。
variable "cluster_addons" { 
  type = list(object({
    name   = string
    config = string
  }))

  default = [
    {
      "name"   = "terway-eniip",
      "config" = "",
    },
    {
      "name"   = "csi-plugin",
      "config" = "",
    },
    {
      "name"   = "csi-provisioner",
      "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\":\"\"}",
    }
  ]
}

locals {
  all_zone_ids = [for zones in data.alicloud_enhanced_nat_available_zones.enhanced.zones : zones.zone_id]
  common_zone_ids = setintersection(toset(var.zone_ids),toset(local.all_zone_ids))
   
  # 擷取每個可用性區域支援的執行個體類型
  instance_types_per_az = { for az, types in data.alicloud_instance_types.default : az => [for t in types.instance_types : t.id] }

  # 擷取所有列出的可用性區域中的執行個體類型列表
  all_instance_types_in_zones = [for zone in local.common_zone_ids : local.instance_types_per_az[zone]]

  # 將每個列錶轉換成集合
  sets = [for s in local.all_instance_types_in_zones : toset(s)]
  
  # 計算所有可用性區域間共有的執行個體類型
  common_instance_types = [for element in local.sets[0]: element if length([for set in local.sets: set if contains(set, element)]) == length(local.sets)]
}

# 查詢用於擷取支援增強型網關NAT的地區。
data "alicloud_enhanced_nat_available_zones" "enhanced" {
} 

# 當沒有提供vpc_id變數時,這個資源將建立一個新的專用網路,其CIDR塊由vpc_cidr變數指定。
resource "alicloud_vpc" "vpc" {  
  count      = var.vpc_id == "" ? 1 : 0
  cidr_block = var.vpc_cidr
}

# 當沒有提供vswitch_ids變數時,預設會根據填寫的vswitch_cidrs建立新的vSwitch。
resource "alicloud_vswitch" "vswitches" { 
  count      = length(var.vswitch_ids) > 0 ? 0 : length(var.vswitch_cidrs)
  vpc_id     = var.vpc_id == "" ? join("", alicloud_vpc.vpc.*.id) : var.vpc_id
  cidr_block = element(var.vswitch_cidrs, count.index)
  zone_id    = tolist(local.common_zone_ids)[count.index]
}

# 當沒有提供terway_vswitch_ids變數時,預設會根據填寫的vswitch_cidrs建立Terway使用的vSwitch。
resource "alicloud_vswitch" "terway_vswitches" { 
  count      = length(var.terway_vswitch_ids) > 0 ? 0 : length(var.terway_vswitch_cidrs)
  vpc_id     = var.vpc_id == "" ? join("", alicloud_vpc.vpc.*.id) : var.vpc_id
  cidr_block = element(var.terway_vswitch_cidrs, count.index)
  zone_id    = tolist(local.common_zone_ids)[count.index]
}

# 查詢當前阿里雲使用者的資源群組。
data "alicloud_resource_manager_resource_groups" "default" { 
  status = "OK"
}

# 查詢阿里雲的ECS執行個體類型。
data "alicloud_instance_types" "default" {
  for_each            = toset(local.common_zone_ids )
  availability_zone   = each.key
  cpu_core_count      = 8
  memory_size         = 16
  kubernetes_node_role = "Master"
  system_disk_category = "cloud_essd"
}

 # 建立ACK專有叢集,配置包括控制面虛擬交換器、Pod虛擬交換器、執行個體類型、磁碟、密碼、Service網路位址區段等。
resource "alicloud_cs_kubernetes" "default" { 
  master_vswitch_ids    = length(var.vswitch_ids) > 0 ? split(",", join(",", var.vswitch_ids)) : length(var.vswitch_cidrs) < 1 ? [] : split(",", join(",", alicloud_vswitch.vswitches.*.id)) # 查詢支援增強型NAT的可用性區域列表。
  pod_vswitch_ids       = length(var.terway_vswitch_ids) > 0 ? split(",", join(",", var.terway_vswitch_ids)) : length(var.terway_vswitch_cidrs) < 1 ? [] : split(",", join(",", alicloud_vswitch.terway_vswitches.*.id)) # 使用Terway時pod網路的vswitch位址區段。
  master_instance_types = [local.common_instance_types[0],local.common_instance_types[0],local.common_instance_types[0]] # 控制面節點的執行個體類型。
  master_disk_category  = "cloud_essd"            # 控制面節點系統硬碟類型。
  password              = "Yourpassword1234"     # SSH登入密碼。
  service_cidr          = "172.18.0.0/16"        # Service網路位址區段。
  load_balancer_spec    = "slb.s1.small"         # 負載平衡規格。
  install_cloud_monitor = "true"                 # 安裝CloudMonitor服務。
  resource_group_id     = data.alicloud_resource_manager_resource_groups.default.groups.0.id # 叢集所屬資源群組ID,實現不同資源的隔離。
  deletion_protection   = "false"                # 叢集刪除保護,防止通過控制台或API誤刪除叢集。
  timezone              = "Asia/Shanghai"        # 叢集使用的時區。
  os_type               = "Linux"                # 作業系統平台類型。
  platform              = "AliyunLinux3"         # 作業系統發行版。
  cluster_domain        = "cluster.local"        # 叢集本地區名。
  proxy_mode            = "ipvs"                 # kube-proxy代理模式。
  custom_san            = "www.terraform.io"     # 自訂認證SAN。
  new_nat_gateway       = "true"                 # 建立一個新的NAT Gateway。
  dynamic "addons" {
    for_each = var.cluster_addons
    content {
      name   = lookup(addons.value, "name", var.cluster_addons)
      config = lookup(addons.value, "config", var.cluster_addons)
    }
  }
}

相關文檔