Vytvoření kontroleru Application Gateway příchozího přenosu dat ve službě Azure Kubernetes

Azure Kubernetes Service (AKS) spravuje hostované prostředí Kubernetes. AKS umožňuje rychle a snadno nasazovat a spravovat aplikace s využitím kontejnerů bez odbornosti pro orchestraci kontejnerů. AKS také eliminuje zatížení při práci s aplikacemi offline pro úlohy provozu a údržby. Pomocí AKS můžete provádět tyto úlohy – včetně zřizování, upgradování a škálování prostředků – dá se provést na vyžádání.

Kontroler příchozího přenosu dat poskytuje různé funkce pro služby Kubernetes Services. Mezi tyto funkce patří reverzní proxy, konfigurovatelné směrování provozu a ukončení protokolu TLS. Kubernetes příchozí prostředky se používají ke konfiguraci pravidel příchozího přenosu pro jednotlivé služby Kubernetes. Pomocí řadiče příchozího přenosu dat a pravidel příchozího přenosu dat může jedna IP adresa směrovat provoz do několika služeb v clusteru Kubernetes. Tuto funkci poskytuje Azure Application Gatewaya díky tomu je ideálním řadičem příchozího přenosu dat pro Kubernetes v Azure.

V tomto článku se dozvíte, jak:

  • Vytvoření clusteru Kubernetes pomocí AKS s Application Gateway jako adaptér příchozího přenosu dat
  • Definování clusteru Kubernetes
  • Vytvořit prostředek Application Gateway
  • Vytvoření clusteru Kubernetes
  • Testování dostupnosti clusteru Kubernetes

1. konfigurace prostředí

  • Předplatné Azure: Pokud ještě nemáte předplatné Azure, vytvořte si bezplatný účet před tím, než začnete.
  • Instanční objekt Azure: Pokud ještě nemáte instanční objekt, vytvořte instanční objekt. Poznamenejte si hodnoty pro appId ,, a displayNamepasswordtenant .

  • ID objektu instančního objektu: spusťte následující příkaz, který získá ID objektu instančního objektu:

2. konfigurace úložiště Azure pro ukládání stavu Terraformu

Terraform sleduje stav místně prostřednictvím souboru terraform.tfstate. Tento model funguje dobře v prostředí s jednou osobou. Ve více praktických prostředích pro více uživatelů je ale potřeba sledovat stav na serveru pomocí služby Azure Storage. V této části se dozvíte, jak načíst potřebné informace o účtu úložiště a vytvořit kontejner úložiště. Informace o stavu Terraformu jsou následně uloženy v tomto kontejneru.

  1. Přejděte na Azure Portal.

  2. v části služby Azurevyberte účty Storage. (pokud se možnost účty Storage na hlavní stránce nezobrazuje, vyberte další služby a vyhledejte možnost.)

  3. na stránce Storage účty vyberte název účtu úložiště, do kterého má terraformu ukládat stav. Můžete například použít účet úložiště, který se vytvoří při prvním otevření služby Cloud Shell. Název účtu úložiště vytvořeného službou Cloud Shell obvykle začíná na cs a následuje ho řetězec náhodných čísel a písmen.

  4. Poznamenejte si vybraný název účtu úložiště.

  5. Na stránce účtu úložiště vyberte Přístupové klíče.

    Nabídka účtu úložiště

  6. Poznamenejte si hodnotuklíčeklíč1. (Výběr ikony napravo od klíče zkopíruje příslušnou hodnotu do schránky.)

    Přístupové klíče účtu úložiště

  7. Vytvořte kontejner v účtu úložiště Azure. Zástupné symboly nahraďte odpovídajícími hodnotami pro svůj účet úložiště Azure.

    az storage container create -n tfstate --account-name <storage_account_name> --account-key <storage_account_key>
    

