有奖捉虫:办公协同&微信生态&物联网文档专题 HOT
本文介绍如何使用 Terraform 创建腾讯云 TKE 标准集群并结合 Terraform Kubernetes Provider 部署一个简单的 Nginx 应用。

前置条件

为了使用 Terraform 部署 TKE 资源,您需要满足以下条件:
Terraform 版本大于等于1.2.9。
获取凭证,在 API 密钥管理 页面中创建并复制 SecretId 和 SecretKey。
登录 容器服务控制台,按照界面提示为腾讯云容器服务授权。
完成授权后,请参考下述步骤,创建一个 TKE 资源,并基于该资源配置 Provider。

创建 TKE 相关资源

您可以通过以下两种方式创建 TKE 资源:

方式1:使用 TKE Module 创建实例

您可以直接使用 TKE Module(terraform-tencentcloud-tke) 来创建一个实例。然后,跳过本节内容,开始 配置 Kubernetes

方式2:逐步创建 TKE 集群

如果您想了解如何逐步创建一个 TKE 集群,可以按照以下步骤进行操作:

步骤1:创建目录

在您的本地终端创建任意空目录,例如 tf-tke-example。按照本节内容,您将创建以下文件:
tf-tke-example
├── cluster.tf # 用于管理和配置集群资源
├── network.tf # 用于配置网络和安全组信息
└── provider.tf # 用于设置terraform provider和地域

步骤2:配置 Provider

1. 在创建 TKE 资源之前,您需要在 provider.tf 文件中设置所需的 Terraform Provider 和资源所在地域。以在广州地域配置腾讯云 Provider 为例,请创建 provider.tf 文件,参考代码如下:
terraform {
required_providers { #该block用于配置terraform provider,支持配置多个provider
tencentcloud = {
source = "tencentcloudstack/tencentcloud" #用于指定源位置,默认无需修改,会从terraform中下载
#version = ">=1.81.14" # 用于指定版本,缺省时使用latest版本
}
#kubernetes = {
# source = "hashicorp/kubernetes"
# version = ">= 2.0.0"
#}
}
}

provider "tencentcloud" {
region = "ap-guangzhou" #在这里替换您的地域
}
注意:
由于国内网络环境的一些限制,下载可能无法完成或者下载速度很慢,出现这种问题时,请使用 TencentCloud 镜像
2. 设置完 Terraform Provider 后,在命令行终端执行terraform init命令,如果显示以下信息,则说明 Terraform Provider 已经完成初始化。




步骤3:配置基础网络

1. 在创建 TKE 资源之前,您需要先配置私有网络 VPC、子网和安全组。请创建 network.tf 文件,并参考以下示例代码配置文件:
注意:
请根据您的实际业务需求替换代码中相应的配置。
# Networks
variable "vpc_name" {
default = "example-vpc"
description = "Specify the name of vpc."
}

variable "subnet_name" {
default = "example-subnet"
description = "Specify the name of subnet."
}

variable "security_group_name" {
default = "example-security-group"
description = "Specify the name of security group."
}

variable "network_cidr" {
default = "10.0.0.0/16"
description = "Specify the cidr of vpc and subnet."
}

variable "security_ingress_rules" {
default = [
"ACCEPT#10.0.0.0/16#ALL#ALL",
"ACCEPT#172.16.0.0/22#ALL#ALL",
"DROP#0.0.0.0/0#ALL#ALL"
]
description = "Define the ingress rules of security group."
}

variable "available_zone" {
default = "ap-guangzhou-3" # 在这里指定您的可用区
description = "Specify the available zone for your network."
}

variable "tags" {
default = {
terraform = "example"
}
description = "Specify the resource tags for your network."
}

# 配置vpc资源
resource "tencentcloud_vpc" "vpc" {
cidr_block = var.network_cidr
name = var.vpc_name
tags = var.tags
}

# 基于上面的vpc资源,创建一个subnet资源
resource "tencentcloud_subnet" "subnet" {
availability_zone = var.available_zone
cidr_block = var.network_cidr
name = var.subnet_name
vpc_id = tencentcloud_vpc.vpc.id
tags = var.tags
}

