使用Terraform為節點池指定部署集
部署集是控制ECS實例分布的策略,該策略將ECS實例分散部署在不同的物理服務器上,提升業務的高可用性和底層容災能力。通過為節點池指定部署集,能夠保證節點池彈出的ECS實例不會分布于同一物理機上,并通過親和性配置,使您的應用對底層的節點拓撲進行感知,使其均勻地分布在不同節點上,保證應用的容災能力和高可用性。本文介紹如何通過Terraform為節點池指定部署集。
本教程所含示例代碼支持一鍵運行,您可以直接運行代碼。一鍵運行
前提條件
準備Terraform運行環境,您可以選擇以下任一方式來使用Terraform。
在Terraform Explorer中使用Terraform:阿里云提供了Terraform的在線運行環境,您無需安裝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、g6h、g5、g5ne、sn2ne
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
d3s、d3c、d2s、d2c、d1、d1ne、d1-c14d3、d1-c8d3
i4、i4g、i4r、i3g、i3、i2、i2g、i2ne、i2gne、i1
ebmg5、ebmc7、ebmg7、ebmr7、sccgn6、scch5、scch5s、sccg5、sccg5s
e、s6、t6、xn4、mn4、n4、e4
gn6i
u1
網絡低時延策略
g8a、g8i、g8ae、g8y
c8a、c8i、c8ae、c8y
ebmc8i、ebmg8i、ebmr8i
r8a、r8i、r8ae、r8y
i4
hfc8i、hfg8i、hfr8i
ebmgn7ex、ebmc7、ebmg7、ebmr7
在部署集內創建ECS實例失敗,或重啟按量付費ECS實例(節省停機模式)失敗,可能是因為地域內實例資源庫存不足,您可以等待一段時間后重試創建實例或重啟實例。
使用的資源
本教程示例包含的部分資源會產生一定費用,請在不需要時及時進行釋放或退訂。
alicloud_vpc:創建專有網絡VPC。
alicloud_vswitch:創建虛擬交換機(vSwitch)為VPC劃分一個或多個子網。
alicloud_ecs_deployment_set:創建部署集。
alicloud_cs_managed_kubernetes:創建ACK托管版集群。
alicloud_cs_kubernetes_node_pool:為ACK托管集群創建節點池。
通過Terraform創建指定部署集的節點池
使用以下示例內容,創建指定部署集的節點池。
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" } # 指定虛擬交換機(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版集群。 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 = 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" desired_size = 2 # 節點池的期望節點數。 password = var.password # SSH登錄集群節點的密碼。 install_cloud_monitor = true # 是否為Kubernetes的節點安裝云監控。 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 # 節點數據盤大小。 } }
執行如下命令,初始化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.
執行以下命令完成創建。
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.
驗證結果
執行terraform show命令
您可以使用以下命令查詢Terraform已創建的資源詳細信息。
terraform show
登錄ACK控制臺
您可以在容器服務管理控制臺的節點池頁面查看到新建的節點池。單擊操作列的編輯,可以查看到指定的部署集。
清理資源
當您不再需要上述通過Terraform創建或管理的資源時,請運行terraform destroy
命令以釋放資源。關于terraform destroy
的更多信息,請參見Terraform常用命令。
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"
}
# 指定虛擬交換機(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版集群。
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 = 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"
desired_size = 2 # 節點池的期望節點數。
password = var.password # SSH登錄集群節點的密碼。
install_cloud_monitor = true # 是否為Kubernetes的節點安裝云監控。
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 # 節點數據盤大小。
}
}
如果您想體驗更多完整示例,請前往更多完整示例中對應產品的文件夾查看。
相關文檔
如何在ACK節點池中使用部署集控制ECS實例的分布,請參見節點池部署集最佳實踐。
ROS提供了Terraform托管服務,因此您可以直接在ROS控制臺部署Terraform模板。詳細操作,請參見創建Terraform類型資源棧。