Docker Desktop + Kafka + KRaft + Kerberos

准备文件

相关文件如下:

Local
├─ docker-compose.yml
├─ kafka_jaas.conf
├─ kafka_ui_jaas.conf
└─ krb5.conf

krb5.conf

[libdefaults]
 dns_lookup_realm = false
 dns_canonicalize_hostname = false
 ticket_lifetime = 24h
 renew_lifetime = 7d
 forwardable = true
 rdns = false
 default_realm = EXAMPLE.COM
 
 [realms]
 EXAMPLE.COM = {
    kdc = kdc.example.com
    admin_server = kdc.example.com
 }

kafka_jaas.conf

KafkaServer {
    com.sun.security.auth.module.Krb5LoginModule required
    useKeyTab=true
    storeKey=true
    keyTab="/etc/security/keytabs/kafka.keytab"
    principal="kafka/kafka@EXAMPLE.COM";
};

kafka_ui_jaas.conf

KafkaClient {
    com.sun.security.auth.module.Krb5LoginModule required
    useKeyTab=true
    storeKey=true
    keyTab="/etc/security/keytabs/kafka-ui.keytab"
    principal="kafka-ui/kafka-ui@EXAMPLE.COM";
};

docker-compose.yml

# 网络
networks:
  kerberos-net:
    driver: bridge

# 本地挂载
volumes:
  krb5_data:
    driver: local
    driver_opts:
      type: none
      o: bind
      # docker desktop + windows11 根据实际情况修改
      device: D:\Docker\LOCAL_KAFKA\krb5_data

services:
  kdc:
    image: gcavalcante8808/krb5-server:latest
    container_name: kdc
    hostname: kdc.example.com
    networks:
      - kerberos-net
    environment:
      - KRB5_REALM=EXAMPLE.COM
      - KRB5_KDC=kdc.example.com
      - KRB5_ADMINSERVER=kdc.example.com
    volumes:
      - krb5_data:/var/lib/krb5kdc
      - ./krb5.conf:/etc/krb5.conf:ro
    ports:
      - "88:88/tcp"
      - "88:88/udp"
      - "749:749"
    # 健康检查
    healthcheck:
      test: ["CMD", "kadmin.local", "list_principals"]
      interval: 10s
      timeout: 5s
      retries: 5

  kafka:
    image: confluentinc/cp-kafka
    container_name: kafka
    networks:
      - kerberos-net
	# 等待kdc启动完成
    depends_on:
      kdc:
        condition: service_healthy
    volumes:
      - krb5_data:/etc/security/keytabs:ro
      - ./krb5.conf:/etc/krb5.conf:ro
      - ./kafka_jaas.conf:/etc/kafka/kafka_jaas.conf:ro
    environment:
      CLUSTER_ID: "MkU3OEVBNTcwOTJENDQ0Nk"
      KAFKA_PROCESS_ROLES: broker,controller
      KAFKA_NODE_ID: 1
      KAFKA_CONTROLLER_QUORUM_VOTERS: 1@kafka:9093
      KAFKA_CONTROLLER_LISTENER_NAMES: CONTROLLER
      KAFKA_LISTENERS: PLAINTEXT://0.0.0.0:9092,CONTROLLER://0.0.0.0:9093,SASL_PLAINTEXT://0.0.0.0:9094
      KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://localhost:9092,SASL_PLAINTEXT://kafka:9094
      KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: PLAINTEXT:PLAINTEXT,CONTROLLER:PLAINTEXT,SASL_PLAINTEXT:SASL_PLAINTEXT
      KAFKA_INTER_BROKER_LISTENER_NAME: PLAINTEXT
      KAFKA_SASL_ENABLED_MECHANISMS: GSSAPI
      KAFKA_SASL_MECHANISM_INTER_BROKER_PROTOCOL: GSSAPI
      KAFKA_SASL_KERBEROS_SERVICE_NAME: kafka
      KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1
      KAFKA_TRANSACTION_STATE_LOG_REPLICATION_FACTOR: 1
      KAFKA_TRANSACTION_STATE_LOG_MIN_ISR: 1
      KAFKA_LOG_DIRS: /var/lib/kafka/data
      KAFKA_OPTS: -Djava.security.krb5.conf=/etc/krb5.conf -Djava.security.auth.login.config=/etc/kafka/kafka_jaas.conf
    ports:
      - "9094:9094"
    healthcheck:
      test: ["CMD", "kafka-broker-api-versions", "--bootstrap-server", "localhost:9092"]
      interval: 15s
      timeout: 10s
      retries: 10

  kafka-ui:
    image: provectuslabs/kafka-ui:latest
    container_name: kafka-ui
    networks:
      - kerberos-net
    depends_on:
      kafka:
        condition: service_healthy
    volumes:
      - krb5_data:/etc/security/keytabs:ro
      - ./krb5.conf:/etc/krb5.conf:ro
      - ./kafka_ui_jaas.conf:/etc/kafka/kafka_ui_jaas.conf:ro   # 挂载 UI 的 JAAS 文件
    environment:
      JAVA_OPTS: -Djava.security.krb5.conf=/etc/krb5.conf -Djava.security.auth.login.config=/etc/kafka/kafka_ui_jaas.conf
      KAFKA_CLUSTERS_0_NAME: local
      KAFKA_CLUSTERS_0_BOOTSTRAPSERVERS: kafka:9094
      KAFKA_CLUSTERS_0_PROPERTIES_SECURITY_PROTOCOL: SASL_PLAINTEXT
      KAFKA_CLUSTERS_0_PROPERTIES_SASL_MECHANISM: GSSAPI
      KAFKA_CLUSTERS_0_PROPERTIES_SASL_KERBEROS_SERVICE_NAME: kafka
    ports:
      - "39099:8080"

