全部產品
Search
文件中心

Container Service for Kubernetes:使用Terraform為節點池指定部署集

更新時間:Dec 04, 2024

部署集是控制ECS執行個體分布的策略,該策略將ECS執行個體分散部署在不同的物理伺服器上,提升業務的高可用性和底層容災能力。通過為節點池指定部署集,能夠保證節點池彈出的ECS執行個體不會分佈於同一物理機上,並通過親和性配置,使您的應用對底層的節點拓撲進行感知,使其均勻地分布在不同節點上,保證應用的容災能力和高可用性。本文介紹如何通過Terraform為節點池指定部署集。

說明

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

前提條件

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

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

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

    說明

    請確認Terraform版本不低於v0.12.28,可通過terraform --version命令查看Terraform版本。

  • 請確保部署集內ECS執行個體配額充足,預設為20台;所需機型庫存充足。具體資訊,請參見查看和提升資源配額

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

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

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

    {
        "Version": "1",
        "Statement": [
            {
                "Effect": "Allow",
                "Action": [
                    "vpc:CreateVpc",
                    "vpc:CreateVSwitch",
                    "cs:CreateCluster",
                    "vpc:DescribeVpcAttribute",
                    "vpc:DescribeVSwitchAttributes",
                    "vpc:DescribeRouteTableList",
                    "vpc:DescribeNatGateways",
                    "cs:DescribeTaskInfo",
                    "cs:DescribeClusterDetail",
                    "cs:GetClusterCerts",
                    "cs:CheckControlPlaneLogEnable",
                    "cs:CreateClusterNodePool",
                    "cs:DescribeClusterNodePoolDetail",
                    "cs:ModifyClusterNodePool",
                    "vpc:DeleteVpc",
                    "vpc:DeleteVSwitch",
                    "cs:DeleteCluster",
                    "cs:DeleteClusterNodepool",
                    "ecs:CreateDeploymentSet",
                    "ecs:DescribeDeploymentSets",
                    "ecs:ModifyDeploymentSetAttribute",
                    "ecs:DeleteDeploymentSet"
                ],
                "Resource": "*"
            }
        ]
    }

背景資訊

在同一個可用性區域下,為了保證高可用性,您通常會選擇跨主機部署服務。但當一台物理機出現問題時,會影響到應用的所有副本。為瞭解決這個問題,ECS提供了部署集功能。部署集內的所有ECS執行個體會在指定地區內嚴格分散在不同的物理伺服器上,滿足服務相互隔離的應用架構,大幅降低服務停用幾率。關於部署集的更多資訊,請參見部署集

使用限制

叢集中功能使用須知

  • 部署集僅支援ACK專有叢集ACK託管叢集

  • 部署集僅在建立節點池時支援指定,不支援為已有節點池開啟。每個節點池僅支援綁定一個部署集,且不支援更換。

  • 部署集不支援手動添加或移除節點。您可以通過擴縮容節點池的操作,調整部署集中的節點數。具體操作,請參見建立節點池

  • 開啟部署集功能後,不支援建立搶佔式執行個體。

部署集配額與規格限制

  • 節點池部署集預設基於高可用策略實現。高可用策略下,在部署集內建立ECS執行個體時,一個可用性區域內最多能建立20台ECS執行個體,一個阿里雲地區下能建立的ECS執行個體數量為20*可用性區域數量。更多資訊,請參見部署集

    一個部署集內能容納的執行個體數量不支援提升。但如果您需要提高當前賬戶可擁有的部署集最大數量,請前往配額平台申請。關於部署集使用限制及配額的更多資訊,請參見部署集使用限制

  • 支援的執行個體規格類型系列限制

    不同部署策略僅支援建立特定的執行個體規格類型系列,具體資訊如下。

    說明

    您也可以調DescribeDeploymentSetSupportedInstanceTypeFamily指定部署集策略來擷取各部署集策略支援的執行個體規格類型系列。

    部署策略

    支援的執行個體規格類型系列

    高可用策略和部署集組高可用策略

    • g8a、g8i、g8y、g7se、g7a、g7、g7h、g7t、g7ne、g7nex、g6、g6e、g6a、g5、g5ne、sn2ne、sn2、sn1

    • c8a、c8i、c8y、c7se、c7、c7t、c7nex、c7a、c6、c6a、c6e、c5、ic5、sn1ne

    • r8a、r8i、r8y、r7、r7se、r7t、r7a、r6、r6e、r6a、re6、re6p、r5、re4、se1ne、se1

    • hfc8i、hfg8i、hfr8i、hfc7、hfg7、hfr7、hfc6、hfg6、hfr6、hfc5、hfg5

    • d3c、d2s、d2c、d1、d1ne、d1-c14d3、d1-c8d3

    • i3g、i3、i2、i2g、i2ne、i2gne、i1

    • ebmg5、ebmc7、ebmg7、ebmr7、sccgn6、scch5、scch5s、sccg5、sccg5s

    • e、t6、xn4、mn4、n4、e4、n2、n1、

    • gn6i

    網路低時延策略

    • g8a、g8i、g8ae、g8y

    • c8a、c8i、c8ae、c8y

    • ebmc8i、ebmg8i、ebmr8i

    • r8a、r8i、r8ae、r8y

    • ebmc7、ebmg7、ebmr7

  • 在部署集內建立ECS執行個體失敗,或重啟隨用隨付ECS執行個體(節省停機模式)失敗,可能是因為地區內執行個體資產庫存不足,您可以等待一段時間後重試建立執行個體或重啟執行個體。

