Todos os produtos
Search
Central de documentação

Container Service for Kubernetes:Use Terraform to associate a deployment set with a node pool

Última atualização: Sep 22, 2026

Distribuir as instâncias do pool de nós do Container Service for Kubernetes (ACK) em servidores físicos diferentes melhora a disponibilidade do service e a recuperação de desastres, pois limita o impacto da falha de um único host. Use o Terraform para criar um pool de nós associado a um conjunto de implantação do Elastic Compute Service (ECS) e garantir o isolamento físico dos nós subjacentes do ECS em vários hosts.

Nota

Execute o código de exemplo deste tópico com apenas alguns cliques. Clique em aqui e execute o código de exemplo.

Limitações

Antes de começar, observe as seguintes restrições:

  • Apenas no momento da criação: Associe um conjunto de implantação a um pool de nós apenas durante a criação do pool. Não é possível atualizar pools de nós existentes para usar um conjunto de implantação.

  • Um conjunto de implantação por pool de nós: Cada pool de nós pode ter apenas um conjunto de implantação associado.

  • Sem instâncias spot: Pools de nós associados a um conjunto de implantação não aceitam instâncias spot.

  • Sem gerenciamento manual de instâncias: Adicione ou remova instâncias do ECS em um conjunto de implantação apenas por meio do dimensionamento do pool de nós associado. O sistema não aceita adições e remoções manuais. Para mais informações, consulte Crie e gerencie pools de nós.

  • Cota: Cada conjunto de implantação aceita até 20 instâncias do ECS por zona. O máximo para uma região é 20 × number of zones in the region. Não é possível aumentar esse limite, mas você pode solicitar uma cota maior para o número total de conjuntos de implantação no console do Quota Center.

  • Recursos de instância: A falta de estoque de instâncias em uma zona pode causar falhas na criação ou na inicialização de instâncias do ECS. Se isso ocorrer, aguarde e tente novamente.

Pré-requisitos

Antes de começar, certifique-se de ter:

  • Um ambiente de execução do Terraform configurado com uma das seguintes opções:

    • Terraform Explorer: um ambiente Terraform online fornecido pela Alibaba Cloud. Não requer instalação e é ideal para testes e depuração com baixa sobrecarga.

    • Crie recursos com o Terraform: o Terraform vem pré-instalado e configurado com suas credenciais de identidade, sendo ideal para acesso rápido sem configuração local.

    • Crie um modelo do Terraform: integra modelos do Terraform ao ROS para gerenciar recursos na Alibaba Cloud, na AWS ou no Azure.

    • Instale e configure o Terraform: adequado para ambientes de rede instáveis ou configurações de desenvolvimento personalizadas.

    É obrigatório usar o Terraform 0.12.28 ou posterior. Execute terraform --version para verificar a sua versão.
  • Cota suficiente do ECS no conjunto de implantação e estoque adequado. Especifique os tipos de instância corretos. Por padrão, cada conjunto de implantação pode conter até 20 instâncias do ECS por zona. Para mais informações, consulte Gerencie cotas do ECS.

  • Um Crie um AccessKey para o usuário Crie um usuário do RAM com o qual você faz logon.

    Use um usuário do RAM com permissões limitadas em vez da conta raiz da Alibaba Cloud. Isso reduz o raio de impacto caso as credenciais sejam comprometidas.
  • A seguinte política do RAM anexada ao seu usuário do RAM. Essa política permite que o usuário crie, visualize e exclua redes privadas virtuais (VPCs), vSwitches, conjuntos de implantação e clusters ACK. Para obter detalhes sobre como conceder permissões, consulte Gerencie permissões de usuário do RAM.

    {
        "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": "*"
            }
        ]
    }

Contexto

Um conjunto de implantação é um recurso do ECS que distribui instâncias em diferentes servidores físicos dentro de uma zona. Se um servidor físico ficar inativo, apenas as instâncias nesse servidor serão afetadas, e não todas as instâncias do conjunto de implantação. Ao associar um conjunto de implantação a um pool de nós do ACK, você garante a distribuição dos nós subjacentes do ECS em vários hosts físicos. Em seguida, use regras de afinidade de pods para agendar pods de aplicativos em nós diferentes e garantir o isolamento no nível do host.

Há suporte para conjuntos de implantação em clusters dedicados e gerenciados do ACK.

Para mais informações, consulte Deployment sets.

Estratégias de implantação