初始化

在当前目录打开终端,使用docker-compose up -d初次启动,启动后在kdc容器中依次执行以下命令。执行完成后,使用docker-compose down -v关闭当前容器。

kadmin.local -q 'addprinc -randkey kafka/kafka@EXAMPLE.COM'
kadmin.local -q 'ktadd -k /var/lib/krb5kdc/kafka.keytab kafka/kafka@EXAMPLE.COM'
kadmin.local -q 'addprinc -randkey kafka-ui/kafka-ui@EXAMPLE.COM'
kadmin.local -q 'ktadd -k /var/lib/krb5kdc/kafka-ui.keytab kafka-ui/kafka-ui@EXAMPLE.COM'
# 修改文件权限
chmod 644 /var/lib/krb5kdc/*.keytab

正式启动

在当前目录中执行docker-compose up -d即可。

Spring boot

在kdc容器中执行以下命令,生成keytab文件。

kadmin.local -q 'addprinc -randkey user1/user1@EXAMPLE.COM'
kadmin.local -q 'ktadd -k /var/lib/krb5kdc/user1.keytab user1/user1@EXAMPLE.COM'

在本地hosts中增加以下内容

# 本地docker启动的kafka
127.0.0.1 kafka
127.0.0.1 kdc.example.com

准备以下文件

  • user1_jaas.conf
KafkaClient {
    com.sun.security.auth.module.Krb5LoginModule required
    useKeyTab=true
    storeKey=true
    keyTab="conf/user1.keytab"
    principal="user1/user1@EXAMPLE.COM";
};
  • user1.keytab
  • krb5.conf

添加以下配置,开启kafka连接认证

spring:  
  kafka:  
    properties:  
      security.protocol: SASL_PLAINTEXT
      sasl.mechanism: GSSAPI  
      sasl.kerberos.service.name: kafka

添加以下启动参数

  • -Djava.security.krb5.conf=conf/krb5.conf
  • -Djava.security.auth.login.config=conf/user1_jaas.conf
Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