Szybki start: tworzenie klastra Kubernetes przy użyciu Azure Kubernetes Service przy użyciu narzędzia Terraform

Usługa Azure Kubernetes Service (AKS) zarządza hostowanym środowiskiem Kubernetes. Usługa AKS umożliwia wdrażanie konteneryzowanych aplikacji i zarządzanie nimi bez wiedzy dotyczącej orkiestracji kontenerów. Usługa AKS umożliwia również wykonywanie wielu typowych operacji konserwacji bez przełączania aplikacji w tryb offline. Te operacje obejmują aprowizowanie, uaktualnianie i skalowanie zasobów na żądanie.

W tym artykule pokazano, jak utworzyć klaster Kubernetes z Azure Kubernetes Service (AKS) przy użyciu narzędzia Terraform. Przykładowy kod jest w pełni hermetyzowany, tak aby automatycznie tworzył jednostkę usługi i parę kluczy SSH (przy użyciu dostawcy AzAPI).

W tym artykule omówiono sposób wykonywania następujących zadań:

Uwaga

Ten artykuł został częściowo utworzony za pomocą sztucznej inteligencji. Przed opublikowaniem autor przejrzył i skorygował zawartość zgodnie z potrzebami. Zobacz Nasze zasady dotyczące używania zawartości wygenerowanej przez sztuczną inteligencję w usłudze Microsoft Learn.

Wymagania wstępne

Implementowanie kodu narzędzia Terraform

  1. Utwórz katalog, w którym chcesz przetestować przykładowy kod narzędzia Terraform i utwórz go jako bieżący katalog.

  2. Utwórz plik o nazwie providers.tf i wstaw następujący kod:

    terraform {
      required_version = ">=1.0"
    
      required_providers {
        azapi = {
          source  = "azure/azapi"
          version = "~>1.5"
        }
        azurerm = {
          source  = "hashicorp/azurerm"
          version = "~>3.0"
        }
        random = {
          source  = "hashicorp/random"
          version = "~>3.0"
        }
        time = {
          source  = "hashicorp/time"
          version = "0.9.1"
        }
      }
    }
    
    provider "azurerm" {
      features {}
    }
    
  3. Utwórz plik o nazwie sp.tf i wstaw następujący kod:

    # Create Azure AD App Registration
    resource "azuread_application" "app" {
      display_name = "my-app"
      owners       = [local.current_user_id]
    }
    
    # Create Service Principal
    resource "azuread_service_principal" "app" {
      application_id               = azuread_application.app.application_id
      app_role_assignment_required = true
      owners                       = [local.current_user_id]
    }
    
    # Create Service Principal password
    resource "azuread_service_principal_password" "app" {
      service_principal_id = azuread_service_principal.app.id
    }
    
    # Sleep for 30 seconds to allow for propagation
    # of the Service Principal creation before attempting
    # to create the AKS cluster.
    resource "time_sleep" "wait_30_seconds" {
      create_duration = "30s"
    
      depends_on = [azuread_service_principal_password.app]
    }
    
    # Output the Service Principal and password
    output "sp" {
      value     = azuread_service_principal.app.id
      sensitive = true
    }
    
    output "sp_password" {
      value     = azuread_service_principal_password.app.value
      sensitive = true
    }
    
  4. Utwórz plik o nazwie ssh.tf i wstaw następujący kod:

    resource "random_pet" "ssh_key_name" {
      prefix    = "ssh"
      separator = ""
    }
    
    resource "azapi_resource" "ssh_public_key" {
      type      = "Microsoft.Compute/sshPublicKeys@2022-11-01"
      name      = random_pet.ssh_key_name.id
      location  = "westus3"
      parent_id = azurerm_resource_group.rg.id
    }
    
    resource "azapi_resource_action" "ssh_public_key_gen" {
      type        = "Microsoft.Compute/sshPublicKeys@2022-11-01"
      resource_id = azapi_resource.ssh_public_key.id
      action      = "generateKeyPair"
      method      = "POST"
    
      response_export_values = ["publicKey"]
    }
    
    output "key_data" {
      value     = azapi_resource.ssh_public_key.body
      sensitive = true
    }
    
  5. Utwórz plik o nazwie main.tf i wstaw następujący kod:

    # 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
    }
    
    data "azurerm_client_config" "current" {}
    
    locals {
      current_user_id = coalesce(var.msi_id, data.azurerm_client_config.current.object_id)
    }
    
    resource "random_pet" "azurerm_log_analytics_workspace_name" {
      prefix = "ws"
    }
    
    resource "azurerm_log_analytics_workspace" "test" {
      location            = var.log_analytics_workspace_location
      name                = random_pet.azurerm_log_analytics_workspace_name.id
      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 "random_pet" "azurerm_kubernetes_cluster_name" {
      prefix = "cluster"
    }
    
    resource "random_pet" "azurerm_kubernetes_cluster_dns_prefix" {
      prefix = "dns"
    }
    
    resource "azurerm_kubernetes_cluster" "k8s" {
      location            = azurerm_resource_group.rg.location
      name                = random_pet.azurerm_kubernetes_cluster_name.id
      resource_group_name = azurerm_resource_group.rg.name
      dns_prefix          = random_pet.azurerm_kubernetes_cluster_dns_prefix.id
    
      default_node_pool {
        name       = "agentpool"
        vm_size    = "Standard_D2_v2"
        node_count = var.node_count
      }
      linux_profile {
        admin_username = "ubuntu"
    
        ssh_key {
          key_data = jsondecode(azapi_resource_action.ssh_public_key_gen.output).publicKey
        }
      }
      network_profile {
        network_plugin    = "kubenet"
        load_balancer_sku = "standard"
      }
      service_principal {
        client_id     = azuread_service_principal.app.application_id
        client_secret = azuread_service_principal_password.app.value
      }
    
      depends_on = [time_sleep.wait_30_seconds]
    }
    
  6. Utwórz plik o nazwie variables.tf i wstaw następujący kod:

    variable "resource_group_location" {
      type        = string
      default     = "eastus"
      description = "Location of the resource group."
    }
    
    variable "resource_group_name_prefix" {
      type        = string
      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 "node_count" {
      type        = number
      description = "The initial quantity of nodes for the node pool."
      default     = 3
    }
    
    # For available Log Analytics regions, refer to:
    # https://azure.microsoft.com/global-infrastructure/services/?products=monitor
    variable "log_analytics_workspace_location" {
      type        = string
      default     = "eastus"
      description = "Location of the Log Analytics workspace."
    }
    
    # For Log Analytics pricing, refer to:
    # https://azure.microsoft.com/pricing/details/monitor
    variable "log_analytics_workspace_sku" {
      type        = string
      description = "The SKU of the Log Analytics workspace. Choose from: Free, PerNode, Premium, Standard, Standalone, Unlimited, CapacityReservation, PerGB2018"
      default     = "PerGB2018"
    
      validation {
        condition     = contains(["Free", "PerNode", "Premium", "Standard", "Standalone", "Unlimited", "CapacityReservation", "PerGB2018"], var.log_analytics_workspace_sku)
        error_message = "The Log Analytics workspace SKU must be one of the following: Free, PerNode, Premium, Standard, Standalone, Unlimited, CapacityReservation, PerGB2018"
      }
    }
    
    variable "msi_id" {
      type        = string
      description = "The Managed Service Identity ID used to create the service principal. If this value is null (the default), the AzureRM provider configuration Object ID is used.."
      default     = null
    }
    
  7. Utwórz plik o nazwie outputs.tf i wstaw następujący kod:

    output "resource_group_name" {
      value = azurerm_resource_group.rg.name
    }
    
    output "kubernetes_cluster_name" {
      value = azurerm_kubernetes_cluster.k8s.name
    }
    
    output "log_analytics_workspace_name" {
      value = azurerm_log_analytics_workspace.test.name
    }
    
    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
    }
    

Inicjowanie narzędzia Terraform

Uruchom narzędzie terraform init, aby zainicjować wdrożenie narzędzia Terraform. To polecenie pobiera dostawcę platformy Azure wymaganego do zarządzania zasobami platformy Azure.

terraform init -upgrade

Kluczowe punkty:

  • -upgrade Parametr uaktualnia niezbędne wtyczki dostawcy do najnowszej wersji, która jest zgodna z ograniczeniami wersji konfiguracji.

Tworzenie planu wykonania programu Terraform

Uruchom plan terraform , aby utworzyć plan wykonania.

terraform plan -out main.tfplan

Kluczowe punkty:

  • Polecenie terraform plan tworzy plan wykonania, ale go nie wykonuje. Zamiast tego określa, jakie akcje są niezbędne do utworzenia konfiguracji określonej w plikach konfiguracji. Ten wzorzec umożliwia sprawdzenie, czy plan wykonania jest zgodny z oczekiwaniami przed wprowadzeniem jakichkolwiek zmian w rzeczywistych zasobach.
  • Opcjonalny -out parametr umożliwia określenie pliku wyjściowego planu. Użycie parametru -out gwarantuje, że zweryfikowany plan jest dokładnie stosowany.
  • Aby dowiedzieć się więcej na temat utrwalania planów wykonywania i zabezpieczeń, zobacz sekcję Ostrzeżenie o zabezpieczeniach.

Stosowanie planu wykonywania narzędzia Terraform

Uruchom narzędzie terraform, aby zastosować plan wykonywania do infrastruktury chmury.

terraform apply main.tfplan

Kluczowe punkty:

  • terraform apply Przykładowe polecenie zakłada, że wcześniej uruchomiono terraform plan -out main.tfplanpolecenie .
  • Jeśli określono inną nazwę pliku dla parametru -out , użyj tej samej nazwy pliku w wywołaniu metody terraform apply.
  • Jeśli nie użyto parametru, wywołaj metodę -outterraform apply bez żadnych parametrów.

Weryfikowanie wyników

  1. Pobierz nazwę grupy zasobów platformy Azure.

    resource_group_name=$(terraform output -raw resource_group_name)
    
  2. Uruchom polecenie az monitor log-analytics workspace list ,aby wyświetlić nazwę nowego obszaru roboczego usługi Log Analytics.

    az monitor log-analytics workspace list \
      --resource-group $resource_group_name \
      --query "[].{\"Workspace name\":name}" \
      --output table  
    
  3. Uruchom polecenie az monitor log-analytics solution list , aby wyświetlić nazwę nowego rozwiązania usługi Log Analytics.

    az monitor log-analytics solution list \
      --resource-group $resource_group_name \
      --query "value[*].{\"Solution name\":name}" \
      --output table  
    

    Kluczowe punkty:

    • Wartość w nawiasach to nazwa obszaru roboczego usługi Log Analytics, w którym utworzono rozwiązanie log analityczne.
  4. Uruchom polecenie az aks list , aby wyświetlić nazwę nowego klastra Kubernetes.

    az aks list \
      --resource-group $resource_group_name \
      --query "[].{\"K8s cluster name\":name}" \
      --output table
    
  5. Pobierz konfigurację usługi Kubernetes ze stanu narzędzia Terraform i zapisz ją w pliku możliwym do odczytania przez narzędzie kubectl.

    echo "$(terraform output kube_config)" > ./azurek8s
    
  6. Sprawdź, czy poprzednie polecenie nie dodało znaku ASCII EOT.

    cat ./azurek8s
    

    Kluczowe punkty:

    • Jeśli zobaczysz << EOT na początku i EOT na końcu, usuń te znaki z pliku. W przeciwnym razie może zostać wyświetlony następujący komunikat o błędzie: error: error loading config file "./azurek8s": yaml: line 2: mapping values are not allowed in this context
  7. Ustaw zmienną środowiskową tak, aby narzędzie kubectl pobrało poprawną konfigurację.

    export KUBECONFIG=./azurek8s
    
  8. Sprawdź kondycję klastra.

    kubectl get nodes
    

    Narzędzie kubectl umożliwia sprawdzenie kondycji klastra Kubernetes

Kluczowe punkty:

  • Podczas tworzenia klastra AKS włączono monitorowanie, aby przechwycić metryki kondycji dla zasobników i węzłów klastra. Te metryki kondycji są dostępne w witrynie Azure Portal. Aby uzyskać więcej informacji dotyczących monitorowania kondycji kontenera, zobacz Monitorowanie kondycji usługi Azure Kubernetes Service.
  • Podczas stosowania planu wykonywania narzędzia Terraform było kilka wartości kluczowych. Na przykład adres hosta, nazwa użytkownika klastra usługi AKS i hasło klastra usługi AKS są danymi wyjściowymi.

Czyszczenie zasobów

Usuwanie zasobów usługi AKS

Jeśli zasoby utworzone za pomocą narzędzia Terraform nie są już potrzebne, wykonaj następujące czynności:

  1. Uruchom plan narzędzia terraform i określ flagę destroy .

    terraform plan -destroy -out main.destroy.tfplan
    

    Kluczowe punkty:

    • Polecenie terraform plan tworzy plan wykonania, ale go nie wykonuje. Zamiast tego określa, jakie akcje są niezbędne do utworzenia konfiguracji określonej w plikach konfiguracji. Ten wzorzec umożliwia sprawdzenie, czy plan wykonania jest zgodny z oczekiwaniami przed wprowadzeniem jakichkolwiek zmian w rzeczywistych zasobach.
    • Opcjonalny -out parametr umożliwia określenie pliku wyjściowego planu. Użycie parametru -out gwarantuje, że zweryfikowany plan jest dokładnie stosowany.
    • Aby dowiedzieć się więcej na temat utrwalania planów wykonywania i zabezpieczeń, zobacz sekcję Ostrzeżenie o zabezpieczeniach.
  2. Uruchom narzędzie terraform, aby zastosować plan wykonania.

    terraform apply main.destroy.tfplan
    

Usuwanie jednostki usługi

  1. Pobierz identyfikator jednostki usługi.

    sp=$(terraform output -raw sp)
    
  2. Uruchom polecenie az ad sp delete , aby usunąć jednostkę usługi.

    az ad sp delete --id $sp
    

Rozwiązywanie problemów z programem Terraform na platformie Azure

Rozwiązywanie typowych problemów podczas korzystania z narzędzia Terraform na platformie Azure

Następne kroki