如何在 Docker 和 DigitalOcean Kubernetes 上部署 Kafka

发布于:2024-04-27 ⋅ 阅读:(28) ⋅ 点赞:(0)

Apache Kafka 是一个开源的分布式事件和流处理平台,使用 Java 编写,旨在处理要求严苛的实时数据流。它被设计为具有容错能力,并支持每个集群拥有数百个节点。高效运行更多数量的节点需要容器化和编排流程以实现最优资源使用,例如使用 Kubernetes

在本教程中,你将学习如何使用 Docker Compose 部署 Kafka。你还将学习如何在 DigitalOcean Kubernetes上使用 Strimzi 部署 Kafka,Strimzi 能够集成到 Kubernetes 中,并允许你使用常规 Kubernetes 清单配置和维护 Kafka 集群,无需手动操作。

准备工作

要想跟着本教程后续的步骤,你需要:

步骤1 - 使用 Docker Compose 运行 Kafka

在本节中,你将学习如何在 KRaft 模式下使用 Docker Compose 运行 Kafka。使用 KRaft 可以简化整体配置和资源使用,因为不需要 ZooKeeper 实例。

首先,定义一个包含已解压 Kafka 发布版的 Docker 镜像。之后会使用它来测试与 Kafka 容器的连接,通过使用包含的脚本。

在 Dockerfile 中存储所需的命令。创建并打开它进行编辑:

nano Dockerfile

添加以下行:

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 配置。通过运行以下命令创建并打开它进行编辑:

nano kafka-compose.yaml

在这个 yaml 文件中添加以下内容:

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(卡其虚拟终端),保持与容器的会话。这一步很重要,因为容器在启动后如果没有进一步的命令,将会立即退出。

保存并关闭文件,然后运行以下命令在后台启动服务:

docker-compose -f kafka-compose.yaml up -d

因为 kafka-test 是第一次构建,输出将会很长。输出将如下所示::

Output...
Creating docker_kafka_1      ... done
Creating docker_kafka-test_1 ... done

你可以使用以下命令列出正在运行的容器:

docker ps

输出将如下所示:

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:

docker exec -it docker_kafka-test_1 bash

Shell 将已经定位在 /kafka-test 目录中:

root@2a0cd13859e3:/kafka-test#

然后,尝试使用 kafka-topics.sh 创建一个主题:

bin/kafka-topics.sh --create --topic first-topic --bootstrap-server kafka:9092

请注意,在 Docker Compose 配置中,你可以通过其名称(kafka)引用 Kafka。

输出将如下所示:

Output

Created topic first-topic.

你已经成功地从 Docker Compose 服务内部连接到 Kafka 部署。输入 exit 并按 Enter 键以关闭 shell。

要想停止 Docker Compose 部署,请运行以下命令:

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 图表:

​
helm repo add strimzi https://strimzi.io/charts

输出将如下所示:

Output
"strimzi" has been added to your repositories

然后,刷新 Helm 的缓存以下载其内容:

helm repo update

输出将如下所示:

Output

...Successfully got an update from the "strimzi" chart repository

Update Complete. ⎈Happy Helming!⎈

最后,通过运行以下命令将 Strimzi 安装到您的集群:

helm install strimzi strimzi/strimzi-kafka-operator

输出将如下所示:

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 的文件中。创建并打开它进行编辑:

nano kafka.yaml

在你的文件中添加以下行内容:

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。

保存并关闭文件,然后通过运行以下命令应用它:

kubectl apply -f kafka.yaml

kubectl 将显示以下输出:

Output
kafka.kafka.strimzi.io/my-cluster created

你可以通过运行以下命令观察部署变得可用:

kubectl get strimzipodset -w

几分钟后,Kafka 和 Zookeeper 的 pod 将变得可用并准备就绪:

OutputNAME                   PODS   READY PODS   CURRENT PODS   AGE
...
my-cluster-kafka       1      1            1              28s
my-cluster-zookeeper   1      1            1              61s

要列出 Kafka 部署,请运行以下命令:

kubectl get kafka

输出将如下所示:

Output
NAME         DESIRED KAFKA REPLICAS   DESIRED ZK REPLICAS   READY   METADATA STATE   WARNINGS
my-cluster   1                        1

现在 Kafka 正在运行,下面我们在其中创建一个主题。打开一个名为 kafka-topic.yaml 的文件进行编辑:

nano kafka-topic.yaml

添加以下内容:

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)中。

保存并关闭文件,然后通过运行以下命令应用它:

kubectl apply -f kafka-topic.yaml

输出将如下所示:

Output

kafkatopic.kafka.strimzi.io/my-topic created

然后,列出集群中的所有 Kafka 主题:

kubectl get kafkatopic

kubectl 输出将如下所示:

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)。

运行以下命令在集群内运行生产者脚本:

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作为主题名称。

输出将如下所示:

Output
If you don't see a command prompt, try pressing enter.
>

你可以输入任何文本消息并按 Enter 键发送到主题:

Output
If you don't see a command prompt, try pressing enter.
>Hello World!
>

要退出,请按 CTRL+C 并按 Enter 确认。然后,运行以下命令在集群内运行消费者脚本:

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 键以继续执行命令。输出将类似于如下这样:

Output
Hello World!
...

你已经学会了如何从集群内部连接到您的Kafka部署。现在,你将把Kafka暴露给外部世界。

步骤5 - 在Kubernetes外部暴露Kafka

在这一步中你将通过使用负载均衡器来向外部暴露你的Kafka部署。

Strimzi内置了为Kafka创建和配置负载均衡器的方法。通过运行以下命令来打开 kafka.yaml 文件进行编辑:

nano kafka.yaml

在 listeners 部分添加以下内容:

...
    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 加密的连接。

保存并关闭文件,然后通过运行以下命令应用新的配置文件:

kubectl apply -f kafka.yaml

输出将会是:

Output
kafka.kafka.strimzi.io/my-cluster configured

运行以下命令以观察其可用性:

kubectl get service my-cluster-kafka-external-bootstrap -w -o=jsonpath='{.status.loadBalancer.ingress[0].ip}{"\n"}'

当为Kafka提供前端流量的负载均衡器变得可用时,输出将是其IP地址。

作为先决条件的一部分,你已经下载并解压了最新的Kafka版本到您的机器。导航到该目录并运行控制台消费者,将your_lb_ip替换为前一个命令输出的IP地址:

bin/kafka-console-consumer.sh --bootstrap-server your_lb_ip:9094 --topic my-topic --from-beginning

你很快就会看到从主题中读取的消息,这意味着你已经成功连接了:

Output
Hello World!
...

要从你的集群中删除所有与Strimzi相关的资源(如Kafka部署和主题),运行以下命令:

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