文档

使用Terraform创建ACK托管版集群

更新时间:

本文介绍如何使用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"         # 替换为您集群所在的地域。
  • 已开通容器服务 Kubernetes 版ACK。若需要使用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网关。默认为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的节点安装云监控。
      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的节点安装云监控。
      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.