如何为docker容器订购Kafka启动shell脚本?

时间:2017-10-12 21:21:44

标签: bash shell docker apache-kafka dockerfile

我正试图将Kafka服务器容器化。 Kafka服务器的正常启动顺序如下:

A: start Zookeeper server
B: start Broker server
C: create topic

AB是长时间运行的过程。 C需要等待B启动并运行。

所以我编写了一个Dockerfile,ENTRYPOINT执行上述序列的shell脚本:

#!/bin/sh

$KAFKA_HOME/bin/zookeeper-server-start.sh $KAFKA_HOME/config/zookeeper.properties &
$KAFKA_HOME/bin/kafka-server-start.sh $KAFKA_HOME/config/server.properties &

$KAFKA_HOME/bin/kafka-topics.sh --create --zookeeper localhost:2181 --replication-factor 1 --partitions 1 --topic test_topic

但是,在运行由此构建的docker镜像时遇到了三个问题:

  • Docker要求ENTRYPOINT进程长时间运行,而上面的脚本则不需要。 (只要主题创建完成就会退出)
  • 代理服务器语句(第二个)是长时间运行的进程。目前我必须使用结束&将其作为后台进程,因为否则后面的语句根本不执行。 (但使其成为后台也有问题:主题创建立即执行,而代理服务器尚未准备好。)
  • 我无法将代理服务器语句作为最后一个长时间运行的进程,因为主题创建语句必须在服务器创建之后。

安排这个启动序列的好方法是什么?

3 个答案:

答案 0 :(得分:2)

Docker Compose涵盖了许多在脚本中实现的非常简单的编排任务。

depends_onhealthcheck服务配置可用于创建适当的服务依赖关系,其中服务B在运行之前等待服务A“健康”。

虽然Compose实际上还没有定义短期运行任务的概念,但主题创建总是可以在启动时运行,因此立即退出的附加服务可以正常工作。

compose definition, Dockerfile and check script on github实现此依赖项设置。

version: "2.1"

services:

  zookeeper:
    image: deployable/kafka:latest
    command: zookeeper
    ports:
     - "2181:2181"
    healthcheck:
      test: [ "CMD", "/kafka/check.sh", "zookeeper" ]
      interval: 30s
      timeout: 5s
      retries: 3

  kafka:
    image: deployable/kafka:latest
    command: kafka
    environment:
      ADVERTISE_LISTENERS: 'localhost:9092'
    ports:
     - "9092:9092"
    depends_on:
      zookeeper:
        condition: service_healthy
    healthcheck:
      test: ["CMD", "/kafka/check.sh", "kafka" ]
      interval: 30s
      timeout: 5s
      retries: 3


  kafka-setup:
    image: deployable/kafka:latest
    command: setup
    depends_on:
      kafka:
        condition: service_healthy
    environment:
      KAFKA_TOPIC: my-test-topic

答案 1 :(得分:2)

基本上你想要开始ZK,然后是Kafka。 然后不知何故等到Kafka准备好了(这是棘手的部分),用kafka做你的工作(例如在你的情况下创建主题),然后等到Kafka& ZK已经完成(中断时会发生什么)。

start-zookeeper &
ZK_PID=$!
start-kafka &
KAFKA_PID=$!

# that's the tricky part
wait_for_kafka
create-topic.sh

wait "${KAFKA_PID}"
wait "${ZK_PID}"

如上所述,Kafka准备就绪可能很棘手 - 以下方式可能会有所帮助:

  • 等到Kafka响应读取请求(例如定期用kafka-topic.sh --list进行探测)
  • 创建口袋消费者/ AdminClient(java kafka 0.11+)并获取元数据(类似于上述点)
  • 检查日志/控制器等JMX bean的存在。
  • 检查侦听端口可用性

答案 2 :(得分:1)

我建议将主题创建包装到单独的脚本中,该脚本在尝试创建主题之前暂停,并且不在后台运行Kafka服务器。类似的东西:

start-zookeeper &
create-topic.sh &
start-kafka

create-topic.sh看起来如下:

sleep 5s
kafka-topics --create...

P.S。虽然不是睡觉,但最好通过nc -z来探测Kafka的可用性