如何订购Docker容器的Kafka启动shell脚本?

我正在尝试装入一个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 

不过,在运行由此构build的docker镜像时,我遇到了三个问题:

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

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

Docker Compose涵盖了很多编排任务,这些任务在脚本中实现是非常重要的。

可以使用depends_onhealthcheck服务configuration来创build适当的服务依赖关系,其中服务B在运行之前等待服务A“健康”。

尽pipeCompose实际上还没有定义短期运行任务的概念,但是主题创build始终可以在启动时运行,因此立即退出的其他服务也可以正常运行。

在github上有一个组合的定义,Dockerfile和检查脚本来实现这个依赖设置。

 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 

基本上你想开始ZK,然后是Kafka。 然后以某种方式等到Kafka准备好了(这是棘手的部分),用kafka做你的工作(例如在你的案例中创build主题),然后等到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-topic.sh --list探测)
  • 创build一个口袋里的消费者/ AdminClient(java kafka 0.11+)和获取元数据(类似于上面的点)
  • 检查日志/控制器的JMX bean是否存在
  • 检查监听端口可用性

我build议将主题创build封装到单独的脚本中,在试图创build主题之前暂停,然后在后台运行Kafka服务器。 就像是:

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

而create-topic.sh将如下所示:

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

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