terraform 入门:创建腾讯云 k8s 集群

2021-08-05 23:22:36 浏览数 (1)

本文适合不喜欢在浏览器中点点点,并刚刚入门或者想要入门 terraform 的小伙伴。

准备工作

只需要下载 terraform,并将其提供的可执行文件放到系统路径。

tf 文件编写

云 Provider

各个云厂商都有相应的 SDK,以 provider 的形式提供给 terraform,腾讯云的 provider api 参考如下地址:

https://registry.terraform.io/providers/tencentcloudstack/tencentcloud/latest/docs

需要编写类似如下配置:

代码语言:txt复制
terraform {
  required_providers {
    tencentcloud = {
      source = "tencentcloudstack/tencentcloud"
    }
  }
}

provider "tencentcloud" {
  secret_id  = var.SECRET_ID
  secret_key = var.SECRET_KEY
  region     = "ap-shanghai"
}
  • tencentcloudstack/tencentcloud 这个是 SDK 的位置,设定了这个之后,运行 terraform init 后,系统会去下载腾讯云的相关 SDK。
  • 如果指定了默认的环境变量 TENCENTCLOUD_SECRET_ID 和 TENCENTCLOUD_SECRET_KEY, secret_id 和 secret_key 可以不指定。

密钥

首先通过腾讯云的 CAM 可以生产密钥,请到这个地址:https://console.cloud.tencent.com/cam/capi

在实际的使用中,我们不应该将 secret_id 和 secret_key 这些敏感信息写入到 tf 文件中,下面的例子将这个信息写入 环境变量。

代码语言:txt复制
export TF_VAR_SECRET_ID=xxxx
export TF_VAR_SECRET_KEY=xxxx
  • 上面的代码在 shell 中运行,或者可以写在你在 .bashrc 或者 .zshrc 中。
  • 变量名使用 TF_VAR_ 作为前缀。
  • 然后 SECRET_ID 和 SECRET_KEY 便可以在 tf 文件引用。
  • 建议使用这种方式设置密钥,不会误传到代码仓库。

腾讯云的 SDK 中直接支持如下变量,可以直接使用。

代码语言:txt复制
export TENCENTCLOUD_SECRET_ID="my-secret-id" 
export TENCENTCLOUD_SECRET_KEY="my-secret-key" 
export TENCENTCLOUD_REGION="ap-guangzhou" 
export TENCENTCLOUD_ASSUME_ROLE_ARN="my-role-arn" 
export TENCENTCLOUD_ASSUME_ROLE_SESSION_NAME="my-session-name"
export TENCENTCLOUD_ASSUME_ROLE_SESSION_DURATION=3600

现在 provider 中可以删除密钥了。

代码语言:txt复制
provider "tencentcloud" {
  region = "ap-beijing"
}

定义安全组

创建安全组,并指定出入规则。

代码语言:txt复制
resource "tencentcloud_security_group" "sg01" {
  name        = "some-sg"
  description = "security group @ powered by terraform"
}


resource "tencentcloud_security_group_lite_rule" "sg01-rule" {
  security_group_id = tencentcloud_security_group.sg01.id

  ingress = [
    "ACCEPT#0.0.0.0/0#ALL#ICMP",
    "ACCEPT#0.0.0.0/0#22#TCP",
    "ACCEPT#0.0.0.0/0#30000-32768#TCP",
    "ACCEPT#0.0.0.0/0#30000-32768#UDP",
  ]

  egress = [
    "ACCEPT#0.0.0.0/0#ALL#ALL",
  ]
}

创建 VPC 和子网

基础的 provider 和 region 设置好之后,可以创建 vpc 和子网了。

代码语言:txt复制
# 查询当前可用区
data "tencentcloud_availability_zones" "all_zones" {
}

# 定义一个 VPC 网络
resource "tencentcloud_vpc" "vpc01" {
  name         = "some-01"
  cidr_block   = "10.0.0.0/16"
  is_multicast = false
}

# 定义子网,这里会给每个 zone 定义一个子网
resource "tencentcloud_subnet" "subset01" {
  count             = length(data.tencentcloud_availability_zones.all_zones.zones)
  name              = "some-subset-${count.index}"
  vpc_id            = tencentcloud_vpc.vpc01.id
  availability_zone = data.tencentcloud_availability_zones.all_zones.zones[count.index].name
  cidr_block        = "10.0.${count.index}.0/24"
  is_multicast      = false
}
  • 上述代码查询了可用区,并在每一个可用区都创建了一个子网。
  • 请注意如何在 terrraform 中使用循环:countcount.index

创建 TKE 集群

创建一个 k8s 集群需要的参数很多,直接上代码:

代码语言:txt复制
# 创建 TKE 集群
resource "tencentcloud_kubernetes_cluster" "tke_managed" {
  vpc_id                                     = tencentcloud_vpc.vpc01.id
  cluster_version                            = "1.18.4"
  cluster_cidr                               = "172.16.0.0/16"
  cluster_max_pod_num                        = 64
  cluster_name                               = "some-tke-01"
  cluster_desc                               = "created by terraform"
  cluster_max_service_num                    = 2048
  cluster_internet                           = true
  managed_cluster_internet_security_policies = ["0.0.0.0/0"]
  cluster_deploy_type                        = "MANAGED_CLUSTER"
  cluster_os                                 = "tlinux2.4x86_64"
  container_runtime                          = "containerd"
  deletion_protection                        = false

  worker_config {
    instance_name              = "some-node"
    availability_zone          = data.tencentcloud_availability_zones.all_zones.zones[0].name
    instance_type              = "S2.MEDIUM4"
    system_disk_type           = "CLOUD_SSD"
    system_disk_size           = 50
    internet_charge_type       = "TRAFFIC_POSTPAID_BY_HOUR"
    internet_max_bandwidth_out = 1
    public_ip_assigned         = true
    subnet_id                  = tencentcloud_subnet.subset01[0].id
    security_group_ids         = [tencentcloud_security_group.sg01.id]
    enhanced_security_service = false
    enhanced_monitor_service  = false
    password                  = "youPassword_@"
  }

}
  • 上述代码创建了一个 1.18.4 的 k8s 集群,装的系统为 “tlinux2.4x86_64”。
  • 在第一个可用区增加了一个 node,机型为 “S2.MEDIUM4”
  • 创建之前需要查询目标可用区的 机型是否有供应,否则会执行失败。
  • 创建集群的过程中,就直接开通了外网的 api-server 访问权限,实际生产中请注意保护集群安全。

创建节点池

TKE 建议使用节点池增加或者减少节点,并支持弹性伸缩。

代码语言:txt复制
#  创建一个节点池
resource "tencentcloud_kubernetes_node_pool" "node-pool" {
  name                 = "some-pool"
  cluster_id           = tencentcloud_kubernetes_cluster.tke_managed.id
  max_size             = 10
  min_size             = 0
  vpc_id               = tencentcloud_vpc.vpc01.id
  subnet_ids           = [for s in tencentcloud_subnet.subset01 : s.id]
  retry_policy         = "INCREMENTAL_INTERVALS"
  desired_capacity     = 1
  enable_auto_scale    = true
  delete_keep_instance = false
  node_os              = "tlinux2.4x86_64"

  auto_scaling_config {
    instance_type      = "S2.MEDIUM4"
    system_disk_type   = "CLOUD_PREMIUM"
    system_disk_size   = "50"
    security_group_ids = [tencentcloud_security_group.sg01.id]

    data_disk {
      disk_type = "CLOUD_PREMIUM"
      disk_size = 50
    }

    internet_charge_type       = "TRAFFIC_POSTPAID_BY_HOUR"
    internet_max_bandwidth_out = 10
    public_ip_assigned         = true
    password                   = "youPassword_@"
    enhanced_security_service  = false
    enhanced_monitor_service   = false

  }
}
  • 上述代码创建节点池,可以分布到所有子网。请注意看如何从数组中获取子网 id。

输出 kubeconfig

创建完集群之后,我们希望能直接保存 kubeconfig 文件。这里可以增加一个 output,如下:

代码语言:txt复制
output "KUBECONFIG" {
  value       = tencentcloud_kubernetes_cluster.tke_managed.kube_config
}

上述代码可以都写入 main.tf 文件中。

执行

初始化项目

代码语言:txt复制
terraform init

执行 tf 脚本

代码语言:txt复制
terraform apply -auto-approve

导出kubeconfig

代码语言:txt复制
terraform output -raw KUBECONFIG > kube.config

删除所有操作

代码语言:txt复制
terraform destroy --auto-approve

完整代码

代码语言:txt复制
# main.tf

# 名字标识
variable "name" {
  default = "wellxie"
}
# 机型
variable "region" {
  default = "ap-bangkok"
}
# k8s 版本
variable "k8s_ver" {
  default = "1.18.4"
}

# pod ip 地址段
variable "pod_ip_seg" {
  default = "172.16"
}

# vpc ip 地址段
variable "vpc_ip_seg" {
  default = "10.0"
}

# 机型
variable "default_instance_type" {
  default = "S2.MEDIUM4"
}

# node 密码
variable "node_password" {
  default = "P@ssw@rd123"
}




terraform {
  required_providers {
    tencentcloud = {
      source = "tencentcloudstack/tencentcloud"
    }
  }
}

# 指定腾讯云和其大区
provider "tencentcloud" {
  region = var.region
}

# 定义安全组
resource "tencentcloud_security_group" "sg01" {
  name        = "${var.name}-sg"
  description = "${var.name} security group @ powered by terraform"
}

