docker 网络配置_Kafka的AWS Docker网络设置

ca5b306f9a1d06b3b6d7a4e5487517a0.png

Kafka是一个分布式流处理平台,最近几年获得了长足的发展和进步。这篇文章主要针对在AWS 上部署 Kafka Docker镜像的注意事项。其中最容易出问题的部分就是Kafka的listeners配置,如果不能正确配置Listener,会造成Kafka 客户端找不到Broker,无法使用。这个问题在Docker背景下更加复杂一些,因为这里涉及到三个网络:Docker内部网络,运行的Docker的机器本地网络(这里可以是AWS的VPC网络)以及外网(即Internet)。

目前AWS部署Docker镜像应用主要有两种方式,一种是传统的EC2部署,另一种是托管的ECS部署。理论上,只要你的docker-compose文件在一种方式通过测试,那么在另一种应该也会通过测试,因为ECS和EC2的docker环境几乎是一样的。

Kafka Broker和Zookeeper

我们需要弄清楚Zookeeper和Kafka Broker之间的关系。Zookeeper是Apache开发用来集中管理、协调分布式系统,比如Kafka集群,的工具。他就相当于是一个指挥官,负责协调kafka集群中的各个Broker,Zookeeper会把集群信息分散到Broker,这样每一个Broker会知道是否有新的Broker加入?是否有Broker离线?是否有新的Topic加入?等等。(我想这也是Zookeeper名字的来源吧,就是动物园管理员的身份。。。。)

没有Zookeeper不能运行Kafka集群。

62422b46b54115e885cfa750865bfbf5.png
Zookeeper与Kafka集群

所以,在配置Kafka时,需要首先部署Zookeeper,然后将Zoopeeker的端口信息暴露给每一个Kafka的Broker,并且确保网络通讯,即尽量把他们放在同一个网络中。如果不行,就需要保证不同的Zookeeper之间能够通讯协调,而Broker之间是不会互相对话的。

d2a1e878507b66bad8a73d84c0540554.png
不同服务器的Zookeeper链接

Kafka的Listener

Kafka是一个分布式系统,客户端(Consumer、Producer或者其他Connector)第一次连接集群时,会向集群请求Meta Data,他可以向集群中的任何一个Broker读取或者写入数据。但是,容易出问题的地方就是如何找到集群中的一个Broker呢?通常我们使用IP地址或者DNS名称寻找broker。但是当我们使用Docker部署在AWS时候,涉及到三个网络:Docker内部网络,运行的Docker的机器本地网络(这里可以是AWS的VPC网络)以及外网(即Internet),我们必须为不同的网络配置对应的Listener,才能保证Broker可以被不用网络的用户正确的发现。否则,会出现找不到Broker的问题。

问题的关键是,当你启动一个Kafka客户端,你传入的Broker会成为客户端发现整个集群的入口。此后,客户端读取、写入数据所使用的Host&IP会基于这个Broker传回的信息。比如,下面的情况,这个Producer就会连接server1.xxxx.com:9092

import json
from kafka import KafkaProducer

producer = KafkaProducer(
    bootstrap_servers=['server1.xxxx.com:9092'],
    value_serializer=lambda v: json.dumps(v).encode('utf-8'),
)

重点来了:一个Kafka Broker可以有多个Listener,这就是在多个网络环境下配置Kafka的关键。每一个Listener包含如下属性:

  1. Host/IP
  2. Port
  3. Protocol

我们来看一个例子:

KAFKA_LISTENERS: INTERNAL://0.0.0.0:29092, EXTERNAL://0.0.0.0:9092, AWS://0.0.0.0:29094
KAFKA_ADVERTISED_LISTENERS: INTERNAL://kafka:29092,EXTERNAL://xxxx.xxxx.com:9092, AWS://172.31.x.x:29094
KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: INTERNAL:PLAINTEXT,EXTERNAL:PLAINTEXT,AWS:PLAINTEXT
KAFKA_INTER_BROKER_LISTENER_NAME: INTERNAL

acac58f12e70133bdbc2e4fde273002d.png

上面配置涉及三个不同Listener,分别是Internal、External和AWS,黄色代表了AWS本地网络,或VPC网络,蓝色代表了Docker内部网络,绿色代表非AWS网络,或者一般的公网或者其他VPC网络。可以看到,Producer1 处于Docker内部,需要连接Internal Listener:29092才能正确连接集群。而Producer2 处于AWS本地网络,或者VPC网络,他需要连接对应的AWS listener:29094。而对于Producer3和Consumer3,他们处于VPC之外,需要访问External listerner: 9092。

这里值得注意的是,理论上Producer2也可以访问External。可是通常,处于安全考虑,防火墙会限制外网访问端口和IP,所以最好的方案是为外网和内网配置不同的Listener,以便防火墙进行安全管理。

Kafka部署的Compose文件配置

根据上面的配置文件,我们形成了如下Compose文件:

---
version: '2'
services:
  zookeeper:
    image: confluentinc/cp-zookeeper:latest
    environment:
      ZOOKEEPER_CLIENT_PORT: 2181
      ZOOKEEPER_TICK_TIME: 2000

  kafka:
    image: confluentinc/cp-kafka:latest
    depends_on:
      - zookeeper
    ports:
      - 9092:9092
      - 29094:29094
    environment:
      KAFKA_BROKER_ID: 1
      KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
      KAFKA_LISTENERS: INTERNAL://0.0.0.0:29092, EXTERNAL://0.0.0.0:9092, AWS://0.0.0.0:29094
      KAFKA_ADVERTISED_LISTENERS: INTERNAL://kafka:29092,EXTERNAL://xxxx.xxxx.com:9092, AWS://172.31.x.x:29094
      KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: INTERNAL:PLAINTEXT,EXTERNAL:PLAINTEXT,AWS:PLAINTEXT
      KAFKA_INTER_BROKER_LISTENER_NAME: INTERNAL
      KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1

参考:

  • https://medium.com/hacking-talent/kafka-all-you-need-to-know-8c7251b49ad0
  • https://github.com/wurstmeister/kafka-docker/wiki/Connectivity
  • https://rmoff.net/2018/08/02/kafka-listeners-explained/
  • https://github.com/confluentinc/cp-docker-images/tree/5.3.1-post/examples
  • 利用docker-compose部署ECS
  • http://cloudurable.com/blog/kafka-architecture/index.html
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值