Azure Kubernetes hizmetinde bir Application Gateway ingcontroller oluşturma

Azure Kubernetes hizmeti (AKS) , barındırılan Kubernetes ortamınızı yönetir. AKS, kapsayıcı düzenleme uzmanlığı olmadan Kapsayıcılı uygulamaları dağıtmayı ve yönetmeyi hızlı ve kolay hale getirir. AKS Ayrıca, işletimsel ve bakım görevleri için uygulamaları çevrimdışına alma yükünü ortadan kaldırır. AKS 'i kullanarak, kaynakları sağlama, yükseltme ve ölçeklendirme dahil olmak üzere bu görevler isteğe bağlı olarak gerçekleştirilebilir.

Bir giriş denetleyicisi, Kubernetes Hizmetleri için çeşitli özellikler sağlar. Bu özellikler ters proxy, yapılandırılabilir trafik yönlendirme ve TLS sonlandırmasını içerir. Kubernetes giriş kaynakları, bağımsız bir Kubernetes hizmeti için giriş kurallarını yapılandırmak üzere kullanılır. Giriş denetleyicisi ve giriş kurallarını kullanarak tek bir IP adresi, trafiği bir Kubernetes kümesinde birden çok hizmete yönlendirebilir. Bu işlevlerin tümü Azure Application Gatewaytarafından sağlanır ve Azure 'Da Kubernetes için Ideal bir giriş denetleyicisi haline gelir.

Bu makalede şunları öğreneceksiniz:

  • Inks denetleyicisi olarak Application Gateway ile AKS kullanarak Kubernetes kümesi oluşturma
  • Kubernetes kümesi tanımlama
  • Application Gateway kaynağı oluşturma
  • Kubernetes kümesi oluşturma
  • Bir Kubernetes kümesinin kullanılabilirliğini test etme

1. ortamınızı yapılandırın

  • Azure aboneliği: Azure aboneliğiniz yoksa başlamadan önce ücretsiz bir hesap oluşturun.
  • Azure hizmet sorumlusu: hizmet sorumlusu yoksa hizmet sorumlusu oluşturun. ,, Ve değerlerini unutmayın appIddisplayNamepasswordtenant .

  • Hizmet sorumlusu nesne kimliği: hizmet SORUMLUSUNUN nesne kimliğini almak için aşağıdaki komutu çalıştırın:

2. Terrayform durumunu depolamak için Azure Storage 'ı yapılandırma

Terraform, durumu terraform.tfstate dosyasıyla yerel olarak izler. Bu model tek kişilik bir ortamda iyi çalışır. Ancak, daha pratik bir çoklu kişi ortamında, Azure depolama'yı kullanarak sunucuda durumu izlemeniz gerekir. Bu bölümde, gerekli depolama hesabı bilgilerini almayı ve bir depolama kapsayıcısı oluşturmayı öğreneceksiniz. Terrayform durum bilgileri bu kapsayıcıda depolanır.

  1. Azure Portalgidin.

  2. Azure hizmetlerialtında Depolama hesapları' nı seçin. ( Depolama hesapları seçeneği ana sayfada görünmüyorsa, seçeneği bulmak için diğer hizmetler ' i seçin.)

  3. Depolama hesapları sayfasında, terrayform 'un durumu depolamak için gereken depolama hesabının adını seçin. Örneğin Cloud Shell'i ilk açtığınızda oluşturulmuş olan depolama hesabını kullanabilirsiniz. Cloud Shell tarafından oluşturulan depolama hesabı genellikle cs ile başlar ve sonrasında rastgele sayı ve harf dizesi bulunur.

  4. Seçilen depolama hesabı adını aklınızda edin.

  5. Depolama hesabı sayfasında Erişim anahtarları'nı seçin.

    Depolama hesabı adı

  6. KEY1anahtar değerini aklınızda edin. (Anahtarın sağ tarafındaki simgeyi seçtiğinizde değer panoya kopyalanır.)

    Depolama hesabı erişim anahtarları

  7. Azure depolama hesabınızda bir kapsayıcı oluşturun. Yer tutucuları, Azure depolama hesabınız için uygun değerlerle değiştirin.

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

3. Terrayform kodunu uygulama

  1. Örnek Terüform kodunu test etmek ve geçerli dizin yapmak için bir dizin oluşturun.

  2. Adlı bir dosya oluşturun main.tf ve aşağıdaki kodu ekleyin:

    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. variables.tfProje değişkenlerini içerecek şekilde adlı bir dosya oluşturun ve aşağıdaki kodu ekleyin:

    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. Adlı bir dosya oluşturun resources.tf ve aşağıdaki kodu ekleyin.

    # # 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
    }
    

    Anahtar noktaları:

    • Dosyadaki kod, resources.tf kümenin adını, konumunu ve resource_group_name ayarlar.
    • dns_prefixDeğer-kümeye erişmek için kullanılan tam etki alanı adının (FQDN) bir parçasını oluşturur.
    • linux_profileKayıt, SSH kullanarak çalışan düğümlerinde oturum açmayı etkinleştiren ayarları yapılandırmanıza olanak tanır.
    • AKS ile yalnızca çalışan düğümleri için ödeme yaparsınız.
    • agent_pool_profileKayıt, bu çalışan düğümlerinin ayrıntılarını yapılandırır.
    • , agent_pool_profile record Oluşturulacak çalışan düğümlerinin sayısını ve çalışan düğümlerinin türünü içerir.
    • Daha sonra kümede ölçeği büyütme veya küçültme yapmanız gerekiyorsa, count kayıttaki değeri değiştirin agent_pool_profile record .
  5. Adlı bir dosya oluşturun output.tf ve aşağıdaki kodu ekleyin.

    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
    }
    

    Anahtar noktaları:

    • Terrayform çıkışları , terrayform bir plan uygularken kullanıcıya vurgulanmış değerleri tanımlamanızı sağlar.
    • Bu değerler komutu kullanılarak sorgulanabilir terraform output .
    • Bu bölümde kubectl ile kümeye erişmenizi sağlayan bir çıkış dosyası oluşturacaksınız.
  6. Adlı bir dosya oluşturun terraform.tfvars ve aşağıdaki kodu ekleyin.

    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>"
    

    Anahtar noktaları:

    • az account list-locationsOrtamınızın konum değerini almak için öğesini çalıştırın

4. Kubernetes kümesini test etme

Yeni oluşturulan kümeyi doğrulamak için Kubernetes araçlarını kullanabilirsiniz.

  1. Azure 'dan Kubernetes yapılandırmasını ve erişim kimlik bilgilerini almak için az aks Get-Credentials komutunu çalıştırın.

    az aks get-credentials --name <aks_cluster_name>  --resource-group <resource_group_name>
    
  2. Kümenin durumunu doğrulayın.

    kubectl get nodes
    

    Anahtar noktaları:

    • Çalışan düğümlerinizin ayrıntıları, hazırlıkdurumuyla birlikte görüntülenir.

    kubectl aracı, Kubernetes kümenizin durumunu doğrulamanızı sağlar

5. Azure AD Pod kimliğini yüklemeyi

Azure Active Directory Pod kimliği, Azure Resource Managerbelirteç tabanlı erişim sağlar.

Azure AD Pod Identity , Kubernetes kümenize aşağıdaki bileşenleri ekler:

RBAC etkinse, KÜMENIZE Azure AD Pod kimliğini yüklemek için şu komutu çalıştırın:

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

RBAC devre dışıysa, KÜMENIZE Azure AD Pod kimliğini yüklemek için şu komutu çalıştırın:

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

6. Held 'yi yükler

Bu bölümdeki kod, helk -Kubernetes paket yöneticisini kullanır-paketi yüklemek için :

AGIC Held deposunu eklemek için, aşağıdaki helk komutlarını çalıştırın:

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

7. giriş denetleyicisi Held grafiğini yükler

  1. helm-config.yamlAGIC 'yi yapılandırmak için indirin:

    wget https://raw.githubusercontent.com/Azure/application-gateway-kubernetes-ingress/master/docs/examples/sample-helm-config.yaml -O helm-config.yaml
    
  2. ' İ düzenleyin helm-config.yaml ve bölümleri için uygun değerleri girin appgwarmAuth .

    code helm-config.yaml
    

    Değerler aşağıdaki şekilde açıklanmıştır:

    • verbosityLevel: AGIC günlük altyapısının ayrıntı düzeyini ayarlar. Olası değerler için günlük düzeylerini görüntüleyin.
    • appgw.subscriptionId: Uygulama ağ geçidi için Azure abonelik KIMLIĞI. Örnek: a123b234-a3b4-557d-b2df-a0bc12de1234
    • appgw.resourceGroup: Uygulama ağ geçidinin oluşturulduğu Azure Kaynak grubunun adı.
    • appgw.name: Application Gateway adı. Örnek: applicationgateway1.
    • appgw.shared: Bu Boole bayrağı varsayılan olarak ayarlanmalıdır false . truetrueihtiyacınız olacak şekilde ayarlayın.
    • kubernetes.watchNamespace: AGIC 'in izlemeniz gereken ad alanını belirtin. Ad alanı, tek bir dize değeri veya ad alanlarının virgülle ayrılmış bir listesi olabilir. Bu değişkenin açıklama olarak bırakılması veya boş ya da boş dize olarak ayarlanması, giriş denetleyicisindeki tüm erişilebilir ad alanlarını gözlemleyerek.
    • armAuth.type: Ya da değeri aadPodIdentityservicePrincipal .
    • armAuth.identityResourceID: Yönetilen kimliğin kaynak KIMLIĞI.
    • armAuth.identityClientId: Kimliğin Istemci KIMLIĞI.
    • armAuth.secretJSON: Yalnızca hizmet sorumlusu gizli türü seçildiğinde ( armAuth.type olarak ayarlandığında servicePrincipal ) gereklidir.

    Anahtar noktaları:

    • identityResourceIDDeğer, terrayform betiği içinde oluşturulur ve şu şekilde çalıştırılarak bulunabilir: echo "$(terraform output identity_resource_id)" .
    • identityClientIDDeğer, terrayform betiği içinde oluşturulur ve şu şekilde çalıştırılarak bulunabilir: echo "$(terraform output identity_client_id)" .
    • <resource-group>Değer, uygulama ağ geçidinizin kaynak grubudur.
    • <identity-name>Değer, oluşturulan kimliğin adıdır.
    • Belirli bir aboneliğin tüm kimlikleri: kullanılarak listelenebilir az identity list .
  3. Application Gateway giriş denetleyicisi paketini yükler:

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

8. örnek bir uygulama yükler

Uygulama ağ geçidi, AKS ve AGIC yüklendikten sonra, örnek bir uygulama yüklersiniz.

  1. YAML dosyasını indirmek için kıvrımlı komutunu kullanın:

    curl https://raw.githubusercontent.com/Azure/application-gateway-kubernetes-ingress/master/docs/examples/aspnetapp.yaml -o aspnetapp.yaml
    
  2. YAML dosyasını uygulayın:

    kubectl apply -f aspnetapp.yaml
    

9. Kaynakları Temizleme

Terrayform ile oluşturulan kaynaklara artık ihtiyacınız kalmadığında aşağıdaki adımları uygulayın:

  1. Terrayform planını çalıştırın ve bayrağını belirtin .

    terraform plan -destroy -out main.destroy.tfplan
    

    Anahtar noktaları:

    • terraform planKomut bir yürütme planı oluşturur, ancak yürütmez. Bunun yerine, yapılandırma dosyalarınızda belirtilen yapılandırmayı oluşturmak için hangi eylemlerin gerekli olduğunu belirler. Bu model, gerçek kaynaklarda herhangi bir değişiklik yapmadan önce yürütme planının beklentilerinizi eşleşip eşleşmediğini doğrulamanızı sağlar.
    • İsteğe bağlı -out parametresi, plan için bir çıkış dosyası belirtmenize olanak tanır. Parametresinin kullanılması, -out gözden geçirdiğiniz planın tam olarak uygulanmış olmasını sağlar.
    • Kalıcı yürütme planları ve güvenlik hakkında daha fazla bilgi edinmek için güvenlik uyarısı bölümünebakın.
  2. Yürütme planını uygulamak için terrayform Uygula ' yı çalıştırın.

    terraform apply main.destroy.tfplan
    

Azure 'da Terrampaform sorunlarını giderme

Azure 'da Terrampaform kullanırken karşılaşılan yaygın sorunları giderme

Sonraki adımlar