【问题标题】:How to order a Kafka startup shell script for a docker container?如何为 docker 容器订购 Kafka 启动 shell 脚本?
【发布时间】:2018-03-24 22:48:41
【问题描述】:

我正在尝试将 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 进程长时间运行,而上述脚本不需要。 (只要主题创建完成,它就会退出)
  • 代理服务器语句(第二条)是长时间运行的过程。目前我必须将它作为后台进程使用结束&,否则它之后的语句根本不会执行。 (但是做后台也有问题:主题创建是立即执行的,而代理服务器还没有准备好。)
  • 我不能将代理服务器语句作为最后一个长时间运行的进程,因为主题创建语句必须在服务器创建之后。

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

【问题讨论】:

    标签: bash shell docker apache-kafka dockerfile


    【解决方案1】:

    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
    

    【讨论】:

      【解决方案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。
      • 检查监听端口的可用性

      【讨论】:

        【解决方案3】:

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

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

        create-topic.sh 如下所示:

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

        附:尽管通过nc -z 探测Kafka 的可用性而不是睡眠更好

        【讨论】:

          猜你喜欢
          • 2021-05-19
          • 2020-07-21
          • 2017-02-06
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-03-16
          • 2018-05-20
          • 1970-01-01
          相关资源
          最近更新 更多