GitHub user rvesse opened a pull request:

    https://github.com/apache/spark/pull/22904

    [SPARK-25887][K8S] Configurable K8S context support

    ## What changes were proposed in this pull request?
    
    This enhancement allows for specifying the desired context to use for
    the initial K8S client auto-configuration.  This allows users to more
    easily access alternative K8S contexts without having to first
    explicitly change their current context via kubectl.
    
    ## How was this patch tested?
    
    Explicitly set my K8S context to a context pointing to a non-existent 
cluster, then launched Spark jobs with explicitly specified contexts via the 
new `spark.kubernetes.context` configuration property.
    
    Example Output:
    
    ```
    > kubectl config current-context
    minikube
    > minikube status
    minikube: Stopped
    cluster: 
    kubectl: 
    > ./spark-submit --master k8s://https://localhost:6443 --deploy-mode 
cluster --name spark-pi --class org.apache.spark.examples.SparkPi --conf 
spark.executor.instances=2 --conf spark.kubernetes.context=docker-for-desktop 
--conf spark.kubernetes.container.image=rvesse/spark:debian 
local:///opt/spark/examples/jars/spark-examples_2.11-3.0.0-SNAPSHOT.jar 4
    18/10/31 11:57:51 WARN NativeCodeLoader: Unable to load native-hadoop 
library for your platform... using builtin-java classes where applicable
    18/10/31 11:57:51 INFO SparkKubernetesClientFactory: Auto-configuring K8S 
client using context docker-for-desktop from users K8S config file
    18/10/31 11:57:52 INFO LoggingPodStatusWatcherImpl: State changed, new 
state: 
         pod name: spark-pi-1540987071845-driver
         namespace: default
         labels: spark-app-selector -> spark-2c4abc226ed3415986eb602bd13f3582, 
spark-role -> driver
         pod uid: 32462cac-dd04-11e8-b6c6-025000000001
         creation time: 2018-10-31T11:57:52Z
         service account name: default
         volumes: spark-local-dir-1, spark-conf-volume, default-token-glpfv
         node name: N/A
         start time: N/A
         phase: Pending
         container status: N/A
    18/10/31 11:57:52 INFO LoggingPodStatusWatcherImpl: State changed, new 
state: 
         pod name: spark-pi-1540987071845-driver
         namespace: default
         labels: spark-app-selector -> spark-2c4abc226ed3415986eb602bd13f3582, 
spark-role -> driver
         pod uid: 32462cac-dd04-11e8-b6c6-025000000001
         creation time: 2018-10-31T11:57:52Z
         service account name: default
         volumes: spark-local-dir-1, spark-conf-volume, default-token-glpfv
         node name: docker-for-desktop
         start time: N/A
         phase: Pending
         container status: N/A
    ...
    18/10/31 11:58:03 INFO LoggingPodStatusWatcherImpl: State changed, new 
state: 
         pod name: spark-pi-1540987071845-driver
         namespace: default
         labels: spark-app-selector -> spark-2c4abc226ed3415986eb602bd13f3582, 
spark-role -> driver
         pod uid: 32462cac-dd04-11e8-b6c6-025000000001
         creation time: 2018-10-31T11:57:52Z
         service account name: default
         volumes: spark-local-dir-1, spark-conf-volume, default-token-glpfv
         node name: docker-for-desktop
         start time: 2018-10-31T11:57:52Z
         phase: Succeeded
         container status: 
                 container name: spark-kubernetes-driver
                 container image: rvesse/spark:debian
                 container state: terminated
                 container started at: 2018-10-31T11:57:54Z
                 container finished at: 2018-10-31T11:58:02Z
                 exit code: 0
                 termination reason: Completed
    ```
    
    Without the `spark.kubernetes.context` setting this will fail because the 
