所以我在Google Kubernetes Engine上有一个集群节点,我做spark-submit来运行一些spark作业。(我没有使用spark-submit,我使用java代码启动submit,但它们本质上调用了相同的Scala类,即SparkSubmit.class)
在我的例子中,我有两个集群,我可以通过使用gcloud命令在我的笔记本电脑上连接它们。
例如
gcloud container clusters get-credentials cluster-1
gcloud container clusters get-credentials cluster-2
当我连接到cluster-1时,spark-submit正在提交到cluster-1,它可以工作。但是当我运行第二个gcloud命令并仍然提交到cluster-1时,它不起作用,并出现以下堆栈跟踪(删节版)
io.fabric8.kubernetes.client.KubernetesClientException: Failed to start websocket
at io.fabric8.kubernetes.client.dsl.internal.WatchConnectionManager$2.onFailure(WatchConnectionManager.java:194)
at okhttp3.internal.ws.RealWebSocket.failWebSocket(RealWebSocket.java:543)
at okhttp3.internal.ws.RealWebSocket$2.onFailure(RealWebSocket.java:208)
at okhttp3.RealCall$AsyncCall.execute(RealCall.java:148)
at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:748)
Caused by: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.security.ssl.Alerts.getSSLException(Alerts.java:192)
at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1949)
at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:302)
at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:296)
at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1514)
at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:216)
我已经找了一段时间没有成功。主要问题可能是当spark-submit启动时,它会在本地机器上搜索与Kubernetes相关的某种凭证,而前两个gcloud命令更改的上下文将其搞乱。
我只是好奇,当我们进行spark提交时,远程K8s服务器是如何知道我是谁的?所有这些都涉及到什么认证过程?
先谢谢你。
2条答案
按热度按时间vcirk6k61#
PKIX path building failed
错误意味着Java尝试打开SSL连接,但无法找到验证服务器提供的证书的证书链(路径)。您正在运行的代码不信任群集提供的证书。群集可能使用自签名证书。
从命令行运行时,Java在位于jre/lib/security/cacerts的信任库中查找链。作为较大环境(Tomcat、Glassfish等)的一部分运行时,它将使用该环境的证书信任库。
由于您是手动启动spark_submit的,因此可能会缺少一个选项来指定在何处查找密钥库(服务器证书和私钥)和信任库(CA证书)。这些通常被指定为:
如果您运行的是Java 9+,则还需要指定StoreType:
直到Java 8,密钥库一直是JKS。从Java 9开始,它们也可以是PKCS 12。
对于自签名密钥,您可以将其从密钥库导出,并将其作为受信任证书导入到信任库中。有几个网站提供了如何做到这一点的说明。我觉得Jakob Jenkov's site非常可读。
0pizxfdo2#
如果您想了解
gcloud container clusters get-credentials cluster-1
命令的功能,可以重新从头开始并查看~/.kube/config
的内容有些东西可能不匹配或冲突。或者用户/上下文。也许您具有两个群集的凭据,但您正在使用
cluster-1
的上下文访问cluster-2
~/.kube/config
文件的结构应该如下所示:在代码中,它看起来像是使用了
io.fabric8.kubernetes.client.KubernetesClient
库。例如,在此文件KubernetesDriverBuilder.scala中