【kafka】使用kafka client连接 kerberos认证的 kafka,scala版

注意keytab路径中不要使用\\,都使用/作为分隔符

使用kerberos需要配置jaas如下日志打印,两个配置至少设置一个:

[DEBUG] org.apache.kafka.common.security.JaasContext:106 --- System property 'java.security.auth.login.config' and Kafka SASL property 'sasl.jaas.config' are not set, using default JAAS configuration.
import org.slf4j.Logger
trait Logging {
  val LOG: Logger = org.slf4j.LoggerFactory.getLogger(this.getClass)
}
import org.apache.kafka.clients.producer.ProducerRecord
import org.scalatest.FunSuite
import java.util.Properties
import org.apache.kafka.clients.CommonClientConfigs
import org.apache.kafka.clients.consumer.{ConsumerConfig, KafkaConsumer}
import org.apache.kafka.clients.producer.KafkaProducer
import org.apache.kafka.clients.producer.ProducerConfig
import org.apache.kafka.common.config.SaslConfigs
import org.apache.kafka.common.serialization.{StringDeserializer, StringSerializer}
import java.time.Duration
import scala.collection.JavaConversions._

class KafkaClientTest extends FunSuite with Logging {

  val JAAS_CONFIG_KEYTAB_TEMPLATE: String =
    s"""
       |com.sun.security.auth.module.Krb5LoginModule required
       |debug=true
       |doNotPrompt=true
       |storeKey=true
       |useKeyTab=true
       |keyTab="%s"
       |principal="%s";
       |""".stripMargin

  val topic = "tmp_test"
  val bootstrapServers = "01.xxx.com:6667,01.xxx..com:6667,01.xxx..com:6667"

  val principal = "xxx@XXXXX.COM"
  val keytab = "D:/xxx/xxx.keytab"
  val krb5conf = "D:/xxx/krb5.conf"

  def getProducerProps: Properties = {
    val properties = new Properties()
    properties.setProperty(CommonClientConfigs.BOOTSTRAP_SERVERS_CONFIG, bootstrapServers)
    properties.setProperty(CommonClientConfigs.SECURITY_PROTOCOL_CONFIG, "SASL_PLAINTEXT")
    properties.setProperty(SaslConfigs.SASL_MECHANISM, "GSSAPI")
    properties.setProperty(SaslConfigs.SASL_KERBEROS_SERVICE_NAME, "kafka")
    properties.setProperty(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, classOf[StringSerializer].getName)
    properties.setProperty(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, classOf[StringSerializer].getName)
    properties
  }

  def getConsumerProps: Properties = {
    val properties = new Properties()
    properties.setProperty(CommonClientConfigs.BOOTSTRAP_SERVERS_CONFIG, bootstrapServers)
    properties.setProperty(CommonClientConfigs.SECURITY_PROTOCOL_CONFIG, "SASL_PLAINTEXT")
    properties.setProperty(SaslConfigs.SASL_MECHANISM, "GSSAPI")
    properties.setProperty(SaslConfigs.SASL_KERBEROS_SERVICE_NAME, "kafka")
    properties.setProperty(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, classOf[StringDeserializer].getName)
    properties.setProperty(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, classOf[StringDeserializer].getName)
    properties.setProperty(ConsumerConfig.GROUP_ID_CONFIG, "tester")
    properties.setProperty(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "earliest")
    properties
  }

  def setEnv(props: Properties) = {
    System.setProperty("java.security.krb5.conf", krb5conf)

    // 以下二者选其中之一就可以了。
    // 方式一:
    System.setProperty("java.security.auth.login.config", "D:/configs/kafka_client_jaas.conf")

    // 方式二:
    val jaasStr = JAAS_CONFIG_KEYTAB_TEMPLATE.format(keytab, principal).trim
    LOG.warn(s"format str: \n${jaasStr}")
    props.setProperty(SaslConfigs.SASL_JAAS_CONFIG, jaasStr)
  }

  test("produce") {
    val props = getConsumerProps
    setEnv(props)
    try {
      val producer = new KafkaProducer[String, String](props)
      var counter = 0;
      while (true) {
        val record = new ProducerRecord[String, String](topic, s"hello ${counter}")
        val fu = producer.send(record)
        Thread.sleep(3000L)
        if (counter % 10 == 0) {
          producer.flush()
        }
        counter += 1
      }
    } catch {
      case e: Exception =>
        throw new RuntimeException(e)
    }
  }

  test("consumer") {
    val props = getConsumerProps
    setEnv(props)
    val consumer = new KafkaConsumer(props)
    consumer.subscribe(List(topic))
    while (true) {
      val record = consumer.poll(Duration.ofSeconds(3))
      val it = record.iterator()
      while (it.hasNext) {
        LOG.info(s"${it.next().value()}")
      }
    }
  }
}

kafka_client_jaas.conf 文件内容:
文件模板参考:KAFKA_HOME/conf/kafka_client_jaas.conf

KafkaClient {
com.sun.security.auth.module.Krb5LoginModule required
    useKeyTab = true
    useTicketCache=false
    storeKey = true
    keyTab="D:/***/xxx.keytab"
    principal="xxx@XXXXX.COM"
    serviceName="kafka";
};
$KAFKA_HOME/bin/kafka-console-consumer.sh --bootstrap-server k01.com:6667,k02.com:6667,k03.com:6667 --topic mytopic --from-beginning  --consumer-property security.protocol=SASL_PLAINTEXT --group tester

$KAFKA_HOME/bin/kafka-console-producer.sh --bootstrap-server k01.com:6667,k02.com:6667,k03.com:6667 --topic mytopic --producer-property security.protocol=SASL_PLAINTEXT
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Kafka 开启了 Kerberos 认证后,连接 ZooKeeper 需要进行以下步骤: 1. 配置 Kafka 服务器以使用 Kerberos 认证。在 Kafka 配置文件(通常是 `server.properties`)中,添加以下属性: ``` listeners=SASL_PLAINTEXT://<Kafka_server_host>:<Kafka_server_port> security.inter.broker.protocol=SASL_PLAINTEXT sasl.mechanism.inter.broker.protocol=GSSAPI sasl.kerberos.service.name=kafka ``` 2. 配置 ZooKeeper 服务器以支持 Kerberos 认证。在 ZooKeeper 配置文件(通常是 `zoo.cfg`)中,添加以下属性: ``` authProvider.1=org.apache.zookeeper.server.auth.SASLAuthenticationProvider requireClientAuthScheme=sasl jaasLoginRenew=3600000 jaasLoginRefresh=3600000 ``` 3. 生成 Kafka 和 ZooKeeper 的 Kerberos Keytab 文件。Keytab 文件包含了用于服务认证的凭证信息。可以使用 `kadmin` 命令行工具生成 Keytab 文件。 4. 在 Kafka 服务器上配置 Kerberos 客户端。将 Kafka 和 ZooKeeper 相关的 Keytab 文件分发到 Kafka 服务器上,并配置 Kerberos 客户端以使用这些文件。 5. 启动 Kafka 服务器和 ZooKeeper 服务器。确保 Kafka 服务器和 ZooKeeper 服务器都已正确配置并启动。 6. 使用 Kafka 客户端连接到 ZooKeeper。在代码中,使用适当的配置和认证信息创建 Kafka 客户端,并指定 ZooKeeper 的连接字符串,例如: ```java Properties props = new Properties(); props.put("bootstrap.servers", "<Kafka_server_host>:<Kafka_server_port>"); props.put("security.protocol", "SASL_PLAINTEXT"); props.put("sasl.kerberos.service.name", "kafka"); props.put("group.id", "<consumer_group_id>"); KafkaConsumer<String, String> consumer = new KafkaConsumer<>(props); consumer.subscribe(Arrays.asList("<topic_name>")); while (true) { ConsumerRecords<String, String> records = consumer.poll(Duration.ofMillis(100)); // 处理消费记录 } ``` 请注意,上述步骤是一个基本的指南,实际操作中可能会有其他配置和设置需求。详细的步骤和配置可以参考 Kafka 和 ZooKeeper 的官方文档。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值