【问题标题】:Issue using NodeJS Kafka and Docker, the resolved host is container ID使用 NodeJS Kafka 和 Docker 的问题,解析的主机是容器 ID
【发布时间】:2018-08-16 23:22:54
【问题描述】:

我正在运行 CentOS 7.5 虚拟机,我正在尝试将 ZooKeeper/Kafka 服务器运行到容器中(使用 docker compose)。

我正在使用 kafka-node(2.6.1) 来使用 Kafka。直接在 VM 上运行时一切正常。但是当 Kafak 服务器被 dockerized 时,会出现一个与 IPv6 相关的问题。

当我在容器外(在主机上)使用/bin/kafka-topics.sh 脚本时,我可以在 Kafka 服务器上创建主题,这意味着容器正常并且端口(2181、9092)已打开。

这是我正在使用的版本:

//CentOS Version
SB Version:    :core-4.1-amd64:core-4.1-noarch
Distributor ID: CentOS
Description:    CentOS Linux release 7.5.1804 (Core)
Release:        7.5.1804
Codename:       Core

//nodejs verison
5.3.0

//kafka version
2.11-2.0.0

// docker version
Client:
 Version:           18.06.0-ce
 API version:       1.38
 Go version:        go1.10.3
 Git commit:        0ffa825
 Built:             Wed Jul 18 19:08:18 2018
 OS/Arch:           linux/amd64
 Experimental:      false
Server:
 Engine:
  Version:          18.06.0-ce
  API version:      1.38 (minimum version 1.12)
  Go version:       go1.10.3
  Git commit:       0ffa825
  Built:            Wed Jul 18 19:10:42 2018
  OS/Arch:          linux/amd64
  Experimental:     false
  
//docker compose version
docker-compose version 1.21.2, build a133471
docker-py version: 3.4.1
CPython version: 2.7.5
OpenSSL version: OpenSSL 1.0.2k-fips  26 Jan 2017

这是我的 nodejs 脚本,当 kafka 在主机上时可以正常工作,但当 kafka 在 docker 中时不能正常工作:

var fs = require('fs'),
    kafka = require('kafka-node'),
    path = require('path'),
    cassandra = require('cassandra-driver'),
    moment = require('moment');
//Producer
const client = new kafka.Client("127.0.0.1:2181");

const producer = new kafka.HighLevelProducer(client);
var interval;
console.log('Hello');

producer.on("ready", function () {
    console.log("Ingestion Complete Event Producer is connected and ready.");
    interval = setInterval(function () {
        _scanDirectoryAndTagReport();
    }, (process.argv[2] || 1500));
});
producer.on('error', function(err) {
    console.log('error', err);
    
});

这是我从 VM 运行此脚本时的输出:

Hello
Ingestion Complete Event Producer is connected and ready.
error { Error: getaddrinfo ENOTFOUND d98e973bc4a7 d98e973bc4a7:9092
    at errnoException (dns.js:28:10)
    at GetAddrInfoReqWrap.onlookup [as oncomplete] (dns.js:79:26)
  code: 'ENOTFOUND',
  errno: 'ENOTFOUND',
  syscall: 'getaddrinfo',
  hostname: 'd98e973bc4a7',
  host: 'd98e973bc4a7',
  port: '9092' } 
error { Error: getaddrinfo ENOTFOUND d98e973bc4a7 d98e973bc4a7:9092
    at errnoException (dns.js:28:10)
    at GetAddrInfoReqWrap.onlookup [as oncomplete] (dns.js:79:26)
  code: 'ENOTFOUND',
  errno: 'ENOTFOUND',
  syscall: 'getaddrinfo',
  hostname: 'd98e973bc4a7',
  host: 'd98e973bc4a7',
  port: '9092' } 
  error { Error: getaddrinfo ENOTFOUND d98e973bc4a7 d98e973bc4a7:9092
    at errnoException (dns.js:28:10)
    at GetAddrInfoReqWrap.onlookup [as oncomplete] (dns.js:79:26)
  code: 'ENOTFOUND',
  errno: 'ENOTFOUND',
  syscall: 'getaddrinfo',
  hostname: 'd98e973bc4a7',
  host: 'd98e973bc4a7',
  port: '9092' } 
  error { Error: getaddrinfo ENOTFOUND d98e973bc4a7 d98e973bc4a7:9092
    at errnoException (dns.js:28:10)
    at GetAddrInfoReqWrap.onlookup [as oncomplete] (dns.js:79:26)
  code: 'ENOTFOUND',
  errno: 'ENOTFOUND',
  syscall: 'getaddrinfo',
  hostname: 'd98e973bc4a7',
  host: 'd98e973bc4a7',
  port: '9092' } 
  error { Error: getaddrinfo ENOTFOUND d98e973bc4a7 d98e973bc4a7:9092
    at errnoException (dns.js:28:10)
    at GetAddrInfoReqWrap.onlookup [as oncomplete] (dns.js:79:26)
  code: 'ENOTFOUND',
  errno: 'ENOTFOUND',
  syscall: 'getaddrinfo',
  hostname: 'd98e973bc4a7',
  host: 'd98e973bc4a7',
  port: '9092' } 
  error { Error: getaddrinfo ENOTFOUND d98e973bc4a7 d98e973bc4a7:9092
    at errnoException (dns.js:28:10)
    at GetAddrInfoReqWrap.onlookup [as oncomplete] (dns.js:79:26)
  code: 'ENOTFOUND',
  errno: 'ENOTFOUND',
  syscall: 'getaddrinfo',
  hostname: 'd98e973bc4a7',
  host: 'd98e973bc4a7',
  port: '9092' } 

错误消息正在循环。

有人有线索吗?

祝你有美好的一天,

NeitoFR

编辑 1:正如评论中指出的,这不是 IPv6 相关问题,但问题是我的生产者解析的主机是容器 ID

【问题讨论】:

  • 您确定这是您正在运行的代码吗?我看到你发布了const client = new kafka.Client("127.0.0.1:2181"); 但错误消息表明有东西试图连接到"d98e973bc4a7:9092"。我在这里也没有看到任何与 IPv6 相关的内容。所以我不明白为什么它被标记为 IPv6?
  • 好吧,脚本日志Ingestion Complete Event Producer is connected and ready.,这是在引发“就绪”事件时记录的,当我的客户端成功连接到kafka服务器时(我假设)会引发就绪事件。让我觉得它与 IPv6 相关的原因是该错误与 GetAddrInfo 异常有关,并且返回的字符串看起来确实像十六进制代码(以及 IPv6 子字符串)。我完全同意这是牵强的,当然是不正确的,但它看起来就是这样
  • 这不是 IPv6 地址。它甚至不像一个。它看起来像一个 Docker 容器 ID。
  • 你说的没错,其实是kafka的容器ID,还是不知道怎么解决
  • 这引起了我的注意,因为我关注了ipv6 标签。但我建议您也发布您的docker-compose.yml

标签: node.js apache-kafka centos docker-compose


【解决方案1】:

我找到了一个解决方案,您可以在 docker-compose.yml 中指定一个主机名,并将 nodejs 客户端设置为连接到该主机名。

这是 .yml :

version: '3'

services:
  kafkazoo:
    build: ./kafka
    hostname: kafkazoo
    ports:
      - 9092:9092
      - 2181:2181
  data_input_service:
    build: ./data_input_service
    # environment:
    #   - SCRIPT_NAME=pull_data_service.js
    volumes: 
      - /predix/shared/linux_shared/JSON_REPORTS:/data/JSON_REPORTS
    depends_on: 
      - kafkazoo
  external_pull_data_service:
    build: ./external_pull_data_service
    # environment:
    #   - SCRIPT_NAME=report_generator.js
    volumes: 
      - /predix/shared/linux_shared/JSON_REPORTS:/data/JSON_REPORTS
    depends_on: 
      - kafkazoo

如您所见,我添加了主机名:kafakazoo,这是新的 Kafka 客户端:

const client = new kafka.Client("kafkazoo:2181");

const producer = new kafka.HighLevelProducer(client);

而且效果很好

感谢Michael Hampton

【讨论】:

  • Kafka 客户端应该连接到端口 9092,而不是 2181 上的 Zookeeper,您是否有理由构建自己的映像而不是使用现有映像?
  • 感谢您的洞察力,我正在制作自己的镜像只是因为我正在发现 Docker,并且我想知道如何构建自己的镜像
  • Kafka 构建自己的容器非常复杂,根据我的尝试(默认属性文件在容器中无法正常工作,也不意味着形成集群)。了解 Web 应用程序或控制台应用程序要容易得多
  • 我同意,我切换到 ches/kafka + zookeeper 官方图像,因为 :) 现在效果很好
  • 嗯,“confluentinc”图像应该是“官方”图像,因为那是它的企业支持公司,拥有最多的 Kafka 核心开发人员
猜你喜欢
  • 2020-06-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-11-13
  • 1970-01-01
  • 2017-04-12
  • 1970-01-01
  • 2015-05-29
相关资源
最近更新 更多