使用的資源

說明

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

通過Terraform建立指定部署集的節點池

  1. 使用以下樣本內容,建立指定部署集的節點池。

    provider "alicloud" {
      region = var.region_id
    }
    
    variable "region_id" {
      type    = string
      default = "cn-shenzhen"
    }
    
    variable "name" {
      default = "tf-example"
    }
    
    variable "strategy" {
      default     = "Availability"
      description = "The deployment strategy. Valid values: Availability, AvailabilityGroup, LowLatency."
    }
    
    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叢集安裝的組件。包括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" = "",
        }
      ]
    }
    
    # 指定建立ACK託管叢集名稱的首碼。
    variable "k8s_name_prefix" {
      description = "The name prefix used to create managed kubernetes cluster."
      default     = "tf-ack"
    }
    
    variable "vpc_name" {
      default = "tf-vpc"
    }
    variable "nodepool_name" {
      default = "default-nodepool"
    }
    
    # 預設資源名稱。
    locals {
      k8s_name_terway = substr(join("-", [var.k8s_name_prefix, "terway"]), 0, 63)
    }
    
    # 專用網路。
    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)
    }
    
    # 建立部署集
    resource "alicloud_ecs_deployment_set" "default" {
      strategy            = var.strategy
      domain              = "Default"
      granularity         = "Host"
      deployment_set_name = var.name
      description         = "example_value"
    }
    
    # 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)
        }
      }
    }
    
    # 普通節點池。
    resource "alicloud_cs_kubernetes_node_pool" "default" {
      cluster_id            = alicloud_cs_managed_kubernetes.default.id              # Kubernetes叢集名稱。
      node_pool_name        = var.nodepool_name                                      # 節點池名稱。
      vswitch_ids           = split(",", join(",", alicloud_vswitch.vswitches.*.id)) # 節點池所在的vSwitch。指定一個或多個vSwitch的ID,必須在availability_zone指定的地區中。
      instance_types        = var.worker_instance_types
      instance_charge_type  = "PostPaid"
      runtime_name          = "containerd"
      runtime_version       = "1.6.20"
      desired_size          = 2            # 節點池的期望節點數。
      password              = var.password # SSH登入叢集節點的密碼。
      install_cloud_monitor = true         # 是否為Kubernetes的節點安裝CloudMonitor。
      system_disk_category  = "cloud_essd"
      system_disk_size      = 100
      image_type            = "AliyunLinux"
      deployment_set_id     = alicloud_ecs_deployment_set.default.id
    
      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 

    返回資訊如下,部署集指定成功

    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
    
    ...
    
    Apply complete! Resources: 10 added, 0 changed, 0 destroyed.
  4. 驗證結果

    執行terraform show命令

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

    terraform show

    image

    登入ACK控制台

    您可以在Container Service管理主控台節點池頁面查看到建立的節點池。單擊操作列的編輯,可以查看到指定的部署集。image

清理資源

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

terraform destroy

完整樣本

說明

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

provider "alicloud" {
  region = var.region_id
}

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

variable "name" {
  default = "tf-example"
}

variable "strategy" {
  default     = "Availability"
  description = "The deployment strategy. Valid values: Availability, AvailabilityGroup, LowLatency."
}

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叢集安裝的組件。包括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" = "",
    }
  ]
}

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

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

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

# 專用網路。
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)
}

# 建立部署集
resource "alicloud_ecs_deployment_set" "default" {
  strategy            = var.strategy
  domain              = "Default"
  granularity         = "Host"
  deployment_set_name = var.name
  description         = "example_value"
}

# 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)
    }
  }
}

# 普通節點池。
resource "alicloud_cs_kubernetes_node_pool" "default" {
  cluster_id            = alicloud_cs_managed_kubernetes.default.id              # Kubernetes叢集名稱。
  node_pool_name        = var.nodepool_name                                      # 節點池名稱。
  vswitch_ids           = split(",", join(",", alicloud_vswitch.vswitches.*.id)) # 節點池所在的vSwitch。指定一個或多個vSwitch的ID,必須在availability_zone指定的地區中。
  instance_types        = var.worker_instance_types
  instance_charge_type  = "PostPaid"
  runtime_name          = "containerd"
  runtime_version       = "1.6.20"
  desired_size          = 2            # 節點池的期望節點數。
  password              = var.password # SSH登入叢集節點的密碼。
  install_cloud_monitor = true         # 是否為Kubernetes的節點安裝CloudMonitor。
  system_disk_category  = "cloud_essd"
  system_disk_size      = 100
  image_type            = "AliyunLinux"
  deployment_set_id     = alicloud_ecs_deployment_set.default.id

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

相關文檔