O guia mostra como usar o operador Strimzi para implantar clusters do Apache Kafka.
O Kafka é um sistema de mensagens distribuído de código aberto projetado para lidar com dados de streaming de alto volume, alta capacidade e em tempo real. Ele permite criar pipelines de dados de streaming para transferência de dados confiável em diferentes sistemas e aplicativos, para dar suporte a tarefas de processamento e análise.
Operadores são extensões de software que usam recursos personalizados para gerenciar aplicativos e seus componentes. Para saber mais sobre a motivação para usar operadores, consulte Padrão de operador (em inglês) na documentação de código aberto do Kubernetes. O operador Strimzi oferece flexibilidade nas opções de implantação e permite usar taints e tolerâncias do Kubernetes para executar o Kafka em nós dedicados.
Este guia é destinado a administradores de plataformas, arquitetos de nuvem e profissionais de operações interessados em implantar clusters do Kafka no GKE.
Esta solução é um bom ponto de partida se você quiser saber como implantar clusters do Kafka usando um operador de terceiros para automatizar o gerenciamento e reduzir erros. Se preferir um controle operacional mais granular, consulte Implantar clusters do Kafka altamente disponíveis no GKE.
Prepare o ambiente
Neste tutorial, você vai usar o Cloud Shell para gerenciar recursos hospedados no
Google Cloud. O Cloud Shell vem pré-instalado com o software necessário para este tutorial, incluindo kubectl
, a CLI gcloud, o Helm e o Terraform.
Para configurar o ambiente com o Cloud Shell, siga estas etapas:
Inicie uma sessão do Cloud Shell no console do Google Cloud clicando em
Ativar o Cloud Shell no console doGoogle Cloud . Isso inicia uma sessão no painel inferior do console Google Cloud .
Defina as variáveis de ambiente:
export PROJECT_ID=PROJECT_ID export KUBERNETES_CLUSTER_PREFIX=kafka export REGION=us-central1
Substitua
PROJECT_ID
: seu Google Cloud pelo ID do projeto.Clone o repositório do GitHub:
git clone https://github.com/GoogleCloudPlatform/kubernetes-engine-samples
Mude para o diretório de trabalho:
cd kubernetes-engine-samples/streaming/
Criar a infraestrutura do cluster
Nesta seção, você executa um script do Terraform para criar um cluster regional do GKE privado e altamente disponível. As etapas a seguir permitem acesso público ao plano de controle. Para restringir o acesso, crie um cluster particular.
É possível instalar o operador usando um cluster padrão ou Autopilot.
Padrão
O diagrama a seguir mostra um cluster regional padrão particular do GKE implantado em três zonas diferentes:
Para implantar essa infraestrutura, execute os seguintes comandos no Cloud Shell:
export GOOGLE_OAUTH_ACCESS_TOKEN=$(gcloud auth print-access-token)
terraform -chdir=kafka/terraform/gke-standard init
terraform -chdir=kafka/terraform/gke-standard apply -var project_id=${PROJECT_ID} \
-var region=${REGION} \
-var cluster_prefix=${KUBERNETES_CLUSTER_PREFIX}
Quando solicitado, digite yes
. Pode levar vários minutos para que esse comando seja concluído e o cluster mostre um status pronto.
O Terraform cria os seguintes recursos:
- Uma rede VPC e uma sub-rede particular para os nós do Kubernetes.
- Um roteador para acessar a Internet por meio de NAT.
- Um cluster particular do GKE na região
us-central1
. - 2 pools de nós com escalonamento automático ativado (de 1 a 2 nós por zona, no mínimo 1 nó por zona)
- Um
ServiceAccount
com permissões de geração de registros e monitoramento. - Backup do GKE para recuperação de desastres.
- Google Cloud Managed Service para Prometheus para monitoramento de clusters.
O resultado será assim:
...
Apply complete! Resources: 14 added, 0 changed, 0 destroyed.
Outputs:
kubectl_connection_command = "gcloud container clusters get-credentials strimzi-cluster --region us-central1"
Piloto automático
O diagrama a seguir mostra um cluster particular regional do Autopilot do GKE:
Para implantar a infraestrutura, execute os seguintes comandos do Cloud Shell:
export GOOGLE_OAUTH_ACCESS_TOKEN=$(gcloud auth print-access-token)
terraform -chdir=kafka/terraform/gke-autopilot init
terraform -chdir=kafka/terraform/gke-autopilot apply -var project_id=${PROJECT_ID} \
-var region=${REGION} \
-var cluster_prefix=${KUBERNETES_CLUSTER_PREFIX}
Quando solicitado, digite yes
. Pode levar vários minutos para que esse comando seja concluído e o cluster mostre um status pronto.
O Terraform cria os seguintes recursos:
- Rede VPC e sub-rede privada para os nós do Kubernetes.
- Um roteador para acessar a Internet por meio de NAT.
- Um cluster particular do GKE na região
us-central1
. - Um
ServiceAccount
com permissões de registro e monitoramento - Google Cloud Managed Service para Prometheus para monitoramento de clusters.
O resultado será assim:
...
Apply complete! Resources: 12 added, 0 changed, 0 destroyed.
Outputs:
kubectl_connection_command = "gcloud container clusters get-credentials strimzi-cluster --region us-central1"
Como se conectar ao cluster
Configure kubectl
para se comunicar com o cluster:
gcloud container clusters get-credentials ${KUBERNETES_CLUSTER_PREFIX}-cluster --region ${REGION}
Implantar o operador do Strimzi no cluster
Nesta seção, você implantará o operador do Strimzi usando um gráfico do Helm. Há também várias outras maneiras de implantar o Strimzi.
Adicione o repositório do Strimzi Helm Chart:
helm repo add strimzi https://strimzi.io/charts/
Adicione um namespace para o operador do Strimzi e o cluster do Kafka:
kubectl create ns kafka
Implante o operador de cluster do Strimzi usando o Helm:
helm install strimzi-operator strimzi/strimzi-kafka-operator -n kafka
Para implantar os clusters do Strimzi Cluster Operator e do Kafka em diferentes namespaces, adicione o parâmetro
--set watchNamespaces="{kafka-namespace,kafka-namespace-2,...}"
ao comando helm.Verifique se o operador de cluster do Strimzi foi implantado usando o Helm:
helm ls -n kafka
O resultado será assim:
NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION strimzi-operator kafka 1 2023-06-27 11:22:15.850545 +0200 CEST deployed strimzi-kafka-operator-0.35.0 0.35.0
Implantar o Kafka
Depois que o operador for implantado no cluster, você estará pronto para implantar uma instância de cluster do Kafka.
Nesta seção, você implantará o Kafka em uma configuração básica e, em seguida, testará vários cenários de configuração avançada para atender aos requisitos de disponibilidade, segurança e observabilidade.
Configuração básica
A configuração básica da instância do Kafka inclui os seguintes componentes:
- Três réplicas de agentes do Kafka, com um mínimo de duas réplicas disponíveis necessárias para a consistência do cluster.
- Três réplicas de nós do ZooKeeper, formando um cluster.
- Dois listeners Kafka: um sem autenticação e outro usando a autenticação TLS com um certificado gerado pelo Strimzi.
- Java MaxHeapSize e MinHeapSize definidos como 4 GB para Kafka e 2 GB para ZooKeeper.
- Alocação de recursos de CPU de uma solicitação de CPU e dois limites de CPU para o Kafka e o ZooKeeper, junto com 5 GB de solicitações de memória e limites para o Kafka (4 GB para o serviço principal e 0,5 GB para o exportador de métricas) e 2,5 GB para o ZooKeeper (2 GB para o serviço principal e 0,5 GB para o exportador de métricas).
- Operador de entidade com as seguintes solicitações e limites:
tlsSidecar
: CPU de 100 m/500 m e memória de 128 Mi.topicOperator
: CPU de 100 m/500 m e memória de 512 Mi.userOperator
: CPU de 500 m e memória de 2 Gi.
- 100 GB de armazenamento alocado para cada pod usando
premium-rwo
storageClass
. - Tolerâncias, nodeAffinities e podAntiAffinities configurados para cada carga de trabalho, garantindo a distribuição apropriada entre nós, utilizando os respectivos pools de nós e zonas diferentes.
- Comunicação dentro do cluster protegida por certificados autoassinados: CAs (Autoridades de certificação) separadas para cluster e clientes (mTLS). Também é possível configurar para usar uma autoridade de certificação diferente.
Essa configuração representa a configuração mínima necessária para criar um cluster do Kafka pronto para produção. As seções a seguir demonstram configurações personalizadas para abordar aspectos como segurança de cluster, listas de controle de acesso (ACLs), gerenciamento de tópicos, gerenciamento de certificados e muito mais.
Criar um cluster básico do Kafka
Crie um novo cluster do Kafka usando a configuração básica:
kubectl apply -n kafka -f kafka-strimzi/manifests/01-basic-cluster/my-cluster.yaml
Esse comando cria um recurso personalizado do Kafka do operador Strimzi que inclui solicitações e limites de CPU e memória, solicitações de armazenamento em blocos e uma combinação de taints e afinidades para distribuir os pods provisionados nos nós do Kubernetes.
Aguarde alguns minutos enquanto o Kubernetes inicia as cargas de trabalho necessárias:
kubectl wait kafka/my-cluster --for=condition=Ready --timeout=600s -n kafka
Verifique se as cargas de trabalho do Kafka foram criadas:
kubectl get pod,service,deploy,pdb -l=strimzi.io/cluster=my-cluster -n kafka
O resultado será assim:
NAME READY STATUS RESTARTS AGE pod/my-cluster-entity-operator-848698874f-j5m7f 3/3 Running 0 44m pod/my-cluster-kafka-0 1/1 Running 0 5m pod/my-cluster-kafka-1 1/1 Running 0 5m pod/my-cluster-kafka-2 1/1 Running 0 5m pod/my-cluster-zookeeper-0 1/1 Running 0 6m pod/my-cluster-zookeeper-1 1/1 Running 0 6m pod/my-cluster-zookeeper-2 1/1 Running 0 6m NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/my-cluster-kafka-bootstrap ClusterIP 10.52.8.80 <none> 9091/TCP,9092/TCP,9093/TCP 5m service/my-cluster-kafka-brokers ClusterIP None <none> 9090/TCP,9091/TCP,9092/TCP,9093/TCP 5m service/my-cluster-zookeeper-client ClusterIP 10.52.11.144 <none> 2181/TCP 6m service/my-cluster-zookeeper-nodes ClusterIP None <none> 2181/TCP,2888/TCP,3888/TCP 6m NAME READY UP-TO-DATE AVAILABLE AGE deployment.apps/my-cluster-entity-operator 1/1 1 1 44m NAME MIN AVAILABLE MAX UNAVAILABLE ALLOWED DISRUPTIONS AGE poddisruptionbudget.policy/my-cluster-kafka 2 N/A 1 5m poddisruptionbudget.policy/my-cluster-zookeeper 2 N/A 1 6m
O operador cria os seguintes recursos:
- Dois
StrimziPodSets
para Kafka e ZooKeeper. - Três pods para réplicas do agente do Kafka.
- Três pods para réplicas do ZooKeeper.
- Dois
PodDisruptionBudgets
, garantindo a disponibilidade mínima de duas réplicas para consistência de cluster. - Um serviço chamado
my-cluster-kafka-bootstrap
, que serve como o servidor de inicialização para os clientes do Kafka que se conectam de dentro do cluster do Kubernetes. Todos os listeners internos do Kafka estão disponíveis neste serviço. - Um serviço sem comando chamado
my-cluster-kafka-brokers
que permite a resolução de DNS dos endereços IP do pod do agente do Kafka diretamente. Esse serviço é usado para comunicação entre agentes. - Um serviço chamado
my-cluster-zookeeper-client
que permite que os agentes do Kafka se conectem aos nós do ZooKeeper como clientes. - Um serviço sem comando chamado
my-cluster-zookeeper-nodes
que permite a resolução de DNS dos endereços IP do pod do ZooKeeper diretamente. Esse serviço é usado para conectar-se entre as réplicas do ZooKeeper. - Uma implantação chamada
my-cluster-entity-operator
que contém o topic-operator e user-operator e facilita o gerenciamento dos recursos personalizadosKafkaTopics
eKafkaUsers
.
Também é possível configurar dois NetworkPolicies
para facilitar a conectividade com os listeners do Kafka de qualquer pod e namespace. Essas políticas também restringiriam as conexões com o ZooKeeper para agentes e permitiriam a comunicação entre os pods de cluster e as portas de serviço internas exclusivas para a comunicação de cluster.
Autenticação e gerenciamento de usuários
Esta seção mostra como ativar a autenticação e autorização para proteger os listeners do Kafka e compartilhar credenciais com os clientes.
O Strimzi fornece um método nativo do Kubernetes para gerenciamento de usuários usando um
User Operator
separado e o recurso personalizado do Kubernetes correspondente,
KafkaUser
, que define a configuração do usuário. A configuração do usuário inclui definições para autenticação e autorização e provisiona o usuário correspondente no Kafka.
O Strimzi pode criar listeners e usuários do Kafka compatíveis com vários mecanismos de autenticação, como autenticação baseada em nome de usuário e senha (SCRAM-SHA-512) ou TLS. Também é possível usar a autenticação do OAuth 2.0, que geralmente é considerada uma abordagem melhor do que o uso de senhas ou certificados para autenticação por causa do gerenciamento de segurança e de credenciais externas.
Implantar um cluster do Kafka
Esta seção mostra como implantar um operador do Strimzi que demonstra os recursos de gerenciamento de usuários, incluindo:
- Um cluster do Kafka com autenticação baseada em senha (SCRAM-SHA-512) ativado em um dos listeners.
- Uma
KafkaTopic
com três réplicas. - Uma
KafkaUser
com uma ACL que especifica que o usuário tem permissões de leitura e gravação no tópico.
Configure seu cluster do Kafka para usar um listener com autenticação SCRAM-SHA-512 baseada em senha na porta 9094 e autorização simples:
kubectl apply -n kafka -f kafka-strimzi/manifests/03-auth/my-cluster.yaml
Crie um
Topic
, umUser
e um pod cliente para executar comandos no cluster do Kafka:kubectl apply -n kafka -f kafka-strimzi/manifests/03-auth/topic.yaml kubectl apply -n kafka -f kafka-strimzi/manifests/03-auth/my-user.yaml
O
Secret
my-user
com as credenciais de usuário é ativado no pod cliente como um Volume.Essas credenciais confirmam que o usuário tem permissões para publicar mensagens no tópico usando o listener com a autenticação baseada em senha (SCRAM-SHA-512) ativada.
Crie um pod de cliente:
kubectl apply -n kafka -f kafka-strimzi/manifests/03-auth/kafkacat.yaml
Aguarde alguns minutos até que o pod cliente se torne
Ready
e se conecte a ele:kubectl wait --for=condition=Ready pod --all -n kafka --timeout=600s kubectl exec -it kafkacat -n kafka -- /bin/sh
Produza uma nova mensagem com credenciais
my-user
e tente consumi-la:echo "Message from my-user" |kcat \ -b my-cluster-kafka-bootstrap.kafka.svc.cluster.local:9094 \ -X security.protocol=SASL_SSL \ -X sasl.mechanisms=SCRAM-SHA-512 \ -X sasl.username=my-user \ -X sasl.password=$(cat /my-user/password) \ -t my-topic -P kcat -b my-cluster-kafka-bootstrap.kafka.svc.cluster.local:9094 \ -X security.protocol=SASL_SSL \ -X sasl.mechanisms=SCRAM-SHA-512 \ -X sasl.username=my-user \ -X sasl.password=$(cat /my-user/password) \ -t my-topic -C
O resultado será assim:
Message from my-user % Reached end of topic my-topic [0] at offset 0 % Reached end of topic my-topic [2] at offset 1 % Reached end of topic my-topic [1] at offset 0
Digite
CTRL+C
para interromper o processo do consumidor.Saia do shell do pod
exit
Backups e recuperação de desastres
Embora o operador do Strimzi não ofereça funcionalidade de backup integrada, é possível implementar estratégias de backup eficientes seguindo determinados padrões.
Use o Backup para GKE para fazer backup:
- Manifestos do recurso do Kubernetes.
- Recursos personalizados da API Strimzi e as definições extraídas do servidor da API Kubernetes do cluster que está em backup.
- Volumes correspondentes aos recursos PersistentVolumeClaim encontrados nos manifestos.
Para mais informações sobre como fazer backup e restaurar clusters do Kafka usando o Backup para GKE, consulte Preparar-se para a recuperação de desastres.
Você também pode fazer um backup de um cluster do Kafka que foi implantado usando o operador do Strimzi. Faça o backup:
- A configuração do Kafka, que inclui todos os recursos personalizados da
API Strimzi, como
KafkaTopics
eKafkaUsers
. - Os dados, armazenados nos PersistentVolumes dos agentes do Kafka.
Armazenar manifestos de recursos do Kubernetes, incluindo configurações do Strimzi, em repositórios Git pode eliminar a necessidade de um backup separado para a configuração do Kafka, porque os recursos podem ser reaplicados a um novo cluster do Kubernetes quando necessário.
Para proteger a recuperação de dados do Kafka em cenários em que uma instância do servidor do Kafka ou um cluster do Kubernetes em que o Kafka está implantado é perdida, recomendamos que você configure a classe de armazenamento do Kubernetes usada para provisionar volumes para agentes do Kafka. com a opção reclaimPolicy
definida como Retain
. Também recomendamos que você tire snapshots dos volumes do agente do Kafka.
O manifesto a seguir descreve um StorageClass que usa a opção reclaimPolicy
Retain
:
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: premium-rwo-retain
...
reclaimPolicy: Retain
volumeBindingMode: WaitForFirstConsumer
O exemplo a seguir mostra o StorageClass adicionado ao spec
de um recurso personalizado do cluster do Kafka:
# ...
spec:
kafka:
# ...
storage:
type: persistent-claim
size: 100Gi
class: premium-rwo-retain
Com essa configuração, os PersistentVolumes provisionados usando a classe de armazenamento não são excluídos, mesmo quando o PersistentVolumeClaim correspondente é excluído.
Para recuperar a instância do Kafka em um novo cluster do Kubernetes usando a configuração atual e os dados da instância do agente:
- Aplique os recursos personalizados atuais do Strimzi Kafka (
Kakfa
,KafkaTopic
,KafkaUser
etc.) a um novo cluster do Kubernetes - Atualize os PersistentVolumeClaims com o nome das novas instâncias do agente do Kafka para os PersistentVolumes antigos usando a propriedade
spec.volumeName
no PersistentVolumeClaim.