找回密码
立即注册
搜索
热搜: Java Python Linux Go
发回帖 发新帖

4667

积分

0

好友

645

主题
发表于 昨天 07:51 | 查看: 5| 回复: 0

对于需要在 Azure 上快速、一致地部署和管理 Kubernetes 服务的团队而言,通过控制台手动点击不仅效率低下,更难以保证环境的一致性。基础设施即代码(IaC)是解决这一问题的理想方案。本文将详细介绍如何使用 Terraform 这一流行的 IaC 工具,在 Azure 上自动化部署一个完整的 AKS (Azure Kubernetes Service) 集群,涵盖从环境准备、资源定义、部署验证到资源清理的全过程。

1. 在 CentOS 9 上安装 Terraform

首先,需要在操作系统中安装 Terraform 命令行工具。以下是在 CentOS 9 上的安装步骤:

  1. 下载指定版本的 Terraform 二进制包 (本文以 1.7.0 为例):
    [root@k8sworker starttech]# wget "https://releases.hashicorp.com/terraform/1.7.0/terraform_1.7.0_linux_amd64.zip"
  2. 解压下载的压缩包:
    [root@k8sworker starttech]# unzip terraform_1.7.0_linux_amd64.zip
  3. 将可执行文件移动到系统路径下,以便全局调用:
    [root@k8sworker starttech]# mv terraform /usr/local/bin/
  4. 在项目目录中初始化 Terraform,它会根据配置文件下载所需的 Azure 提供商插件:

    [root@k8sworker starttech]# terraform init
    
    Initializing the backend...
    
    Initializing provider plugins...
    - Finding latest version of hashicorp/azurerm...
    - Installing hashicorp/azurerm v4.66.0...
    - Installed hashicorp/azurerm v4.66.0 (signed by HashiCorp)
    
    Terraform has created a lock file .terraform.lock.hcl to record the provider
    selections it made above. Include this file in your version control repository
    so that Terraform can guarantee to make the same selections by default when
    you run “terraform init” in the future.
    
    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 has been successfully initialized!” 提示,说明初始化成功。

2. 编写 Terraform 资源文件

一个典型的 Terraform 项目包含多个 .tf 文件,用于定义提供商、变量和资源。

2.1 提供商配置文件 (providers.tf)
此文件指定了所需的 Terraform 版本和云提供商(此处为 Azure)。

terraform {
  required_version = “>= 1.0“

  required_providers {
    azurerm = {
      source  = “hashicorp/azurerm“
      version = “~> 4.0“
    }
  }
}

provider “azurerm“ {
  features {}
}

2.2 变量定义文件 (variables.tf)
使用变量可以使配置更灵活,便于复用和管理。

# ==========================================
# 通用变量
# ==========================================

variable “location“ {
  description = “Azure region“
  type        = string
  default     = “westeurope“
}

variable “environment“ {
  description = “Environment name“
  type        = string
  default     = “demo“
}

# ==========================================
# Resource Group 变量
# ==========================================

variable “resource_group_name“ {
  description = “Resource group name“
  type        = string
  default     = “test-rg“
}

# ==========================================
# Virtual Network 变量
# ==========================================

variable “vnet_name“ {
  description = “Virtual network name“
  type        = string
  default     = “vnet-aks-demo“
}

variable “vnet_address_space“ {
  description = “VNet address space“
  type        = list(string)
  default     = [“10.0.0.0/16“]
}

# ==========================================
# Subnet 变量
# ==========================================

variable “node_subnet_name“ {
  description = “AKS node subnet name“
  type        = string
  default     = “snet-aks-nodes“
}

variable “node_subnet_prefix“ {
  description = “AKS node subnet address prefix“
  type        = string
  default     = “10.0.1.0/24“
}

# ==========================================
# AKS 变量
# ==========================================

variable “aks_name“ {
  description = “AKS cluster name“
  type        = string
  default     = “aks-demo“
}

variable “aks_kubernetes_version“ {
  description = “Kubernetes version“
  type        = string
  default     = “1.33.7“
}

variable “aks_node_pool_name“ {
  description = “Default node pool name“
  type        = string
  default     = “agentpool“
}

variable “aks_node_count“ {
  description = “Node count (manual scale)“
  type        = number
  default     = 2
}