current context - `minikube` - is pointing to a non-running cluster e.g.
    
    ```
    > ./spark-submit --master k8s://https://localhost:6443 --deploy-mode 
cluster --name spark-pi --class org.apache.spark.examples.SparkPi --conf 
spark.executor.instances=2 --conf 
spark.kubernetes.container.image=rvesse/spark:debian 
local:///opt/spark/examples/jars/spark-examples_2.11-3.0.0-SNAPSHOT.jar 4
    18/10/31 12:02:30 WARN NativeCodeLoader: Unable to load native-hadoop 
library for your platform... using builtin-java classes where applicable
    18/10/31 12:02:30 INFO SparkKubernetesClientFactory: Auto-configuring K8S 
client using current context from users K8S config file
    18/10/31 12:02:31 WARN WatchConnectionManager: Exec Failure
    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:1509)
        at 
sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:216)
        at sun.security.ssl.Handshaker.processLoop(Handshaker.java:979)
        at sun.security.ssl.Handshaker.process_record(Handshaker.java:914)
        at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1062)
        at 
sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1375)
        at 
sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1403)
        at 
sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1387)
        at 
okhttp3.internal.connection.RealConnection.connectTls(RealConnection.java:281)
        at 
okhttp3.internal.connection.RealConnection.establishProtocol(RealConnection.java:251)
        at 
okhttp3.internal.connection.RealConnection.connect(RealConnection.java:151)
        at 
okhttp3.internal.connection.StreamAllocation.findConnection(StreamAllocation.java:195)
        at 
okhttp3.internal.connection.StreamAllocation.findHealthyConnection(StreamAllocation.java:121)
        at 
okhttp3.internal.connection.StreamAllocation.newStream(StreamAllocation.java:100)
        at 
okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.java:42)
        at 
okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
        at 
okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67)
        at 
okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.java:93)
        at 
okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
        at 
okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67)
        at 
okhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.java:93)
        at 
okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
        at 
okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.java:120)
        at 
okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
        at 
okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67)
        at 
io.fabric8.kubernetes.client.utils.BackwardsCompatibilityInterceptor.intercept(BackwardsCompatibilityInterceptor.java:119)
        at 
okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
        at 
okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67)
        at 
io.fabric8.kubernetes.client.utils.ImpersonatorInterceptor.intercept(ImpersonatorInterceptor.java:66)
        at 
okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
        at 
okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67)
        at 
io.fabric8.kubernetes.client.utils.HttpClientUtils$2.intercept(HttpClientUtils.java:109)
        at 
okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
        at 
okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67)
        at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:185)
        at okhttp3.RealCall$AsyncCall.execute(RealCall.java:135)
        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:745)
    Caused by: 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.validator.PKIXValidator.doBuild(PKIXValidator.java:387)
        at 
sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:292)
        at sun.security.validator.Validator.validate(Validator.java:260)
        at 
sun.security.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:324)
        at 
sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:229)
        at 
sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:124)
        at 
sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1491)
        ... 39 more
    Caused by: sun.security.provider.certpath.SunCertPathBuilderException: 
unable to find valid certification path to requested target
        at 
sun.security.provider.certpath.SunCertPathBuilder.build(SunCertPathBuilder.java:141)
        at 
sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:126)
        at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:280)
        at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:382)
        ... 45 more
    Exception in thread "kubernetes-dispatcher-0" Exception in thread "main" 
java.util.concurrent.RejectedExecutionException: Task 
java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask@611a9c09 
rejected from 
java.util.concurrent.ScheduledThreadPoolExecutor@404819e4[Terminated, pool size 
= 0, active threads = 0, queued tasks = 0, completed tasks = 0]
        at 
java.util.concurrent.ThreadPoolExecutor$AbortPolicy.rejectedExecution(ThreadPoolExecutor.java:2047)
        at 
java.util.concurrent.ThreadPoolExecutor.reject(ThreadPoolExecutor.java:823)
        at 
java.util.concurrent.ScheduledThreadPoolExecutor.delayedExecute(ScheduledThreadPoolExecutor.java:326)
        at 
java.util.concurrent.ScheduledThreadPoolExecutor.schedule(ScheduledThreadPoolExecutor.java:533)
        at 
java.util.concurrent.ScheduledThreadPoolExecutor.submit(ScheduledThreadPoolExecutor.java:632)
        at 
java.util.concurrent.Executors$DelegatedExecutorService.submit(Executors.java:678)
        at 
io.fabric8.kubernetes.client.dsl.internal.WatchConnectionManager.scheduleReconnect(WatchConnectionManager.java:300)
        at 
io.fabric8.kubernetes.client.dsl.internal.WatchConnectionManager.access$800(WatchConnectionManager.java:48)
        at 
io.fabric8.kubernetes.client.dsl.internal.WatchConnectionManager$2.onFailure(WatchConnectionManager.java:213)
        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:745)
    io.fabric8.kubernetes.client.KubernetesClientException: Failed to start 
websocket
        at 
io.fabric8.kubernetes.client.dsl.internal.WatchConnectionManager$2.onFailure(WatchConnectionManager.java:204)
        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:745)
    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:1509)
        at 
sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:216)
        at sun.security.ssl.Handshaker.processLoop(Handshaker.java:979)
        at sun.security.ssl.Handshaker.process_record(Handshaker.java:914)
        at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1062)
        at 
sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1375)
        at 
sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1403)
        at 
sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1387)
        at 
okhttp3.internal.connection.RealConnection.connectTls(RealConnection.java:281)
        at 
okhttp3.internal.connection.RealConnection.establishProtocol(RealConnection.java:251)
        at 
okhttp3.internal.connection.RealConnection.connect(RealConnection.java:151)
        at 
okhttp3.internal.connection.StreamAllocation.findConnection(StreamAllocation.java:195)
        at 
okhttp3.internal.connection.StreamAllocation.findHealthyConnection(StreamAllocation.java:121)
        at 
okhttp3.internal.connection.StreamAllocation.newStream(StreamAllocation.java:100)
        at 
okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.java:42)
        at 
okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
        at 
okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67)
        at 
okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.java:93)
        at 
okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
        at 
okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67)
        at 
okhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.java:93)
        at 
okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
        at 
okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.java:120)
        at 
okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
        at 
okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67)
        at 
io.fabric8.kubernetes.client.utils.BackwardsCompatibilityInterceptor.intercept(BackwardsCompatibilityInterceptor.java:119)
        at 
okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
        at 
okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67)
        at 
io.fabric8.kubernetes.client.utils.ImpersonatorInterceptor.intercept(ImpersonatorInterceptor.java:66)
        at 
okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
        at 
okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67)
        at 
io.fabric8.kubernetes.client.utils.HttpClientUtils$2.intercept(HttpClientUtils.java:109)
        at 
okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
        at 
okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67)
        at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:185)
        at okhttp3.RealCall$AsyncCall.execute(RealCall.java:135)
        ... 4 more
    Caused by: 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.validator.PKIXValidator.doBuild(PKIXValidator.java:387)
        at 
sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:292)
        at sun.security.validator.Validator.validate(Validator.java:260)
        at 
sun.security.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:324)
        at 
sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:229)
        at 
sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:124)
        at 
sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1491)
        ... 39 more
    Caused by: sun.security.provider.certpath.SunCertPathBuilderException: 
unable to find valid certification path to requested target
        at 
sun.security.provider.certpath.SunCertPathBuilder.build(SunCertPathBuilder.java:141)
        at 
sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:126)
        at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:280)
        at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:382)
        ... 45 more
    18/10/31 12:02:31 INFO ShutdownHookManager: Shutdown hook called
    18/10/31 12:02:31 INFO ShutdownHookManager: Deleting directory 
/private/var/folders/6b/y1010qp107j9w2dhhy8csvz0000xq3/T/spark-5e649891-8a0f-4f17-bf3a-33b34082eba8
    ```
    
    Suggested reviews: @mccheah @liyinan926 - this is the follow up fix to the 
bug discovered while working on SPARK-25809 (PR #22805)

You can merge this pull request into a Git repository by running:

    $ git pull https://github.com/rvesse/spark SPARK-25887

Alternatively you can review and apply these changes as the patch at:

    https://github.com/apache/spark/pull/22904.patch

To close this pull request, make a commit to your master/trunk branch
with (at least) the following in the commit message:

    This closes #22904
    
----
commit 670ece9d44b1d496eb92c390f96ae1d2a1ad6518
Author: Rob Vesse <rvesse@...>
Date:   2018-10-31T11:07:31Z

    [SPARK-25887][K8S] Configurable K8S context support
    
    This enhancement allows for specifying the desired context to use for
    the initial K8S client auto-configuration.  This allows users to more
    easily access alternative K8S contexts without having to first
    explicitly change their current context via kubectl.

----


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscr...@spark.apache.org
For additional commands, e-mail: reviews-h...@spark.apache.org

Reply via email to