在Docker環境下的kafka部署之二:SSL連線及內外網分別訪問

猛禽大叔發表於2018-10-09

準備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發訊息了。

相關文章