3. implementace kódu Terraformu

  1. Vytvořte adresář, ve kterém chcete otestovat ukázkový kód Terraformu a nastavte ho jako aktuální adresář.

  2. Vytvořte soubor s názvem main.tf a vložte následující kód:

    terraform {
    
      required_version = ">=0.12"
    
      required_providers {
        azurerm = {
          source = "hashicorp/azurerm"
          version = "~>2.0"
        }
      }
      backend "azurerm" {
        resource_group_name = var.resource_group_name
        storage_account_name = var.storage_account_name
        container_name = "tfstate"
        key = "codelab.microsoft.tfstate"
      }
      }
    
      provider "azurerm" {
      features {}
    }
    
  3. Vytvořte soubor s názvem variables.tf , který obsahuje proměnné projektu, a vložte následující kód:

    variable "resource_group_name" {
        description = "Name of the resource group."
    }
    
    variable "location" {
        description = "Location of the cluster."
    }
    
    variable "aks_service_principal_app_id" {
        description = "Application ID/Client ID  of the service principal. Used by AKS to manage AKS related resources on Azure like vms, subnets."
    }
    
    variable "aks_service_principal_client_secret" {
        description = "Secret of the service principal. Used by AKS to manage Azure."
    }
    
    variable "aks_service_principal_object_id" {
        description = "Object ID of the service principal."
    }
    
    variable "virtual_network_name" {
        description = "Virtual network name"
        default     = "aksVirtualNetwork"
    }
    
    variable "virtual_network_address_prefix" {
        description = "VNET address prefix"
        default     = "15.0.0.0/8"
    }
    
    variable "aks_subnet_name" {
        description = "Subnet Name."
        default     = "kubesubnet"
    }
    
    variable "aks_subnet_address_prefix" {
        description = "Subnet address prefix."
        default     = "15.0.0.0/16"
    }
    
    variable "app_gateway_subnet_address_prefix" {
        description = "Subnet server IP address."
        default     = "15.1.0.0/16"
    }
    
    variable "app_gateway_name" {
        description = "Name of the Application Gateway"
        default = "ApplicationGateway1"
    }
    
    variable "app_gateway_sku" {
        description = "Name of the Application Gateway SKU"
        default = "Standard_v2"
    }
    
    variable "app_gateway_tier" {
        description = "Tier of the Application Gateway tier"
        default = "Standard_v2"
    }
    
    variable "aks_name" {
        description = "AKS cluster name"
        default     = "aks-cluster1"
    }
    variable "aks_dns_prefix" {
        description = "Optional DNS prefix to use with hosted Kubernetes API server FQDN."
        default     = "aks"
    }
    
    variable "aks_agent_os_disk_size" {
        description = "Disk size (in GB) to provision for each of the agent pool nodes. This value ranges from 0 to 1023. Specifying 0 applies the default disk size for that agentVMSize."
        default     = 40
    }
    
    variable "aks_agent_count" {
        description = "The number of agent nodes for the cluster."
        default     = 3
    }
    
    variable "aks_agent_vm_size" {
        description = "VM size"
        default     = "Standard_D3_v2"
    }
    
    variable "kubernetes_version" {
        description = "Kubernetes version"
        default     = "1.11.5"
    }
    
    variable "aks_service_cidr" {
        description = "CIDR notation IP range from which to assign service cluster IPs"
        default     = "10.0.0.0/16"
    }
    
    variable "aks_dns_service_ip" {
        description = "DNS server IP address"
        default     = "10.0.0.10"
    }
    
    variable "aks_docker_bridge_cidr" {
        description = "CIDR notation IP for Docker bridge."
        default     = "172.17.0.1/16"
    }
    
    variable "aks_enable_rbac" {
        description = "Enable RBAC on the AKS cluster. Defaults to false."
        default     = "false"
    }
    
    variable "vm_user_name" {
        description = "User name for the VM"
        default     = "vmuser1"
    }
    
    variable "public_ssh_key_path" {
        description = "Public key path for SSH."
        default     = "~/.ssh/id_rsa.pub"
    }
    
    variable "tags" {
        type = map(string)
    
        default = {
        source = "terraform"
        }
    }
    
    variable "storage_account_name" {
        description = "Name of storage account"
    }
    
  4. Vytvořte soubor s názvem resources.tf a vložte následující kód.

    # # Locals block for hardcoded names. 
    locals {
        backend_address_pool_name      = "${azurerm_virtual_network.test.name}-beap"
        frontend_port_name             = "${azurerm_virtual_network.test.name}-feport"
        frontend_ip_configuration_name = "${azurerm_virtual_network.test.name}-feip"
        http_setting_name              = "${azurerm_virtual_network.test.name}-be-htst"
        listener_name                  = "${azurerm_virtual_network.test.name}-httplstn"
        request_routing_rule_name      = "${azurerm_virtual_network.test.name}-rqrt"
        app_gateway_subnet_name = "appgwsubnet"
    }
    
    data "azurerm_resource_group" "rg" {
        name = var.resource_group_name
    }
    
    # User Assigned Identities 
    resource "azurerm_user_assigned_identity" "testIdentity" {
        resource_group_name = data.azurerm_resource_group.rg.name
        location            = data.azurerm_resource_group.rg.location
    
        name = "identity1"
    
        tags = var.tags
    }
    
    resource "azurerm_virtual_network" "test" {
        name                = var.virtual_network_name
        location            = data.azurerm_resource_group.rg.location
        resource_group_name = data.azurerm_resource_group.rg.name
        address_space       = [var.virtual_network_address_prefix]
    
        subnet {
        name           = var.aks_subnet_name
        address_prefix = var.aks_subnet_address_prefix
        }
    
        subnet {
        name           = "appgwsubnet"
        address_prefix = var.app_gateway_subnet_address_prefix
        }
    
        tags = var.tags
    }
    
    data "azurerm_subnet" "kubesubnet" {
        name                 = var.aks_subnet_name
        virtual_network_name = azurerm_virtual_network.test.name
        resource_group_name  = data.azurerm_resource_group.rg.name
        depends_on = [azurerm_virtual_network.test]
    }
    
    data "azurerm_subnet" "appgwsubnet" {
        name                 = "appgwsubnet"
        virtual_network_name = azurerm_virtual_network.test.name
        resource_group_name  = data.azurerm_resource_group.rg.name
        depends_on = [azurerm_virtual_network.test]
    }
    
    # Public Ip 
    resource "azurerm_public_ip" "test" {
        name                         = "publicIp1"
        location                     = data.azurerm_resource_group.rg.location
        resource_group_name          = data.azurerm_resource_group.rg.name
        allocation_method            = "Static"
        sku                          = "Standard"
    
        tags = var.tags
    }
    
    resource "azurerm_application_gateway" "network" {
        name                = var.app_gateway_name
        resource_group_name = data.azurerm_resource_group.rg.name
        location            = data.azurerm_resource_group.rg.location
    
        sku {
        name     = var.app_gateway_sku
        tier     = "Standard_v2"
        capacity = 2
        }
    
        gateway_ip_configuration {
        name      = "appGatewayIpConfig"
        subnet_id = data.azurerm_subnet.appgwsubnet.id
        }
    
        frontend_port {
        name = local.frontend_port_name
        port = 80
        }
    
        frontend_port {
        name = "httpsPort"
        port = 443
        }
    
        frontend_ip_configuration {
        name                 = local.frontend_ip_configuration_name
        public_ip_address_id = azurerm_public_ip.test.id
        }
    
        backend_address_pool {
        name = local.backend_address_pool_name
        }
    
        backend_http_settings {
        name                  = local.http_setting_name
        cookie_based_affinity = "Disabled"
        port                  = 80
        protocol              = "Http"
        request_timeout       = 1
        }
    
        http_listener {
        name                           = local.listener_name
        frontend_ip_configuration_name = local.frontend_ip_configuration_name
        frontend_port_name             = local.frontend_port_name
        protocol                       = "Http"
        }
    
        request_routing_rule {
        name                       = local.request_routing_rule_name
        rule_type                  = "Basic"
        http_listener_name         = local.listener_name
        backend_address_pool_name  = local.backend_address_pool_name
        backend_http_settings_name = local.http_setting_name
        }
    
        tags = var.tags
    
        depends_on = [azurerm_virtual_network.test, azurerm_public_ip.test]
    }
    
    resource "azurerm_role_assignment" "ra1" {
        scope                = data.azurerm_subnet.kubesubnet.id
        role_definition_name = "Network Contributor"
        principal_id         = var.aks_service_principal_object_id 
    
        depends_on = [azurerm_virtual_network.test]
    }
    
    resource "azurerm_role_assignment" "ra2" {
        scope                = azurerm_user_assigned_identity.testIdentity.id
        role_definition_name = "Managed Identity Operator"
        principal_id         = var.aks_service_principal_object_id
        depends_on           = [azurerm_user_assigned_identity.testIdentity]
    }
    
    resource "azurerm_role_assignment" "ra3" {
        scope                = azurerm_application_gateway.network.id
        role_definition_name = "Contributor"
        principal_id         = azurerm_user_assigned_identity.testIdentity.principal_id
        depends_on           = [azurerm_user_assigned_identity.testIdentity, azurerm_application_gateway.network]
    }
    
    resource "azurerm_role_assignment" "ra4" {
        scope                = data.azurerm_resource_group.rg.id
        role_definition_name = "Reader"
        principal_id         = azurerm_user_assigned_identity.testIdentity.principal_id
        depends_on           = [azurerm_user_assigned_identity.testIdentity, azurerm_application_gateway.network]
    }
    
    resource "azurerm_kubernetes_cluster" "k8s" {
        name       = var.aks_name
        location   = data.azurerm_resource_group.rg.location
        dns_prefix = var.aks_dns_prefix
    
        resource_group_name = data.azurerm_resource_group.rg.name
    
        linux_profile {
        admin_username = var.vm_user_name
    
        ssh_key {
            key_data = file(var.public_ssh_key_path)
        }
        }
    
        addon_profile {
        http_application_routing {
            enabled = false
        }
        }
    
        default_node_pool {
        name            = "agentpool"
        node_count      = var.aks_agent_count
        vm_size         = var.aks_agent_vm_size
        os_disk_size_gb = var.aks_agent_os_disk_size
        vnet_subnet_id  = data.azurerm_subnet.kubesubnet.id
        }
    
        service_principal {
        client_id     = var.aks_service_principal_app_id
        client_secret = var.aks_service_principal_client_secret
        }
    
        network_profile {
        network_plugin     = "azure"
        dns_service_ip     = var.aks_dns_service_ip
        docker_bridge_cidr = var.aks_docker_bridge_cidr
        service_cidr       = var.aks_service_cidr
        }
    
        role_based_access_control {
        enabled = var.aks_enable_rbac
        }
    
        depends_on = [azurerm_virtual_network.test, azurerm_application_gateway.network]
        tags       = var.tags
    }
    

    Klíčové body:

    • Kód v resources.tf souboru nastaví název clusteru, umístění a resource_group_name.
    • dns_prefixHodnota – která tvoří součást plně kvalifikovaného názvu domény (FQDN), která se používá pro přístup ke clusteru – je nastavená hodnota.
    • linux_profileZáznam umožňuje nakonfigurovat nastavení, která umožňují přihlašovat se k pracovním uzlům pomocí SSH.
    • Se službou AKS platíte jenom za pracovní uzly.
    • agent_pool_profileZáznam nakonfiguruje podrobnosti pro tyto pracovní uzly.
    • agent_pool_profile recordZahrnuje počet pracovních uzlů, které se mají vytvořit, a typ pracovních uzlů.
    • Pokud potřebujete v budoucnu horizontální navýšení nebo snížení kapacity clusteru, upravte count hodnotu v agent_pool_profile record záznamu.
  5. Vytvořte soubor s názvem output.tf a vložte následující kód.

    output "client_key" {
        value = azurerm_kubernetes_cluster.k8s.kube_config.0.client_key
    }
    
    output "client_certificate" {
        value = azurerm_kubernetes_cluster.k8s.kube_config.0.client_certificate
    }
    
    output "cluster_ca_certificate" {
        value = azurerm_kubernetes_cluster.k8s.kube_config.0.cluster_ca_certificate
    }
    
    output "cluster_username" {
        value = azurerm_kubernetes_cluster.k8s.kube_config.0.username
    }
    
    output "cluster_password" {
        value = azurerm_kubernetes_cluster.k8s.kube_config.0.password
    }
    
    output "kube_config" {
        value = azurerm_kubernetes_cluster.k8s.kube_config_raw
        sensitive = true
    }
    
    output "host" {
        value = azurerm_kubernetes_cluster.k8s.kube_config.0.host
    }
    
    output "identity_resource_id" {
        value = azurerm_user_assigned_identity.testIdentity.id
    }
    
    output "identity_client_id" {
        value = azurerm_user_assigned_identity.testIdentity.client_id
    }
    

    Klíčové body:

    • Terraformuové výstupy umožňují definovat hodnoty, které jsou zvýrazněné uživateli, když terraformu použije plán.
    • Tyto hodnoty lze dotazovat pomocí terraform output příkazu.
    • V této části vytvoříte výstupní soubor, který pomocí kubectl umožňuje přístup ke clusteru.
  6. Vytvořte soubor s názvem terraform.tfvars a vložte následující kód.

    resource_group_name = "<Name of the Resource Group already created>"
    
    location = "<Location of the Resource Group>"
        
    aks_service_principal_app_id = "<Service Principal AppId>"
        
    aks_service_principal_client_secret = "<Service Principal Client Secret>"
        
    aks_service_principal_object_id = "<Service Principal Object Id>"
    

    Klíčové body:

    • Spusťte az account list-locations , abyste získali hodnotu umístění vašeho prostředí.

