Apache Kafka是一个开源的分布式事件和流处理平台,使用 Java 编写,旨在处理要求严苛的实时数据流。它被设计为具有容错能力,并支持每个集群拥有数百个节点。高效运行更多数量的节点需要容器化和编排流程以实现最优资源使用,例如使用 Kubernetes。
在本教程中,你将学习如何使用 Docker Compose 部署 Kafka。你还将学习如何在 DigitalOcean Kubernetes上使用Strimzi部署 Kafka,Strimzi 能够集成到 Kubernetes 中,并允许你使用常规 Kubernetes 清单配置和维护 Kafka 集群,无需手动操作。
准备工作
要想跟着本教程后续的步骤,你需要:
- 在你的电脑上安装 Docker。至于 Ubuntu,可以阅读我们写的 如何在 Ubuntu 上安装和使用 Docker。你只需要完成其中的第1步和第2步。
- 在你的电脑上安装 Docker Compose。
- 一个配置了kubectl默认连接的DigitalOcean Kubernetes v1.23+集群。创建集群时,可以在"连接到你的集群"步骤下找到如何配置kubectl的说明。要在 DigitalOcean 上创建 Kubernetes集群,请阅读Kubernetes 快速入门。
- 在你的本地电脑上安装 Helm 3 包管理器。完成 如何使用 Helm 3 包管理器在 Kubernetes 集群上安装软件教程的第1步即可。
- 理解 Kafka ,包括主题、生产者和消费者。了解更多信息,可访问 Kafka 介绍。
步骤1 - 使用 Docker Compose 运行 Kafka
在本节中,你将学习如何在 KRaft 模式下使用 Docker Compose 运行 Kafka。使用 KRaft 可以简化整体配置和资源使用,因为不需要 ZooKeeper 实例。
首先,定义一个包含已解压 Kafka 发布版的 Docker 镜像。之后会使用它来测试与 Kafka 容器的连接,通过使用包含的脚本。
在 Dockerfile 中存储所需的命令。创建并打开它进行编辑:
nano Dockerfile
添加以下行:
bash
FROM ubuntu:latest AS build
RUN apt-get update
RUN apt-get install curl default-jre -y
WORKDIR /kafka-test
RUN curl -o kafka.tgz https://dlcdn.apache.org/kafka/3.7.0/kafka_2.13-3.7.0.tgz
RUN tar -xzf kafka.tgz --strip-components=1
容器基于最新的 Ubuntu 版本。在更新包缓存和安装 curl 及 Java 之后,下载一个 Kafka 发布包。在我们写这篇文章教程时,Kafka 的最新版本是 3.7.0。你可以在官方下载页面查找最新版本。
然后,你设置工作目录(WORKDIR)为 /kafka-test,在该目录下下载并解压 Kafka 发布包。在 tar 命令中传递 --strip-components=1 参数,以跳过存档中的第一个目录,该目录以存档本身的名称命名。
保存并关闭文件。
接下来,你将在名为 kafka-compose.yaml 的文件中定义 Docker Compose 配置。通过运行以下命令创建并打开它进行编辑:
Go
nano kafka-compose.yaml
在这个 yaml 文件中添加以下内容:
bash
version: '3'
services:
kafka:
image: 'bitnami/kafka:latest'
environment:
- KAFKA_CFG_NODE_ID=0
- KAFKA_CFG_PROCESS_ROLES=controller,broker
- KAFKA_CFG_LISTENERS=PLAINTEXT://:9092,CONTROLLER://:9093
- KAFKA_CFG_LISTENER_SECURITY_PROTOCOL_MAP=CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT
- KAFKA_CFG_CONTROLLER_QUORUM_VOTERS=0@kafka:9093
- KAFKA_CFG_CONTROLLER_LISTENER_NAMES=CONTROLLER
kafka-test:
build:
dockerfile: Dockerfile
context: .
tty: true
在这里,你定义了两个服务,kafka 和 kafka-test。kafka 服务基于最新的 Bitnami Kafka 镜像。在环境变量部分,你传入必要的环境变量及其值,这些变量和值会降 Kafka 节点配置为独立模式,并设置 ID 为 0。
对于 kafka-test,传入刚刚创建的 Dockerfile 作为构建容器镜像的基础。通过设置 tty 为 true(卡其虚拟终端),保持与容器的会话。这一步很重要,因为容器在启动后如果没有进一步的命令,将会立即退出。
保存并关闭文件,然后运行以下命令在后台启动服务:
bash
docker-compose -f kafka-compose.yaml up -d
因为 kafka-test 是第一次构建,输出将会很长。输出将如下所示::
bash
Output...
Creating docker_kafka_1 ... done
Creating docker_kafka-test_1 ... done
你可以使用以下命令列出正在运行的容器:
bash
docker ps
输出将如下所示:
bash
Output
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3ce3e3190f6e bitnami/kafka:latest "/opt/bitnami/script..." 4 seconds ago Up 3 seconds 9092/tcp docker_kafka_1
2a0cd13859e3 docker_kafka-test "/bin/bash" 4 seconds ago Up 3 seconds docker_kafka-test_1
通过运行以下命令在 kafka-test 容器中打开一个 shell:
bash
docker exec -it docker_kafka-test_1 bash
Shell 将已经定位在 /kafka-test 目录中:
bash
root@2a0cd13859e3:/kafka-test#
然后,尝试使用 kafka-topics.sh 创建一个主题:
bash
bin/kafka-topics.sh --create --topic first-topic --bootstrap-server kafka:9092
请注意,在 Docker Compose 配置中,你可以通过其名称(kafka)引用 Kafka。
输出将如下所示:
bash
Output
Created topic first-topic.
你已经成功地从 Docker Compose 服务内部连接到 Kafka 部署。输入 exit 并按 Enter 键以关闭 shell。
要想停止 Docker Compose 部署,请运行以下命令:
bash
docker-compose -f kafka-compose.yaml down
在这一步中,你已经使用 Docker Compose 部署了 Kafka。你还通过部署一个包含用于连接到 Kafka 的 shell 脚本的自定义镜像,测试了 Kafka 是否可以从其他容器内部访问。接下来,你将学习如何在 DigitalOcean Kubernetes上部署 Kafka。
步骤2 - 将 Strimzi 安装到 Kubernetes
在本节中,你将了解如何把 Strimzi 安装到你的 Kubernetes 集群中。这包括将其仓库添加到 Helm 并创建一个 Helm release。
首先,你需要将 Strimzi Helm 仓库添加到 Helm,该仓库包含 Strimzi 图表:
bash
helm repo add strimzi https://strimzi.io/charts
输出将如下所示:
bash
Output
"strimzi" has been added to your repositories
然后,刷新 Helm 的缓存以下载其内容:
bash
helm repo update
输出将如下所示:
bash
Output
...Successfully got an update from the "strimzi" chart repository
Update Complete. ⎈Happy Helming!⎈
最后,通过运行以下命令将 Strimzi 安装到您的集群:
bash
helm install strimzi strimzi/strimzi-kafka-operator
输出将如下所示:
bash
Output
NAME: strimzi
LAST DEPLOYED: ...
NAMESPACE: default
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
Thank you for installing strimzi-kafka-operator-0.40.0
To create a Kafka cluster refer to the following documentation.
https://strimzi.io/docs/operators/latest/deploying.html#deploying-cluster-operator-helm-chart-str
你现在已经在您的 Kubernetes 集群中安装了 Strimzi。在下一节中,你将学习使用它来将 Kafka 部署到你的集群。
步骤3 - 向 Kubernetes 部署 Kafka 集群
在这一节中,你将向你的 Kubernetes 集群部署一个带有 ZooKeeper 的单节点 Kafka 集群。在撰写本文时,Strimzi 中通常还不支持使用 KRaft 部署 Kafka。
你将把部署的 Kubernetes 清单存储在一个名为 kafka.yaml 的文件中。创建并打开它进行编辑:
bash
nano kafka.yaml
在你的文件中添加以下行内容:
bash
apiVersion: kafka.strimzi.io/v1beta2
kind: Kafka
metadata:
name: my-cluster
spec:
kafka:
version: 3.7.0
replicas: 1
listeners:
- name: plain
port: 9092
type: internal
tls: false
- name: tls
port: 9093
type: internal
tls: true
config:
offsets.topic.replication.factor: 1
transaction.state.log.replication.factor: 1
transaction.state.log.min.isr: 1
default.replication.factor: 1
min.insync.replicas: 1
inter.broker.protocol.version: "3.7"
storage:
type: jbod
volumes:
- id: 0
type: persistent-claim
size: 100Gi
deleteClaim: false
zookeeper:
replicas: 1
storage:
type: persistent-claim
size: 100Gi
deleteClaim: false
entityOperator:
topicOperator: {}
userOperator: {}
spec的第一部分与 Kafka 本身相关。你设置了版本以及副本数量。然后,你定义了两个监听器,这些是 Kafka 部署将用来通信的端口。第二个监听器因为你设置了 tls 为 true 而加密。由于监听器不能冲突,你为第二个指定了 9093 作为端口号。
由于你在 config 部分只部署了一个 Kafka 节点,那么将各种副本因子(主题、事件和副本)设置为1。对于 storage,将 type 设置为 jbod(意为"仅仅一堆磁盘"),这让你可以指定多个 volumes。在这里,你定义了一个类型为 persistent-claim 的 volume,大小为 100GB。这将创建一个 DigitalOcean Volume 并将其分配给 Kafka。你还设置了 deleteClaim 为 false,以确保在销毁 Kafka 集群时数据不会被删除。
为了配置 zookeeper 部署,将其 replicas 数量设置为 1,并为其提供一个 100GB 的单一 persistent-claim,因为只有 Kafka 支持 jbod storage type。在 entityOperator 下的两个定义指示 Strimzi 创建用于处理 Kafka topics 和 users 的集群范围 operators。
保存并关闭文件,然后通过运行以下命令应用它:
bash
kubectl apply -f kafka.yaml
kubectl 将显示以下输出:
bash
Output
kafka.kafka.strimzi.io/my-cluster created
你可以通过运行以下命令观察部署变得可用:
bash
kubectl get strimzipodset -w
几分钟后,Kafka 和 Zookeeper 的 pod 将变得可用并准备就绪:
bash
OutputNAME PODS READY PODS CURRENT PODS AGE
...
my-cluster-kafka 1 1 1 28s
my-cluster-zookeeper 1 1 1 61s
要列出 Kafka 部署,请运行以下命令:
bash
kubectl get kafka
输出将如下所示:
bash
Output
NAME DESIRED KAFKA REPLICAS DESIRED ZK REPLICAS READY METADATA STATE WARNINGS
my-cluster 1 1
现在 Kafka 正在运行,下面我们在其中创建一个主题。打开一个名为 kafka-topic.yaml 的文件进行编辑:
bash
nano kafka-topic.yaml
添加以下内容:
bash
apiVersion: kafka.strimzi.io/v1beta2
kind: KafkaTopic
metadata:
name: my-topic
labels:
strimzi.io/cluster: "my-cluster"
spec:
partitions: 1
replicas: 1
这个 KafkaTopic 定义了一个名为 my-topic 的主题,在你刚刚部署的集群(my-cluster)中。
保存并关闭文件,然后通过运行以下命令应用它:
bash
kubectl apply -f kafka-topic.yaml
输出将如下所示:
bash
Output
kafkatopic.kafka.strimzi.io/my-topic created
然后,列出集群中的所有 Kafka 主题:
bash
kubectl get kafkatopic
kubectl 输出将如下所示:
bash
Output
NAME CLUSTER PARTITIONS REPLICATION FACTOR READY
my-topic my-cluster 1 1 True
在这一步中,你已经通过Strimzi将Kafka部署到您的Kubernetes集群中,Strimzi负责管理实际资源和ZooKeeper实例。您还创建了一个主题,您将在下一步连接Kafka时使用它。
步骤4 - 在Kubernetes中连接到Kafka
在这一部分,你将学习如何从Kubernetes集群内部连接到部署在Kubernetes上的Kafka集群。
多亏了Strimzi,你的Kafka部署已经可以供集群内的pods访问。集群内的任何应用都可以连接到 my-cluster-kafka-bootstrap 端点,该端点会自动解析到 my-cluster 集群。
你现在将基于Strimzi提供的Docker镜像,向Kubernetes部署一个临时的pod。这个镜像包含了一个Kafka安装和一些shell脚本,用于生产和消费文本消息(kafka-console-producer.sh 和 kafka-console-consumer.sh)。
运行以下命令在集群内运行生产者脚本:
bash
kubectl run kafka-producer -ti \
--image=quay.io/strimzi/kafka:0.40.0-kafka-3.7.0 --rm=true --restart=Never \
-- bin/kafka-console-producer.sh --bootstrap-server my-cluster-kafka-bootstrap:9092 --topic my-topic
临时pod将被命名为kafka-producer,并将使用Strimzi项目的镜像。命令执行完后,它将被删除(--rm=true),并且不会重启,因为它是一次性任务。然后,您将传入运行kafka-console-producer.sh脚本的命令。如前所述,您将使用my-cluster-kafka-bootstrap作为服务器的指定符,以及my-topic作为主题名称。
输出将如下所示:
bash
Output
If you don't see a command prompt, try pressing enter.
>
你可以输入任何文本消息并按 Enter 键发送到主题:
bash
Output
If you don't see a command prompt, try pressing enter.
>Hello World!
>
要退出,请按 CTRL+C 并按 Enter 确认。然后,运行以下命令在集群内运行消费者脚本:
bash
kubectl run kafka-consumer -ti \
--image=quay.io/strimzi/kafka:0.40.0-kafka-3.7.0 --rm=true --restart=Never \
-- bin/kafka-console-consumer.sh --bootstrap-server my-cluster-kafka-bootstrap:9092 --topic my-topic --from-beginning
你可能需要按 Enter 键以继续执行命令。输出将类似于如下这样:
bash
Output
Hello World!
...
你已经学会了如何从集群内部连接到您的Kafka部署。现在,你将把Kafka暴露给外部世界。
步骤5 - 在Kubernetes外部暴露Kafka
在这一步中你将通过使用负载均衡器来向外部暴露你的Kafka部署。
Strimzi内置了为Kafka创建和配置负载均衡器的方法。通过运行以下命令来打开 kafka.yaml 文件进行编辑:
bash
nano kafka.yaml
在 listeners 部分添加以下内容:
bash
...
listeners:
- name: plain
port: 9092
type: internal
tls: false
- name: tls
port: 9093
type: internal
tls: true
- name: external
port: 9094
type: loadbalancer
tls: false
...
高亮部分定义了一个新的监听器,类型为 loadbalancer,它将在端口 9094 接受不使用 TLS 加密的连接。
保存并关闭文件,然后通过运行以下命令应用新的配置文件:
bash
kubectl apply -f kafka.yaml
输出将会是:
bash
Output
kafka.kafka.strimzi.io/my-cluster configured
运行以下命令以观察其可用性:
bash
kubectl get service my-cluster-kafka-external-bootstrap -w -o=jsonpath='{.status.loadBalancer.ingress[0].ip}{"\n"}'
当为Kafka提供前端流量的负载均衡器变得可用时,输出将是其IP地址。
作为先决条件的一部分,你已经下载并解压了最新的Kafka版本到您的机器。导航到该目录并运行控制台消费者,将your_lb_ip替换为前一个命令输出的IP地址:
bash
bin/kafka-console-consumer.sh --bootstrap-server your_lb_ip:9094 --topic my-topic --from-beginning
你很快就会看到从主题中读取的消息,这意味着你已经成功连接了:
bash
Output
Hello World!
...
要从你的集群中删除所有与Strimzi相关的资源(如Kafka部署和主题),运行以下命令:
bash
kubectl delete $(kubectl get strimzi -o name)
总结
在本文中,你已经使用 Docker Compose 部署了 Kafka,并验证了你可以连接到它。你还学习了如何将 Strimzi 安装到你的 DigitalOcean Kubernetes 集群,并使用提供的清单部署了一个 Kafka 集群。
如果在 DigitalOcean Kubernetes 使用过程中遇到问题,或需要咨询DigitalOcean 云服务解决方案,可联系 DigitalOcean 中国区独家战略合作伙伴卓普云 AI Droplet
阅读更多教程:点击访问DigitalOcean相关教程与博客
阅读原文:How To Deploy Kafka on Docker and DigitalOcean Kubernetes | DigitalOcean