Defina a variável strategy na configuração do Terraform para controlar a distribuição das instâncias. Os valores válidos são Availability, AvailabilityGroup e LowLatency. Por padrão, os conjuntos de implantação de pool de nós usam a estratégia de alta disponibilidade (Availability).

Escolha a estratégia adequadamente, pois ela afeta a compatibilidade com as famílias de instâncias do ECS. Para verificar quais famílias de instâncias aceitam uma determinada estratégia, chame a API DescribeDeploymentSetSupportedInstanceTypeFamily .

Compatibilidade de famílias de instâncias

A tabela a seguir lista as famílias de instâncias compatíveis com cada estratégia de implantação.

Estratégia de implantação

Famílias de instâncias compatíveis

Estratégia de alta disponibilidade ou estratégia de grupo de alta disponibilidade

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

Estratégia de baixa latência

g8a, g8i, g8ae, g8y; c8a, c8i, c8ae, c8y; ebmc8i, ebmg8i, ebmr8i; r8a, r8i, r8ae, r8y; ebmc7, ebmg7, ebmr7

Recursos necessários

Os recursos deste exemplo geram cobranças. Libere-os quando não precisar mais deles.

A configuração do Terraform cria os seguintes recursos nesta ordem:

  1. alicloud_vpc — uma VPC para a rede do cluster

  2. alicloud_vswitch (×2 conjuntos) — vSwitches de nós e vSwitches de pods do Terway em cada zona

  3. alicloud_ecs_deployment_set — o conjunto de implantação que aplica o isolamento de host físico

  4. alicloud_cs_managed_kubernetes — um cluster gerenciado do ACK

  5. alicloud_cs_kubernetes_node_pool — um pool de nós que referencia o ID do conjunto de implantação

O campo deployment_set_id do pool de nós o vincula ao conjunto de implantação. Essa é a configuração principal que aciona a distribuição em hosts físicos para todos os nós do pool.

Criar um pool de nós com um conjunto de implantação

  1. Crie o arquivo de configuração do Terraform usando o seguinte modelo:

    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"
    }
    
    # Specify the zones of vSwitches.
    variable "availability_zone" {
      description = "The availability zones of vswitches."
      default     = ["cn-shenzhen-c", "cn-shenzhen-e", "cn-shenzhen-f"]
    }
    
    # The CIDR blocks used to create vSwitches.
    variable "node_vswitch_cidrs" {
      type    = list(string)
      default = ["172.16.0.0/23", "172.16.2.0/23", "172.16.4.0/23"]
    }
    
    # The CIDR blocks used to create Terway vSwitches.
    variable "terway_vswitch_cidrs" {
      type    = list(string)
      default = ["172.16.208.0/20", "172.16.224.0/20", "172.16.240.0/20"]
    }
    
    # Specify the ECS instance types of worker nodes.
    variable "worker_instance_types" {
      description = "The ecs instance types used to launch worker nodes."
      default     = ["ecs.g6.2xlarge", "ecs.g6.xlarge"]
    }
    
    # Specify a password for the worker node.
    variable "password" {
      description = "The password of ECS instance."
      default     = "Test123456"
    }
    
    # Specify the cluster add-on components (Terway, csi-plugin, csi-provisioner, logtail-ds, nginx-ingress-controller, 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" = "",
        }
      ]
    }
    
    # Specify the prefix of the name of the ACK managed cluster.
    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"
    }
    
    # The default resource names.
    locals {
      k8s_name_terway = substr(join("-", [var.k8s_name_prefix, "terway"]), 0, 63)
    }
    
    # The VPC.
    resource "alicloud_vpc" "default" {
      vpc_name   = var.vpc_name
      cidr_block = "172.16.0.0/12"
    }
    
    # The node vSwitches.
    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)
    }
    
    # The pod vSwitches.
    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)
    }
    
    # Create a deployment set.
    resource "alicloud_ecs_deployment_set" "default" {
      strategy            = var.strategy
      domain              = "Default"
      granularity         = "Host"
      deployment_set_name = var.name
      description         = "example_value"
    }
    
    # The ACK managed cluster.
    resource "alicloud_cs_managed_kubernetes" "default" {
      name         = local.k8s_name_terway # The ACK cluster name.
      cluster_spec = var.cluster_spec      # Create an ACK Pro cluster.
      worker_vswitch_ids           = split(",", join(",", alicloud_vswitch.vswitches.*.id))        # The vSwitches used by the node pool. Specify one or more vSwitch IDs. The vSwitches must reside in the zone specified by availability_zone.
      pod_vswitch_ids              = split(",", join(",", alicloud_vswitch.terway_vswitches.*.id)) # The vSwitches used by pods.
      new_nat_gateway              = true                                                          # Specify whether to create a NAT gateway when the ACK cluster is created. Default value: true.
      service_cidr                 = "10.11.0.0/16"                                                # The pod CIDR block. If you set the cluster_network_type parameter to flannel, this parameter is required. The pod CIDR block cannot be the same as the VPC CIDR block or the CIDR blocks of other ACK clusters in the VPC. You cannot change the pod CIDR block after the cluster is created. Maximum number of hosts in the cluster: 256.
      slb_internet_enabled         = true                                                          # Specify whether to create an Internet-facing SLB instance for the API server of the cluster. Default value: false.
      enable_rrsa                  = true
      control_plane_log_components = ["apiserver", "kcm", "scheduler", "ccm"] # The control plane logs.
    
      dynamic "addons" { # Component management.
        for_each = var.cluster_addons
        content {
          name   = lookup(addons.value, "name", var.cluster_addons)
          config = lookup(addons.value, "config", var.cluster_addons)
        }
      }
    }
    
    # The regular node pool.
    # deployment_set_id links this node pool to the deployment set created above.
    # All nodes in this pool are distributed across separate physical hosts, as defined by the strategy.
    # You can associate a deployment set with a node pool only when you create the node pool.
    resource "alicloud_cs_kubernetes_node_pool" "default" {
      cluster_id           = alicloud_cs_managed_kubernetes.default.id              # The ACK cluster name.
      node_pool_name       = var.nodepool_name                                      # The node pool name.
      vswitch_ids          = split(",", join(",", alicloud_vswitch.vswitches.*.id)) # The vSwitches used by the node pool. Specify one or more vSwitch IDs. The vSwitches must reside in the zone specified by availability_zone.
      instance_types       = var.worker_instance_types
      instance_charge_type = "PostPaid"
      runtime_name         = "containerd"
      desired_size          = 2            # The expected number of nodes in the node pool.
      password              = var.password # The password that is used to log on to the cluster by using SSH.
      install_cloud_monitor = true         # Specify whether to install the CloudMonitor agent on the nodes in the cluster.
      system_disk_category  = "cloud_essd"
      system_disk_size      = 100
      image_type            = "AliyunLinux"
      deployment_set_id     = alicloud_ecs_deployment_set.default.id
    
      data_disks {              # The data disk configuration of the node.
        category = "cloud_essd" # The disk category.
        size     = 120          # The disk size.
      }
    }
  2. Inicialize o ambiente de execução do Terraform:

    terraform init

    Uma inicialização bem-sucedida retorna uma saída semelhante à seguinte:

    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. Crie os recursos:

    terraform apply

    Quando solicitado, insira yes e confirme. A execução bem-sucedida retorna uma saída semelhante à seguinte:

    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.

    A mensagem Resources: 10 added confirma o provisionamento de todos os recursos necessários, incluindo a VPC, os vSwitches, o conjunto de implantação, o cluster ACK e o pool de nós.

Verifique o resultado

Verifique com o Terraform

Execute o seguinte comando para inspecionar o estado do Terraform:

terraform show

image

Na saída, localize o recurso alicloud_cs_kubernetes_node_pool.default e confirme se o deployment_set_id corresponde ao ID de alicloud_ecs_deployment_set.default. Isso confirma o vínculo do pool de nós com o conjunto de implantação correto.

Verifique no console do ACK

No console do ACK, acesse a página Node Pools e localize o pool de nós criado. Clique em Edit na coluna Actions e visualize o conjunto de implantação associado.image

Limpar recursos

Quando não precisar mais dos recursos, execute o seguinte comando para liberá-los:

terraform destroy

Para mais informações sobre o comando terraform destroy, consulte Common Terraform commands.

Exemplo

Nota

Execute o código de exemplo deste tópico com apenas alguns cliques. Clique em aqui e execute o código de exemplo.

Código de exemplo

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"
}

# Specify the zones of vSwitches.
variable "availability_zone" {
  description = "The availability zones of vswitches."
  default     = ["cn-shenzhen-c", "cn-shenzhen-e", "cn-shenzhen-f"]
}

# The CIDR blocks used to create vSwitches.
variable "node_vswitch_cidrs" {
  type    = list(string)
  default = ["172.16.0.0/23", "172.16.2.0/23", "172.16.4.0/23"]
}