# 配置安全组资源
resource "tencentcloud_security_group" "sg" {
name = var.security_group_name
description = "example security groups for kubernetes networks"
tags = var.tags
}

# 为安全组配置入站和出站规则
resource "tencentcloud_security_group_lite_rule" "sg_rules" {
security_group_id = tencentcloud_security_group.sg.id
ingress = var.security_ingress_rules
egress = [
"ACCEPT#0.0.0.0/0#ALL#ALL"
]
}
2. 文件配置完成后,执行terraform plan命令,如果提示将会创建上述4个资源,则说明配置正确。



3. 执行terraform apply命令,确认创建信息无误后,键入 yes,开始创建。创建需要一些时间,请您耐心等待。



4. 创建完成后,登录 私有网络控制台,分别查看已经创建的资源。如下图所示:
私有网络:



子网:



安全组:




步骤4:配置集群

1. 在网络配置完成后,您可以创建并配置一个TKE 集群。请创建 cluster.tf 文件,并参考以下示例代码配置文件:
注意:
请根据您的实际业务需求替换代码中相应的配置。
# TKE
variable "cluster_name" {
default = "example-cluster"
description = "Specify the name of your cluster."
}

variable "cluster_version" {
default = "1.22.5" # 在这里指定您的集群版本
description = "Specify the name of your cluster."
}

variable "cluster_cidr" {
default = "172.16.0.0/22"
description = "Specify the cidr of your cluster."
}

variable "cluster_os" {
default = "tlinux2.2(tkernel3)x86_64"
description = "Specify the kind of OS for your cluster."
}

variable "cluster_public_access" {
default = false # 在这里指定是否打开外网访问,true为打开,false为关闭(这里暂时关闭以避免安全风险)
description = "Specify the switch of public access of your cluster. false means closed public access, and true means open it."
}

variable "cluster_private_access" {
default = true
description = "Specify the switch of private access of your cluster. false means closed the private access, and true means open it."
}

variable "worker_count" {
default = 1
description = "Specify the initial count of the worker nodes."
}

variable "worker_instance_type" {
default = "S5.MEDIUM2" # 在这里指定您的worker版本
description = "Specify the type of the worker nodes."
}

variable "cluster_available_zone" {
default = "ap-guangzhou-3" # 在这里指定您的可用区
description = "Specify the available zone for your cluster."
}

variable "cluster_tags" {
default = {
terraform = "example"
}
description = "Specify the resource tags for your cluster."
}

# 定义随机密码
resource "random_password" "worker_pwd" {
length = 12
min_numeric = 1
min_special = 1
min_upper = 1
override_special = "!#$%&*()-_=+[]{}<>:?"
}

# 基于以上variables, 定义一个TKE集群
resource "tencentcloud_kubernetes_cluster" "cluster" {
cluster_name = var.cluster_name
cluster_version = var.cluster_version
cluster_cidr = var.cluster_cidr
cluster_os = var.cluster_os
cluster_internet = var.cluster_public_access
cluster_internet_security_group = var.cluster_public_access ? tencentcloud_security_group.sg.id : null
cluster_intranet = var.cluster_private_access
cluster_intranet_subnet_id = var.cluster_private_access ? tencentcloud_subnet.subnet.id : null
vpc_id = tencentcloud_vpc.vpc.id

# 工作节点配置
worker_config {
availability_zone = var.cluster_available_zone
count = var.worker_count
instance_type = var.worker_instance_type
subnet_id = tencentcloud_subnet.subnet.id
security_group_ids = [tencentcloud_security_group.sg.id]
password = random_password.worker_pwd.result
}

tags = var.cluster_tags
}

2. 文件配置完成后,由于引入一个新的 Provider(random),您需要在命令行终端执行terraform init -upgrade命令,更新 Terraform Provider。



3. 与配置网络类似,执行terraform plan命令后,如果提示将会创建2个资源,则说明配置正确。
4. 执行terraform apply命令,确认创建信息无误后,键入yes,开始创建。创建需要一些时间,请您耐心等待。



