你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn

快速入门:使用 Terraform 部署适用于 AKS 的 Azure Linux 容器主机群集

通过使用 Terraform 部署 Azure Linux 容器主机群集,开始使用 Azure Linux 容器主机。 安装必备组件后,可实施 Terraform 代码、初始化 Terraform、创建并应用 Terraform 执行计划。

使用 Terraform 可以定义、预览和部署云基础结构。 使用 Terraform 时,请使用 HCL 语法来创建配置文件。 利用 HCL 语法,可指定云提供程序和构成云基础结构的元素。 创建配置文件后,请创建一个执行计划,利用该计划,可在部署基础结构更改之前先预览这些更改。 验证了更改后,请应用该执行计划以部署基础结构。

注意

本文中的示例代码位于 Microsoft Terraform GitHub 存储库中。

先决条件

创建 SSH 密钥对

若要访问 AKS 节点,请使用通过 ssh-keygen 命令生成的 SSH 密钥对(公钥和私钥)进行连接。 默认情况下,这些文件在 ~/.ssh 目录中创建。 运行 ssh-keygen 命令会覆盖给定位置中同名的任何 SSH 密钥对。

  1. 在浏览器中访问 https://shell.azure.com 以打开 Cloud Shell。

  2. 运行 ssh-keygen 命令。 以下示例使用 RSA 加密和 4096 位长度创建 SSH 密钥对:

    ssh-keygen -t rsa -b 4096
    

有关创建 SSH 密钥的详细信息,请参阅在 Azure 中创建和管理用于身份验证的 SSH 密钥

实现 Terraform 代码

  1. 创建用于测试和运行示例 Terraform 代码的目录,并将其设为当前目录。

  2. 创建名为 providers.tf 的文件并插入下列代码:

        terraform {
          required_version = ">=1.0"
    
          required_providers {
            azurerm = {
              source  = "hashicorp/azurerm"
              version = "~>3.0"
            }
            random = {
              source  = "hashicorp/random"
              version = "~>3.0"
            }
          }
        }
    
        provider "azurerm" {
          features {}
        }
    
  3. 创建名为 main.tf 的文件并插入下列代码:

        # Generate random resource group name
        resource "random_pet" "rg_name" {
          prefix = var.resource_group_name_prefix
        }
    
        resource "azurerm_resource_group" "rg" {
          location = var.resource_group_location
          name     = random_pet.rg_name.id
        }
    
        resource "random_id" "log_analytics_workspace_name_suffix" {
          byte_length = 8
        }
    
        resource "azurerm_log_analytics_workspace" "test" {
          location            = var.log_analytics_workspace_location
          # The WorkSpace name has to be unique across the whole of azure;
          # not just the current subscription/tenant.
          name                = "${var.log_analytics_workspace_name}-${random_id.log_analytics_workspace_name_suffix.dec}"
          resource_group_name = azurerm_resource_group.rg.name
          sku                 = var.log_analytics_workspace_sku
        }
    
        resource "azurerm_log_analytics_solution" "test" {
          location              = azurerm_log_analytics_workspace.test.location
          resource_group_name   = azurerm_resource_group.rg.name
          solution_name         = "ContainerInsights"
          workspace_name        = azurerm_log_analytics_workspace.test.name
          workspace_resource_id = azurerm_log_analytics_workspace.test.id
    
          plan {
            product   = "OMSGallery/ContainerInsights"
            publisher = "Microsoft"
          }
        }
    
        resource "azurerm_kubernetes_cluster" "k8s" {
          location            = azurerm_resource_group.rg.location
          name                = var.cluster_name
          resource_group_name = azurerm_resource_group.rg.name
          dns_prefix          = var.dns_prefix
          tags                = {
            Environment = "Development"
          }
    
          default_node_pool {
            name       = "azurelinuxpool"
            vm_size    = "Standard_D2_v2"
            node_count = var.agent_count
            os_sku = "AzureLinux"
          }
          linux_profile {
            admin_username = "azurelinux"
    
            ssh_key {
              key_data = file(var.ssh_public_key)
            }
          }
          network_profile {
            network_plugin    = "kubenet"
            load_balancer_sku = "standard"
          }
          service_principal {
            client_id     = var.aks_service_principal_app_id
            client_secret = var.aks_service_principal_client_secret
          }
        }
    

    同样,可以在 azurerm_kubernetes_cluster_node_pool 中指定 Azure Linux os_sku

  4. 创建名为 variables.tf 的文件并插入下列代码:

        variable "agent_count" {
            default = 3
        }
    
        # The following two variable declarations are placeholder references.
        # Set the values for these variable in terraform.tfvars
        variable "aks_service_principal_app_id" {
          default = ""
        }
    
        variable "aks_service_principal_client_secret" {
          default = ""
        }
    
        variable "cluster_name" {
          default = "k8stest"
        }
    
        variable "dns_prefix" {
          default = "k8stest"
        }
    
        # Refer to https://azure.microsoft.com/global-infrastructure/services/?products=monitor for available Log Analytics regions.
        variable "log_analytics_workspace_location" {
          default = "eastus"
        }
    
        variable "log_analytics_workspace_name" {
          default = "testLogAnalyticsWorkspaceName"
        }
    
        # Refer to https://azure.microsoft.com/pricing/details/monitor/ for Log Analytics pricing
        variable "log_analytics_workspace_sku" {
          default = "PerGB2018"
        }
    
        variable "resource_group_location" {
          default     = "eastus"
          description = "Location of the resource group."
        }
    
        variable "resource_group_name_prefix" {
          default     = "rg"
          description = "Prefix of the resource group name that's combined with a random ID so name is unique in your Azure subscription."
        }
    
        variable "ssh_public_key" {
          default = "~/.ssh/id_rsa.pub"
        }
    
  5. 创建名为 outputs.tf 的文件并插入下列代码:

        output "client_certificate" {
          value     = azurerm_kubernetes_cluster.k8s.kube_config[0].client_certificate
          sensitive = true
        }
    
        output "client_key" {
          value     = azurerm_kubernetes_cluster.k8s.kube_config[0].client_key
          sensitive = true
        }
    
        output "cluster_ca_certificate" {
          value     = azurerm_kubernetes_cluster.k8s.kube_config[0].cluster_ca_certificate
          sensitive = true
        }
    
        output "cluster_password" {
          value     = azurerm_kubernetes_cluster.k8s.kube_config[0].password
          sensitive = true
        }
    
        output "cluster_username" {
          value     = azurerm_kubernetes_cluster.k8s.kube_config[0].username
          sensitive = true
        }
    
        output "host" {
          value     = azurerm_kubernetes_cluster.k8s.kube_config[0].host
          sensitive = true
        }
    
        output "kube_config" {
          value     = azurerm_kubernetes_cluster.k8s.kube_config_raw
          sensitive = true
        }
    
        output "resource_group_name" {
          value = azurerm_resource_group.rg.name
        }
    
  6. 创建名为 terraform.tfvars 的文件并插入下列代码:

        aks_service_principal_app_id = "<service_principal_app_id>"
        aks_service_principal_client_secret = "<service_principal_password>"
    

初始化 Terraform 并创建执行计划

  1. 使用 terraform init 命令初始化 Terraform 并下载管理 Azure 资源所需的 Azure 模块。

    terraform init
    
  2. 使用 terraform plan 命令创建 Terraform 执行计划。

    terraform plan -out main.tfplan
    

    terraform plan 命令将创建一个执行计划,但不会执行它。 它会确定创建配置文件中指定的配置需要执行哪些操作。 此模式允许你在对实际资源进行任何更改之前验证执行计划是否符合预期。

    使用可选 -out 参数可以为计划指定输出文件。 使用 -out 参数可以确保所查看的计划与所应用的计划完全一致。

    若要详细了解如何使执行计划和安全性持久化,请参阅安全警告

  3. 使用 terraform apply 命令应用 Terraform 执行计划。

    terraform apply main.tfplan
    

    上面的 terraform apply 命令假设之前运行了 terraform plan -out main.tfplan。 如果为 -out 参数指定了不同的文件名,请在对 terraform apply 的调用中使用相同的文件名。 如果未使用 -out 参数,请调用不带任何参数的 terraform apply

验证结果

  1. 请使用以下 echo 命令获取资源组名称。

    echo "$(terraform output resource_group_name)"
    
  2. 浏览到 Azure 门户

  3. 在“Azure 服务”下,选择“资源组”并找到新的资源组,以查看在此演示中创建的以下资源:

    • 解决方案:默认情况下,该演示会将此解决方案命名为 ContainerInsights。 门户会在括号中显示解决方案的工作区名称。
    • Kubernetes 服务:默认情况下,该演示会将此服务命名为 k8stest。 (托管 Kubernetes 群集也称为 AKS/Azure Kubernetes 服务。)
    • Log Analytics 工作区:默认情况下,该演示以前缀 TestLogAnalyticsWorkspaceName- 后跟随机数的形式来命名此工作区。
  4. 使用以下 echo 命令从 Terraform 状态中获取 Kubernetes 配置,并将其存储在 kubectl 可以读取的文件中。

    echo "$(terraform output kube_config)" > ./azurek8s
    
  5. 使用以下命令 cat 确认上一个命令未添加 ASCII EOT 字符。

    cat ./azurek8s
    

    如果在开头看到 << EOT,在末尾看到 EOT,请从文件中移除这些字符。 否则,可能会收到以下错误消息:error: error loading config file "./azurek8s": yaml: line 2: mapping values are not allowed in this context

  6. 使用以下 export 命令设置环境变量,以便 kubectl 选取正确的配置。

    export KUBECONFIG=./azurek8s
    
  7. 使用 kubectl get nodes 命令验证群集的运行状况。

    kubectl get nodes
    

    创建 Azure Linux 容器主机群集以后,已启用监视功能来捕获群集节点和 Pod 的运行状况指标。 Azure 门户提供这些运行状况指标。 有关容器运行状况监视的详细信息,请参阅监视 Azure Kubernetes 服务运行状况

    应用 Terraform 执行计划时输出了几个键值。 例如,将输出主机地址、Azure Linux 容器主机群集用户名和 Azure Linux 容器主机群集密码。

    若要查看所有输出值,请运行 terraform output。 若要查看特定的输出值,请运行 echo "$(terraform output <output_value_name>)"

清理资源

删除 AKS 资源

如果不再需要使用 Terraform 创建的资源,则可以使用以下步骤将其删除。

  1. 运行 terraform plan 命令并指定 destroy 标志。

    terraform plan -destroy -out main.destroy.tfplan
    
  2. 使用 terraform apply 命令删除执行计划。

    terraform apply main.destroy.tfplan
    

删除服务主体

注意

仅当无需将此演示中使用的服务主体用于其他用途时,才将其删除。

  1. 使用 az ad sp list 命令获取服务主体的对象 ID

    az ad sp list --display-name "<display_name>" --query "[].{\"Object ID\":id}" --output table
    
  2. 使用 az ad sp delete 命令删除服务主体。

    az ad sp delete --id <service_principal_object_id>
    

Azure 上的 Terraform 故障排除

排查在 Azure 上使用 Terraform 时遇到的常见问题

后续步骤

在本快速入门中,你部署了 Azure Linux 容器主机群集。 若要详细了解 Azure Linux 容器主机,并演练完整的群集部署和管理示例,请继续学习 Azure Linux 容器主机教程。