# The CIDR blocks used to create Terway vSwitches.
variable "terway_vswitch_cidrs" {
  type    = list(string)
  default = ["172.16.208.0/20", "172.16.224.0/20", "172.16.240.0/20"]
}

# Specify the ECS instance types of worker nodes.
variable "worker_instance_types" {
  description = "The ecs instance types used to launch worker nodes."
  default     = ["ecs.g6.2xlarge", "ecs.g6.xlarge"]
}

# Specify a password for the worker node.
variable "password" {
  description = "The password of ECS instance."
  default     = "Test123456"
}

# Specify the cluster add-on components (Terway, csi-plugin, csi-provisioner, logtail-ds, nginx-ingress-controller, 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" = "",
    }
  ]
}

# Specify the prefix of the name of the ACK managed cluster.
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"
}

# The default resource names.
locals {
  k8s_name_terway = substr(join("-", [var.k8s_name_prefix, "terway"]), 0, 63)
}

# The VPC.
resource "alicloud_vpc" "default" {
  vpc_name   = var.vpc_name
  cidr_block = "172.16.0.0/12"
}

# The node vSwitches.
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)
}

# The pod vSwitches.
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)
}

# Create a deployment set.
resource "alicloud_ecs_deployment_set" "default" {
  strategy            = var.strategy
  domain              = "Default"
  granularity         = "Host"
  deployment_set_name = var.name
  description         = "example_value"
}

# The ACK managed cluster.
resource "alicloud_cs_managed_kubernetes" "default" {
  name         = local.k8s_name_terway # The ACK cluster name.
  cluster_spec = var.cluster_spec      # Create an ACK Pro cluster.
  worker_vswitch_ids           = split(",", join(",", alicloud_vswitch.vswitches.*.id))        # The vSwitches used by the node pool. Specify one or more vSwitch IDs. The vSwitches must reside in the zone specified by availability_zone.
  pod_vswitch_ids              = split(",", join(",", alicloud_vswitch.terway_vswitches.*.id)) # The vSwitch used by pods.
  new_nat_gateway              = true                                                          # Specify whether to create a NAT gateway when the ACK cluster is created. Default value: true.
  service_cidr                 = "10.11.0.0/16"                                                # The pod CIDR block. If you set the cluster_network_type parameter to flannel, this parameter is required. The pod CIDR block cannot be the same as the VPC CIDR block or the CIDR blocks of other ACK clusters in the VPC. You cannot change the pod CIDR block after the cluster is created. Maximum number of hosts in the cluster: 256.
  slb_internet_enabled         = true                                                          # Specify whether to create an Internet-facing SLB instance for the API server of the cluster. Default value: false.
  enable_rrsa                  = true
  control_plane_log_components = ["apiserver", "kcm", "scheduler", "ccm"] # The control plane logs.

  dynamic "addons" { # Component management.
    for_each = var.cluster_addons
    content {
      name   = lookup(addons.value, "name", var.cluster_addons)
      config = lookup(addons.value, "config", var.cluster_addons)
    }
  }
}

# The regular node pool.
resource "alicloud_cs_kubernetes_node_pool" "default" {
  cluster_id           = alicloud_cs_managed_kubernetes.default.id              # The ACK cluster name.
  node_pool_name       = var.nodepool_name                                      # The node pool name.
  vswitch_ids          = split(",", join(",", alicloud_vswitch.vswitches.*.id)) # The vSwitches used by the node pool. Specify one or more vSwitch IDs. The vSwitches must reside in the zone specified by availability_zone.
  instance_types       = var.worker_instance_types
  instance_charge_type = "PostPaid"
  runtime_name         = "containerd"
  desired_size          = 2            # The expected number of nodes in the node pool.
  password              = var.password # The password that is used to log on to the cluster by using SSH.
  install_cloud_monitor = true         # Specify whether to install the CloudMonitor agent on the nodes in the cluster.
  system_disk_category  = "cloud_essd"
  system_disk_size      = 100
  image_type            = "AliyunLinux"
  deployment_set_id     = alicloud_ecs_deployment_set.default.id

  data_disks {              # The data disk configuration of the node.
    category = "cloud_essd" # The disk category.
    size     = 120          # The disk size.
  }
}

Para exemplos mais completos, acesse Mais exemplos e selecione o diretório do Container Service for Kubernetes (ACK).

Próximos passos