简体   繁体   English

如何为Docker容器订购Kafka启动Shell脚本?

[英]How to order a Kafka startup shell script for a docker container?

I am trying to containerize a Kafka server. 我正在尝试将Kafka服务器容器化。 A normal start-up sequence for a Kafka server is like this: Kafka服务器的正常启动顺序如下:

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

Item A and B are long running process. 项目AB是长期运行的过程。 And C need to wait for B to come up and running. C需要等待B启动并运行。

So I wrote a Dockerfile, with ENTRYPOINT executing a shell script for the above sequence: 因此,我编写了一个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

However, I encountered three problems when run the docker image built from this: 但是,在运行由此生成的docker映像时遇到三个问题:

  • Docker requires the ENTRYPOINT process to be long-running, while above script does not. Docker要求ENTRYPOINT进程可以长时间运行,而上述脚本则不需要。 (it exits as long as the topic-creation is done) (只要完成主题创建,它就会退出)
  • The broker server statement (the 2nd one) is long-running process. 代理服务器语句(第二个)是长时间运行的过程。 Currently I have to put it as background process using ending & , because otherwise the statements after it are not executed at all. 目前,我必须使用&结尾将其作为后台进程,因为否则它之后的语句根本不会执行。 (But making it background also has problem: the topic creation is executed immediately, while the broker server is not ready yet.) (但是,使其成为背景也有问题:在代理服务器尚未准备就绪时,立即执行主题创建。)
  • I could not put the broker server statement as the last long-running process, because the topic creation statement has to come after the server creation. 我不能将代理服务器语句作为最后一个长时间运行的过程,因为主题创建语句必须在服务器创建之后进行。

What could be a good way to arrange this start-up sequence? 安排启动顺序的好方法是什么?

Docker Compose covers a lot of orchestration tasks that are non trivial to implement in scripts. Docker Compose涵盖了许多编排任务,这些编排任务很难在脚本中实现。

The depends_on and healthcheck service configurations can be used to create proper service dependencies where service B waits for service A to be "healthy" before running. depends_on和运行状况healthcheck服务配置可用于创建适当的服务依赖关系,其中服务B在运行之前会等待服务A“运行正常”。

Although Compose doesn't really have a defined concept of short running tasks yet, topic creation can always run at startup so an additional service that immediately exits works fine. 尽管Compose尚未真正定义短期任务的概念,但是主题创建始终可以在启动时运行,因此立即退出的附加服务可以正常工作。

There's a compose definition, Dockerfile and check script on github that implements this dependency setup. 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

Basically you want to start ZK, then Kafka. 基本上,您想启动ZK,然后是Kafka。 Then somehow wait until Kafka is ready (that's the tricky part), do your job with kafka (eg topic creation in your case), and then wait until Kafka & ZK have finished (what happens on interrupt). 然后以某种方式等待,直到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}"

As mentioned, the Kafka-readiness might be tricky - the following ways might be helpful: 如前所述,准备Kafka可能会有些棘手-以下方式可能会有所帮助:

  • waiting until Kafka responds to read requests (eg probing with kafka-topic.sh --list periodically) 等待,直到Kafka响应读取请求(例如,定期使用kafka-topic.sh --list探测)
  • creating a pocket consumer / AdminClient (java kafka 0.11+) and getting metadata (similar to above point) 创建一个口袋用户/ AdminClient(java kafka 0.11+)并获取元数据(类似于以上几点)
  • checking existence of JMX beans for logs/controller etc. 检查是否存在用于日志/控制器等的JMX bean。
  • checking listening port availability 检查监听端口可用性

I suggest to wrap topic creation into separate script that is doing pause before trying to create topic, and run Kafka server not in background. 我建议将主题创建包装到单独的脚本中,该脚本在尝试创建主题之前会先暂停一下,然后不要在后台运行Kafka服务器。 Something like: 就像是:

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

And create-topic.sh will look as following: 并且create-topic.sh将如下所示:

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

PS Although instead of sleep it's better to probe Kafka's availability via nc -z PS虽然最好不要睡觉,但最好通过nc -z探索Kafka的可用性

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM