在Docker环境中启动分布式Kafka连接后创建Kafka连接器

时间:2020-07-03 12:48:31

标签: apache-kafka apache-kafka-connect

我试图在执行connect-distributed命令之后创建一个kafka连接器。我编写了一个entrypoint.sh脚本,并将其与CMD一起使用。我有这样的docker文件:

FROM confluentinc/cp-kafka
RUN mkdir /plugins
RUN mkdir /config
COPY kafka-connect-couchbase-*.jar /plugins/
COPY config /config/
RUN chmod +x /config/stage/entrypoint.sh
ENV EXPOSED_PORT 8083
CMD /config/stage/entrypoint.sh

我的入口点脚本文件为:

connect-distributed config/"${DEPLOY_ENV}"/connect-distributed.properties
curl -X POST -H "Content-Type: application/json" -d @config.json http://localhost:8083/connectors

deploy_env无关紧要,它来自詹金斯。配置文件和distributed.properties也无关紧要,这是正确的,我手动尝试过。

Kafka连接启动没有问题, ,但是用于创建连接器的 curl 命令无效。

简而言之,我想在启动connect-distributed之后创建一个连接器,而不在容器外部执行任何休息请求。我该如何实现?

2 个答案:

答案 0 :(得分:2)

您需要确保您正在等待Kafka Connect工作者完全启动。

顺便说一句,您最好从Kafka Connect基本映像开始

FROM confluentinc/cp-kafka-connect-base:5.5.0

通常,您会使用Confluent Hub来安装连接器,但是看起来Couchbase那里不存在,因此您必须像完成操作一样在JAR中进行复制。

在Connect映像中启动Kafka Connect的实际脚本为/etc/confluent/docker/run,因此您的/config/stage/entrypoint.sh应该如下所示:

# Launch the worker
/etc/confluent/docker/run &

# Wait for it to start running
# Change the port here if not using the default
bash -c ' \
echo -e "\n\n=============\nWaiting for Kafka Connect to start listening on localhost ⏳\n=============\n"
while [ $(curl -s -o /dev/null -w %{http_code} http://localhost:8083/connectors) -ne 200 ] ; do
  echo -e "\t" $(date) " Kafka Connect listener HTTP state: " $(curl -s -o /dev/null -w %{http_code} http://localhost:8083/connectors) " (waiting for 200)"
  sleep 5
done
echo -e $(date) "\n\n--------------\n\o/ Kafka Connect is ready! Listener HTTP state: " $(curl -s -o /dev/null -w %{http_code} http://localhost:8083/connectors) "\n--------------\n"

# Now create your connector
## Inline config example: 
curl -i -X PUT -H  "Content-Type:application/json" http://localhost:8083/connectors/sink-file-jsonschema-as-json/config \
    -d '{
            "connector.class": "org.apache.kafka.connect.file.FileStreamSinkConnector",
            "key.converter": "org.apache.kafka.connect.storage.StringConverter",
            "value.converter": "org.apache.kafka.connect.json.JsonConverter",
            "tasks.max": 1,
            "file": "/jsonschema-as-json.txt",
            "topics": "test-jsonschema"
}'
## External file example: 
curl -X POST -H "Content-Type: application/json" -d @config.json http://localhost:8083/connectors

另请参阅https://rmoff.net/2018/12/15/docker-tips-and-tricks-with-ksql-and-kafka/

答案 1 :(得分:0)

由于罗宾·莫法特(Robin Moffatt)出色的解决方案,我将其与自己的需求结合在一起,并且有效。

自从将映像部署到kubernetes以来,/etc/confluent/docker/run &后台命令导致容器传递到完成状态而不是运行。这样,使用如下所示的Rest接口无法从外部访问容器:

http://some-ip:31682/connectors

为了解决这个问题,我在最初的问题中使用了Dockerfile,但是通过删除合流的docker run命令并添加了其他检查连接器是否存在的修改了Robin的脚本。

bash -c ' \
echo -e "\n\n=============\nWaiting for Kafka Connect to start listening on localhost ⏳\n=============\n"
while [ $(curl -s -o /dev/null -w %{http_code} http://localhost:8083/connectors) -ne 200 ] ; do
  echo -e "\t" $(date) " Kafka Connect listener HTTP state: " $(curl -s -o /dev/null -w %{http_code} http://localhost:8083/connectors) " (waiting for 200)"
  sleep 5
done
echo -e $(date) "\n\n--------------\n\o/ Kafka Connect is ready! Listener HTTP state: " $(curl -s -o /dev/null -w %{http_code} http://localhost:8083/connectors) "\n--------------\n"

if [ $(curl -s -o /dev/null -w %{http_code} http://localhost:8083/connectors/cbconnector2) -ne 200 ]
then
  curl -X POST -H "Content-Type: application/json" -d @config/stage/config.json http://localhost:8083/connectors
fi'

之后,我通过添加启动后生命周期来修改Kubernetes部署文件,并将entrypoint.sh脚本作为要执行的命令,如下所示:

lifecycle:
  postStart:
    exec:
      command: ["/bin/sh", "/config/stage/entrypoint.sh"] 

基本上,它首先启动kafka-connect,然后在启动process(pod)之后,我只需执行自定义外壳脚本来创建kafka连接器。

希望这对使用情况类似的人有所帮助。我也愿意接受其他(更好)的解决方案。非常感谢Robin Moffatt。