MK
摩柯社区 - 一个极简的技术知识社区
AI 面试

Kafka 基于 Docker 的部署实践

2024-04-241.1k 阅读

Kafka 简介

Kafka 是一个分布式流平台,最初由 LinkedIn 开发,并于 2011 年开源。它被设计用来处理大量的实时数据,具备高吞吐量、低延迟、可扩展性等特性。Kafka 基于发布 - 订阅模型,生产者将消息发布到主题(Topic),消费者从主题中订阅并消费消息。

在现代的后端开发中,Kafka 被广泛应用于多种场景,例如日志收集、消息系统、流处理等。比如,在大型网站的日志处理中,Kafka 可以高效地收集和分发用户行为日志,为后续的数据分析提供数据基础。

Docker 简介

Docker 是一种开源的应用容器引擎,它允许开发者将应用程序及其依赖打包到一个可移植的容器中,然后发布到任何支持 Docker 的操作系统上运行。Docker 的核心概念包括镜像(Image)、容器(Container)和仓库(Registry)。

镜像可以看作是一个只读的模板,用于创建容器。容器是镜像的运行实例,多个容器可以基于同一个镜像创建。仓库则是用于存储镜像的地方,常见的有 Docker Hub 等公共仓库,也可以搭建私有的仓库。通过 Docker,我们可以实现应用的快速部署、隔离运行以及环境一致性。

Kafka 基于 Docker 部署的优势

  1. 环境一致性:在不同的开发、测试和生产环境中,使用 Docker 部署 Kafka 可以确保 Kafka 及其依赖的环境完全一致,避免了因环境差异导致的问题。
  2. 快速部署:通过 Docker 镜像,我们可以快速创建 Kafka 实例,大大缩短了部署时间。相比传统的手动安装和配置方式,效率得到显著提升。
  3. 易于管理和维护:Docker 提供了统一的命令行接口来管理容器,例如启动、停止、删除容器等操作都非常方便。对于 Kafka 集群的管理,也可以通过 Docker 轻松实现扩缩容等操作。

准备工作

  1. 安装 Docker:首先,确保你的系统上已经安装了 Docker。以 Ubuntu 系统为例,可以通过以下命令安装 Docker:
sudo apt-get update
sudo apt-get install docker.io

安装完成后,可以通过 docker --version 命令验证 Docker 是否安装成功。 2. 安装 Docker Compose:Docker Compose 是用于定义和运行多容器 Docker 应用程序的工具。在部署 Kafka 集群时,使用 Docker Compose 可以方便地管理多个相关容器。同样在 Ubuntu 系统上,可以通过以下命令安装 Docker Compose:

sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker - compose - $(uname -s)-$(uname -m)" -o /usr/local/bin/docker - compose
sudo chmod +x /usr/local/bin/docker - compose

安装完成后,使用 docker - compose --version 命令验证安装。

单节点 Kafka 基于 Docker 的部署

  1. 创建 Docker Compose 文件:在一个新的目录下,创建一个名为 docker - compose.yml 的文件,内容如下:
version: '3'
services:
  zookeeper:
    image: confluentinc/cp - zookeeper:6.2.1
    environment:
      ZOOKEEPER_CLIENT_PORT: 2181
      ZOOKEEPER_TICK_TIME: 2000
    ports:
      - 2181:2181
  kafka:
    image: confluentinc/cp - kafka:6.2.1
    depends_on:
      - zookeeper
    environment:
      KAFKA_BROKER_ID: 1
      KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
      KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://localhost:9092
      KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1
    ports:
      - 9092:9092

在这个配置文件中:

  • zookeeper 服务使用了 Confluent 提供的 Zookeeper 镜像。Kafka 依赖 Zookeeper 来管理集群状态等信息。ZOOKEEPER_CLIENT_PORT 配置了 Zookeeper 的客户端端口,ZOOKEEPER_TICK_TIME 是 Zookeeper 的基本时间单位。
  • kafka 服务依赖于 zookeeper 服务。KAFKA_BROKER_ID 是 Kafka 节点的唯一标识,KAFKA_ZOOKEEPER_CONNECT 配置了 Kafka 连接 Zookeeper 的地址,KAFKA_ADVERTISED_LISTENERS 定义了 Kafka 对外暴露的监听地址,KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR 配置了 Kafka 偏移量主题的副本因子。
  1. 启动 Kafka 单节点:在包含 docker - compose.yml 文件的目录下,执行以下命令启动 Kafka 单节点:
docker - compose up -d

-d 参数表示在后台运行容器。启动成功后,可以通过 docker ps 命令查看正在运行的容器,应该可以看到 zookeeperkafka 两个容器正在运行。

  1. 验证 Kafka 安装:可以通过 Kafka 自带的命令行工具来验证 Kafka 是否安装成功。例如,创建一个新的主题:
docker exec -it kafka bash -c 'kafka - topics --create --topic test - topic --bootstrap - servers localhost:9092 --replication - factor 1 --partitions 1'

然后,使用生产者向主题发送消息:

docker exec -it kafka bash -c 'kafka - console - producer --topic test - topic --bootstrap - servers localhost:9092'

在生产者终端输入一些消息,如 Hello, Kafka!。接着,使用消费者从主题消费消息:

docker exec -it kafka bash -c 'kafka - console - consumer --topic test - topic --from - beginning --bootstrap - servers localhost:9092'

如果能看到刚才生产者发送的消息,说明 Kafka 单节点部署成功。

多节点 Kafka 集群基于 Docker 的部署

  1. 修改 Docker Compose 文件:为了部署一个多节点的 Kafka 集群,需要对 docker - compose.yml 文件进行修改。以下是一个三节点 Kafka 集群的配置示例:
version: '3'
services:
  zookeeper:
    image: confluentinc/cp - zookeeper:6.2.1
    environment:
      ZOOKEEPER_CLIENT_PORT: 2181
      ZOOKEEPER_TICK_TIME: 2000
    ports:
      - 2181:2181
  kafka1:
    image: confluentinc/cp - kafka:6.2.1
    depends_on:
      - zookeeper
    environment:
      KAFKA_BROKER_ID: 1
      KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
      KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafka1:9092
      KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 3
    ports:
      - 9092:9092
  kafka2:
    image: confluentinc/cp - kafka:6.2.1
    depends_on:
      - zookeeper
    environment:
      KAFKA_BROKER_ID: 2
      KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
      KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafka2:9093
      KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 3
    ports:
      - 9093:9093
  kafka3:
    image: confluentinc/cp - kafka:6.2.1
    depends_on:
      - zookeeper
    environment:
      KAFKA_BROKER_ID: 3
      KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
      KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafka3:9094
      KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 3
    ports:
      - 9094:9094

在这个配置中:

  • 新增了 kafka2kafka3 两个服务,分别对应 Kafka 集群中的第二个和第三个节点。
  • 每个 Kafka 节点的 KAFKA_BROKER_ID 是唯一的,KAFKA_ADVERTISED_LISTENERS 配置了每个节点对外暴露的监听地址和端口,并且 KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR 设置为 3,以保证偏移量主题在多个节点上有副本,提高数据的可靠性。
  1. 启动 Kafka 集群:在包含修改后的 docker - compose.yml 文件的目录下,执行以下命令启动 Kafka 集群:
docker - compose up -d

同样,使用 docker ps 命令可以查看所有正在运行的容器,应该能看到 zookeeperkafka1kafka2kafka3 容器。

  1. 验证 Kafka 集群:可以通过创建一个具有多个副本的主题来验证 Kafka 集群的功能。例如:
docker exec -it kafka1 bash -c 'kafka - topics --create --topic multi - replica - topic --bootstrap - servers kafka1:9092,kafka2:9093,kafka3:9094 --replication - factor 3 --partitions 3'

然后,通过生产者向主题发送消息:

docker exec -it kafka1 bash -c 'kafka - console - producer --topic multi - replica - topic --bootstrap - servers kafka1:9092,kafka2:9093,kafka3:9094'

最后,使用消费者从主题消费消息:

docker exec -it kafka1 bash -c 'kafka - console - consumer --topic multi - replica - topic --from - beginning --bootstrap - servers kafka1:9092,kafka2:9093,kafka3:9094'

如果能正常发送和消费消息,说明 Kafka 多节点集群部署成功。

Kafka 安全配置

  1. SSL/TLS 加密:为了保证 Kafka 通信的安全性,可以配置 SSL/TLS 加密。首先,需要生成 SSL 证书和密钥。可以使用 OpenSSL 工具来生成:
keytool -keystore kafka.server.keystore.jks -alias kafka -validity 365 -genkey -keyalg RSA
keytool -keystore kafka.server.truststore.jks -alias CARoot -import -file ca.crt

然后,将生成的证书和密钥复制到 Kafka 容器内相应的位置,并在 docker - compose.yml 文件中添加相关的环境变量配置,例如:

kafka1:
  image: confluentinc/cp - kafka:6.2.1
  depends_on:
    - zookeeper
  environment:
    KAFKA_BROKER_ID: 1
    KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
    KAFKA_ADVERTISED_LISTENERS: SSL://kafka1:9092
    KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: SSL:SSL
    KAFKA_SSL_KEYSTORE_LOCATION: /etc/kafka/secrets/kafka.server.keystore.jks
    KAFKA_SSL_KEYSTORE_PASSWORD: your - keystore - password
    KAFKA_SSL_KEY_PASSWORD: your - key - password
    KAFKA_SSL_TRUSTSTORE_LOCATION: /etc/kafka/secrets/kafka.server.truststore.jks
    KAFKA_SSL_TRUSTSTORE_PASSWORD: your - truststore - password
  ports:
    - 9092:9092
  1. SASL 认证:除了 SSL/TLS 加密,还可以配置 SASL 认证来确保只有授权的用户可以访问 Kafka。以 PLAIN 机制为例,首先需要创建用户和密码,例如使用 kafka - configs 命令:
kafka - configs --zookeeper zookeeper:2181 --alter --add - config 'SCRAM - SHA - 256=[password=your - password],SCRAM - SHA - 512=[password=your - password]' --entity - type users --entity - name your - username

然后,在 docker - compose.yml 文件中配置 SASL 相关的环境变量:

kafka1:
  image: confluentinc/cp - kafka:6.2.1
  depends_on:
    - zookeeper
  environment:
    KAFKA_BROKER_ID: 1
    KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
    KAFKA_ADVERTISED_LISTENERS: SASL_PLAINTEXT://kafka1:9092
    KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: SASL_PLAINTEXT:SASL_PLAINTEXT
    KAFKA_SASL_ENABLED_MECHANISMS: SCRAM - SHA - 256,SCRAM - SHA - 512
    KAFKA_SASL_MECHANISM_INTER_BROKER_PROTOCOL: SCRAM - SHA - 256
  ports:
    - 9092:9092

同时,在客户端连接 Kafka 时,也需要配置相应的 SASL 认证信息。例如,在生产者和消费者的配置文件中添加:

sasl.mechanism = SCRAM - SHA - 256
security.protocol = SASL_PLAINTEXT
sasl.jaas.config = org.apache.kafka.common.security.scram.ScramLoginModule required username="your - username" password="your - password";

Kafka 监控与管理

  1. 使用 Kafka 自带的监控工具:Kafka 自带了一些命令行工具来监控集群状态,例如 kafka - topics 命令可以查看主题的详细信息,包括分区数量、副本分布等。kafka - brokers 命令可以查看集群中各个节点的状态。
docker exec -it kafka1 bash -c 'kafka - topics --describe --topic multi - replica - topic --bootstrap - servers kafka1:9092,kafka2:9093,kafka3:9094'
docker exec -it kafka1 bash -c 'kafka - brokers --bootstrap - servers kafka1:9092,kafka2:9093,kafka3:9094 --describe'
  1. 使用第三方监控工具:除了 Kafka 自带的工具,还可以使用一些第三方监控工具,如 Prometheus 和 Grafana。首先,需要安装 Prometheus 和 Grafana 容器。可以通过以下 docker - compose.yml 文件来配置:
version: '3'
services:
  prometheus:
    image: prom/prometheus:v2.31.1
    ports:
      - 9090:9090
    volumes:
      -./prometheus.yml:/etc/prometheus/prometheus.yml
  grafana:
    image: grafana/grafana:8.3.4
    ports:
      - 3000:3000

然后,配置 Prometheus 来收集 Kafka 的指标数据,在 prometheus.yml 文件中添加:

scrape_configs:
  - job_name: 'kafka'
    static_configs:
      - targets: ['kafka1:9092', 'kafka2:9093', 'kafka3:9094']
    metrics_path: /metrics
    params:
      module: [kafka]
    relabel_configs:
      - source_labels: [__address__]
        target_label: __param_target
      - source_labels: [__param_target]
        target_label: instance
      - target_label: __address__
        replacement: kafka - exporter:9308

还需要部署 Kafka Exporter 来暴露 Kafka 的指标数据,通过以下 docker - compose.yml 配置:

version: '3'
services:
  kafka - exporter:
    image: danielqsj/kafka - exporter:v1.2.0
    ports:
      - 9308:9308
    environment:
      KAFKA_SERVERS: kafka1:9092,kafka2:9093,kafka3:9094

最后,在 Grafana 中导入 Kafka 相关的仪表盘模板,就可以直观地监控 Kafka 集群的各项指标,如吞吐量、延迟、副本状态等。

故障处理与高可用性

  1. 节点故障处理:在 Kafka 集群运行过程中,如果某个节点发生故障,Kafka 会自动进行一些调整。例如,如果一个副本所在的节点故障,Kafka 会将该副本的角色转移到其他正常的节点上,以保证数据的可用性。可以通过监控工具观察到这种变化,例如在 Grafana 中查看副本状态指标。
  2. 提高高可用性的策略:为了进一步提高 Kafka 集群的高可用性,可以采取以下策略:
  • 增加副本因子:适当增加主题的副本因子,可以提高数据的冗余度,降低因节点故障导致数据丢失的风险。但同时也会增加存储和网络开销。
  • 部署多套 Zookeeper 集群:Zookeeper 是 Kafka 集群的重要依赖,如果 Zookeeper 集群出现故障,可能会影响 Kafka 的正常运行。部署多套 Zookeeper 集群,并配置 Kafka 连接多个 Zookeeper 集群,可以提高 Zookeeper 的可用性。
  • 定期备份:定期对 Kafka 的数据进行备份,可以在出现严重故障时快速恢复数据。可以使用 Kafka 自带的工具或者第三方备份工具来实现数据备份。

通过以上步骤和方法,我们详细介绍了 Kafka 基于 Docker 的部署实践,包括单节点和多节点部署、安全配置、监控与管理以及故障处理等方面,希望能帮助读者在后端开发中更好地应用 Kafka 消息队列。