5. 登录 容器服务控制台,可以看到您已经创建的资源。如下图所示:
在集群列表中,可查看已创建的集群:


单击集群名称,在节点管理 > Worker 节点中,选择节点页面,可查看已经创建的节点:



步骤5:(可选)配置 CAM 角色

1. 您的账号需要创建 TKE_QCSRole 角色并授予其预设策略 TF_QcloudAccessForTKERoleTF_QcloudAccessForTKERoleInOpsManagement ,用于访问其它的云资源。(如果您已经拥有该角色权限,请跳过本小节)。
说明:
如果您已经在控制台完成授权(如下图所示),则不需要创建 cam.tf 文件。



2. 创建 cam.tf 文件,配置 CAM 角色并关联策略。代码如下:
# 配置TKE_QCSRole角色,该角色用于TKE访问您的相关云服务资源
resource "tencentcloud_cam_role" "TKE_QCSRole" {
name = "TKE_QCSRole"
document = <<EOF
{
"statement": [
{
"action":"name/sts:AssumeRole",
"effect":"allow",
"principal":{
"service":"ccs.qcloud.com"
}
}
],
"version":"2.0"
}
EOF
description = "The TKE service role."
}

# 设置角色ops_mgr策略:该权限用于腾讯云容器服务(TKE)对云资源的访问,包含日志服务(CLS)的访问
data "tencentcloud_cam_policies" "ops_mgr" {
name = "TF_QcloudAccessForTKERoleInOpsManagement"
}

# 设置角色qca策略:该权限用于腾讯云容器服务(TKE)对云资源的访问
data "tencentcloud_cam_policies" "qca" {
name = "TF_QcloudAccessForTKERole"
}

locals {
ops_policy_id = data.tencentcloud_cam_policies.ops_mgr.policy_list.0.policy_id
qca_policy_id = data.tencentcloud_cam_policies.qca.policy_list.0.policy_id
}

# 角色与策略ops_mgr关联
resource "tencentcloud_cam_role_policy_attachment" "QCS_OpsMgr" {
role_id = lookup(tencentcloud_cam_role.TKE_QCSRole, "id")
policy_id = local.ops_policy_id
}

# 角色与策略qca关联
resource "tencentcloud_cam_role_policy_attachment" "QCS_QCA" {
role_id = lookup(tencentcloud_cam_role.TKE_QCSRole, "id")
policy_id = local.qca_policy_id
}
3. 与配置网络类似,执行terraform plan命令后,如果提示将会创建3个资源,则说明配置正确。
4. 执行terraform apply命令,确认创建信息无误后,键入yes,开始创建。创建需要一些时间,请您耐心等待。



5. 登录访问管理控制台,选择 角色,查看您已经创建的角色:


查看该角色对应的权限策略:



步骤6:(可选)封装为 Module

完成上述步骤后,您已经创建了一个基础可用的 TKE 资源实例。为了更好地组织代码并减少关注内部实现,建议将上述步骤中的所有 .tf 文件组织成一个 Module 进行使用。您也可以参考现有的 TKE Module(terraform-tencentcloud-tke)


配置 Kubernetes

在完成 创建 TKE 相关资源 后,您已经获得了一个 TKE 集群,从而可以获取它的外网访问地址,CA 证书和用户凭证。接下来,您可以基于这个 TKE 集群或者使用 TKE Module(terraform-tencentcloud-tke) 来配置 Kubernetes,部署一个简单的 Nginx 应用。在本示例中,您将创建和修改以下文件:
.
├── main.tf # 用于配置module
├── clb.tf # 用于配置负载均衡
├── kubernetes.tf # 用于配置一套kubernetes资源
├── network.tf # 用于配置网络和安全组信息
└── provider.tf # 用于定义tencentcloud和kubernetes两个provider
现在,我们以 方式1:使用 TKE Module 创建实例 为例,创建一个 TKE 集群并进行相关配置。

配置 Kubernetes Provider

1. 在您的本地终端,新建一个新的文件夹,如 tf-tke-k8s-example
注意:
如果您是基于上一小节 方式2:逐步创建 TKE 集群 创建的集群,那么直接修改 tf-tke-example中的 provider.tf 即可。
2. 您需要执行以下操作配置 Provider:在该目录中,新建一个 provider.tf 文件,然后添加配置,具体包括:
创建 provider.tf 文件,配置 kubernetestencentcloud Provider。
创建 main.tf 文件,配置 tencentcloud_tke Module。
provider.tf 文件示例代码如下:
terraform {
required_providers {
kubernetes = { # 添加一个kubernetes provider
source = "hashicorp/kubernetes"
}
tencentcloud = {
source = "tencentcloudstack/tencentcloud"
}
}
}

provider "tencentcloud" {
region = "ap-guangzhou"
}

# 对kubernetes provider进行配置,关联已有的TKE集群
provider "kubernetes" {
host = module.tencentcloud_tke.cluster_endpoint
cluster_ca_certificate = module.tencentcloud_tke.cluster_ca_certificate
client_key = base64decode(module.tencentcloud_tke.client_key)
client_certificate = base64decode(module.tencentcloud_tke.client_certificate)
}
main.tf 文件示例代码如下:
# 引用module
module "tencentcloud_tke" {
source = "github.com/terraform-tencentcloud-modules/terraform-tencentcloud-tke"
#available_zone = "ap-guangzhou-3" # Available zone must belongs to the region.
}
3. 在命令行终端执行terraform init命令,Terraform 会下载 TKE Module,以及 TencentCloud、Kubernetes 和 Random 三个 Provider。



配置 TKE Module

您需要执行以下操作配置 TKE Module:
创建 network.tf 文件,配置网络和安全组。
修改 main.tf 文件,完善 Module 中的参数项。

配置安全组外网访问

请创建 network.tf 文件。以下是一个 network.tf 的示例代码:
variable "accept_ip" {
type = string
default = "x.x.x.x" # 设置为您的IP
}

variable "available_zone" {
default = "ap-guangzhou-3"
}

variable "region" {
default = "ap-guangzhou"
}

resource "tencentcloud_security_group" "this" {
name = "tke-security-group"
}

resource "tencentcloud_security_group_lite_rule" "this" {
security_group_id = tencentcloud_security_group.this.id

ingress = [
"ACCEPT#10.0.0.0/16#ALL#ALL",
"ACCEPT#172.16.0.0/22#ALL#ALL",
# "ACCEPT#${var.accept_ip}#ALL#ALL", # 添加您的IP
"DROP#0.0.0.0/0#ALL#ALL",
]

egress = [
"ACCEPT#172.16.0.0/22#ALL#ALL",
]
}

resource "tencentcloud_vpc" "this" {
cidr_block = "10.0.0.0/16"
name = "tke-test"
}

resource "tencentcloud_subnet" "intranet" {
cidr_block = "10.0.1.0/24"
name = "tke-subnet"
availability_zone = var.available_zone
vpc_id = tencentcloud_vpc.this.id
}
我们不推荐完全放通外网访问,默认的安全组仅放通 10.0.0.0/16172.16.0.0/22 网段。如果您需要测试集群的外网访问,您需要将自己的 IP 添加到安全组的规则中。

配置 TKE 资源

我们将通过节点池来创建节点,并使用 tencentcloud_kubernetes_cluster_endpoint 资源来开启网络访问。
请修改 main.tf 文件中的 tencentcloud_tke module 块,以下是一个可用的参数项示例:
注意:
请根据您的实际业务需求替换代码中相应的配置。
module "tencentcloud_tke" {
source = "github.com/terraform-tencentcloud-modules/terraform-tencentcloud-tke"
available_zone = var.available_zone # Available zone must belongs to the region.
create_cam_strategy = false
enhanced_monitor_service = true
create_endpoint_with_cluster = false # 使用 endpoint 资源开启网络访问
create_workers_with_cluster = false # 使用 节点池 资源创建节点
cluster_public_access = true # 开启公网
cluster_private_access = true # 开启内网
cluster_security_group_id = tencentcloud_security_group.this.id
node_security_group_id = tencentcloud_security_group.this.id
cluster_private_access_subnet_id = tencentcloud_subnet.intranet.id
vpc_id = tencentcloud_vpc.this.id
intranet_subnet_id = tencentcloud_subnet.intranet.id
enable_cluster_audit_log = true
worker_bandwidth_out = 100
tags = {
module = "tke"
}
# 配置标准节点池
self_managed_node_groups = {
test = {
max_size = 4
min_size = 1
subnet_ids = [tencentcloud_subnet.intranet.id]
retry_policy = "INCREMENTAL_INTERVALS"
desired_capacity = 2
enable_auto_scale = true
multi_zone_subnet_policy = "EQUALITY"
auto_scaling_config = [{
instance_type = "S5.MEDIUM2"
system_disk_type = "CLOUD_PREMIUM"
system_disk_size = 50
orderly_security_group_ids = [tencentcloud_security_group.this.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
enhanced_security_service = false
enhanced_monitor_service = false
host_name = "12.123.0.0"
host_name_style = "ORIGINAL"
}]
labels = {
"test1" = "test1",
"test2" = "test2",
}
taints = [{
key = "test_taint"
value = "taint_value"
effect = "PreferNoSchedule"
},
{
key = "test_taint2"
value = "taint_value2"
effect = "PreferNoSchedule"
}]
node_config = [{
extra_args = ["root-dir=/var/lib/kubelet"]
}]
}
}
}

配置 Kubernetes resources

在 Terraform 中,您可以使用 HCL 替代原来的 yaml 声明 Namespace、Deployment 和 Service。通过使用 Kubernetes Provider 的kubernetes_namespacekubernetes_deploymentkubernetes_service资源,可以完成上述配置。
请创建 kubernetes.tf 文件,并参考以下示例代码:
# 配置k8 namespace
resource "kubernetes_namespace" "test" {
metadata {
name = "nginx"
}
}

# 定义了一个k8s Deployment资源,把两个Pod部署到Kubernetes集群中
resource "kubernetes_deployment" "test" {
metadata {
name = "nginx"
namespace = kubernetes_namespace.test.metadata.0.name
}
spec {
replicas = 2
selector {
match_labels = {
app = "MyTestApp"
}
}
# 设置nginx的container和对应镜像
template {
metadata {
labels = {
app = "MyTestApp"
}
}
# 使用Nginx镜像
spec {
container {
image = "nginx"
name = "nginx-container"
port {
container_port = 80
}
}
}
}
}
}

# 创建名为nginx的k8 service
resource "kubernetes_service" "test" {
metadata {
name = "nginx"
namespace = kubernetes_namespace.test.metadata.0.name
}
# 将NodePort类型的服务映射到nginx的Pod上
spec {
selector = {
app = kubernetes_deployment.test.spec.0.template.0.metadata.0.labels.app
}
type = "NodePort"
port {
node_port = 30201
port = 80
target_port = 80
}
}
}

配置 Ingress

您需要配置 Ingress 关联负载均衡 CLB,以便通过 CLB 提供的访问地址访问 Nginx 服务,从而实现公网访问。
1. 创建一个 CLB 实例。请创建 clb.tf 文件,并参考以下示例代码:
locals {
lb_vpc = tencentcloud_vpc.this.id
lb_sg = tencentcloud_security_group.this.id
}

# 配置clb,而后通过clb提供的访问地址访问nginx服务
resource "tencentcloud_clb_instance" "ingress-lb" {
address_ip_version = "ipv4"
clb_name = "example-lb"
internet_bandwidth_max_out = 1
internet_charge_type = "BANDWIDTH_POSTPAID_BY_HOUR"
load_balancer_pass_to_target = true
network_type = "OPEN"
security_groups = [local.lb_sg]
vpc_id = local.lb_vpc
}
2. 在 kubernetes.tf 文件中配置 Ingress,并指定刚才创建的 CLB ID。为此,您需要定义一个 Kubernetes Ingress 资源,将外部流量路由到 Nginx 服务上。示例代码如下:
# 定义一个k8s Ingress资源,将外部流量路由到名为"test-ingress"的Ingress中的Nginx服务上。
resource "kubernetes_ingress_v1" "test" {
metadata {
name = "test-ingress"
namespace = "nginx"
annotations = {
"ingress.cloud.tencent.com/direct-access" = "false"
"kubernetes.io/ingress.class" = "qcloud"
"kubernetes.io/ingress.existLbId" = tencentcloud_clb_instance.ingress-lb.id
"kubernetes.io/ingress.extensiveParameters" = "{\\"AddressIPVersion\\": \\"IPV4\\"}"
"kubernetes.io/ingress.http-rules" = "[{\\"path\\":\\"/\\",\\"backend\\":{\\"serviceName\\":\\"nginx\\",\\"servicePort\\":\\"80\\"}}]"
"kubernetes.io/ingress.https-rules" = "null"
"kubernetes.io/ingress.qcloud-loadbalance-id" = tencentcloud_clb_instance.ingress-lb.id
"kubernetes.io/ingress.rule-mix" = "false"
}
}
spec {
rule {
http {
path {
backend {
service {
name = kubernetes_service.test.metadata.0.name
port {
number = 80
}
}
}
path = "/"
}
}
}
}
}
3. 为了方便观察调试结果,我们可以获取 CLB 的 IP 地址并输出。请创建一个 output 变量,示例代码如下:
output "load_balancer_ip" {
value = kubernetes_ingress_v1.test.status.0.load_balancer.0.ingress.0.ip
}

(可选)配置 PVC

您可以通过指定 PVC,为 TKE 集群挂载存储资源。您需要执行以下操作:
创建 cbs.tf,配置磁盘资源。
修改 kubernetes.tf 文件,添加 PV 与对应 PVC 配置。
请创建 cbs.tf 文件。以下是一个 cbs.tf 的示例代码:
# 配置CBS, 而后用于k8s PV存储资源
resource "tencentcloud_cbs_storage" "stroage" {
storage_name = "example-cbs"
storage_type = "CLOUD_SSD"
storage_size = 100
availability_zone = var.available_zone
project_id = 0
encrypt = false

}
修改 kubernetes.tf 文件。以下是一个 kubernetes.tf 的示例代码:
# 定义一个PVC资源
resource "kubernetes_persistent_volume_claim" "test" {
metadata {
name = "example-pv-claim"
namespace = kubernetes_namespace.test.metadata.0.name
}
spec {
storage_class_name = "my-storage"
access_modes = ["ReadWriteMany"]
resources {
requests = {
storage = "5Gi"
}
}
volume_name = "${kubernetes_persistent_volume.test.metadata.0.name}"
}
}
# 定义一个PV资源
resource "kubernetes_persistent_volume" "test" {
metadata {
name = "example-pv"
}
spec {
capacity = {
storage = "10Gi"
}
storage_class_name = "my-storage"
access_modes = ["ReadWriteMany"]
persistent_volume_source {
# 配置cbs
csi {
driver = "com.tencent.cloud.csi.cbs"
volume_handle = tencentcloud_cbs_storage.stroage.id
fs_type = "ext4"
}
}
}
}

执行创建

1. 在编写完所有的 .tf 文件后,按照以下顺序执行命令:
初始化:
$ terraform init
预览并确认将创建的资源:
$ terraform plan
执行资源创建:
$ terraform apply
2. 创建成功后,控制台将输出上文中定义的 output 信息。
Apply complete! Resources: 16 added, 0 changed, 0 destroyed.

Outputs:

load_balancer_ip = "xxx.xxx.xxx.xxx"

验证部署

1. 登录 容器服务控制台,选择 example-cluster 集群,进入节点页面,在Pod管理页,可以查看 Nginx 相关的 Pod 是否已经处于 Running 状态。如果相关 Pod 已经处于 Running 状态,则说明应用已经成功部署。



2. 访问 load_balancer_ip 显示的地址,如果页面显示 Welcome To Nginx,则说明应用已经成功部署并可以通过 CLB 访问。



3. 如果您执行过(可选)配置 PVC,可以在 example-cluster 集群的存储管理页中,查看刚才配置的 PV、PVC 和 CBS 信息。
PV 列表:



PVC 列表:


StorageClass 列表: