Kafka Connect no Azure Container Instances

Kafka Connect no Azure Container Instances

Neste artigo você vai fazer o deploy do Kafka Connect no Azure Container Instances com Terraform, usando a imagem oficial do Confluent. O Kafka Connect no Azure Container Instances permite integrar o Event Hubs com outros sistemas — bancos de dados, blob storage, APIs — sem escrever código de produtor ou consumidor. A comunicação com o Event Hubs usa SASL_SSL, o mesmo protocolo Kafka dos artigos anteriores.

Série: Kafka no Azure com Event Hubs
  • 📖 Art. 01: Kafka no Azure com Event Hubs
  • 📖 Art. 02: Azure Event Hubs com Terraform
  • 📖 Art. 03: Python e Kafka no Azure Event Hubs
  • ⚙️ Art. 04 (este): Kafka Connect no Azure Container Instances
  • 🔒 Art. 05: Schema Registry no Azure Event Hubs
  • 🔒 Art. 06: Monitoramento Kafka com Grafana no Azure

Sumário

O que é Kafka Connect

Kafka Connect é um framework de integração distribuído que faz parte do ecossistema Apache Kafka. Ele move dados entre o Kafka (ou, no nosso caso, o Event Hubs via protocolo Kafka) e sistemas externos usando conectores: connectors source importam dados de sistemas externos para o Kafka, e connectors sink exportam dados do Kafka para sistemas externos. O Kafka Connect no Azure Container Instances é uma alternativa ao Kafka Connect self-hosted, mais simples de operar para workloads de lab e pequenos ambientes.

O Kafka Connect expõe uma REST API na porta 8083 para gerenciar conectores sem reiniciar o processo. Você registra um conector via POST, monitora seu status via GET e o para via DELETE. Toda a configuração — incluindo o bootstrap server do Event Hubs e as credenciais SASL — é passada via variáveis de ambiente no container.

Por que Azure Container Instances

O Azure Container Instances (ACI) é o serviço serverless de containers do Azure: você define CPU, memória e imagem, e a Microsoft gerencia o host. Para o Kafka Connect no Azure Container Instances, o ACI é ideal para labs e ambientes de desenvolvimento porque: (1) não exige cluster Kubernetes; (2) o custo é por segundo de execução; (3) o provisionamento leva menos de 30 segundos; (4) o Terraform suporta ACI nativamente via módulo. Para produção com alta disponibilidade, migre para AKS com múltiplos workers do Kafka Connect.

Pré-requisitos

Para este artigo de Kafka Connect no Azure Container Instances, você precisa dos Arts. 01, 02 e 03 aplicados. A connection string SAS do namespace (com permissão manage) é necessária para o Kafka Connect criar os tópicos internos de configuração, offset e status. Obtenha-a via CLI antes do deploy:

az eventhubs namespace authorization-rule keys list \
  --resource-group rg-kafka-blog-castilho-eus \
  --namespace-name evhns-kafka-blog-castilho-eus \
  --name RootManageSharedAccessKey \
  --query primaryConnectionString -o tsv

Arquitetura do deploy

O Kafka Connect no Azure Container Instances que provisionamos usa a imagem confluentinc/cp-kafka-connect:7.6.0 com 1 vCPU e 2 GB de memória. O container escuta na porta 8083 (REST API) e se conecta ao namespace Event Hubs via SASL_SSL na porta 9093. As variáveis de ambiente configuram o bootstrap server, o group ID do Connect, os tópicos internos e os converters de key/value.

VariávelValor
CONNECT_BOOTSTRAP_SERVERSevhns-kafka-blog-castilho-eus.servicebus.windows.net:9093
CONNECT_GROUP_IDkafka-connect-group
CONNECT_SECURITY_PROTOCOLSASL_SSL
CONNECT_SASL_MECHANISMPLAIN
CONNECT_REST_PORT8083
CONNECT_KEY_CONVERTERorg.apache.kafka.connect.storage.StringConverter
CONNECT_VALUE_CONVERTERorg.apache.kafka.connect.json.JsonConverter

Passo 1 — variables.tf com senha segura

A connection string SAS é uma credencial sensível e não deve estar no main.tf ou em qualquer arquivo commitado. Defina-a via variável de ambiente Terraform antes do apply:

variable "kafka_connect_sasl_password" {
  type      = string
  sensitive = true
  description = "Connection string SAS do namespace Event Hubs para o Kafka Connect"
}

variable "tags" {
  type = map(string)
  default = {
    project     = "kafka-blog-castilho"
    environment = "lab"
    managed_by  = "terraform"
    series      = "kafka-azure"
  }
}
# Exportar antes do terraform apply
export TF_VAR_kafka_connect_sasl_password="$(az eventhubs namespace authorization-rule keys list \
  --resource-group rg-kafka-blog-castilho-eus \
  --namespace-name evhns-kafka-blog-castilho-eus \
  --name RootManageSharedAccessKey \
  --query primaryConnectionString -o tsv)"

Passo 2 — main.tf: módulo ACI

data "azurerm_resource_group" "kafka" {
  name = "rg-kafka-blog-castilho-eus"
}

module "kafka_connect" {
  source              = "../../terraform-aci-modules"
  name                = "aci-kafka-connect-blog-castilho-eus"
  resource_group_name = data.azurerm_resource_group.kafka.name
  location            = data.azurerm_resource_group.kafka.location
  container_name      = "kafka-connect"
  image               = "confluentinc/cp-kafka-connect:7.6.0"
  cpu                 = "1.0"
  memory              = "2.0"
  restart_policy      = "Always"

  ports = [
    { port = 8083, protocol = "TCP" },
  ]

  environment_variables = {
    CONNECT_BOOTSTRAP_SERVERS                 = "evhns-kafka-blog-castilho-eus.servicebus.windows.net:9093"
    CONNECT_GROUP_ID                          = "kafka-connect-group"
    CONNECT_CONFIG_STORAGE_TOPIC              = "__connect-configs"
    CONNECT_OFFSET_STORAGE_TOPIC              = "__connect-offsets"
    CONNECT_STATUS_STORAGE_TOPIC              = "__connect-status"
    CONNECT_REST_PORT                         = "8083"
    CONNECT_SECURITY_PROTOCOL                 = "SASL_SSL"
    CONNECT_SASL_MECHANISM                    = "PLAIN"
    CONNECT_KEY_CONVERTER                     = "org.apache.kafka.connect.storage.StringConverter"
    CONNECT_VALUE_CONVERTER                   = "org.apache.kafka.connect.json.JsonConverter"
    CONNECT_VALUE_CONVERTER_SCHEMAS_ENABLE    = "false"
    CONNECT_CONFIG_STORAGE_REPLICATION_FACTOR = "1"
    CONNECT_OFFSET_STORAGE_REPLICATION_FACTOR = "1"
    CONNECT_STATUS_STORAGE_REPLICATION_FACTOR = "1"
  }

  secure_environment_variables = {
    CONNECT_SASL_JAAS_CONFIG = "org.apache.kafka.common.security.plain.PlainLoginModule required username=\"$ConnectionString\" password=\"${var.kafka_connect_sasl_password}\";"
  }

  tags = var.tags
}

O campo secure_environment_variables do módulo ACI garante que a connection string seja passada de forma segura — ela não aparece no estado do Terraform em texto claro. O replication factor 1 é adequado para lab; em produção use o número de partições disponíveis.

Passo 3 — Executar o Terraform

cp backend.hcl.example backend.hcl
terraform init -backend-config=backend.hcl
terraform plan
terraform apply

O ACI demora cerca de 60-90 segundos para ser provisionado. O pull da imagem Docker Hub pode causar lentidão na primeira inicialização — ou um erro 409 de rate limit, conforme descrito na seção abaixo.

Resultado do apply

RecursoNomeDetalhe
Container Instanceaci-kafka-connect-blog-castilho-eus1 vCPU, 2 GB, East US
REST APIIP público do ACI, porta 8083Disponível após ~90s

Verificar a REST API do Kafka Connect

Após o ACI estar Running, obtenha o IP público e teste a REST API do Kafka Connect no Azure Container Instances:

# Obter IP público do ACI
ACI_IP=$(az container show \
  --resource-group rg-kafka-blog-castilho-eus \
  --name aci-kafka-connect-blog-castilho-eus \
  --query ipAddress.ip -o tsv)

# Verificar status do Kafka Connect
curl http://$ACI_IP:8083/

# Listar conectores registrados
curl http://$ACI_IP:8083/connectors

A resposta do endpoint raiz retorna a versão do Kafka Connect e do Kafka. Se retornar um erro de conexão, aguarde mais 30 segundos para o container terminar de inicializar.

Registrar um conector sink

Com o Kafka Connect no Azure Container Instances rodando, você pode registrar um conector sink para exportar eventos do Event Hubs para o Azure Blob Storage. O exemplo abaixo usa o FileStreamSink (incluído na imagem base) para fins de demonstração:

curl -X POST http://$ACI_IP:8083/connectors \
  -H "Content-Type: application/json" \
  -d '{
    "name": "pedidos-file-sink",
    "config": {
      "connector.class": "org.apache.kafka.connect.file.FileStreamSinkConnector",
      "tasks.max": "1",
      "topics": "evh-pedidos-blog-castilho-eus",
      "file": "/tmp/pedidos-output.txt"
    }
  }'

Nota: Docker Hub rate limit no ACI

O Azure Container Instances faz pull de imagens diretamente do Docker Hub. Contas anônimas têm limite de 100 pulls por 6 horas por IP. Em ambientes compartilhados (como subscriptions corporativas com muitos ACI), esse rate limit pode causar um erro 409 Conflict durante o provisionamento do Kafka Connect no Azure Container Instances. Para resolver: (1) aguarde 6 horas e execute terraform apply novamente; (2) autentique o ACI com uma conta Docker Hub paga via image_registry_credential no módulo; (3) copie a imagem para um Azure Container Registry privado e use ACR como registry.

Troubleshooting

Erro: 409 Conflict ao fazer pull da imagem — Docker Hub rate limit. Veja a seção acima. O nome do ACI fica como aci-kafka-connect-blog-castilho-eus no estado Terraform mas sem container rodando.

Kafka Connect não conecta ao Event Hubs — verifique se a connection string em TF_VAR_kafka_connect_sasl_password inclui o EntityPath ou não. O Kafka Connect usa a connection string do namespace (sem EntityPath), não do event hub individual.

Tópicos internos (__connect-configs) não criados — o Kafka Connect cria automaticamente os tópicos internos na inicialização. Se o Event Hubs não permitir criação automática de tópicos, crie manualmente os event hubs __connect-configs, __connect-offsets e __connect-status com 1 partição cada.

Próximos passos

Com o Kafka Connect no Azure Container Instances configurado, o próximo artigo adiciona o Schema Registry do Event Hubs, que garante que produtores e consumidores usem o mesmo schema Avro, evitando erros de deserialização quando o schema evolui.

Série: Kafka no Azure com Event Hubs
  • 📖 Art. 01: Kafka no Azure com Event Hubs
  • 📖 Art. 02: Azure Event Hubs com Terraform
  • 📖 Art. 03: Python e Kafka no Azure Event Hubs
  • ⚙️ Art. 04 (este): Kafka Connect no Azure Container Instances
  • 🔒 Art. 05: Schema Registry no Azure Event Hubs
  • 🔒 Art. 06: Monitoramento Kafka com Grafana no Azure

Interessado em saber mais sobre artigos relacionados ao Microsoft Azure CLIQUE AQUI

🚀 Vamos nos conectar?

Não perca nenhuma oportunidade! Cadastre-se nas minhas redes e no canal do YouTube para receber conteúdos de TI, Cloud, Azure, Kubernetes e DevOps em primeira mão.

Dica: No Facebook, todos os artigos do blog são publicados automaticamente. Vale a pena curtir!


💬 Dúvidas ou Problemas?

Com o intuito de ajudar a comunidade, caso você tenha dúvidas ou encontre problemas na execução dos comandos deste artigo, deixe um comentário abaixo. Responderei o mais breve possível!

Muito obrigado pela visita e até o próximo post!

Jefferson Castilho Especialista em Cloud & DevOps.

Este guia técnico é exclusivo do Blog do Castilho. Explore nossa para mais conteúdos sobre IA e Cloud.

 

Deixe uma resposta

Rolar para cima

Descubra mais sobre Blog do Castilho - Tecnologia | FinOps | DevOps | Cloud

Assine agora mesmo para continuar lendo e ter acesso ao arquivo completo.

Continue reading