Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
Questo articolo illustra come preparare l'infrastruttura per la distribuzione di un cluster Kafka nel servizio Azure Kubernetes.
Panoramica dell'architettura
L'architettura AKS di destinazione per la distribuzione di Kafka dà priorità all'alta disponibilità grazie a una progettazione completa con ridondanza tra zone. La progettazione richiede tre pool di nodi, uno per zona di disponibilità, per mantenere l'allineamento della distribuzione e dell'archiviazione del carico di lavoro. Questa configurazione di zona è fondamentale perché i volumi persistenti in questa architettura hanno affinità di zona. Tutti i nuovi nodi provisionati con l'autoscaler del cluster devono essere creati nella zona appropriata. Senza questa specificità di zona, i pod con volumi permanenti associati alla zona rimarranno in uno stato in sospeso. Più repliche dell'operatore cluster Strimzi e delle istanze del broker Kafka vengono definite e distribuite tra zone, offrendo resilienza sia in caso di errori di nodo che di intere zone all'interno dell'area di destinazione. Per evitare conflitti di risorse e garantire prestazioni prevedibili, è consigliabile usare pool di nodi dedicati per i carichi di lavoro Kafka.
Prerequisiti
- Se non l'hai già fatto, consulta l'Overview per la distribuzione di Kafka su Azure Kubernetes Service (AKS) utilizzando Strimzi.
- Terraform v1.3.0 o versione successiva installata.
- CLI di Azure installata e autenticata.
- Autorizzazioni sufficienti per creare risorse infrastrutturali e assegnare il controllo degli accessi basato sui ruoli alle identità gestite: Collaboratore di rete, Collaboratore del servizio Azure Kubernetes e Amministratore del controllo degli accessi basato sui ruoli.
Distribuire l'infrastruttura
La procedura seguente illustra la distribuzione del cluster AKS e l'infrastruttura di supporto necessaria per la distribuzione Kafka.
Suggerimento
Se si dispone di un cluster del servizio Azure Kubernetes o di un'infrastruttura di supporto esistente: è possibile ignorare i passaggi di distribuzione completi o apportare modifiche al codice, ma assicurarsi che l'infrastruttura e il cluster del servizio Azure Kubernetes soddisfino i requisiti seguenti:
- Rete virtuale con subnet per i nodi.
- Driver CSI del disco di Azure abilitato nel cluster AKS (abilitato per impostazione predefinita).
- Pool di nodi per zona di disponibilità (1, 2 e 3).
- Pool di nodi dedicati per Kafka con dimensioni di vm appropriate in base ai requisiti del carico di lavoro.
- Azure Managed Prometheus e Grafana con gestione Azure configurati.
Impostare le variabili di ambiente
Prima di eseguire qualsiasi comando dell'interfaccia della riga di comando, impostare le variabili di ambiente seguenti da usare in questa guida con valori che soddisfano i requisiti:
export RESOURCE_GROUP_NAME="rg-kafka" export LOCATION="canadacentral" export VNET_NAME="vnet-aks-kafka" export SUBNET_NAME="node-subnet" export AKS_CLUSTER_NAME="aks-kafka-cluster" export AKS_TIER=standard export NAT_GATEWAY_NAME="nat-kafka" export ADDRESS_SPACE="10.31.0.0/20" export SUBNET_PREFIX="10.31.0.0/21" export SYSTEM_NODE_COUNT_MIN=3 export SYSTEM_NODE_COUNT_MAX=6 export SYSTEM_NODE_VM_SIZE="Standard_D4ds_v5" export KAFKA_NODE_COUNT_MIN=1 export KAFKA_NODE_COUNT_MAX=3 export KAFKA_NODE_COUNT=1 export KAFKA_NODE_VM_SIZE="Standard_D16ds_v5" export LOG_ANALYTICS_WORKSPACE_NAME="law-monitoring" export DIAGNOSTIC_SETTINGS_NAME="aks-diagnostic-settings" export ACR_NAME="aksacr123" export ACR_SKU="Premium" export USER_ASSIGNED_IDENTITY_NAME="uami-aks" export KUBERNETES_VERSION="1.30.0" export AAD_ADMIN_GROUP_OBJECT_IDS="<your-admin-group-object-id>" export AAD_TENANT_ID="<your-tenant-id>" export GRAFANA_NAME="grafana-kafka-aks" export PROMETHEUS_WORKSPACE_NAME="prometheus-aks"
Implementazioni di rete pre-cluster
Prima di distribuire il cluster AKS per Kafka, distribuire le risorse di rete necessarie che supportano la distribuzione del cluster AKS.
Creare un gruppo di risorse usando il comando
az group create.az group create --name $RESOURCE_GROUP_NAME --location $LOCATIONCreare una rete virtuale usando il comando
az network vnet create.az network vnet create \ --resource-group $RESOURCE_GROUP_NAME \ --name $VNET_NAME \ --address-prefix $ADDRESS_SPACE \ --location $LOCATIONCreare una subnet usando il
az network vnet subnet createcomando .az network vnet subnet create \ --resource-group $RESOURCE_GROUP_NAME \ --vnet-name $VNET_NAME \ --name $SUBNET_NAME \ --address-prefix $SUBNET_PREFIXCreare un indirizzo IP pubblico per il gateway NAT usando il
az network public-ip createcomando .az network public-ip create \ --resource-group $RESOURCE_GROUP_NAME \ --name ${NAT_GATEWAY_NAME}-public-ip \ --sku Standard \ --location $LOCATIONCreare un gateway NAT usando il
az network nat gateway createcomando .az network nat gateway create \ --resource-group $RESOURCE_GROUP_NAME \ --name $NAT_GATEWAY_NAME \ --public-ip-addresses ${NAT_GATEWAY_NAME}-public-ip \ --location $LOCATIONAssociare il gateway NAT alla subnet del nodo usando il comando
az network vnet subnet update.az network vnet subnet update \ --resource-group $RESOURCE_GROUP_NAME \ --vnet-name $VNET_NAME \ --name $SUBNET_NAME \ --nat-gateway $NAT_GATEWAY_NAME
Distribuzioni di monitoraggio e governance pre-cluster
Prima di distribuire il cluster AKS per Kafka, distribuire le risorse di monitoraggio e governance necessarie come prerequisiti per supportare la distribuzione del cluster AKS.
Creare un'area di lavoro Log Analytics usando il
az monitor log-analytics workspace createcomando .az monitor log-analytics workspace create \ --resource-group $RESOURCE_GROUP_NAME \ --workspace-name $LOG_ANALYTICS_WORKSPACE_NAME \ --location $LOCATIONCreare un'area di lavoro di Monitoraggio di Azure per Prometheus usando il
az monitor account createcomando .az monitor account create \ --resource-group $RESOURCE_GROUP_NAME \ --name $PROMETHEUS_WORKSPACE_NAME \ --location $LOCATIONCreare un'istanza di Grafana gestita di Azure usando il
az grafana createcomando .az grafana create \ --resource-group $RESOURCE_GROUP_NAME \ --name $GRAFANA_NAME \ --location $LOCATION \ --api-key Enabled \ --deterministic-outbound-ip Enabled \ --public-network-access Enabled \ --grafana-major-version 11Annotazioni
Azure Managed Grafana dispone della ridondanza di zona disponibile nelle aree selezionate. Se l'area di destinazione ha ridondanza della zona, usare l'argomento
--zone-redundancy Enabled.Creare un Registro Azure Container usando il comando
az acr create.az acr create \ --resource-group $RESOURCE_GROUP_NAME \ --name $ACR_NAME \ --sku $ACR_SKU \ --location $LOCATION \ --admin-enabled false \ --zone-redundancy EnabledCreare un'identità gestita assegnata dall'utente usando il comando
az identity create.az identity create \ --resource-group $RESOURCE_GROUP_NAME \ --name $USER_ASSIGNED_IDENTITY_NAME \ --location $LOCATIONAssegna i permessi RBAC all'identità gestita dell'istanza di Grafana utilizzando il comando
az role assignment create.az role assignment create \ --assignee $(az grafana show --resource-group $RESOURCE_GROUP_NAME --name $GRAFANA_NAME --query identity.principalId -o tsv) \ --role "Monitoring Reader" --scope $(az group show --name $RESOURCE_GROUP_NAME --query id -o tsv)
Distribuzione del cluster del servizio Azure Kubernetes
Distribuire il cluster AKS con pool di nodi dedicati per Kafka per zone di disponibilità usando la CLI di Azure.
Assegnare il ruolo di Collaboratore di rete all'identità gestita assegnata dall'utente per il servizio Azure Kubernetes usando il comando
az role assignment create.az role assignment create \ --assignee $(az identity show --resource-group $RESOURCE_GROUP_NAME --name $USER_ASSIGNED_IDENTITY_NAME --query principalId -o tsv) \ --role "Network Contributor" \ --scope $(az group show --name $RESOURCE_GROUP_NAME --query id -o tsv)Creare un cluster AKS usando il comando
az aks create.az aks create \ --name $AKS_CLUSTER_NAME \ --aad-admin-group-object-ids $AAD_ADMIN_GROUP_OBJECT_IDS \ --aad-tenant-id $AAD_TENANT_ID \ --assign-identity $(az identity show --resource-group $RESOURCE_GROUP_NAME --name $USER_ASSIGNED_IDENTITY_NAME --query id -o tsv) \ --attach-acr $(az acr show --resource-group $RESOURCE_GROUP_NAME --name $ACR_NAME --query id -o tsv) \ --auto-upgrade-channel patch \ --enable-aad \ --enable-addons monitoring \ --enable-azure-monitor-metrics \ --enable-cluster-autoscaler \ --enable-managed-identity \ --enable-oidc-issuer \ --enable-workload-identity \ --kubernetes-version $KUBERNETES_VERSION \ --load-balancer-sku standard \ --location $LOCATION \ --max-count $SYSTEM_NODE_COUNT_MAX \ --max-pods 110 \ --min-count $SYSTEM_NODE_COUNT_MIN \ --network-dataplane cilium \ --network-plugin azure \ --network-plugin-mode overlay \ --network-policy cilium \ --node-osdisk-type Ephemeral \ --node-os-upgrade-channel NodeImage \ --node-vm-size $SYSTEM_NODE_VM_SIZE \ --nodepool-labels "role=system" \ --nodepool-name systempool \ --nodepool-tags "env=production" \ --os-sku AzureLinux \ --outbound-type userAssignedNATGateway \ --pod-cidr 10.244.0.0/16 \ --resource-group $RESOURCE_GROUP_NAME \ --tags "env=production" \ --tier $AKS_TIER \ --vnet-subnet-id $(az network vnet subnet show --resource-group $RESOURCE_GROUP_NAME --vnet-name $VNET_NAME --name $SUBNET_NAME --query id -o tsv) \ --workspace-resource-id $(az monitor log-analytics workspace show --resource-group $RESOURCE_GROUP_NAME --workspace-name $LOG_ANALYTICS_WORKSPACE_NAME --query id -o tsv) \ --zones 1 2 3Creare un pool di nodi aggiuntivo per zona di disponibilità usando un ciclo for e il
az aks nodepool addcomando .for zone in 1 2 3; do az aks nodepool add \ --cluster-name $AKS_CLUSTER_NAME \ --enable-cluster-autoscaler \ --labels app=kafka \ --max-count $KAFKA_NODE_COUNT_MAX \ --max-surge 10% \ --min-count $KAFKA_NODE_COUNT_MIN \ --node-count $KAFKA_NODE_COUNT \ --mode User \ --name "kafka$zone" \ --node-osdisk-type Ephemeral \ --node-vm-size $KAFKA_NODE_VM_SIZE \ --os-sku AzureLinux \ --resource-group $RESOURCE_GROUP_NAME \ --vnet-subnet-id $(az network vnet subnet show --resource-group $RESOURCE_GROUP_NAME --vnet-name $VNET_NAME --name $SUBNET_NAME --query id -o tsv) \ --zones $zone doneAbilitare l'integrazione di Prometheus e Grafana gestita di Azure usando il
az aks updatecomando .az aks update \ --name $AKS_CLUSTER_NAME \ --resource-group $RESOURCE_GROUP_NAME \ --enable-azure-monitor-metrics \ --azure-monitor-workspace-resource-id $(az monitor account show --resource-group $RESOURCE_GROUP_NAME --name $PROMETHEUS_WORKSPACE_NAME --query id -o tsv) \ --grafana-resource-id $(az grafana show --resource-group $RESOURCE_GROUP_NAME --name $GRAFANA_NAME --query id -o tsv)Facoltativo: configurare le impostazioni di diagnostica per il cluster AKS utilizzando il comando
az monitor diagnostic-settings create.az monitor diagnostic-settings create \ --resource $(az aks show --resource-group $RESOURCE_GROUP_NAME --name $AKS_CLUSTER_NAME --query id -o tsv) \ --name $DIAGNOSTIC_SETTINGS_NAME \ --workspace $(az monitor log-analytics workspace show --resource-group $RESOURCE_GROUP_NAME --workspace-name $LOG_ANALYTICS_WORKSPACE_NAME --query id -o tsv) \ --logs '[{"category": "kube-apiserver", "enabled": true}, {"category": "kube-audit", "enabled": true}, {"category": "kube-audit-admin", "enabled": true}, {"category": "kube-controller-manager", "enabled": true}, {"category": "kube-scheduler", "enabled": true}, {"category": "cluster-autoscaler", "enabled": true}, {"category": "cloud-controller-manager", "enabled": true}, {"category": "guard", "enabled": true}, {"category": "csi-azuredisk-controller", "enabled": true}, {"category": "csi-azurefile-controller", "enabled": true}, {"category": "csi-snapshot-controller", "enabled": true}]' \ --metrics '[{"category": "AllMetrics", "enabled": true}]'
In questa sezione, si distribuisce un cluster AKS e le risorse di supporto dell'infrastruttura usando Terraform.
- Un cluster AKS privato con un pool di nodi per zona di disponibilità usando l'Azure Verified Module (AVM).
- Configurazioni di rete virtuale e subnet.
- Gateway NAT per la connettività in uscita.
- Registro Azure Container con endpoint privato.
- Identità gestita assegnata dall'utente per il servizio Azure Kubernetes.
- Area di lavoro di Azure Monitor per le metriche di Prometheus.
- Dashboard di Grafana con gestione Azure con l'integrazione di Prometheus.
- Pool di nodi dedicati per carichi di lavoro Kafka con etichette appropriate.
- Driver CSI del disco di Azure per volumi persistenti (abilitato per impostazione predefinita).
Annotazioni
Questa distribuzione Terraform utilizza il Modulo Verificato di Azure per un cluster AKS di produzione. Di conseguenza, il cluster viene distribuito come cluster privato e con configurazioni predefinite. Per eseguire i comandi kubectl successivi, è necessario implementare la connettività appropriata.
Per personalizzare la configurazione del modulo in base alle esigenze, creare una copia tramite fork o clonare il repository e aggiornare il riferimento all'origine del modulo.
Copiare
variables.tfnella directory Terraform.variable "azure_subscription_id" { type = string description = "The Azure subscription ID to use for the resources." } variable "enable_telemetry" { type = bool default = true description = "This variable controls whether or not telemetry is enabled for the module." } variable "kubernetes_cluster_name" { type = string default = "kafka-cluster" description = "The name of the Kubernetes cluster." } variable "kubernetes_version" { type = string default = "1.30" description = "The version of Kubernetes to use for the cluster." } variable "resource_group_name" { type = string description = "The name of the resource group in which to create the resources." } variable "rbac_aad_admin_group_object_ids" { type = list(string) description = "The object IDs of the Azure AD groups that should be granted admin access to the Kubernetes cluster." } variable "location" { type = string description = "The location in which to create the resources." }Esaminare le variabili e creare un oggetto
kafka.tfvarsin base alle esigenze. Aggiornare con i valori che soddisfano i requisiti:# Replace placeholder values with your actual configuration azure_subscription_id = "00000000-0000-0000-0000-000000000000" # Replace with your actual subscription ID location = "Canada Central" enable_telemetry = true kubernetes_cluster_name = "kafka-aks-cluster" kubernetes_version = "1.30" resource_group_name = "rg-kafka-prod" rbac_aad_admin_group_object_ids = [ "0000-0000-0000-0000", # Add additional admin group object IDs as needed ]Copiare
main.tfnella directory Terraform.terraform { required_version = ">= 1.3.0" required_providers { azurerm = { source = "hashicorp/azurerm" version = ">= 4, <5" } } } provider "azurerm" { features { resource_group { prevent_deletion_if_contains_resources = false } } subscription_id = var.azure_subscription_id } module "naming" { source = "Azure/naming/azurerm" version = ">= 0.3.0" } resource "azurerm_user_assigned_identity" "this" { location = var.location name = "uami-${var.kubernetes_cluster_name}" resource_group_name = var.resource_group_name } data "azurerm_client_config" "current" {} module "avm-ptn-aks-production" { source = "github.com/Azure/terraform-azurerm-avm-ptn-aks-production" kubernetes_version = "1.30" enable_telemetry = var.enable_telemetry name = var.kubernetes_cluster_name resource_group_name = var.resource_group_name location = var.location default_node_pool_vm_sku = "Standard_D8ds_v5" network = { name = module.avm_res_network_virtualnetwork.name resource_group_name = var.resource_group_name node_subnet_id = module.avm_res_network_virtualnetwork.subnets["subnet"].resource_id pod_cidr = "192.168.0.0/16" } acr = { name = module.naming.container_registry.name_unique subnet_resource_id = module.avm_res_network_virtualnetwork.subnets["private_link_subnet"].resource_id private_dns_zone_resource_ids = [azurerm_private_dns_zone.this.id] } managed_identities = { user_assigned_resource_ids = [ azurerm_user_assigned_identity.this.id ] } rbac_aad_tenant_id = data.azurerm_client_config.current.tenant_id rbac_aad_admin_group_object_ids = var.rbac_aad_admin_group_object_ids rbac_aad_azure_rbac_enabled = true node_pools = { kafka = { name = "kafka" vm_size = "Standard_D16ds_v5" orchestrator_version = "1.30" max_count = 3 min_count = 1 os_sku = "AzureLinux" mode = "User" os_disk_size_gb = 128 labels = { "app" = "kafka" } } } } resource "azurerm_private_dns_zone" "this" { name = "privatelink.azurecr.io" resource_group_name = var.resource_group_name } resource "azurerm_nat_gateway" "this" { location = var.location name = module.naming.nat_gateway.name_unique resource_group_name = var.resource_group_name } resource "azurerm_public_ip" "this" { name = module.naming.public_ip.name_unique location = var.location resource_group_name = var.resource_group_name allocation_method = "Static" sku = "Standard" } resource "azurerm_nat_gateway_public_ip_association" "this" { nat_gateway_id = azurerm_nat_gateway.this.id public_ip_address_id = azurerm_public_ip.this.id } module "avm_res_network_virtualnetwork" { source = "Azure/avm-res-network-virtualnetwork/azurerm" version = "0.7.1" address_space = ["10.31.0.0/16"] location = var.location name = "vnet-aks-lab" resource_group_name = var.resource_group_name subnets = { "subnet" = { name = "nodecidr" address_prefixes = ["10.31.0.0/17"] nat_gateway = { id = azurerm_nat_gateway.this.id } private_link_service_network_policies_enabled = false } "private_link_subnet" = { name = "private_link_subnet" address_prefixes = ["10.31.129.0/24"] } } } resource "azurerm_monitor_workspace" "this" { name = "prometheus-aks" location = var.location resource_group_name = var.resource_group_name } resource "azurerm_monitor_data_collection_endpoint" "dataCollectionEndpoint" { name = "prom-aks-endpoint" location = var.location resource_group_name = var.resource_group_name kind = "Linux" } resource "azurerm_monitor_data_collection_rule" "dataCollectionRule" { name = "prom-aks-dcr" location = var.location resource_group_name = var.resource_group_name data_collection_endpoint_id = azurerm_monitor_data_collection_endpoint.dataCollectionEndpoint.id kind = "Linux" description = "DCR for Azure Monitor Metrics Profile (Managed Prometheus)" destinations { monitor_account { monitor_account_id = azurerm_monitor_workspace.this.id name = "PrometheusAzMonitorAccount" } } data_flow { streams = ["Microsoft-PrometheusMetrics"] destinations = ["PrometheusAzMonitorAccount"] } data_sources { prometheus_forwarder { streams = ["Microsoft-PrometheusMetrics"] name = "PrometheusDataSource" } } } resource "azurerm_monitor_data_collection_rule_association" "dataCollectionRuleAssociation" { name = "prom-aks-dcra" target_resource_id = module.avm-ptn-aks-production.resource_id data_collection_rule_id = azurerm_monitor_data_collection_rule.dataCollectionRule.id description = "Association of data collection rule. Deleting this association will break the data collection for this AKS Cluster." } resource "azurerm_dashboard_grafana" "this" { name = "grafana-kafka-aks" location = var.location resource_group_name = var.resource_group_name api_key_enabled = true deterministic_outbound_ip_enabled = true public_network_access_enabled = true grafana_major_version = 11 azure_monitor_workspace_integrations { resource_id = azurerm_monitor_workspace.this.id } identity { type = "SystemAssigned" } } data "azurerm_resource_group" "current" { name = var.resource_group_name depends_on = [azurerm_dashboard_grafana.this] } resource "azurerm_role_assignment" "grafana_monitoring_reader" { scope = data.azurerm_resource_group.current.id role_definition_name = "Monitoring Reader" principal_id = azurerm_dashboard_grafana.this.identity[0].principal_id skip_service_principal_aad_check = true } resource "azurerm_kubernetes_cluster_extension" "container_storage" { name = "microsoft-azurecontainerstorage" cluster_id = module.avm-ptn-aks-production.resource_id extension_type = "microsoft.azurecontainerstorage" configuration_settings = { "enable-azure-container-storage" : "azureDisk", } }Inizializzare Terraform usando il
terraform initcomando .terraform initCreare un piano di distribuzione usando il
terraform plancomando .terraform plan -var-file="kafka.tfvars"Applicare la configurazione usando il
terraform applycomando .terraform apply -var-file="kafka.tfvars"
Convalidare la distribuzione e connettersi al cluster
Dopo aver distribuito il cluster del servizio Azure Kubernetes, seguire questa procedura per convalidare la distribuzione e connettersi al server API del servizio Azure Kubernetes.
Verificare la distribuzione del cluster del servizio Azure Kubernetes usando il comando
az aks show.az aks show --resource-group $RESOURCE_GROUP_NAME --name $AKS_CLUSTER_NAME --output tableDopo aver verificato la distribuzione, connetterti al cluster AKS usando il comando
az aks get-credentials.az aks get-credentials --resource-group $RESOURCE_GROUP_NAME --name $AKS_CLUSTER_NAMEVerificare la connettività elencando i nodi usando il
kubectl getcomando .kubectl get nodes
Creare una classe di archiviazione per Kafka
Creare una classe di archiviazione per dischi SSD Premium v2 usando il
kubectl applycomando .kubectl apply -f - <<EOF --- apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: kafka-premium-ssd-v2 provisioner: disk.csi.azure.com parameters: skuName: PremiumV2_LRS diskIOPSReadWrite: "5000" diskMBpsReadWrite: "200" reclaimPolicy: Delete volumeBindingMode: WaitForFirstConsumer allowVolumeExpansion: true EOFImportante
La configurazione di archiviazione precedente rappresenta un punto di partenza. Per le distribuzioni di produzione, modificare i valori di
diskIOPSReadWriteediskMBpsReadWritein base alla dimensione prevista del cluster Kafka e ai requisiti di carico di lavoro.
Passaggio successivo
Contributori
Microsoft gestisce questo articolo. I collaboratori seguenti l'hanno originariamente scritto:
- Sergio Navar | Senior Customer Engineer
- Erin Schaffer | Sviluppatore di contenuti 2