对 Kafka TLS/SSL 连接问题进行故障排除

将 Vertica、Kafka 和调度程序配置为使用 TLS/SSL 身份验证和加密后,可能会遇到数据流式传输问题。此部分介绍您可能会遇到的一些常见错误,以及如何对这些错误进行故障排除。

启动调度程序时出错

启动调度程序时,可能会显示如下错误:

$ vkconfig launch --conf weblog.conf
java.sql.SQLNonTransientException: com.vertica.solutions.kafka.exception.ConfigurationException:
       No keystore system property found: null
    at com.vertica.solutions.kafka.util.SQLUtilities.getConnection(SQLUtilities.java:181)
    at com.vertica.solutions.kafka.cli.CLIUtil.assertDBConnectionWorks(CLIUtil.java:40)
    at com.vertica.solutions.kafka.Launcher.run(Launcher.java:135)
    at com.vertica.solutions.kafka.Launcher.main(Launcher.java:263)
Caused by: com.vertica.solutions.kafka.exception.ConfigurationException: No keystore system property found: null
    at com.vertica.solutions.kafka.security.KeyStoreUtil.loadStore(KeyStoreUtil.java:77)
    at com.vertica.solutions.kafka.security.KeyStoreUtil.<init>(KeyStoreUtil.java:42)
    at com.vertica.solutions.kafka.util.SQLUtilities.getConnection(SQLUtilities.java:179)
    ... 3 more

当调度程序找不到或无法读取密钥库或信任库文件时,就会引发这些错误。要解决此问题,请执行以下操作:

  • 验证是否已设置 VKCONFIG_JVM_OPTS Linux 环境变量。如果没有此变量,调度程序将不知道在何处找到创建 TLS/SSL 连接时要使用的信任库和密钥库。请参阅步骤 2:设置 VKCONFIG_JVM_OPTS 环境变量以了解详细信息。

  • 验证密钥库和信任库文件是否位于在 VKCONFIG_JVM_OPTS 环境变量中设置的路径中。

  • 验证运行调度程序的用户帐户是否对信任库和密钥库文件具有读取权限。

  • 验证在调度程序配置中提供的密钥密码是否正确。请注意,必须提供密钥的密码,而非密钥库。

另一个可能的错误消息是无法设置 TLS 密钥库:

Exception in thread "main" java.sql.SQLRecoverableException: [Vertica][VJDBC](100024) IOException while communicating with server: java.io.IOException: Failed to create an SSLSocketFactory when setting up TLS: keystore not found.
        at com.vertica.io.ProtocolStream.logAndConvertToNetworkException(Unknown Source)
        at com.vertica.io.ProtocolStream.enableSSL(Unknown Source)
        at com.vertica.io.ProtocolStream.initSession(Unknown Source)
        at com.vertica.core.VConnection.tryConnect(Unknown Source)
        at com.vertica.core.VConnection.connect(Unknown Source)
        . . .

使用非 JKS 格式的密钥库或信任库文件以及未提供正确的文件扩展名可能会导致此错误。如果调度程序无法识别密钥库或信任库文件名的文件扩展名,它会假设该文件采用 JKS 格式。如果该文件不是采用此格式,调度程序将退出并显示如上所示的错误消息。要更正此错误,请重命名密钥库和信任库文件,以使用正确的文件扩展名。例如,如果文件采用 PKCS 12 文件格式,请将其文件扩展名更改为 .p12.pks

数据不加载

如果您发现调度程序未将数据加载到数据库,应先查询 stream_microbatch_history 表以确定调度程序是否正在执行微批处理。如果是,请记录其结果。错误的 TLS/SSL 配置通常会导致出现 NETWORK_ISSUE 状态:

=> SELECT frame_start, end_reason, end_reason_message FROM weblog_sched.stream_microbatch_history;
       frame_start       |  end_reason   | end_reason_message
-------------------------+---------------+--------------------
 2019-04-05 11:35:18.365 | NETWORK_ISSUE |
 2019-04-05 11:35:38.462 | NETWORK_ISSUE |

如果您怀疑是 SSL 问题,可通过查看 Kafka 的 server.log 文件来验证 Vertica 是否正在建立与 Kafka 的连接。失败的 SSL 连接尝试会显示在此日志中,如以下示例所示:

java.io.IOException: Unexpected status returned by SSLEngine.wrap, expected
        CLOSED, received OK. Will not send close message to peer.
        at org.apache.kafka.common.network.SslTransportLayer.close(SslTransportLayer.java:172)
        at org.apache.kafka.common.utils.Utils.closeAll(Utils.java:703)
        at org.apache.kafka.common.network.KafkaChannel.close(KafkaChannel.java:61)
        at org.apache.kafka.common.network.Selector.doClose(Selector.java:739)
        at org.apache.kafka.common.network.Selector.close(Selector.java:727)
        at org.apache.kafka.common.network.Selector.pollSelectionKeys(Selector.java:520)
        at org.apache.kafka.common.network.Selector.poll(Selector.java:412)
        at kafka.network.Processor.poll(SocketServer.scala:551)
        at kafka.network.Processor.run(SocketServer.scala:468)
        at java.lang.Thread.run(Thread.java:748)

如果未看到此类错误,则可能是 Kafka 与 Vertica 之间存在网络问题。如果确实看到这些错误,请考虑执行以下调试步骤:

  • 验证 Kafka 群集的配置是否一致。例如,如果将某些 Kafka 节点设置为需要进行客户端身份验证,而其他节点不需要,则可能会看到连接错误。

  • 验证证书和密钥中的公用名称 (CN) 是否与系统的主机名相匹配。

  • 验证 Kafka 群集是否接受使用在 server.properties 文件的侦听器属性中指定的端口和主机名建立的连接。例如,假设在此设置中使用 IP 地址,但在调度程序的配置中定义群集时使用主机名。那么,Kafka 可能会拒绝 Vertica 进行的连接尝试,或者 Vertica 可能会拒绝 Kafka 节点的身份。

  • 如果在 Kafka 中使用客户端身份验证,请尝试关闭它以查看调度程序是否可以连接。如果禁用身份验证后,调度程序可以流式传输数据,则可以证明该问题与客户端身份验证无关。在这种情况下,请查看 Kafka 群集和调度程序的证书与 CA。确保信任库包括用于对密钥进行签名的所有 CA,直到并包括根 CA。

Avro 架构注册表和 KafkaAvroParser

要在 Avro 架构注册表与 Vertica 之间创建 TLS 连接,KafkaAvroParser 至少需要以下参数:

  • schema_registry_url (对于 https 方案)

  • schema_registry_ssl_ca_path

当且仅当 TLS 访问失败时,请根据以下对象确定 Vertica 需要哪些 TLS 架构注册表信息:

  • 证书颁发机构 (CA)

  • TLS 服务器证书

  • TLS 密钥

仅使用 KafkaAvroParser 参数提供必需的 TLS 架构注册表信息。必须能够在处理 Avro 数据的每个 Vertica 节点的文件系统中访问 TLS 信息。

以下示例显示如何将这些参数传递给 KafkaAvroParser:

KafkaAvroParser(
    schema_registry_url='https://localhost:8081'
    schema_registry_ssl_ca_path='path/to/certificate-authority',
    schema_registry_ssl_cert_path='path/to/tls-server-certificate',
    schema_registry_ssl_key_path='path/to/private-tls-key',
    schema_registry_ssl_key_password_path='path/to/private-tls-key-password'
)