resource "tencentcloud_security_group_lite_rule" "sg01-rule" {
  security_group_id = tencentcloud_security_group.sg01.id

  ingress = [
    "ACCEPT#0.0.0.0/0#ALL#ICMP",
    "ACCEPT#0.0.0.0/0#22#TCP",
    "ACCEPT#0.0.0.0/0#30000-32768#TCP",
    "ACCEPT#0.0.0.0/0#30000-32768#UDP",
  ]

  egress = [
    "ACCEPT#0.0.0.0/0#ALL#ALL",
  ]
}


# 查询当前可用区, 将设置到节点池
data "tencentcloud_availability_zones" "all_zones" {
}

# 定义一个 VPC 网络
resource "tencentcloud_vpc" "vpc01" {
  name         = "${var.name}-01"
  cidr_block   = "${var.vpc_ip_seg}.0.0/16"
  is_multicast = false

  tags = {
    "user" = var.name
  }
}

# 定义子网,这里会给每个 zone 定义一个子网
resource "tencentcloud_subnet" "subset01" {
  count             = length(data.tencentcloud_availability_zones.all_zones.zones)
  name              = "${var.name}-subset-${count.index}"
  vpc_id            = tencentcloud_vpc.vpc01.id
  availability_zone = data.tencentcloud_availability_zones.all_zones.zones[count.index].name
  cidr_block        = "${var.vpc_ip_seg}.${count.index}.0/24"
  is_multicast      = false
  tags = {
    "user" = var.name
  }
}


# 创建 TKE 集群
resource "tencentcloud_kubernetes_cluster" "tke_managed" {
  vpc_id                                     = tencentcloud_vpc.vpc01.id
  cluster_version                            = var.k8s_ver
  cluster_cidr                               = "${var.pod_ip_seg}.0.0/16"
  cluster_max_pod_num                        = 64
  cluster_name                               = "${var.name}-tke-01"
  cluster_desc                               = "created by terraform"
  cluster_max_service_num                    = 2048
  cluster_internet                           = true
  managed_cluster_internet_security_policies = ["0.0.0.0/0"]
  cluster_deploy_type                        = "MANAGED_CLUSTER"
  cluster_os                                 = "tlinux2.4x86_64"
  container_runtime                          = "containerd"
  deletion_protection                        = false

  worker_config {
    instance_name              = "${var.name}-node"
    availability_zone          = data.tencentcloud_availability_zones.all_zones.zones[0].name
    instance_type              = var.default_instance_type
    system_disk_type           = "CLOUD_SSD"
    system_disk_size           = 50
    internet_charge_type       = "TRAFFIC_POSTPAID_BY_HOUR"
    internet_max_bandwidth_out = 1
    public_ip_assigned         = true
    subnet_id                  = tencentcloud_subnet.subset01[0].id
    security_group_ids         = [tencentcloud_security_group.sg01.id]

    enhanced_security_service = false
    enhanced_monitor_service  = false
    password                  = var.node_password
  }


  labels = {
    "user" = var.name
  }
}

#  创建一个节点池
resource "tencentcloud_kubernetes_node_pool" "node-pool" {
  name                 = "${var.name}-pool"
  cluster_id           = tencentcloud_kubernetes_cluster.tke_managed.id
  max_size             = 10
  min_size             = 0
  vpc_id               = tencentcloud_vpc.vpc01.id
  subnet_ids           = [for s in tencentcloud_subnet.subset01 : s.id]
  retry_policy         = "INCREMENTAL_INTERVALS"
  desired_capacity     = 0
  enable_auto_scale    = true
  delete_keep_instance = false
  node_os              = "tlinux2.4x86_64"

  auto_scaling_config {
    instance_type      = var.default_instance_type
    system_disk_type   = "CLOUD_PREMIUM"
    system_disk_size   = "50"
    security_group_ids = [tencentcloud_security_group.sg01.id]

    data_disk {
      disk_type = "CLOUD_PREMIUM"
      disk_size = 50
    }

    internet_charge_type       = "TRAFFIC_POSTPAID_BY_HOUR"
    internet_max_bandwidth_out = 10
    public_ip_assigned         = true
    password                   = var.node_password
    enhanced_security_service  = false
    enhanced_monitor_service   = false

  }

  labels = {
    "user" = var.name,
  }

}

output "KUBECONFIG" {
  description = "下面的配置是 kubeconfig,请拷贝并妥善存储"
  value       = tencentcloud_kubernetes_cluster.tke_managed.kube_config
}
  • variable 部分请自行修改。
  • 执行前,请设置环境变量 TENCENTCLOUD_SECRET_IDTENCENTCLOUD_SECRET_KEY
  • 确保各个部分有相应权限,
  • 确保账户中有一定余额。

腾讯云提供产品化的 terraform,产品名称是 TIC,可以参考如下链接:

https://cloud.tencent.com/product/tic

0 人点赞