Nota
O acesso a esta página requer autorização. Pode tentar iniciar sessão ou alterar os diretórios.
O acesso a esta página requer autorização. Pode tentar alterar os diretórios.
Neste artigo, você prepara a infraestrutura para implantar um cluster Kafka no Serviço Kubernetes do Azure (AKS).
Visão geral da arquitetura
A arquitetura AKS de destino para a implementação do Kafka prioriza a alta disponibilidade através de um design abrangente com redundância zonal. O projeto requer três pools de nós — um por zona de disponibilidade — para manter a distribuição da carga de trabalho e o alinhamento do armazenamento. Essa configuração zonal é crítica porque os volumes persistentes nessa arquitetura têm afinidade zonal. Todos os novos nós provisionados com o autoscaler de cluster devem ser criados na zona apropriada. Sem essa especificidade zonal, os pods com volumes persistentes ligados à zona permaneceriam em estado de espera. Várias réplicas do Operador de Cluster Strimzi e instâncias do broker Kafka são definidas e distribuídas através de zonas, proporcionando resiliência tanto contra falhas em nós como em zonas inteiras na região de destino. Para evitar a contenção de recursos e assegurar um desempenho previsível, é altamente recomendada a utilização de pools de nós dedicados para cargas de trabalho Kafka.
Pré-requisitos
- Se ainda não o fez, consulte a Visão geral da implantação do Kafka no Serviço Kubernetes do Azure (AKS) usando o Strimzi.
- Terraform v1.3.0 ou posterior instalado.
- CLI do Azure instalada e autenticada.
- Permissões suficientes para criar recursos de infraestrutura e atribuir RBAC a identidades gerenciadas: Colaborador de Rede, Colaborador de Serviço Kubernetes do Azure e Administrador de Controle de Acesso Baseado em Função.
Implementar infraestrutura
As etapas a seguir o orientam na implantação do cluster AKS e na infraestrutura de suporte necessária para sua implantação do Kafka.
Sugestão
Se você tiver um cluster AKS existente ou uma infraestrutura de suporte existente: Você pode ignorar as etapas de implantação completas ou fazer ajustes de código, mas garantir que sua infraestrutura e cluster AKS atendam aos seguintes requisitos:
- Rede virtual com sub-rede para nodos
- Armazenamento de Contêiner do Azure instalado no cluster AKS.
- Pool de nós por zona de disponibilidade (1, 2 e 3).
- Grupos de nós dedicados para Kafka com tamanhos de VM apropriados com base nos requisitos da sua carga de trabalho.
- Azure Managed Prometheus e Azure Managed Grafana configurados.
Definir variáveis de ambiente
Antes de executar qualquer comando da CLI, defina as seguintes variáveis de ambiente para usar ao longo deste guia com valores que atendam às suas necessidades:
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"
Implantações de rede pré-cluster
Antes de implantar o cluster AKS para Kafka, implante os recursos de rede de pré-requisito que suportam a implantação do cluster AKS:
Crie um grupo de recursos usando o comando
az group create
.az group create --name $RESOURCE_GROUP_NAME --location $LOCATION
Crie uma rede virtual usando o
az network vnet create
comando.az network vnet create \ --resource-group $RESOURCE_GROUP_NAME \ --name $VNET_NAME \ --address-prefix $ADDRESS_SPACE \ --location $LOCATION
Crie uma sub-rede usando o
az network vnet subnet create
comando.az network vnet subnet create \ --resource-group $RESOURCE_GROUP_NAME \ --vnet-name $VNET_NAME \ --name $SUBNET_NAME \ --address-prefix $SUBNET_PREFIX
Crie um IP público para o gateway NAT usando o
az network public-ip create
comando.az network public-ip create \ --resource-group $RESOURCE_GROUP_NAME \ --name ${NAT_GATEWAY_NAME}-public-ip \ --sku Standard \ --location $LOCATION
Crie um gateway NAT usando o
az network nat gateway create
comando.az network nat gateway create \ --resource-group $RESOURCE_GROUP_NAME \ --name $NAT_GATEWAY_NAME \ --public-ip-addresses ${NAT_GATEWAY_NAME}-public-ip \ --location $LOCATION
Associe o gateway NAT à sub-rede do nó usando
az network vnet subnet update
o comando.az network vnet subnet update \ --resource-group $RESOURCE_GROUP_NAME \ --vnet-name $VNET_NAME \ --name $SUBNET_NAME \ --nat-gateway $NAT_GATEWAY_NAME
Implantações de monitoramento e governança pré-cluster
Antes de implantar o cluster AKS para Kafka, implante os recursos de monitoramento e governança de pré-requisitos que suportam a implantação do cluster AKS:
Crie um espaço de trabalho de análise de log usando o
az monitor log-analytics workspace create
comando.az monitor log-analytics workspace create \ --resource-group $RESOURCE_GROUP_NAME \ --workspace-name $LOG_ANALYTICS_WORKSPACE_NAME \ --location $LOCATION
Crie um espaço de trabalho de monitor do Azure para Prometheus usando o
az monitor account create
comando.az monitor account create \ --resource-group $RESOURCE_GROUP_NAME \ --name $PROMETHEUS_WORKSPACE_NAME \ --location $LOCATION
Crie uma instância do Grafana gerenciada do Azure usando o
az grafana create
comando.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 11
Observação
O Azure Managed Grafana tem redundância de zona disponível em regiões selecionadas. Se a região de destino tiver redundância de zona, use o
--zone-redundancy Enabled
argumento.Crie um registro de contêiner do Azure usando o
az acr create
comando.az acr create \ --resource-group $RESOURCE_GROUP_NAME \ --name $ACR_NAME \ --sku $ACR_SKU \ --location $LOCATION \ --admin-enabled false \ --zone-redundancy Enabled
Crie uma identidade gerenciada atribuída pelo usuário usando o
az identity create
comando.az identity create \ --resource-group $RESOURCE_GROUP_NAME \ --name $USER_ASSIGNED_IDENTITY_NAME \ --location $LOCATION
Atribua permissões RBAC à identidade gerenciada da instância do Grafana usando o
az role assignment create
comando.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)
Implantação de cluster AKS
Implante o cluster AKS com pools de nós dedicados para Kafka por zona de disponibilidade e o Armazenamento de Contêiner do Azure habilitado usando a CLI do Azure:
Primeiro, atribua a função de colaborador de rede à identidade gerenciada atribuída pelo usuário para o AKS usando o
az role assignment create
comando.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)
Crie um cluster AKS usando o 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 3
Crie um pool de nós adicional por zona de disponibilidade usando um loop for e o
az aks nodepool add
comando.for zone in 1 2 3; do az aks nodepool add \ --cluster-name $AKS_CLUSTER_NAME \ --enable-cluster-autoscaler \ --labels app=kafka acstor.azure.com/io-engine=acstor \ --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 done
Habilite o Armazenamento de Contêiner do Azure no cluster AKS com azureDisk, usando o comando
az aks update
.az aks update \ --name $AKS_CLUSTER_NAME \ --resource-group $RESOURCE_GROUP_NAME \ --enable-azure-container-storage azureDisk
Habilite a integração do Azure Managed Prometheus e do Grafana usando o
az aks update
comando.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)
Opcional: defina a configuração de diagnóstico para o cluster AKS usando o
az monitor diagnostic-settings create
comando.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}]'
Nesta seção, você implanta um cluster AKS e suporta recursos de infraestrutura usando o Terraform:
- Um cluster AKS privado com um pool de nós por zona de disponibilidade usando o Módulo Verificado do Azure (AVM).
- Configurações de rede virtual e sub-rede.
- Gateway NAT para conectividade de saída.
- Registro de Contentores do Azure com ponto de extremidade privado.
- Identidade gerenciada atribuída pelo usuário para AKS.
- Espaço de trabalho do Azure Monitor para métricas de Prometheus.
- Painel do Azure Managed Grafana com integração Prometheus.
- Pools de nós dedicados para cargas de trabalho do Kafka com rótulos apropriados.
- Extensão do Armazenamento de Contêiner do Azure para volumes persistentes.
Observação
Esta implantação do Terraform usa o Módulo Verificado do Azure para um cluster AKS de produção. Como resultado, o cluster é implantado como um cluster privado e com configurações opinativas. A conectividade apropriada deve estar disponível para executar os subsequentes comandos kubectl.
Para personalizar a configuração do módulo para atender às suas necessidades, bifurque ou clone o repositório e atualize a referência da fonte do módulo.
Copie o para o
variables.tf
diretório 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." }
Revise as variáveis e crie um
kafka.tfvars
conforme necessário. Atualize com valores que atendam às suas necessidades:# 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 ]
Copie o
main.tf
para o diretório 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" "acstor.azure.com/io-engine" = "acstor" } } } } 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", } }
Inicialize o Terraform usando o
terraform init
comando.terraform init
Crie um plano de implantação usando o
terraform plan
comando.terraform plan -var-file="kafka.tfvars"
Aplique a configuração usando o
terraform apply
comando.terraform apply -var-file="kafka.tfvars"
Validar a implantação e conectar-se ao cluster
Depois de implantar seu cluster AKS, use as seguintes etapas para validar a implantação e obter acesso ao AKS API Server:
Verifique a implantação do cluster AKS usando o
az aks show
comando.az aks show --resource-group $RESOURCE_GROUP_NAME --name $AKS_CLUSTER_NAME --output table
Depois de verificar a implantação, conecte-se ao cluster AKS usando o
az aks get-credentials
comando.az aks get-credentials --resource-group $RESOURCE_GROUP_NAME --name $AKS_CLUSTER_NAME
Verifique a conectividade listando nós usando o
kubectl get
comando.kubectl get nodes
Criar pool de armazenamento do Armazenamento de Contêiner do Azure
Verifique se o Armazenamento de Contêiner do Azure está sendo executado em seu cluster AKS usando o
kubectl get
comando.kubectl get deploy,ds -n acstor
Atualmente, não é possível configurar o Armazenamento de Contêiner do Azure com uma tolerância para lidar com nós com manchas. Adicionar manchas aos nós bloqueará a implantação do Armazenamento de Contêiner do Azure.
Depois de implantar o cluster e validar que o Armazenamento de Contêiner do Azure está em execução, aplique a configuração de várias zonas
StoragePool
usando okubectl apply
comando.kubectl apply -f - <<EOF --- apiVersion: containerstorage.azure.com/v1 kind: StoragePool metadata: name: azuredisk-zr namespace: acstor spec: zones: ["1","2","3"] poolType: azureDisk: skuName: PremiumV2_LRS iopsReadWrite: 5000 mbpsReadWrite: 200 resources: requests: storage: 1Ti EOF
Importante
A configuração de armazenamento acima representa um ponto de partida. Para implantações de produção, ajuste o iopsReadWrite
, mbpsReadWrite
e storage
os valores com base no tamanho esperado do cluster Kafka e na carga de trabalho, conforme discutido na seção Armazenamento de Contêiner do Azure.
Próximo passo
Contribuidores
A Microsoft mantém este artigo. Os seguintes colaboradores escreveram-no originalmente:
- Sergio Navar | Engenheiro de Clientes Senior
- Erin Schaffer | Desenvolvedora de Conteúdo 2
Azure Kubernetes Service