Compartir vía


Inicio rápido: Configuración de la copia de seguridad con almacenes para un clúster de Azure Kubernetes Service (AKS) mediante Terraform

En este inicio rápido, se describe cómo configurar la copia de seguridad con almacenes para un clúster de Azure Kubernetes Service (AKS) mediante Terraform.

Azure Backup para AKS es un servicio de copia de seguridad nativo de nube, listo para la empresa y centrado en las aplicaciones que le permite configurar rápidamente la copia de seguridad de los clústeres de AKS.

Nota

Los pasos que se incluyen en este artículo sobre cómo implementar un clúster y protegerlo con la copia de seguridad de AKS son solo con fines de evaluación.

Antes de implementar un clúster listo para producción y usar la configuración avanzada de la copia de seguridad, se recomienda familiarizarse con nuestra arquitectura de referencia de línea base para tener en cuenta cómo se alinea con sus requisitos empresariales.

Requisitos previos

Aspectos que se deben asegurar antes de configurar la copia de seguridad de AKS:

  • En esta guía rápida se presupone un conocimiento básico de los conceptos de Kubernetes. Para obtener más información, consulte [Conceptos básicos de Kubernetes para Azure Kubernetes Service (AKS)][kubernetes-concepts].

  • Necesita una cuenta de Azure con una suscripción activa. Si no tiene ninguna cuenta, cree una gratuita.

  • Instalación y configuración de Terraform.

Nota

Asegúrese de que la versión de Terraform que se usa es la 3.99 o posterior

Inicio de sesión en la cuenta de Azure

Inicie sesión en la cuenta de Azure y autentíquese con uno de los métodos siguientes:

Terraform solo admite la autenticación en Azure con la CLI de Azure. No se admite la autenticación con Azure PowerShell. Por tanto, aunque puede usar el módulo de Azure PowerShell al realizar el trabajo de Terraform, primero debe autenticarse en Azure.

Implementación del código de Terraform

Para implementar el código de Terraform para el flujo de copia de seguridad de AKS, ejecute los siguientes scripts:

  1. Cree un directorio que pueda usar para probar el código de ejemplo de Terraform y conviértalo en el directorio actual.

  2. Cree un archivo llamado providers.tf e inserte el siguiente código:

    terraform {
      required_providers {
        azurerm = {
          source = "hashicorp/azurerm"
          version = "3.99.0"
        }
      }
    }
    
    provider "azurerm" {
       features {}
       subscription_id   = "<azure_subscription_id>"
       tenant_id = "<azure_subscription_tenant_id>"
    }
    
  3. Cree un archivo llamado main.tf e inserte el siguiente código:

     #Get Subscription and Tenant Id from Config
    
    data "azurerm_client_config" "current" {
    }
    
    #Create a Resource Group where Backup Vault and AKS Cluster will be created
    resource "azurerm_resource_group" "rg" {
      location = var.resource_group_location
      name     = var.resource_group_name
    }
    
    #Create a Resource Group where Storage Account and Snapshots related to backup will be created
    resource "azurerm_resource_group" "backuprg" {
      location = var.backup_resource_group_location
      name = var.backup_resource_group_name
    }
    
    #Create an AKS Cluster 
    resource "azurerm_kubernetes_cluster" "akscluster" {
      resource_group_name = azurerm_resource_group.rg.name
      name           = var.aks_cluster_name
      location       = azurerm_resource_group.rg.location
      dns_prefix     = var.dns_prefix
    
      identity {
        type = "SystemAssigned"
      }
    
      default_node_pool {
        name       = "agentpool"
        vm_size    = "Standard_D2_v2"
        node_count = var.node_count
      }
    
      network_profile {
        network_plugin    = "kubenet"
        load_balancer_sku = "standard"
      }
    
      depends_on = [azurerm_resource_group.rg,azurerm_resource_group.backuprg]
    }
    
    #Create a Backup Vault
    resource "azurerm_data_protection_backup_vault" "backupvault" {
      name                = var.backupvault_name
      resource_group_name = resource.azurerm_resource_group.rg.name
      location            = resource.azurerm_resource_group.rg.location
      datastore_type      = var.datastore_type
      redundancy          = var.redundancy
    
      identity {
        type = "SystemAssigned"
      }
      depends_on = [azurerm_kubernetes_cluster.akscluster]
    }
    
    #Create a Backup Policy with 4 hourly backups and 7 day retention duration
    resource "azurerm_data_protection_backup_policy_kubernetes_cluster" "policy" {
      name                = var.backuppolicy_name
      resource_group_name = var.resource_group_name
      vault_name          = var.backupvault_name
    
      backup_repeating_time_intervals = ["R/2024-04-14T06:33:16+00:00/PT4H"]
      default_retention_rule {
        life_cycle {
          duration        = "P7D"
          data_store_type = "OperationalStore"
        }
      }
    depends_on = [resource.azurerm_data_protection_backup_vault.backupvault]
    }
    
    #Create a Trusted Access Role Binding between AKS Cluster and Backup Vault
    resource "azurerm_kubernetes_cluster_trusted_access_role_binding" "trustedaccess" {
      kubernetes_cluster_id = azurerm_kubernetes_cluster.akscluster.id
      name                  = "backuptrustedaccess"
      roles                 = ["Microsoft.DataProtection/backupVaults/backup-operator"]
      source_resource_id    = azurerm_data_protection_backup_vault.backupvault.id
      depends_on = [resource.azurerm_data_protection_backup_vault.backupvault, azurerm_kubernetes_cluster.akscluster]
    }
    
    #Create a Backup Storage Account provided in input for Backup Extension Installation
    resource "azurerm_storage_account" "backupsa" {
      name                     = "tfaksbackup1604"
      resource_group_name      = azurerm_resource_group.backuprg.name
      location                 = azurerm_resource_group.backuprg.location
      account_tier             = "Standard"
      account_replication_type = "LRS"
      depends_on = [azurerm_kubernetes_cluster_trusted_access_role_binding.trustedaccess]
    }
    
    #Create a Blob Container where backup items will stored
    resource "azurerm_storage_container" "backupcontainer" {
      name                  = "tfbackup"
      storage_account_name  = azurerm_storage_account.backupsa.name
      container_access_type = "private"
      depends_on = [azurerm_storage_account.backupsa]
    }
    
    #Create Backup Extension in AKS Cluster
    resource "azurerm_kubernetes_cluster_extension" "dataprotection" {
      name = var.backup_extension_name
      cluster_id = azurerm_kubernetes_cluster.akscluster.id
      extension_type = var.backup_extension_type
      configuration_settings = {
        "configuration.backupStorageLocation.bucket" = azurerm_storage_container.backupcontainer.name
         "configuration.backupStorageLocation.config.storageAccount" = azurerm_storage_account.backupsa.name
         "configuration.backupStorageLocation.config.resourceGroup" = azurerm_storage_account.backupsa.resource_group_name
         "configuration.backupStorageLocation.config.subscriptionId" =  data.azurerm_client_config.current.subscription_id
         "credentials.tenantId" = data.azurerm_client_config.current.tenant_id
         "configuration.backupStorageLocation.config.useAAD" = true
         "configuration.backupStorageLocation.config.storageAccountURI" = azurerm_storage_account.backupsa.primary_blob_endpoint
        }
      depends_on = [azurerm_storage_container.backupcontainer]
    }
    
    #Assign Role to Extension Identity over Storage Account
    resource "azurerm_role_assignment" "extensionrole" {
      scope                = azurerm_storage_account.backupsa.id
      role_definition_name = "Storage Blob Data Contributor"
      principal_id         = azurerm_kubernetes_cluster_extension.dataprotection.aks_assigned_identity[0].principal_id
      depends_on = [azurerm_kubernetes_cluster_extension.dataprotection]
    }
    
    #Assign Role to Backup Vault over AKS Cluster
    resource "azurerm_role_assignment" "vault_msi_read_on_cluster" {
      scope                = azurerm_kubernetes_cluster.akscluster.id
      role_definition_name = "Reader"
      principal_id         = azurerm_data_protection_backup_vault.backupvault.identity[0].principal_id
      depends_on = [azurerm_kubernetes_cluster.akscluster,resource.azurerm_data_protection_backup_vault.backupvault]
    }
    
    #Assign Role to Backup Vault over Snapshot Resource Group
    resource "azurerm_role_assignment" "vault_msi_read_on_snap_rg" {
      scope                = azurerm_resource_group.backuprg.id
      role_definition_name = "Reader"
      principal_id         = azurerm_data_protection_backup_vault.backupvault.identity[0].principal_id
      depends_on = [azurerm_kubernetes_cluster.akscluster,resource.azurerm_data_protection_backup_vault.backupvault]
    }
    
    #Assign Role to AKS Cluster over Snapshot Resource Group
    resource "azurerm_role_assignment" "cluster_msi_contributor_on_snap_rg" {
      scope                = azurerm_resource_group.backuprg.id
      role_definition_name = "Contributor"
      principal_id         = try(azurerm_kubernetes_cluster.akscluster.identity[0].principal_id,null)
      depends_on = [azurerm_kubernetes_cluster.akscluster,resource.azurerm_kubernetes_cluster.akscluster,resource.azurerm_resource_group.backuprg]
    }
    
    #Create Backup Instance for AKS Cluster
    resource "azurerm_data_protection_backup_instance_kubernetes_cluster" "akstfbi" {
      name                         = "example"
      location                     = azurerm_resource_group.backuprg.location
      vault_id                     = azurerm_data_protection_backup_vault.backupvault.id
      kubernetes_cluster_id        = azurerm_kubernetes_cluster.akscluster.id
      snapshot_resource_group_name = azurerm_resource_group.backuprg.name
      backup_policy_id             = azurerm_data_protection_backup_policy_kubernetes_cluster.policy.id
    
      backup_datasource_parameters {
        excluded_namespaces              = []
        excluded_resource_types          = []
        cluster_scoped_resources_enabled = true
        included_namespaces              = []
        included_resource_types          = []
        label_selectors                  = []
        volume_snapshot_enabled          = true
      }
    
      depends_on = [
        resource.azurerm_data_protection_backup_vault.backupvault,
        azurerm_data_protection_backup_policy_kubernetes_cluster.policy,
        azurerm_role_assignment.extensionrole,
        azurerm_role_assignment.vault_msi_read_on_cluster,
        azurerm_role_assignment.vault_msi_read_on_snap_rg,
        azurerm_role_assignment.cluster_msi_contributor_on_snap_rg
      ]
    }
    
  4. Cree un archivo llamado variables.tf e inserte el siguiente código:

    variable "aks_cluster_name" {
      type        = string
      default     = "Contoso_AKS_TF"
      description = "Name of the AKS Cluster."
    }
    
    variable "backup_extension_name" {
      type        = string
      default     = "azure-aks-backup"
      description = "Name of the AKS Cluster Extension."
    }
    
    variable "backup_extension_type" {
      type        = string
      default     = "microsoft.dataprotection.kubernetes"
      description = "Type of the AKS Cluster Extension."
    }
    
    variable "dns_prefix" {
      type        = string
      default     = "contoso-aks-dns-tf"
      description = "DNS Name of AKS Cluster made with Terraform"
    }
    
    variable "node_count" {
      type        = number
      description = "The initial quantity of nodes for the node pool."
      default     = 3
    }
    
    variable "resource_group_location" {
      type        = string
      default     = "eastus"
      description = "Location of the resource group."
    }
    
    variable "backup_resource_group_name" {
      type        = string
      default     = "Contoso_TF_Backup_RG"
      description = "Location of the resource group."
    }
    
    variable "backup_resource_group_location" {
      type        = string
      default     = "eastus"
      description = "Location of the resource group."
    }
    
    variable "resource_group_name" {
      type        = string
      default     = "Contoso_TF_RG"
      description = "Location of the resource group."
    }
    
    variable "cluster_id" {
      type        = string
      default     = "/subscriptions/c3d3eb0c-9ba7-4d4c-828e-cb6874714034/resourceGroups/Contoso_TF_RG/providers/Microsoft.ContainerService/managedClusters/Contoso_AKS_TF"
      description = "Location of the resource group."
    }
    
    variable "backupvault_name" {
      type        = string
      default     = "BackupVaultTF"
      description = "Name of the Backup Vault"
    }
    
    variable "datastore_type" {
      type        = string
      default     = "OperationalStore"
    }
    
    variable "redundancy" {
      type        = string
      default     = "LocallyRedundant"
    }
    
    variable "backuppolicy_name" {
      type        = string
      default     = "aksbackuppolicytfv1"
    }
    
  5. Cree un archivo llamado outputs.tf e inserte el siguiente código:

     output "aks_resource_group" {
       value = azurerm_resource_group.rg.name
     }
    
     output "snapshot_resource_group" {
       value = azurerm_resource_group.backuprg.name
     }
    
     output "kubernetes_cluster_name" {
       value = azurerm_kubernetes_cluster.akscluster.name
     }
    
     output "backup_vault_name" {
       value = azurerm_data_protection_backup_vault.backupvault.name
     }
    
     output "backup_instance_id" {
       value = azurerm_data_protection_backup_instance_kubernetes_cluster.akstfbi.id
     }
    

Inicialización de Terraform

Para inicializar la implementación de Terraform, ejecute terraform init. Este comando descarga el proveedor de Azure necesario para administrar los recursos de Azure.

terraform init -upgrade

Puntos clave:

  • El parámetro -upgrade actualiza los complementos de proveedor necesarios a la versión más reciente que cumpla con las restricciones de versión de la configuración.

Creación de un plan de ejecución de Terraform

Ejecute terraform plan para crear un plan de ejecución.

terraform plan -out main.tfplan

Puntos clave:

  • El comando terraform plan crea un plan de ejecución, pero no lo ejecuta. En su lugar, determina qué acciones son necesarias para crear la configuración especificada en los archivos de configuración. Este patrón le permite comprobar si el plan de ejecución coincide con sus expectativas antes de realizar cambios en los recursos reales.
  • El parámetro -out opcional permite especificar un archivo de salida para el plan. El uso del parámetro -out garantiza que el plan que ha revisado es exactamente lo que se aplica.

Aplicación de un plan de ejecución de Terraform

Ejecute terraform apply para aplicar el plan de ejecución a su infraestructura en la nube.

terraform apply main.tfplan

Puntos clave:

  • El comando terraform apply de ejemplo asume que ejecutó terraform plan -out main.tfplan previamente.
  • Si especificó un nombre de archivo diferente para el parámetro -out, use ese mismo nombre de archivo en la llamada a terraform apply.
  • Si no ha utilizado el parámetro -out, llame a terraform apply sin ningún parámetro.

Solución de problemas de Terraform en Azure

Al usar Terraform en Azure, puede encontrar problemas comunes. Obtenga información sobre cómo solucionar problemas.

Paso siguiente

En este inicio rápido, ha aprendido a implementar un clúster de Kubernetes, a crear un almacén de Backup y a configurar la copia de seguridad para el clúster de Kubernetes.

Más información sobre: