【问题标题】:Java Client - Accessing Kubernetes cluster and MQ cluster over SSLJava Client - 通过 SSL 访问 Kubernetes 集群和 MQ 集群
【发布时间】:2019-09-05 21:16:01
【问题描述】:

拥有一个 Java 客户端应用程序,它可以通过 SSL 使用 io.kubernetes.client.ApiClient 自行连接到 Kubernetes 集群。同一个 Java 客户端应用程序也可以自己通过 SSL 连接到 MQ 集群。但是,同一个应用程序无法同时连接到 SSL 上的 Kubernetes 集群和 MQ 集群。

我相信这可能是因为任何时候都只能在 JVM 上配置一个 SSL 密钥/信任库?但不知道解决这个问题的最佳方法是什么。

让 Java 客户端通过 SSL 连接到 Kubernetes 集群和 MQ 集群的最简单方法是什么?

本文中显示的两种配置在同时运行时会引发以下错误:

WARN  io.kubernetes.client.util.credentials.ClientCertificateAuthentication - Could not create key manager for Client Certificate authentication.
java.security.UnrecoverableKeyException: Cannot recover key

客户端应用程序的Kubernetes部分通过如下配置连接到Kubernetes集群:

String kubeConfigPath = "~/.kube/config";
apiClient = ClientBuilder.kubeconfig(
                    KubeConfig.loadKubeConfig(new FileReader(kubeConfigPath))).build();
apiClient.getHttpClient().setReadTimeout(0, TimeUnit.SECONDS);
            Configuration.setDefaultApiClient(apiClient);

客户端应用的Mq部分通过如下配置连接MQ集群:

System.setProperty("javax.net.ssl.trustStore", "C:\\tmp\\ssl\\dev\\mgr_mq.jks");
System.setProperty("javax.net.ssl.trustStorePassword", "password");
System.setProperty("javax.net.ssl.keyStore", "C:\\tmp\\ssl\\dev\\mgr_mq.jks");
System.setProperty("javax.net.ssl.keyStorePassword", "password");
System.setProperty("com.ibm.mq.cfg.useIBMCipherMappings", "false");

java.net.URL ccdt = new URL("file:./config/qmgrs/mgr/AMQCLCHL.TAB");
MQQueueManager mqQueueManager = new MQQueueManager("*mgr", ccdt);

【问题讨论】:

  • 单独使用 kubernetes 使用什么密钥库?
  • 对于 kubernetes,配置是一个 YAML 配置文件,它引用了一个客户端证书 .crt 文件和一个客户端密钥 .key 文件。
  • 你能不能把客户端证书放在mgr_mq.jks文件里看看会不会被kubernetes取走?另外,如果信任库指向与密钥库相同的文件,则无需指定信任库。
  • 我当然可以试试这个。您知道是否需要使用特定标签或别名添加客户端证书?或者任何字符串都可以?
  • 我认为任何字符串都可以。 Java 将提供与您要连接的 TLS 服务器提供的受信任签名者匹配的证书,它不基于标签。

标签: java kubernetes ssl-certificate ibm-mq


【解决方案1】:

Kubernetes java client API code 似乎强制将.kube/config 中引用的证书添加到一个新的信任库中,它每次在向它添加证书之前都会创建新的。

这似乎发生在ClientCertifiacteAuthentication.java类'provide(ApiClient client)方法中:

final KeyManager[] keyManagers = SSLUtils.keyManagers(certificate, key, algo, "", null, null);

其中两个 null 值是 keyStoreFile 和 keyStorePassphrase 然后强制在其中创建一个新的信任库。

所以现在为了证明解决方案是可能的,我已经将这个类重写为:

final KeyManager[] keyManagers = SSLUtils.keyManagers(certificate, key, algo, "password", "C:\\tmp\\ssl\\dev\\mgr_mq.jks", "password");

使用此覆盖代码,Kubernetes 集群和 MQ 集群都可以通过 SSL 在同一个 JVM 中成功连接。

【讨论】:

    猜你喜欢
    • 2018-07-02
    • 2023-03-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-28
    • 2022-01-26
    • 2023-03-15
    • 2020-05-24
    相关资源
    最近更新 更多