Aprenda como lançar um cluster Apache Kafka com o protocolo de consenso Apache Kafka Raft (KRaft) e autenticação SASL/PLAIN. Este artigo é uma continuação do meu artigo anterior sobre a execução do Kafka no Kubernetes com o modo KRaft.
⚠️ PLAIN versus PLAINTEXT: Não confunda o mecanismo SASL/PLAIN com a opção de criptografia sem TLS/SSL, chamada PLAINTEXT. Parâmetros de configuração, como sasl.enabled.mechanisms ou sasl.mechanism.inter.broker.protocol, podem ser configurados para usar o mecanismo SASL/PLAIN, enquanto security.inter.broker.protocol ou listeners podem ser configurados para usar a opção sem criptografia TLS/SSL, SASL_PLAINTEXT.
Pré-requisitos
É necessário ter um entendimento de Apache Kafka, Kubernetes e Minikube.
Os seguintes passos foram inicialmente realizados em um MacBook Pro com 32 GBdememória, executando o MacOS Ventura v13.4.
Certifique-se de ter as seguintes aplicações instaladas:
Docker v23.0.5
Minikube v1.29.0 (executando o K8s v1.26.1 internamente)
É possível que os passos abaixo funcionem com diferentes versões dasferramentasmencionadas acima, mas, se você encontrar problemas inesperados, érecomendávelgarantir que tenha as versões idênticas. O Minikube foi escolhido para esteexercício devidoao seu foco no desenvolvimento local.
Componentes da Implantação
Precisamos configurar os brokers e clientes para utilizar a autenticaçāo SASL. Acesse a página Kafka Broker and Controller Configurations for Confluent Platform para uma explicaçāo detalhadas das configurações.
A implantação que criaremos terá os seguintes componentes:
Namespace: kafka. Este é o namespace no qual todos os componentes serão abrangidos.
Service Account: kafka. Contas de serviço (Service Accounts) são usadas para controlar permissões e acesso a recursos dentro do cluster.
Headless Service: kafka-headless. Ele expõe as portas 9092 (para comunicação SASL_PLAINTEXT).
StatefulSet: kafka. Ele gerencia os pods do Kafka e garante que eles tenham nomes de host e armazenamento estáveis.
O código-fonte para esta implantação pode ser encontrado neste repositório GitHub.
Broker
Habilite o mecanismos SASL/PLAIN no arquivo server.properties de cada broker.
# List of enabled mechanisms, can be more than one
- name: KAFKA_SASL_ENABLED_MECHANISMS
value: PLAIN
# Specify one of of the SASL mechanisms
- name: KAFKA_SASL_MECHANISM_INTER_BROKER_PROTOCOL
value: PLAIN
Informe aos brokers do Kafka em quais portas devem ouvir as conexões SASL de clientes e interbroker. Configure as propriedades listeners e advertised.listeners da seguinte forma:
- command:
...
export KAFKA_ADVERTISED_LISTENERS=SASL://${POD_NAME}.kafka-headless.kafka.svc.cluster.local:9092
...
env: ...
- name: KAFKA_LISTENER_SECURITY_PROTOCOL_MAP
value: "CONTROLLER:PLAINTEXT,SASL:SASL_PLAINTEXT"
- name: KAFKA_LISTENERS
value: SASL://0.0.0.0:9092,CONTROLLER://0.0.0.0:29093
Configure o JAAS (Serviço de Autenticação e Autorização Java) no Kafka broker como a seguir:
- name: KAFKA_LISTENER_NAME_SASL_PLAIN_SASL_JAAS_CONFIG
value: org.apache.kafka.common.security.plain.PlainLoginModule required username="admin" password="admin-secret" user_admin="admin-secret" user_kafkaclient1="kafkaclient1-secret";
Cliente
Crie um ConfigMap baseado no arquivo sasl_client.properties:
kubectl create configmap kafka-client --from-file sasl_client.properties -n kafka
kubectl describe configmaps -n kafka kafka-client
Output:
configmap/kafka-client created
Name: kafka-client
Namespace: kafka
Labels: <none>
Annotations: <none>
Data
====
sasl_client.properties:
----
sasl.mechanism=PLAIN
security.protocol=SASL_PLAINTEXT sasl.jaas.config=org.apache.kafka.common.security.plain.PlainLoginModule required \
username="kafkaclient1" \
password="kafkaclient1-secret";
BinaryData
====
Events: <none>
Monte o ConfigMap como um volume:
...
volumeMounts:
- mountPath: /etc/kafka/secrets/
name: kafka-client
...
volumes:
- name: kafka-client
configMap:
name: kafka-client
Criando a Implantaçāo
Clone o repositório:
git clone https://github.com/rafaelmnatali/kafka-k8s.git
implemente o Kafka usando os seguintes comandos:
kubectl apply -f 00-namespace.yaml
kubectl apply -f 01-kafka-local.yaml
Verifique a comunicação entre os brokers
Agora deve haver três nós (brokers) Kafka, cada um em execução em pods separados dentro do seu cluster. A resolução de nomes para o headless Service e os três pods dentro do StatefulSet é configurada automaticamente pelo Kubernetes conforme são criados, permitindo a comunicação entre os brokers. Consulte a documentação relacionada para obter mais detalhes sobre esse recurso.
Você pode verificar os logs do primeiro pod com o seguinte comando:
kubectl logs kafka-0
A resoluçāo de nomes para os três pods pode demorar mais tempo do que o pod a iniciar, entāo, você pode ver erros UnknownHostException nos logs durante a inicializaçāo:
WARN [RaftManager nodeId=2] Error connecting to node kafka-1.kafka-headless.kafka.svc.cluster.local:29093 (id: 1 rack: null) (org.apache.kafka.clients.NetworkClient) java.net.UnknownHostException: kafka-1.kafka-headless.kafka.svc.cluster.local ...
Eventualmente, cada pod irá resolver os nomes e iniciar com uma mensagem afirmando que o broker foi unfenced:
INFO [Controller 0] Unfenced broker: UnfenceBrokerRecord(id=1, epoch=176) (org.apache.kafka.controller.ClusterControlManager)
Create a topic using the SASL_PLAINTEXT endpoint
Criar um tópico usando o endpoint SASL_PLAINTEXT
Você pode implantar o Cliente Kafka usando o seguinte comando:
kubectl apply -f 02-kafka-client.yaml
Verifique se o Pod está Running:
kubectl get pods
Saída:
NAME READY STATUS RESTARTS AGE
kafka-cli 1/1 Running 0 12m
Conecte-se ao pod kafka-cli:
kubectl exec -it kafka-cli -- bash
Crie um tópico chamado test-sasl com três partições e um fator de replicação de 3.
kafka-topics --create --topic test-sasl --partitions 3 --replication-factor 3 --bootstrap-server ${BOOTSTRAP_SERVER} --command-config /etc/kafka/secrets/sasl_client.properties Created topic test-sasl.
⚠️ A variável de ambiente BOOTSTRAP_SERVER contém a lista dos brokers, portanto, economizamos tempo digitando.
Liste todos os tópicos no Kafka:
kafka-topics --bootstrap-server ${BOOTSTRAP_SERVER} -list --command-config /etc/kafka/secrets/sasl_client.properties
test
test-sasl
test-ssl
test-test
Resumo e Próximos Passos
Este tutorial mostrou como executar o Kafka no modo KRaft em um cluster Kubernetes com autenticação SASL. Isso representa mais um passo para garantir a comunicação segura entre clientes e brokers, além da criptografia SSL discutida neste artigo. Convido você a continuar estudando e pesquisando maneiras de aprimorar a segurança em seu ambiente.
Referências
https://docs.confluent.io/platform/current/installation/docker/config-reference.html
https://docs.confluent.io/platform/current/kafka/authentication_ssl.html#optional-settings
https://rafaelnatali.wixsite.com/rmn-technology/blog/categories/kafka
https://github.com/rafaelmnatali/kafka-k8s/blob/main/README-pt.md
Comentarios