Terraform 是一种基础架构即代码(Infrastructure as Code, IaC)工具,可用于安全、高效地构建、更改和版本化管理云资源及本地资源。
通过不同的 Provider,可以以声明式方式管理各类资源。本文基于 Rancher2 Provider 进行实践记录。
环境信息
Rancher:v2.8.5-ent
下游集群(RKE2):v1.28.15+rke2r1
Terraform:v1.11.4
Rancher2 Provider:v4.1.0
Provider 版本需与 Rancher 版本匹配,参考:https://github.com/rancher/terraform-provider-rancher2/blob/master/docs/compatibility-matrix.md
参考官方文档:https://developer.hashicorp.com/terraform/install
1 2 3 wget -O - https://apt.releases.hashicorp.com/gpg | sudo gpg --dearmor -o /usr/share/keyrings/hashicorp-archive-keyring.gpg echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/hashicorp.listsudo apt update && sudo apt install terraform
准备配置文件 参考文档:https://registry.terraform.io/providers/rancher/rancher2
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 cat <<EOF > main.tf terraform { required_providers { rancher2 = { source = "rancher/rancher2" version = "4.1.0" } } } provider "rancher2" { api_url = "https://172.16.16.102" access_key = "xxx" secret_key = "yyy" # 建议使用未绑定具体集群的 Rancher admin AK/SK,否则可能返回 401 insecure = true } EOF
初始化:
使用 rancher2_app_v2 安装 NeuVector 在配置文件中添加如下资源:
1 2 3 4 5 6 7 8 9 10 11 resource "rancher2_app_v2" "neuvector" { cluster_id = "c-xxx" name = "neuvector" namespace = "cattle-neuvector-system" repo_name = "rancher-charts" chart_name = "neuvector" chart_version = "103.0.9+up2.8.5" # 如需自定义配置,可提供 values.yaml values = file("values.yaml") }
执行安装:
1 2 terraform plan terraform apply
验证状态:
1 2 terraform state list terraform state show rancher2_app_v2.neuvector
使用 rancher2_cluster_v2 构建 Elemental RKE2 集群 创建 MachineInventorySelectorTemplate 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 kubectl apply -f - <<EOF apiVersion: elemental.cattle.io/v1beta1 kind: MachineInventorySelectorTemplate metadata: name: pool-1 namespace: fleet-default spec: template: spec: selector: matchExpressions: - key: machineUUID operator: In values: xxx --- apiVersion: elemental.cattle.io/v1beta1 kind: MachineInventorySelectorTemplate metadata: name: pool-2 namespace: fleet-default spec: template: spec: selector: matchExpressions: - key: machineUUID operator: In values: yyy --- apiVersion: elemental.cattle.io/v1beta1 kind: MachineInventorySelectorTemplate metadata: name: pool-3 namespace: fleet-default spec: template: spec: selector: matchExpressions: - key: machineUUID operator: In values: zzz EOF
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 locals { machine_pools = { controlplane = { etcd_role = false control_plane_role = true worker_role = false quantity = 1 machine_config_name = "pool-1" } etcd = { etcd_role = true control_plane_role = false worker_role = false quantity = 1 machine_config_name = "pool-2" } worker = { etcd_role = false control_plane_role = false worker_role = true quantity = 1 machine_config_name = "pool-3" } } } resource "rancher2_cluster_v2" "foo" { name = "foo" kubernetes_version = "v1.30.13+rke2r1" rke_config { registries { configs { hostname = "harbor.warnerchen.com" # 需要提前在 local 集群的 fleet-default 下创建仓库凭证 Secret auth_config_secret_name = "registryconfig-auth-xxx" insecure = true } } machine_global_config = <<EOF cni: "cilium" EOF dynamic "machine_pools" { for_each = local.machine_pools content { name = machine_pools.key etcd_role = machine_pools.value.etcd_role control_plane_role = machine_pools.value.control_plane_role worker_role = machine_pools.value.worker_role quantity = machine_pools.value.quantity machine_config { api_version = "elemental.cattle.io/v1beta1" kind = "MachineInventorySelectorTemplate" name = machine_pools.value.machine_config_name } } } } }
证书轮换 1 2 3 4 5 6 7 8 9 10 11 12 resource "rancher2_cluster_v2" "foo" { name = "foo" kubernetes_version = "v1.30.13+rke2r1" rke_config { ... rotate_certificates { generation = 1 } ... } }
当 generation 的值与上次执行 terraform apply 时的值不同时,下一次 terraform apply 将触发证书轮换。
ETCD 快照管理 创建快照 1 2 3 4 5 6 7 8 9 10 11 12 resource "rancher2_cluster_v2" "foo" { name = "foo" kubernetes_version = "v1.30.13+rke2r1" rke_config { ... etcd_snapshot_create { generation = 1 } ... } }
恢复快照 1 2 3 4 5 6 7 8 9 10 11 12 13 14 resource "rancher2_cluster_v2" "foo" { name = "foo" kubernetes_version = "v1.30.13+rke2r1" rke_config { ... etcd_snapshot_restore { # 已有的快照名称 name = "on-demand-m-029d6c9d-9024-4f9b-92de-58334a7aa6b7-1750757634" generation = 1 } ... } }
配置 Agent 代理 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 resource "rancher2_cluster_v2" "foo" { name = "foo" kubernetes_version = "v1.30.13+rke2r1" agent_env_vars { name = "HTTP_PROXY" value = "http://172.16.16.12:10808" } agent_env_vars { name = "HTTPS_PROXY" value = "http://172.16.16.12:10808" } agent_env_vars { name = "NO_PROXY" value = "localhost,127.0.0.1,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16,cattle-system.svc,.svc,.cluster.local,.cn,warnerchen.com" } }