全部產品
Search
文件中心

Container Service for Kubernetes:使用Terraform建立ACK託管版叢集

更新時間:Aug 30, 2024

本文介紹如何使用Terraform建立ACK託管叢集

前提條件

  • 已安裝Terraform

    說明

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

    安裝配置方式如下:

  • 配置阿里雲帳號資訊。

    執行如下命令,建立環境變數,用於存放身份認證資訊。

    阿里雲帳號(主帳號)對帳號中的資源具有完全系統管理權限,一旦泄露風險極大。推薦您建立一個名為Terraform的RAM使用者,並為該RAM使用者建立AccessKey和授權。具體操作,請參見建立RAM使用者為RAM使用者授權

    Linux環境

    export ALICLOUD_ACCESS_KEY="************"   # 替換為阿里雲帳號的AK資訊。
    export ALICLOUD_SECRET_KEY="************"   # 替換為阿里雲帳號的SK資訊。
    export ALICLOUD_REGION="cn-beijing"         # 替換為您叢集所在的地區。

    Windows環境

    set ALICLOUD_ACCESS_KEY="************"   # 替換為阿里雲帳號的AK資訊。
    set ALICLOUD_SECRET_KEY="************"   # 替換為阿里雲帳號的SK資訊。
    set ALICLOUD_REGION="cn-beijing"         # 替換為您叢集所在的地區。
  • 已開通Container Service for KubernetesACK。若需要使用Terraform開通,請參見首次開通ACK並授權角色

  • 建立工作目錄,並且在工作目錄中建立variable.tf設定檔。

    在Terraform中,variable.tf可以定義輸入變數,用於參數化資源,以便在不同配置中重複使用。這些變數隨後將在main.tf檔案中用於具體的資源配置。

    建立1個新的VPC,並建立3個該VPC下的vSwitch、3個Pod vSwitch。

    在建立ACK託管叢集時,預設安裝的組件包括:Terway(網路組件)、csi-plugin(儲存群組件)、csi-provisioner(儲存群組件)、logtail-ds(日誌組件)、Nginx Ingress Controller、ack-arms-prometheus(監控組件)、ack-node-problem-detector(節點診斷組件)。

    展開查看本文用到的variable.tf檔案

    variable "availability_zone" {  # 指定虛擬交換器(vSwitches)的可用性區域。
      description = "The availability zones of vswitches."
      # 請跟下文main.tf設定檔中的地區保持一致。
      default     = ["cn-shenzhen-c", "cn-shenzhen-e", "cn-shenzhen-f"]
    } 
    
    variable "node_vswitch_ids" { # 指定交換器ID(vSwitch IDs)的列表。
      description = "List of existing node vswitch ids for terway."
      type        = list(string)
      default     = []
    }
    
    variable "node_vswitch_cidrs" { # 當沒有提供node_vswitch_ids時,這個變數定義了用於建立新vSwitches的CIDR地址塊列表。
      description = "List of cidr blocks used to create several new vswitches when 'node_vswitch_ids' is not specified."
      type        = list(string)
      default     = ["172.16.0.0/23", "172.16.2.0/23", "172.16.4.0/23"]
    }
    
    variable "terway_vswitch_ids" { # 指定網路組件Terway配置。如果為空白,預設會根據terway_vswitch_cidrs的建立新的terway vSwitch。
      description = "List of existing pod vswitch ids for terway."
      type        = list(string)
      default     = []
    }
    
    variable "terway_vswitch_cidrs" {  # 當沒有指定terway_vswitch_ids時,用於建立Terway使用的vSwitch的CIDR地址塊。
      description = "List of cidr blocks used to create several new vswitches when 'terway_vswitch_ids' is not specified."
      type        = list(string)
      default     = ["172.16.208.0/20", "172.16.224.0/20", "172.16.240.0/20"]
    }
    
    # Node Pool worker_instance_types
    variable "worker_instance_types" { # 定義了用於啟動工作節點的ECS執行個體類型。
      description = "The ecs instance types used to launch worker nodes."
      default     = ["ecs.g6.2xlarge", "ecs.g6.xlarge"]
    }
    
    # Password for Worker nodes
    variable "password" {
      description = "The password of ECS instance."
      default     = "Test123456"
    }
    
    # Cluster Addons
    variable "cluster_addons" {    # 指定ACK叢集安裝的組件。聲明每個組件的名稱和對應配置。
      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" = "",
        }
      ]
    }
    說明

    variable.tf配置中的地區請與下文main.tf設定檔保持一致。

使用Terraform建立ACK託管叢集(Terway)

  1. 前提條件中建立的工作目錄中建立名為main.tf的設定檔。

    說明

    main.tf用來在阿里雲上建立和配置ACK叢集資源。執行建立過程中,main.tf檔案會引用variables.tf檔案中聲明的變數。

    main.tf設定檔描述了以下的Terraform配置:

    • 建立1個新的VPC,並建立3個該VPC下的vSwitch、3個PodVSwitch。

    • 建立1個ACK託管叢集

    • 建立1個包含2個節點的託管節點池。

    • 建立1個託管節點池。

    展開查看main.tf檔案

    provider "alicloud" {
      region = "cn-shenzhen"
      #請與variable.tf 設定檔中得地區保持一致。
    }
    
    variable "k8s_name_prefix" {   # 指定建立ACK託管叢集名稱的首碼。
      description = "The name prefix used to create managed kubernetes cluster."
      default     = "tf-ack-shenzhen"
    }
    
    resource "random_uuid" "this" {}
    # 預設資源名稱。
    locals {
      k8s_name_terway         = substr(join("-", [var.k8s_name_prefix, "terway"]), 0, 63)
      k8s_name_flannel        = substr(join("-", [var.k8s_name_prefix, "flannel"]), 0, 63)
      k8s_name_ask            = substr(join("-", [var.k8s_name_prefix, "ask"]), 0, 63)
      new_vpc_name            = "tf-vpc-172-16"
      new_vsw_name_azD        = "tf-vswitch-azD-172-16-0"
      new_vsw_name_azE        = "tf-vswitch-azE-172-16-2"
      new_vsw_name_azF        = "tf-vswitch-azF-172-16-4"
      nodepool_name           = "default-nodepool"
      managed_nodepool_name   = "managed-node-pool"
      autoscale_nodepool_name = "autoscale-node-pool"
      log_project_name        = "log-for-${local.k8s_name_terway}"
    }
    # 節點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"
    }
    # 滿足執行個體規格的AZ。
    data "alicloud_zones" "default" {
      available_instance_type = data.alicloud_instance_types.default.instance_types[0].id
    }
    # 專用網路。
    resource "alicloud_vpc" "default" {
      vpc_name   = local.new_vpc_name
      cidr_block = "172.16.0.0/12"
    }
    # Node交換器。
    resource "alicloud_vswitch" "vswitches" {
      count      = length(var.node_vswitch_ids) > 0 ? 0 : 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_ids) > 0 ? 0 : 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       = "ack.pro.small"           # 建立Pro版叢集。
      version            = "1.28.9-aliyun.1"
      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 = local.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_efficiency"
      system_disk_size     = 100
      image_type = "AliyunLinux"
    
      data_disks {     # 節點資料盤配置。
        category = "cloud_essd"   # 節點資料盤種類。
        size = 120      # 節點資料盤大小。
      }
    }
    
    resource "alicloud_cs_kubernetes_node_pool" "managed_node_pool" {      # 託管節點池。
      cluster_id = alicloud_cs_managed_kubernetes.default.id              # Kubernetes叢集名稱。
      node_pool_name = local.managed_nodepool_name                         # 節點池名稱。
      vswitch_ids = split(",", join(",", alicloud_vswitch.vswitches.*.id)) # 節點池所在的vSwitch。指定一個或多個vSwitch的ID,必須在availability_zone指定的地區中。
      desired_size = 0         # 節點池的期望節點數。
    
      management {
        auto_repair     = true
        auto_upgrade    = true
        max_unavailable = 1
      }
    
      instance_types       = var.worker_instance_types
      instance_charge_type = "PostPaid"
      runtime_name    = "containerd"
      runtime_version = "1.6.20"
      password = var.password
      install_cloud_monitor = true
      system_disk_category = "cloud_efficiency"
      system_disk_size     = 100
      image_type = "AliyunLinux"
    
      data_disks {
        category = "cloud_essd"
        size = 120
      }
    }
    
    resource "alicloud_cs_kubernetes_node_pool" "autoscale_node_pool" {
      cluster_id = alicloud_cs_managed_kubernetes.default.id
      node_pool_name = local.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                           # 節點資料盤大小。
      }
    }
    

    關於更多的建立ACK託管叢集配置參數資訊,請參見alicloud_cs_managed_kubernetes

  2. 執行以下命令,初始化Terraform運行環境。

    terraform init

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

    Initializing the backend...
    
    Initializing provider plugins...
    - Checking for available provider plugins...
    - Downloading plugin for provider "alicloud" (hashicorp/alicloud) 1.90.1...
    ...
    
    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: 12 to add, 0 to change, 0 to destroy.
    ...
  4. 執行以下命令,建立叢集。

    terraform apply

    返回資訊如下,輸入yes,按Enter鍵,叢集建立成功。

    ...
    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: 12 added, 0 changed, 0 destroyed.