variable “aks_node_vm_size“ {
  description = “Node VM size“
  type        = string
  default     = “Standard_D2ps_v6“
}

variable “aks_os_sku“ {
  description = “Node OS SKU“
  type        = string
  default     = “Ubuntu“
}

variable “aks_scale_method“ {
  description = “Scale method: Manual or Autoscale“
  type        = string
  default     = “Manual“
}

variable “aks_network_plugin“ {
  description = “Network plugin: azure or kubenet“
  type        = string
  default     = “azure“
}

variable “aks_network_policy“ {
  description = “Network policy engine“
  type        = string
  default     = “azure“
}

variable “aks_load_balancer_sku“ {
  description = “Load balancer SKU“
  type        = string
  default     = “standard“
}

variable “aks_service_cidr“ {
  description = “AKS service CIDR“
  type        = string
  default     = “10.1.0.0/16“
}

variable “aks_dns_service_ip“ {
  description = “AKS DNS service IP“
  type        = string
  default     = “10.1.0.10“
}

variable “aks_docker_bridge_cidr“ {
  description = “Docker bridge CIDR“
  type        = string
  default     = “172.17.0.1/16“
}

variable “tags“ {
  description = “Resource tags“
  type        = map(string)
  default = {
    managed_by = “terraform“
    project    = “aks-demo“
  }
}

2.3 核心资源定义文件 (aks.tf)
这是最重要的文件,定义了所有要创建的 Azure 资源及其依赖关系。

# ==========================================
# 1. Resource Group
# ==========================================

resource “azurerm_resource_group“ “main“ {
  name     = var.resource_group_name
  location = var.location

  tags = merge(var.tags, {
    environment = var.environment
  })
}

# ==========================================
# 2. Virtual Network
# ==========================================

resource “azurerm_virtual_network“ “main“ {
  name                = var.vnet_name
  address_space       = var.vnet_address_space
  location            = azurerm_resource_group.main.location
  resource_group_name = azurerm_resource_group.main.name

  tags = merge(var.tags, {
    environment = var.environment
  })

  depends_on = [azurerm_resource_group.main]
}

# ==========================================
# 3. Node Subnet (Azure CNI Node Subnet)
# ==========================================

resource “azurerm_subnet“ “nodes“ {
  name                 = var.node_subnet_name
  resource_group_name  = azurerm_resource_group.main.name
  virtual_network_name = azurerm_virtual_network.main.name
  address_prefixes     = [var.node_subnet_prefix]

  depends_on = [azurerm_virtual_network.main]
}

# ==========================================
# 4. Network Security Group for Node Subnet
# ==========================================

resource “azurerm_network_security_group“ “nodes“ {
  name                = “nsg-${var.node_subnet_name}“
  location            = azurerm_resource_group.main.location
  resource_group_name = azurerm_resource_group.main.name

  security_rule {
    name                       = “Allow_Azure_Load_Balancer“
    priority                   = 100
    direction                  = “Inbound“
    access                     = “Allow“
    protocol                   = “*“
    source_port_range          = “*“
    destination_port_range     = “*“
    source_address_prefix      = “AzureLoadBalancer“
    destination_address_prefix = “*“
  }

  tags = var.tags
}

resource “azurerm_subnet_network_security_group_association“ “nodes“ {
  subnet_id                 = azurerm_subnet.nodes.id
  network_security_group_id = azurerm_network_security_group.nodes.id
}

# ==========================================
# 5. AKS Cluster
# ==========================================

resource “azurerm_kubernetes_cluster“ “main“ {
  name                = var.aks_name
  location            = azurerm_resource_group.main.location
  resource_group_name = azurerm_resource_group.main.name
  dns_prefix          = “aksdemo“
  kubernetes_version  = var.aks_kubernetes_version

  # 自动升级 - 使用 patch 表示禁用自动升级到新的次要版本
  # 或者完全移除 automatic_channel_upgrade 参数

  # 默认节点池 (agentpool, system mode, manual scale)
  default_node_pool {
    name       = var.aks_node_pool_name
    node_count = var.aks_node_count
    vm_size    = var.aks_node_vm_size
    os_sku     = var.aks_os_sku

    # Azure CNI Node Subnet
    vnet_subnet_id = azurerm_subnet.nodes.id

    # Node标签
    node_labels = {
      environment = var.environment
    }

    # 系统节点池标签
    tags = var.tags
  }

  # 网络配置 (Azure CNI + Azure Network Policy)
  network_profile {
    network_plugin    = var.aks_network_plugin
    network_policy    = var.aks_network_policy
    load_balancer_sku = var.aks_load_balancer_sku

    # Service CIDR 配置
    service_cidr       = var.aks_service_cidr
    dns_service_ip     = var.aks_dns_service_ip

    # docker_bridge_cidr 在较新版本中已弃用,移除
    outbound_type = “loadBalancer“
  }

  # 托管身份 (SystemAssigned)
  identity {
    type = “SystemAssigned“
  }

  # Azure Policy 禁用 - 使用 azure_policy_enabled
  azure_policy_enabled = false

  # SKU Tier - Free (之前是 Basic,现在用 Free)
  sku_tier = “Free“

  tags = merge(var.tags, {
    environment = var.environment
  })

  depends_on = [
    azurerm_subnet.nodes,
    azurerm_subnet_network_security_group_association.nodes
  ]
}

# ==========================================
# Outputs
# ==========================================

output “resource_group_name“ {
  description = “Resource group name“
  value       = azurerm_resource_group.main.name
}

output “vnet_name“ {
  description = “Virtual network name“
  value       = azurerm_virtual_network.main.name
}

output “node_subnet_id“ {
  description = “AKS node subnet ID“
  value       = azurerm_subnet.nodes.id
}

output “aks_cluster_name“ {
  description = “AKS cluster name“
  value       = azurerm_kubernetes_cluster.main.name
}

output “aks_cluster_id“ {
  description = “AKS cluster ID“
  value       = azurerm_kubernetes_cluster.main.id
}

output “aks_kubernetes_version“ {
  description = “AKS Kubernetes version“
  value       = azurerm_kubernetes_cluster.main.kubernetes_version
}

output “aks_node_pool_name“ {
  description = “AKS node pool name“
  value       = azurerm_kubernetes_cluster.main.default_node_pool[0].name
}

output “aks_node_count“ {
  description = “AKS node count“
  value       = azurerm_kubernetes_cluster.main.default_node_pool[0].node_count
}

output “aks_fqdn“ {
  description = “AKS API server FQDN“
  value       = azurerm_kubernetes_cluster.main.fqdn
}

# 完整的 kubeconfig 文件内容(敏感)
output “kube_config_raw“ {
  description = “完整的 kubeconfig 文件内容“
  value       = azurerm_kubernetes_cluster.main.kube_config_raw
  sensitive   = true
}

# kubeconfig 文件路径提示
output “kube_config_command“ {
  description = “获取 kubeconfig 的命令“
  value       = “terraform output -raw kube_config_raw > ~/.kube/config-aks-demo && export KUBECONFIG=~/.kube/config-aks-demo“
}

# Azure CLI 获取凭证命令
output “az_get_credentials“ {
  description = “使用 Azure CLI 获取凭证的命令“
  value       = “az aks get-credentials —resource-group ${azurerm_resource_group.main.name} —name ${azurerm_kubernetes_cluster.main.name} —overwrite-existing“
}

3. 校验文件语法

在部署之前,先检查 Terraform 配置文件的语法是否正确。

[root@k8sworker starttech]# ll
total 16
-rw-r—r—. 1 root root 5973 Apr  1 22:15 aks.tf
-rw-r—r—. 1 root root  193 Apr  1 21:34 providers.tf
-rw-r—r—. 1 root root 3152 Apr  1 20:51 variables.tf
[root@k8sworker starttech]# terraform validate
Success! The configuration is valid.

看到 “Success! The configuration is valid.” 表示配置语法无误。

4. 规划部署(Dry-Run)

执行 terraform plan 命令,Terraform 会计算出要创建、修改或销毁哪些资源,而不会实际执行。这是一个非常重要的安全步骤。

[root@k8sworker starttech]# terraform plan -out=tfplan

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

  # azurerm_kubernetes_cluster.main will be created
  + resource “azurerm_kubernetes_cluster“ “main“ {
      + ai_toolchain_operator_enabled       = false
      + azure_policy_enabled                = false
      + current_kubernetes_version          = (known after apply)
      + dns_prefix                          = “aksdemo“
      + fqdn                                = (known after apply)
      + http_application_routing_zone_name  = (known after apply)
      + id                                  = (known after apply)
      + kube_admin_config                   = (sensitive value)
      + kube_admin_config_raw               = (sensitive value)
      + kube_config                         = (sensitive value)
      + kube_config_raw                     = (sensitive value)
      + kubernetes_version                  = “1.33.7“
      + location                            = “westeurope“
      + name                                = “aks-demo“
      + node_os_upgrade_channel             = “NodeImage“
      + node_resource_group                 = (known after apply)
      + node_resource_group_id              = (known after apply)
      + oidc_issuer_url                     = (known after apply)
      + portal_fqdn                         = (known after apply)
      + private_cluster_enabled             = false
      + private_cluster_public_fqdn_enabled = false
      + private_dns_zone_id                 = (known after apply)
      + private_fqdn                        = (known after apply)
      + resource_group_name                 = “test-rg“
      + role_based_access_control_enabled   = true
      + run_command_enabled                 = true
      + sku_tier                            = “Free“
      + support_plan                        = “KubernetesOfficial“
      + tags                                = {
          + “environment“ = “demo“
          + “managed_by“  = “terraform“
          + “project“     = “aks-demo“
        }
      + workload_identity_enabled           = false

      + default_node_pool {
          + kubelet_disk_type    = (known after apply)
          + max_pods             = (known after apply)
          + name                 = “agentpool“
          + node_count           = 2
          + node_labels          = {
              + “environment“ = “demo“
            }
          + orchestrator_version = (known after apply)
          + os_disk_size_gb      = (known after apply)
          + os_disk_type         = “Managed“
          + os_sku               = “Ubuntu“
          + scale_down_mode      = “Delete“
          + tags                 = {
              + “managed_by“ = “terraform“
              + “project“    = “aks-demo“
            }
          + type                 = “VirtualMachineScaleSets“
          + ultra_ssd_enabled    = false
          + vm_size              = “Standard_D2ps_v6“
          + vnet_subnet_id       = (known after apply)
          + workload_runtime     = (known after apply)
        }

      + identity {
          + principal_id = (known after apply)
          + tenant_id    = (known after apply)
          + type         = “SystemAssigned“
        }

      + network_profile {
          + dns_service_ip     = “10.1.0.10“
          + ip_versions        = (known after apply)
          + load_balancer_sku  = “standard“
          + network_data_plane = “azure“
          + network_mode       = (known after apply)
          + network_plugin     = “azure“
          + network_policy     = “azure“
          + outbound_type      = “loadBalancer“
          + pod_cidr           = (known after apply)
          + pod_cidrs          = (known after apply)
          + service_cidr       = “10.1.0.0/16“
          + service_cidrs      = (known after apply)
        }
    }

  # azurerm_network_security_group.nodes will be created
  + resource “azurerm_network_security_group“ “nodes“ {
      + id                  = (known after apply)
      + location            = “westeurope“
      + name                = “nsg-snet-aks-nodes“
      + resource_group_name = “test-rg“
      + security_rule       = [
          + {
              + access                                     = “Allow“
              + description                                = ““
              + destination_address_prefix                 = “*“
              + destination_address_prefixes               = []
              + destination_application_security_group_ids = []
              + destination_port_range                     = “*“
              + destination_port_ranges                    = []
              + direction                                  = “Inbound“
              + name                                       = “Allow_Azure_Load_Balancer“
              + priority                                   = 100
              + protocol                                   = “*“
              + source_address_prefix                      = “AzureLoadBalancer“
              + source_address_prefixes                    = []
              + source_application_security_group_ids      = []
              + source_port_range                          = “*“
              + source_port_ranges                         = []
            },
        ]
      + tags                = {
          + “managed_by“ = “terraform“
          + “project“    = “aks-demo“
        }
    }

  # azurerm_resource_group.main will be created
  + resource “azurerm_resource_group“ “main“ {
      + id       = (known after apply)
      + location = “westeurope“
      + name     = “test-rg“
      + tags     = {
          + “environment“ = “demo“
          + “managed_by“  = “terraform“
          + “project“     = “aks-demo“
        }
    }

  # azurerm_subnet.nodes will be created
  + resource “azurerm_subnet“ “nodes“ {
      + address_prefixes                                 = [
          + “10.0.1.0/24“,
        ]
      + default_outbound_access_enabled                  = true
      + id                                               = (known after apply)
      + name                                            = “snet-aks-nodes“
      + private_endpoint_network_policies               = “Disabled“
      + private_link_service_network_policies_enabled = true
      + resource_group_name                            = “test-rg“
      + virtual_network_name                           = “vnet-aks-demo“
    }

  # azurerm_subnet_network_security_group_association.nodes will be created
  + resource “azurerm_subnet_network_security_group_association“ “nodes“ {
      + id                         = (known after apply)
      + network_security_group_id = (known after apply)
      + subnet_id                 = (known after apply)
    }

  # azurerm_virtual_network.main will be created
  + resource “azurerm_virtual_network“ “main“ {
      + address_space               = [
          + “10.0.0.0/16“,
        ]
      + dns_servers                 = (known after apply)
      + guid                        = (known after apply)
      + id                          = (known after apply)
      + location                    = “westeurope“
      + name                        = “vnet-aks-demo“
      + private_endpoint_vnet_policies = “Disabled“
      + resource_group_name         = “test-rg“
      + subnet                      = (known after apply)
      + tags                        = {
          + “environment“ = “demo“
          + “managed_by“  = “terraform“
          + “project“     = “aks-demo“
        }
    }

Plan: 6 to add, 0 to change, 0 to destroy.

Changes to Outputs:
  + aks_cluster_id         = (known after apply)
  + aks_cluster_name       = “aks-demo“
  + aks_fqdn               = (known after apply)
  + aks_kubernetes_version = “1.33.7“
  + aks_node_count         = 2
  + aks_node_pool_name     = “agentpool“
  + az_get_credentials     = “az aks get-credentials —resource-group test-rg —name aks-demo —overwrite-existing“
  + kube_config_command    = “terraform output -raw kube_config_raw > ~/.kube/config-aks-demo && export KUBECONFIG=~/.kube/config-aks-demo“
  + kube_config_raw        = (sensitive value)
  + node_subnet_id         = (known after apply)
  + resource_group_name    = “test-rg“
  + vnet_name              = “vnet-aks-demo“

───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────

Saved the plan to: tfplan

To perform exactly these actions, run the following command to apply:
    terraform apply “tfplan“

输出显示将有 6 个新资源被创建,与我们定义的资源数量一致。-out=tfplan 参数将执行计划保存到文件,确保后续 apply 操作与此次计划完全一致。

5. 执行部署

确认计划无误后,使用保存的计划文件进行实际部署。

[root@k8sworker starttech]# terraform apply tfplan
azurerm_resource_group.main: Creating...
azurerm_resource_group.main: Still creating... [10s elapsed]
azurerm_resource_group.main: Still creating... [20s elapsed]
azurerm_resource_group.main: Still creating... [30s elapsed]
azurerm_resource_group.main: Creation complete after 31s [id=/subscriptions/c19511ad-c1ed-4f95-9d17-f0e83dc00af4/resourceGroups/test-rg]
azurerm_virtual_network.main: Creating...
azurerm_network_security_group.nodes: Creating...
azurerm_network_security_group.nodes: Creation complete after 8s [id=/subscriptions/c19511ad-c1ed-4f95-9d17-f0e83dc00af4/resourceGroups/test-rg/providers/Microsoft.Network/networkSecurityGroups/nsg-snet-aks-nodes]
azurerm_virtual_network.main: Still creating... [10s elapsed]
azurerm_virtual_network.main: Creation complete after 11s [id=/subscriptions/c19511ad-c1ed-4f95-9d17-f0e83dc00af4/resourceGroups/test-rg/providers/Microsoft.Network/virtualNetworks/vnet-aks-demo]
azurerm_subnet.nodes: Creating...
azurerm_subnet.nodes: Still creating... [10s elapsed]
azurerm_subnet.nodes: Creation complete after 12s [id=/subscriptions/c19511ad-c1ed-4f95-9d17-f0e83dc00af4/resourceGroups/test-rg/providers/Microsoft.Network/virtualNetworks/vnet-aks-demo/subnets/snet-aks-nodes]
azurerm_subnet_network_security_group_association.nodes: Creating...
azurerm_subnet_network_security_group_association.nodes: Still creating... [10s elapsed]
azurerm_subnet_network_security_group_association.nodes: Creation complete after 12s [id=/subscriptions/c19511ad-c1ed-4f95-9d17-f0e83dc00af4/resourceGroups/test-rg/providers/Microsoft.Network/virtualNetworks/vnet-aks-demo/subnets/snet-aks-nodes]
azurerm_kubernetes_cluster.main: Creating...
azurerm_kubernetes_cluster.main: Still creating... [10s elapsed]
azurerm_kubernetes_cluster.main: Still creating... [20s elapsed]
azurerm_kubernetes_cluster.main: Still creating... [30s elapsed]
azurerm_kubernetes_cluster.main: Still creating... [40s elapsed]
azurerm_kubernetes_cluster.main: Still creating... [50s elapsed]
azurerm_kubernetes_cluster.main: Still creating... [1m0s elapsed]
azurerm_kubernetes_cluster.main: Still creating... [1m10s elapsed]
azurerm_kubernetes_cluster.main: Still creating... [1m20s elapsed]
azurerm_kubernetes_cluster.main: Still creating... [1m30s elapsed]
azurerm_kubernetes_cluster.main: Still creating... [1m40s elapsed]
azurerm_kubernetes_cluster.main: Still creating... [1m50s elapsed]
azurerm_kubernetes_cluster.main: Still creating... [2m0s elapsed]
azurerm_kubernetes_cluster.main: Still creating... [2m10s elapsed]
azurerm_kubernetes_cluster.main: Still creating... [2m20s elapsed]
azurerm_kubernetes_cluster.main: Still creating... [2m30s elapsed]
azurerm_kubernetes_cluster.main: Still creating... [2m40s elapsed]
azurerm_kubernetes_cluster.main: Still creating... [2m50s elapsed]
azurerm_kubernetes_cluster.main: Still creating... [3m0s elapsed]
azurerm_kubernetes_cluster.main: Still creating... [3m10s elapsed]
azurerm_kubernetes_cluster.main: Still creating... [3m20s elapsed]
azurerm_kubernetes_cluster.main: Still creating... [3m30s elapsed]
azurerm_kubernetes_cluster.main: Still creating... [3m40s elapsed]
azurerm_kubernetes_cluster.main: Still creating... [3m50s elapsed]
azurerm_kubernetes_cluster.main: Still creating... [4m0s elapsed]
azurerm_kubernetes_cluster.main: Still creating... [4m10s elapsed]
azurerm_kubernetes_cluster.main: Still creating... [4m20s elapsed]
azurerm_kubernetes_cluster.main: Still creating... [4m30s elapsed]
azurerm_kubernetes_cluster.main: Still creating... [4m40s elapsed]
azurerm_kubernetes_cluster.main: Creation complete after 4m56s [id=/subscriptions/c19511ad-c1ed-4f95-9d17-f0e83dc00af4/resourceGroups/test-rg/providers/Microsoft.ContainerService/managedClusters/aks-demo]

Apply complete! Resources: 6 added, 0 changed, 0 destroyed.

Outputs:

aks_cluster_id = “/subscriptions/c19511ad-c1ed-4f95-9d17-f0e83dc00af4/resourceGroups/test-rg/providers/Microsoft.ContainerService/managedClusters/aks-demo“
aks_cluster_name = “aks-demo“
aks_fqdn = “aksdemo-qe7xqpzn.hcp.westeurope.azmk8s.io“
aks_kubernetes_version = “1.33.7“
aks_node_count = 2
aks_node_pool_name = “agentpool“
az_get_credentials = “az aks get-credentials —resource-group test-rg —name aks-demo —overwrite-existing“
kube_config_command = “terraform output -raw kube_config_raw > ~/.kube/config-aks-demo && export KUBECONFIG=~/.kube/config-aks-demo“
kube_config_raw = <sensitive>
node_subnet_id = “/subscriptions/c19511ad-c1ed-4f95-9d17-f0e83dc00af4/resourceGroups/test-rg/providers/Microsoft.Network/virtualNetworks/vnet-aks-demo/subnets/snet-aks-nodes“
resource_group_name = “test-rg“
vnet_name = “vnet-aks-demo“

最终输出 “Apply complete! Resources: 6 added”,表明所有资源已成功创建。

6. 在 Azure 门户中验证

部署完成后,可以登录 Azure 门户,在资源组中查看创建的所有资源。

Azure门户中创建的资源组列表,包含由Terraform管理的MC_test-rg-aks-demo_westeurope等

进入创建的 AKS 集群,可以在 “Workloads” 页面看到系统自动部署的核心组件(如 CoreDNS, metrics-server 等)均已正常运行。

Azure AKS集群Workloads页面,显示CoreDNS等系统部署状态

7. 使用 kubectl 查看 AKS 集群资源

现在,我们可以使用 Terraform 输出的 kubeconfig 连接到集群。按照输出提示的命令操作:

[root@k8sworker starttech]# terraform output -raw kube_config_raw > ~/.kube/config
[root@k8sworker starttech]# ls -la ~/.kube/
total 16
drwxr-xr-x.  3 root root   33 Mar 28 14:09 .
dr-xr-x—-. 18 root root 4096 Apr  1 22:15 ..
drwxr-x—-.  4 root root   35 Mar 28 14:09 cache
-rw——-—-.  1 root root 9662 Apr  5 13:39 config
[root@k8sworker starttech]# kubectl get nodes
NAME                                STATUS   ROLES    AGE     VERSION
aks-agentpool-37018275-vmss000000   Ready    <none>   4m52s   v1.33.7
aks-agentpool-37018275-vmss000001   Ready    <none>   4m51s   v1.33.7

两个节点状态均为 Ready,说明 Kubernetes 集群已成功就绪,可以开始部署应用。

8. 销毁资源(清理环境)

完成测试后,为了不产生额外费用,应销毁所有创建的资源。Terraform 使这一过程变得非常简单。

8.1 查看当前状态管理的资源

[root@k8sworker starttech]# terraform state list
azurerm_kubernetes_cluster.main
azurerm_network_security_group.nodes
azurerm_resource_group.main
azurerm_subnet.nodes
azurerm_subnet_network_security_group_association.nodes
azurerm_virtual_network.main

8.2 执行销毁
可以直接运行 terraform destroy,它会自动计算依赖关系并按正确顺序销毁所有资源。在确认提示中输入 yes
(由于 terraform destroy 的输出非常长,此处省略中间详细的销毁过程日志)

...
Do you really want to destroy all resources?
  Terraform will destroy all your managed infrastructure, as shown above.
  There is no undo. Only ‘yes’ will be accepted to confirm.

  Enter a value: yes
...
Destroy complete! Resources: 6 destroyed.

最终提示 “Resources: 6 destroyed.”,表示由 Terraform 管理的 6 个核心资源已被成功删除。

注意:在 Azure 门户中检查,可能会发现一个名为 NetworkWatcherRG 的资源组仍然存在。

Azure门户中残留的NetworkWatcherRG资源组

这是因为 NetworkWatcherRG 是 Azure 平台为了提供网络监控功能而自动创建的资源组,它不属于我们的 Terraform 配置管理范围,因此 terraform destroy 不会删除它。这是正常现象。

如果需要删除这个资源组,可以使用 Azure CLI 命令:

az group delete —name NetworkWatcherRG —yes —no-wait

总结

通过本文的实践,我们完成了一个完整的基于 Terraform 的 Azure AKS 集群生命周期管理,包括编写声明式配置、规划变更、自动化部署、验证以及一键式清理。这充分展示了基础设施即代码在提升效率、保证环境一致性和实现版本控制方面的巨大价值。无论是用于开发测试环境的快速搭建,还是为生产环境制定可靠的部署流程,这套方法都极具参考意义。

希望这篇在 云栈社区 分享的实战指南能帮助你更好地利用 Terraform 驾驭 Azure 云原生资源。如果你在实践过程中遇到问题,或有更优的配置方案,欢迎交流探讨。




上一篇:基于 Laravel 12 + Swoole + Vue3 的一站式开源后台系统构建方案
下一篇:OpenClaw安全部署指南:遵循TC260官方指引的7大核心要点
您需要登录后才可以回帖 登录 | 立即注册

手机版|小黑屋|网站地图|云栈社区 ( 苏ICP备2022046150号-2 )

GMT+8, 2026-4-7 18:16 , Processed in 1.000731 second(s), 41 queries , Gzip On.

Powered by Discuz! X3.5

© 2025-2026 云栈社区.

快速回复 返回顶部 返回列表