在Docker环境下的kafka部署之二:SSL连接及内外网分别访问

准备SSL连接

先参考这篇《Kafka配置SSL(云环境)》创建一堆的证书。

需要修改的部分有几个:

BASE_DIR=/your_path # SSL各种生成文件的基础路径
...
PASSWORD=yourpassword # 密码
...
DAYS_VALID=3650 # key有效期改为10年
DNAME="CN=domain_name, OU=test, O=your_company, L=Xiamen, ST=Fujian, C=CN"  # 你的信息,注意,其中domain_name为kafka配置的外网访问域名,否则会报证书不一致错误
SUBJ="/C=CN/ST=Fujian/L=Xiament/O=your_company/CN=domain_name"  # 新增参数,说明同上
...
# 把第二步创建CA的subj参数改为这样
-subj "$SUBJ"

修改完成后运行这个脚本创建证书,并把kafka.keystore和kafka.truststore拷到某个文件夹(如secrets)下,再在其中创建一个文本文件password,内容为密码(yourpassword)。

配置compose

接下来是compose的配置:

version: '2'
services:
  zookeeper:
    image: confluentinc/cp-zookeeper
    container_name: zookeeper
    mem_limit: 1024M
    environment:
      ZOOKEEPER_CLIENT_PORT: 2181
  kafka:
    image: confluentinc/cp-kafka
    container_name: kafka
    mem_limit: 1024M
    depends_on:
      - zookeeper
    ports:
      - 9092:9092
      - 9093:9093
    volumes:
      - /home/raptor/path_to/secrets:/etc/kafka/secrets
    environment:
      KAFKA_BROKER_ID: 1
      KAFKA_LISTENERS: PLAINTEXT://:9092,SSL://:9093
      KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafka:9092,SSL://domain_name:9093
      KAFKA_SSL_KEY_CREDENTIALS: password
      KAFKA_SSL_KEYSTORE_FILENAME: kafka.keystore
      KAFKA_SSL_KEYSTORE_CREDENTIALS: password
      KAFKA_SSL_CLIENT_AUTH: required
      KAFKA_SSL_TRUSTSTORE_FILENAME: kafka.truststore
      KAFKA_SSL_TRUSTSTORE_CREDENTIALS: password
      KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
      KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1
      KAFKA_HEAP_OPTS: "-Xmx512M -Xms16M"

其中与SSL相关的配置有几个:

  • 端口9093相关的部分,包括ports的映射及两个SSL的LISTENERS。
  • KAFKA_SSL_开头的一堆配置,需要注意的是,这几个参数都不是server.properties里的,而是官方Dockerfile中的配置,启动脚本里会根据这几个参数构造所需要的最终参数,比如通过FILENAME参数组合出LOCATION参数,通过CREDENTIALS去读出密码等(所以需要把密码保存在password文件中,这里填的是密码文件名)。
  • 因为密钥文件的LOCATION是构造出来的,其默认路径为:/etc/kafka/secrets,所以需要一个volumes映射把之前生成的密钥文件和密码文件映射到这里。

其中与内外网分别访问的配置就是两个LISTENERS配置:内网用PLAINTEXT,外网用SSL。注意,这里不可以用两个一样的类型,比如都是PLAINTEXT或都是SSL。

内外网分别访问的测试

以外网producer,内网(在单独的container里)consumer为例。

启动一个producer container并运行一个producer,通过外网连接kafka:

docker run -it --rm --add-host=domain_name:172.17.0.1 --name producer -v /home/raptor/path_to/secrets:/etc/kafka/secrets confluentinc/cp-kafka /bin/bash

kafka-console-producer --broker-list domain_name:9093 --topic kafkatest --producer.config producer.config

其中producer.config的内容为:

bootstrap.servers=domain_name:9093
security.protocol=SSL
ssl.truststore.location=/etc/kafka/secrets/kafka.truststore
ssl.truststore.password=yourpassword
ssl.keystore.password=yourpassword
ssl.keystore.location=/etc/kafka/secrets/kafka.keystore

再启动一个consumer container并运行consumer,通过docker网络连接kafka:

docker run -it --rm --link kafka:kafka --network kafka_default --name consumer confluentinc/cp-kafka /bin/bash

kafka-console-consumer --bootstrap-server kafka:9092 --topic kafkatest --from-beginning

现在就可以通过producer正常往consumer发消息了。

推送到[go4pro.org]