4. otestujte cluster Kubernetes.

Nově vytvořený cluster můžete pomocí nástrojů Kubernetes ověřit.

  1. Spuštěním AZ AKS Get-Credentials získáte konfiguraci Kubernetes a přihlašovací údaje pro přístup z Azure.

    az aks get-credentials --name <aks_cluster_name>  --resource-group <resource_group_name>
    
  2. Ověřte stav clusteru.

    kubectl get nodes
    

    Klíčové body:

    • Podrobnosti o vašich pracovních uzlech se zobrazí se stavem připraveno.

    Nástroj kubectl vám umožňuje ověřit stav clusteru Kubernetes.

5. instalace Azure AD pod identitou

Azure Active Directory Pod identitou poskytuje přístup založený na tokenech k Azure Resource Manager.

Služba Azure AD pod identitou přidá do clusteru Kubernetes následující součásti:

Pokud je povolenáfunkce RBAC, spusťte následující příkaz, který do svého clusteru nainstaluje IDENTITU Azure AD pod:

kubectl create -f https://raw.githubusercontent.com/Azure/aad-pod-identity/master/deploy/infra/deployment-rbac.yaml

Pokud je funkce RBAC zakázaná, spusťte následující příkaz, který do vašeho clusteru nainstaluje IDENTITU Azure AD pod:

kubectl create -f https://raw.githubusercontent.com/Azure/aad-pod-identity/master/deploy/infra/deployment.yaml

6. instalace Helm

Kód v této části používá správce balíčků Helm -Kubernetes – k instalaci balíčku:

Spusťte následující příkazy Helm a přidejte úložiště AGIC Helm:

helm repo add application-gateway-kubernetes-ingress https://appgwingress.blob.core.windows.net/ingress-azure-helm-package/
helm repo update

7. Nainstalujte graf Helm příchozího adaptéru.

  1. Ke helm-config.yaml konfiguraci AGIC postupujte takto:

    wget https://raw.githubusercontent.com/Azure/application-gateway-kubernetes-ingress/master/docs/examples/sample-helm-config.yaml -O helm-config.yaml
    
  2. Upravte helm-config.yaml a zadejte příslušné hodnoty pro appgw oddíly a armAuth .

    code helm-config.yaml
    

    Hodnoty jsou popsány takto:

    • verbosityLevel: Nastaví úroveň podrobností infrastruktury protokolování AGIC. Možné hodnoty najdete v tématu úrovně protokolování .
    • appgw.subscriptionId: ID předplatného Azure pro službu App Gateway. Příklad: a123b234-a3b4-557d-b2df-a0bc12de1234
    • appgw.resourceGroup: Název skupiny prostředků Azure, ve které se aplikace App Gateway vytvořila.
    • appgw.name: Název Application Gateway. Příklad: applicationgateway1.
    • appgw.shared: Tento logický příznak by měl být nastaven na výchozí hodnotu false . Nastavte na, true Pokud potřebujete true.
    • kubernetes.watchNamespace: Zadejte obor názvů, který má AGIC sledovat. Obor názvů může být jediná řetězcová hodnota nebo seznam oborů názvů oddělených čárkami. Tato proměnná se odvolá nebo ji nastaví na prázdnou nebo prázdný řetězec. Výsledkem je, že kontroler příchozího přístupu se všemi dostupnými obory názvů ponechává.
    • armAuth.type: Hodnota buď aadPodIdentity nebo servicePrincipal .
    • armAuth.identityResourceID: ID prostředku spravované identity.
    • armAuth.identityClientId: ID klienta identity.
    • armAuth.secretJSON: Vyžaduje se jenom v případě, že je zvolený tajný typ objektu služby (Pokud armAuth.type byl nastaven na hodnotu servicePrincipal ).

    Klíčové body:

    • identityResourceIDHodnota je vytvořena v terraformu skriptu a lze ji najít spuštěním: echo "$(terraform output identity_resource_id)" .
    • identityClientIDHodnota je vytvořena v terraformu skriptu a lze ji najít spuštěním: echo "$(terraform output identity_client_id)" .
    • <resource-group>Hodnota je skupina prostředků vaší aplikační brány.
    • <identity-name>Hodnota je název vytvořené identity.
    • Všechny identity pro dané předplatné můžete uvést pomocí: az identity list .
  3. Nainstalujte balíček Application Gateway příchozího řadiče pro příchozí přenosy:

    helm install -f helm-config.yaml application-gateway-kubernetes-ingress/ingress-azure --generate-name
    

8. instalace ukázkové aplikace

Jakmile máte nainstalovanou bránu App Gateway, AKS a AGIC, nainstalujte ukázkovou aplikaci.

  1. K stažení souboru YAML použijte příkaz kudrlinkou:

    curl https://raw.githubusercontent.com/Azure/application-gateway-kubernetes-ingress/master/docs/examples/aspnetapp.yaml -o aspnetapp.yaml
    
  2. Použít soubor YAML:

    kubectl apply -f aspnetapp.yaml
    

9. vyčištění prostředků

Pokud již nepotřebujete prostředky vytvořené prostřednictvím Terraformu, proveďte následující kroky:

  1. Spusťte plán terraformu a zadejte příznak.

    terraform plan -destroy -out main.destroy.tfplan
    

    Klíčové body:

    • terraform planPříkaz vytvoří plán spuštění, ale neprovede ho. Místo toho určuje, jaké akce je potřeba k vytvoření konfigurace zadané v konfiguračních souborech. Tento model vám umožní ověřit, zda plán spuštění odpovídá vašim očekáváním, a teprve potom provádět změny ve skutečných prostředcích.
    • Volitelný -out parametr umožňuje zadat výstupní soubor pro daný plán. Použití -out parametru zajistí, že plán, který jste zkontrolovali, je přesně to, co se používá.
    • Další informace o zachování plánů provádění a zabezpečení najdete v části upozornění zabezpečení.
  2. Spusťte terraformu použít pro použití plánu spuštění.

    terraform apply main.destroy.tfplan
    

Řešení potíží s Terraformu v Azure

Řešení běžných problémů při použití Terraformu v Azure

Další kroky