この記事では、Azure Kubernetes Service (AKS) に Kafka クラスターをデプロイするためのインフラストラクチャを準備します。
アーキテクチャの概要
Kafka デプロイのターゲット AKS アーキテクチャは、包括的なゾーン冗長設計を通じて高可用性に優先順位を付けます。 この設計では、ワークロードの分散とストレージの配置を維持するために、可用性ゾーンごとに 1 つずつ、3 つのノード プールが必要です。 このアーキテクチャの永続ボリュームにはゾーン アフィニティがあるため、このゾーン構成は重要です。 クラスター オートスケーラーでプロビジョニングされた新しいノードは、適切なゾーンに作成する必要があります。 このゾーン固有性がないと、ゾーンにバインドされた永続ボリュームを持つポッドは保留のままとなります。 Strimzi クラスター オペレーターと Kafka ブローカー インスタンスの複数のレプリカが定義され、ゾーン間で分散されるため、ターゲット リージョン内のノードとゾーン全体の障害に対する回復性が提供されます。 リソースの競合を防ぎ、予測可能なパフォーマンスを確保するには、Kafka ワークロード用の専用ノード プールを強くお勧めします。
[前提条件]
- まだ行っていない場合は、 Strimzi を使用して Azure Kubernetes Service (AKS) に Kafka をデプロイするための概要を確認してください。
- Terraform v1.3.0 以降がインストールされています。
- インストールされて認証されている Azure CLI。
- インフラストラクチャ リソースを作成し、マネージド ID に RBAC を割り当てるための十分なアクセス許可:ネットワーク共同作成者、Azure Kubernetes サービス共同作成者、ロール ベースのアクセス制御管理者。
インフラストラクチャのデプロイ
次の手順では、AKS クラスターをデプロイし、Kafka デプロイに必要なインフラストラクチャをサポートする手順について説明します。
ヒント
既存の AKS クラスターまたは既存のサポート インフラストラクチャがある場合: 完全なデプロイ手順をスキップするか、コードを調整できますが、インフラストラクチャと AKS クラスターが次の要件を満たしていることを確認します。
- ノードのサブネットを持つ仮想ネットワーク
- AKS クラスターにインストールされている Azure Container Storage。
- 可用性ゾーンごとのノード プール (1、2、3)。
- ワークロードの要件に基づいて 適切な VM サイズ を持つ Kafka 用の専用ノード プール。
- Azure Managed Prometheus と Azure Managed Grafana が構成されました。
環境変数を設定する
CLI コマンドを実行する前に、要件を満たす値と共に、このガイド全体で使用する次の環境変数を設定します。
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"
Precluster ネットワークのデプロイ
Kafka 用の AKS クラスターをデプロイする前に、AKS クラスターのデプロイをサポートする前提条件のネットワーク リソースをデプロイします。
az group create
コマンドを使用してリソース グループを作成します。az group create --name $RESOURCE_GROUP_NAME --location $LOCATION
az network vnet create
コマンドを使用して、仮想ネットワークを作成します。az network vnet create \ --resource-group $RESOURCE_GROUP_NAME \ --name $VNET_NAME \ --address-prefix $ADDRESS_SPACE \ --location $LOCATION
az network vnet subnet create
コマンドを使用してサブネットを作成します。az network vnet subnet create \ --resource-group $RESOURCE_GROUP_NAME \ --vnet-name $VNET_NAME \ --name $SUBNET_NAME \ --address-prefix $SUBNET_PREFIX
az network public-ip create
コマンドを使用して、NAT ゲートウェイのパブリック IP を作成します。az network public-ip create \ --resource-group $RESOURCE_GROUP_NAME \ --name ${NAT_GATEWAY_NAME}-public-ip \ --sku Standard \ --location $LOCATION
az network nat gateway create
コマンドを使用して NAT ゲートウェイを作成します。az network nat gateway create \ --resource-group $RESOURCE_GROUP_NAME \ --name $NAT_GATEWAY_NAME \ --public-ip-addresses ${NAT_GATEWAY_NAME}-public-ip \ --location $LOCATION
az network vnet subnet update
コマンドを使用して、NAT ゲートウェイをノード サブネットに関連付けます。az network vnet subnet update \ --resource-group $RESOURCE_GROUP_NAME \ --vnet-name $VNET_NAME \ --name $SUBNET_NAME \ --nat-gateway $NAT_GATEWAY_NAME
クラスター前の監視とガバナンスの配置
Kafka 用の AKS クラスターをデプロイする前に、AKS クラスターのデプロイをサポートする前提条件の監視およびガバナンス リソースをデプロイします。
az monitor log-analytics workspace create
コマンドを使用して、Log Analytics ワークスペースを作成します。az monitor log-analytics workspace create \ --resource-group $RESOURCE_GROUP_NAME \ --workspace-name $LOG_ANALYTICS_WORKSPACE_NAME \ --location $LOCATION
az monitor account create
コマンドを使用して、Prometheus 用の Azure Monitor ワークスペースを作成します。az monitor account create \ --resource-group $RESOURCE_GROUP_NAME \ --name $PROMETHEUS_WORKSPACE_NAME \ --location $LOCATION
az grafana create
コマンドを使用して、Azure マネージド Grafana インスタンスを作成します。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
注
Azure Managed Grafana には、 一部のリージョンで使用可能なゾーン冗長性があります。 ターゲット リージョンにゾーン冗長性がある場合は、
--zone-redundancy Enabled
引数を使用します。az acr create
コマンドを使用して Azure コンテナー レジストリを作成します。az acr create \ --resource-group $RESOURCE_GROUP_NAME \ --name $ACR_NAME \ --sku $ACR_SKU \ --location $LOCATION \ --admin-enabled false \ --zone-redundancy Enabled
az identity create
コマンドを使用して、ユーザー割り当てマネージド ID を作成します。az identity create \ --resource-group $RESOURCE_GROUP_NAME \ --name $USER_ASSIGNED_IDENTITY_NAME \ --location $LOCATION
az role assignment create
コマンドを使用して、Grafana インスタンスのマネージド ID に RBAC アクセス許可を割り当てます。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)
AKS クラスターのデプロイ
Azure CLI を使用して、可用性ゾーンごとの Kafka 用の専用ノード プールと Azure Container Storage が有効になっている AKS クラスターをデプロイします。
まず、
az role assignment create
コマンドを使用して、AKS のユーザー割り当てマネージド ID にネットワーク共同作成者ロールを割り当てます。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)
az aks create
コマンドを使用して、AKS クラスターを作成します。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
for ループと
az aks nodepool add
コマンドを使用して、可用性ゾーンごとに追加のノード プールを作成します。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
az aks update
コマンドを使用して、AKS クラスターで azureDisk で Azure Container Storage を有効にします。az aks update \ --name $AKS_CLUSTER_NAME \ --resource-group $RESOURCE_GROUP_NAME \ --enable-azure-container-storage azureDisk
az aks update
コマンドを使用して、Azure Managed Prometheus と Grafana の統合を有効にします。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)
省略可能:
az monitor diagnostic-settings create
コマンドを使用して、AKS クラスターの診断設定を構成します。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}]'
このセクションでは、Terraform を使用して AKS クラスターとサポート インフラストラクチャ リソースをデプロイします。
- Azure 検証済みモジュール (AVM) を使用する可用性ゾーンごとのノード プールを持つプライベート AKS クラスター。
- 仮想ネットワークとサブネットの構成。
- 送信接続用の NAT ゲートウェイ。
- プライベート エンドポイントを持つ Azure Container Registry。
- AKS のユーザー割り当てマネージド ID。
- Prometheus メトリック用の Azure Monitor ワークスペース。
- Prometheus 統合を使用した Azure Managed Grafana ダッシュボード。
- 適切なラベルを持つ Kafka ワークロード用の専用ノード プール。
- 永続ボリューム用の Azure Container Storage 拡張機能。
注
この Terraform デプロイでは、運用 AKS クラスターに Azure 検証済みモジュール を使用します。 その結果、クラスターはプライベート クラスターとしてデプロイされ、特定の設定が施されています。 後続の kubectl コマンドを実行するには、適切な接続が必要です。
ニーズに合わせてモジュール構成をカスタマイズするには、リポジトリをフォークまたは複製し、モジュール ソース参照を更新します。
variables.tf
を 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." }
変数を確認し、必要に応じて
kafka.tfvars
を作成します。 要件を満たす値で更新します。# 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 ]
main.tf
を 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", } }
terraform init
コマンドを使用して Terraform を初期化します。terraform init
terraform plan
コマンドを使用してデプロイ 計画を作成します。terraform plan -var-file="kafka.tfvars"
terraform apply
コマンドを使用して構成を適用します。terraform apply -var-file="kafka.tfvars"
デプロイを検証し、クラスターに接続する
AKS クラスターをデプロイした後、次の手順を使用してデプロイを検証し、AKS API Server にアクセスします。
az aks show
コマンドを使用して、AKS クラスターのデプロイを確認します。az aks show --resource-group $RESOURCE_GROUP_NAME --name $AKS_CLUSTER_NAME --output table
デプロイを確認したら、
az aks get-credentials
コマンドを使用して AKS クラスターに接続します。az aks get-credentials --resource-group $RESOURCE_GROUP_NAME --name $AKS_CLUSTER_NAME
kubectl get
コマンドを使用してノードを一覧表示して、接続を確認します。kubectl get nodes
Azure Container Storage ストレージ プールを作成する
kubectl get
コマンドを使用して、AKS クラスターで Azure Container Storage が実行されていることを確認します。kubectl get deploy,ds -n acstor
現時点では、テイントを持つノードを処理するための容認を使用して Azure Container Storage を構成することはできません。 ノードにテイントを追加すると、Azure Container Storage のデプロイがブロックされます。
クラスターをデプロイし、Azure Container Storage が実行されていることを検証したら、
kubectl apply
コマンドを使用してマルチゾーンStoragePool
構成を適用します。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
重要
上記のストレージ構成は、開始点を表します。 運用環境のデプロイでは、「Azure Container Storage」セクションで説明されているように、予想される Kafka クラスターのサイズとワークロードに基づいて、iopsReadWrite
、mbpsReadWrite
、およびstorage
の値を調整します。
次のステップ
貢献者
Microsoft では、この記事を保持しています。 当初の寄稿者は次のとおりです。
- セルヒオ・ナバー |シニア カスタマー エンジニア
- Erin Schaffer |コンテンツ開発者 2
Azure Kubernetes Service