Skip to content

Commit 0246ea1

Browse files
committed
[SPARK-25809][K8S] Further simplify code
- Combine cloud backends into one - Remove unecessary manipulation of System properties - Documentation tweaks - Ensure we clean up Spark Master URL when overriding master URL in KubeConfigBackend - Reuse utils method from Spark Core rather than duplicating in integration tests module - Fix Bash indentation issues - Insert extra new line prior to error output
1 parent 8d40937 commit 0246ea1

File tree

8 files changed

+90
-142
lines changed

8 files changed

+90
-142
lines changed

resource-managers/kubernetes/integration-tests/README.md

Lines changed: 61 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -26,38 +26,40 @@ The main useful options are outlined below.
2626

2727
## Using a different backend
2828

29-
The integration test backend i.e. the K8S cluster used for testing is controlled by the `--deploy-mode` option. By default this
30-
is set to `minikube`, the available backends are their perquisites are as follows.
29+
The integration test backend i.e. the K8S cluster used for testing is controlled by the `--deploy-mode` option. By
30+
default this is set to `minikube`, the available backends are their perequisites are as follows.
3131

3232
### `minikube`
3333

34-
Uses the local `minikube` cluster, this requires that `minikube` 0.23.0 or greater be installed and that it be allocated at least
35-
4 CPUs and 6GB memory (some users have reported success with as few as 3 CPUs and 4GB memory). The tests will check if `minikube`
36-
is started and abort early if it isn't currently running.
34+
Uses the local `minikube` cluster, this requires that `minikube` 0.23.0 or greater be installed and that it be allocated
35+
at least 4 CPUs and 6GB memory (some users have reported success with as few as 3 CPUs and 4GB memory). The tests will
36+
check if `minikube` is started and abort early if it isn't currently running.
3737

3838
### `docker-for-desktop`
3939

4040
Since July 2018 Docker for Desktop provide an optional Kubernetes cluster that can be enabled as described in this
41-
[blog post](https://blog.docker.com/2018/07/kubernetes-is-now-available-in-docker-desktop-stable-channel/). Assuming this is enabled
42-
using this backend will auto-configure itself from the `docker-for-desktop` context that Docker creates in your `~/.kube/config` file.
43-
If your config file is in a different location you should set the `KUBECONFIG` environment variable appropriately.
41+
[blog post](https://blog.docker.com/2018/07/kubernetes-is-now-available-in-docker-desktop-stable-channel/). Assuming
42+
this is enabled using this backend will auto-configure itself from the `docker-for-desktop` context that Docker creates
43+
in your `~/.kube/config` file. If your config file is in a different location you should set the `KUBECONFIG`
44+
environment variable appropriately.
4445

45-
### `cloud` and `cloud-url`
46+
### `cloud`
4647

47-
These closely related backends configure the tests to use an arbitrary Kubernetes cluster running in the cloud or otherwise.
48+
These cloud backend configures the tests to use an arbitrary Kubernetes cluster running in the cloud or otherwise.
4849

49-
The `cloud` backend auto-configures the cluster to use from your K8S config file, this is assumed to be `~/.kube/config` unless the
50-
`KUBECONFIG` environment variable is set to override this location. By default this will use whatever your current context is in the
51-
config file, to use an alternative context from your config file you can specify the `--context <context>` flag with the desired context.
50+
The `cloud` backend auto-configures the cluster to use from your K8S config file, this is assumed to be `~/.kube/config`
51+
unless the `KUBECONFIG` environment variable is set to override this location. By default this will use whatever your
52+
current context is in the config file, to use an alternative context from your config file you can specify the
53+
`--context <context>` flag with the desired context.
5254

53-
The `cloud-url` backend configures the cluster to simply use a K8S master URL, this should be supplied via the
54-
`--spark-master <master-url>` flag.
55+
You can optionally use a different K8S master URL than the one your K8S config file specified, this should be supplied
56+
via the `--spark-master <master-url>` flag.
5557

5658
## Re-using Docker Images
5759

5860
By default, the test framework will build new Docker images on every test execution. A unique image tag is generated,
59-
and it is written to file at `target/imageTag.txt`. To reuse the images built in a previous run, or to use a Docker image tag
60-
that you have built by other means already, pass the tag to the test script:
61+
and it is written to file at `target/imageTag.txt`. To reuse the images built in a previous run, or to use a Docker
62+
image tag that you have built by other means already, pass the tag to the test script:
6163

6264
dev/dev-run-integration-tests.sh --image-tag <tag>
6365

@@ -67,34 +69,40 @@ where if you still want to use images that were built before by the test framewo
6769

6870
## Spark Distribution Under Test
6971

70-
The Spark code to test is handed to the integration test system via a tarball. Here is the option that is used to specify the tarball:
72+
The Spark code to test is handed to the integration test system via a tarball. Here is the option that is used to
73+
specify the tarball:
7174

7275
* `--spark-tgz <path-to-tgz>` - set `<path-to-tgz>` to point to a tarball containing the Spark distribution to test.
7376

74-
This Tarball should be created by first running `dev/make-distribution.sh` passing the `--tgz` flag and `-Pkubernetes` as one of the
75-
options to ensure that Kubernetes support is included in the distribution. For more details on building a runnable distribution please
76-
see the [Building Spark](https://spark.apache.org/docs/latest/building-spark.html#building-a-runnable-distribution) documentation.
77+
This Tarball should be created by first running `dev/make-distribution.sh` passing the `--tgz` flag and `-Pkubernetes`
78+
as one of the options to ensure that Kubernetes support is included in the distribution. For more details on building a
79+
runnable distribution please see the
80+
[Building Spark](https://spark.apache.org/docs/latest/building-spark.html#building-a-runnable-distribution)
81+
documentation.
7782

78-
**TODO:** Don't require the packaging of the built Spark artifacts into this tarball, just read them out of the current tree.
83+
**TODO:** Don't require the packaging of the built Spark artifacts into this tarball, just read them out of the current
84+
tree.
7985

8086
## Customizing the Namespace and Service Account
8187

82-
If no namespace is specified then a temporary namespace will be created and deleted during the test run. Similarly if no service
83-
account is specified then the `default` service account for the namespace will be used.
88+
If no namespace is specified then a temporary namespace will be created and deleted during the test run. Similarly if
89+
no service account is specified then the `default` service account for the namespace will be used.
8490

85-
Using the `--namespace <namespace>` flag sets `<namespace>` to the namespace in which the tests should be run. If this is supplied
86-
then the tests assume this namespace exists in the K8S cluster and will not attempt to create it. Additionally this namespace must
87-
have an appropriately authorized service account which can be customised via the `--service-account` flag.
91+
Using the `--namespace <namespace>` flag sets `<namespace>` to the namespace in which the tests should be run. If this
92+
is supplied then the tests assume this namespace exists in the K8S cluster and will not attempt to create it.
93+
Additionally this namespace must have an appropriately authorized service account which can be customised via the
94+
`--service-account` flag.
8895

89-
The `--service-account <service account name>` flag sets `<service account name>` to the name of the Kubernetes service account to
90-
use in the namespace specified by the `--namespace` flag. The service account is expected to have permissions to get, list, watch,
91-
and create pods. For clusters with RBAC turned on, it's important that the right permissions are granted to the service account
92-
in the namespace through an appropriate role and role binding. A reference RBAC configuration is provided in `dev/spark-rbac.yaml`.
96+
The `--service-account <service account name>` flag sets `<service account name>` to the name of the Kubernetes service
97+
account to use in the namespace specified by the `--namespace` flag. The service account is expected to have permissions
98+
to get, list, watch, and create pods. For clusters with RBAC turned on, it's important that the right permissions are
99+
granted to the service account in the namespace through an appropriate role and role binding. A reference RBAC
100+
configuration is provided in `dev/spark-rbac.yaml`.
93101

94102
# Running the Test Directly
95103

96-
If you prefer to run just the integration tests directly then you can customise the behaviour via properties passed to Maven using the
97-
`-Dproperty=value` option e.g.
104+
If you prefer to run just the integration tests directly, then you can customise the behaviour via passing system
105+
properties to Maven. For example:
98106

99107
mvn integration-test -am -pl :spark-kubernetes-integration-tests_2.11 \
100108
-Pkubernetes -Phadoop-2.7 -Dhadoop.version=2.7.3 \
@@ -108,8 +116,8 @@ If you prefer to run just the integration tests directly then you can customise
108116
109117
## Available Maven Properties
110118

111-
The following are the available Maven properties that can be passed. For the most part these correspond to flags passed to the
112-
wrapper scripts and using the wrapper scripts will simply set these appropriately behind the scenes.
119+
The following are the available Maven properties that can be passed. For the most part these correspond to flags passed
120+
to the wrapper scripts and using the wrapper scripts will simply set these appropriately behind the scenes.
113121

114122
<table>
115123
<tr>
@@ -134,63 +142,65 @@ wrapper scripts and using the wrapper scripts will simply set these appropriatel
134142
<tr>
135143
<td><code>spark.kubernetes.test.deployMode</code></td>
136144
<td>
137-
The integration test backend to use. Acceptable values are <code>minikube</code>, <code>docker-for-desktop</code>,
138-
<code>cloud</code> and <code>cloud-url</code>.
145+
The integration test backend to use. Acceptable values are <code>minikube</code>,
146+
<code>docker-for-desktop</code> and <code>cloud</code>.
139147
<td><code>minikube</code></td>
140148
</tr>
141149
<tr>
142150
<td><code>spark.kubernetes.test.kubeConfigContext</code></td>
143151
<td>
144-
When using the <code>cloud</code> backend specifies the context from the users K8S config file that should be used as the
145-
target cluster for integration testing. If not set and using the <code>cloud</code> backend then your current context
146-
will be used.
152+
When using the <code>cloud</code> backend specifies the context from the users K8S config file that should be used
153+
as the target cluster for integration testing. If not set and using the <code>cloud</code> backend then your
154+
current context will be used.
147155
</td>
148156
<td></td>
149157
</tr>
150158
<tr>
151159
<td><code>spark.kubernetes.test.master</code></td>
152160
<td>
153-
When using the <code>cloud-url</code> backend must be specified to indicate the K8S master URL to communicate with.
161+
When using the <code>cloud-url</code> backend must be specified to indicate the K8S master URL to communicate
162+
with.
154163
</td>
155164
<td></td>
156165
</tr>
157166
<tr>
158167
<td><code>spark.kubernetes.test.imageTag</code></td>
159168
<td>
160-
A specific image tag to use, when set assumes images with those tags are already built and available in the specified image
161-
repository. When set to <code>N/A</code> (the default) fresh images will be built.
169+
A specific image tag to use, when set assumes images with those tags are already built and available in the
170+
specified image repository. When set to <code>N/A</code> (the default) fresh images will be built.
162171
</td>
163172
<td><code>N/A</code>
164173
</tr>
165174
<tr>
166175
<td><code>spark.kubernetes.test.imageTagFile</code></td>
167176
<td>
168-
A file containing the image tag to use, if no specific image tag is set then fresh images will be built with a generated
169-
tag and that tag written to this file.
177+
A file containing the image tag to use, if no specific image tag is set then fresh images will be built with a
178+
generated tag and that tag written to this file.
170179
</td>
171180
<td><code>${project.build.directory}/imageTag.txt</code></td>
172181
</tr>
173182
<tr>
174183
<td><code>spark.kubernetes.test.imageRepo</code></td>
175184
<td>
176-
The Docker image repository that contains the images to be used if a specific image tag is set or to which the images will
177-
be pushed to if fresh images are being built.
185+
The Docker image repository that contains the images to be used if a specific image tag is set or to which the
186+
images will be pushed to if fresh images are being built.
178187
</td>
179188
<td><code>docker.io/kubespark</code></td>
180189
</tr>
181190
<tr>
182191
<td><code>spark.kubernetes.test.namespace</code></td>
183192
<td>
184-
A specific Kubernetes namespace to run the tests in. If specified then the tests assume that this namespace already exists.
185-
When not specified a temporary namespace for the tests will be created and deleted as part of the test run.
193+
A specific Kubernetes namespace to run the tests in. If specified then the tests assume that this namespace
194+
already exists. When not specified a temporary namespace for the tests will be created and deleted as part of the
195+
test run.
186196
</td>
187197
<td></td>
188198
</tr>
189199
<tr>
190200
<td><code>spark.kubernetes.test.serviceAccountName</code></td>
191201
<td>
192-
A specific Kubernetes service account to use for running the tests. If not specified then the namespaces default service
193-
account will be used and that must have sufficient permissions or the tests will fail.
202+
A specific Kubernetes service account to use for running the tests. If not specified then the namespaces default
203+
service account will be used and that must have sufficient permissions or the tests will fail.
194204
</td>
195205
<td></td>
196206
</tr>

resource-managers/kubernetes/integration-tests/scripts/setup-integration-test-env.sh

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ then
7373
cd $UNPACKED_SPARK_TGZ
7474

7575
case $DEPLOY_MODE in
76-
cloud|cloud-url)
76+
cloud)
7777
# Build images
7878
$UNPACKED_SPARK_TGZ/bin/docker-image-tool.sh -r $IMAGE_REPO -t $IMAGE_TAG build
7979

@@ -86,18 +86,18 @@ then
8686
fi
8787
;;
8888

89-
docker-for-desktop)
89+
docker-for-desktop)
9090
# Only need to build as this will place it in our local Docker repo which is all
9191
# we need for Docker for Desktop to work so no need to also push
9292
$UNPACKED_SPARK_TGZ/bin/docker-image-tool.sh -r $IMAGE_REPO -t $IMAGE_TAG build
9393
;;
9494

95-
minikube)
95+
minikube)
9696
# Only need to build and if we do this with the -m option for minikube we will
9797
# build the images directly using the minikube Docker daemon so no need to push
9898
$UNPACKED_SPARK_TGZ/bin/docker-image-tool.sh -m -r $IMAGE_REPO -t $IMAGE_TAG build
9999
;;
100-
*)
100+
*)
101101
echo "Unrecognized deploy mode $DEPLOY_MODE" && exit 1
102102
;;
103103
esac

resource-managers/kubernetes/integration-tests/src/test/scala/org/apache/spark/deploy/k8s/integrationtest/ProcessUtils.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ object ProcessUtils extends Logging {
4141
assert(proc.waitFor(timeout, TimeUnit.SECONDS),
4242
s"Timed out while executing ${fullCommand.mkString(" ")}")
4343
assert(proc.exitValue == 0,
44-
s"Failed to execute ${fullCommand.mkString(" ")}${if (dumpErrors) outputLines.mkString("\n")}")
44+
s"Failed to execute ${fullCommand.mkString(" ")}${if (dumpErrors) "\n" + outputLines.mkString("\n")}")
4545
outputLines
4646
}
4747
}

resource-managers/kubernetes/integration-tests/src/test/scala/org/apache/spark/deploy/k8s/integrationtest/TestConstants.scala

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ object TestConstants {
2020
val BACKEND_MINIKUBE = "minikube"
2121
val BACKEND_DOCKER_FOR_DESKTOP = "docker-for-desktop"
2222
val BACKEND_CLOUD = "cloud"
23-
val BACKEND_CLOUD_URL = "cloud-url"
2423

2524
val CONFIG_KEY_DEPLOY_MODE = "spark.kubernetes.test.deployMode"
2625
val CONFIG_KEY_KUBE_CONFIG_CONTEXT = "spark.kubernetes.test.kubeConfigContext"

resource-managers/kubernetes/integration-tests/src/test/scala/org/apache/spark/deploy/k8s/integrationtest/Utils.scala

Lines changed: 0 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -27,36 +27,4 @@ object Utils extends Logging {
2727
val resource = createResource
2828
try f.apply(resource) finally resource.close()
2929
}
30-
31-
def checkAndGetK8sMasterUrl(rawMasterURL: String): String = {
32-
require(rawMasterURL.startsWith("k8s://"),
33-
"Kubernetes master URL must start with k8s://.")
34-
val masterWithoutK8sPrefix = rawMasterURL.substring("k8s://".length)
35-
36-
// To handle master URLs, e.g., k8s://host:port.
37-
if (!masterWithoutK8sPrefix.contains("://")) {
38-
val resolvedURL = s"https://$masterWithoutK8sPrefix"
39-
logInfo("No scheme specified for kubernetes master URL, so defaulting to https. Resolved " +
40-
s"URL is $resolvedURL.")
41-
return s"k8s://$resolvedURL"
42-
}
43-
44-
val masterScheme = new URI(masterWithoutK8sPrefix).getScheme
45-
val resolvedURL = masterScheme.toLowerCase match {
46-
case "https" =>
47-
masterWithoutK8sPrefix
48-
case "http" =>
49-
logWarning("Kubernetes master URL uses HTTP instead of HTTPS.")
50-
masterWithoutK8sPrefix
51-
case null =>
52-
val resolvedURL = s"https://$masterWithoutK8sPrefix"
53-
logInfo("No scheme specified for kubernetes master URL, so defaulting to https. Resolved " +
54-
s"URL is $resolvedURL.")
55-
resolvedURL
56-
case _ =>
57-
throw new IllegalArgumentException("Invalid Kubernetes master scheme: " + masterScheme)
58-
}
59-
60-
s"k8s://$resolvedURL"
61-
}
6230
}

resource-managers/kubernetes/integration-tests/src/test/scala/org/apache/spark/deploy/k8s/integrationtest/backend/IntegrationTestBackend.scala

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ package org.apache.spark.deploy.k8s.integrationtest.backend
1919

2020
import io.fabric8.kubernetes.client.DefaultKubernetesClient
2121
import org.apache.spark.deploy.k8s.integrationtest.TestConstants._
22-
import org.apache.spark.deploy.k8s.integrationtest.backend.cloud.{KubeConfigBackend, CloudTestBackend}
22+
import org.apache.spark.deploy.k8s.integrationtest.backend.cloud.KubeConfigBackend
2323
import org.apache.spark.deploy.k8s.integrationtest.backend.docker.DockerForDesktopBackend
2424
import org.apache.spark.deploy.k8s.integrationtest.backend.minikube.MinikubeTestBackend
2525

@@ -35,8 +35,7 @@ private[spark] object IntegrationTestBackendFactory {
3535
.getOrElse(BACKEND_MINIKUBE)
3636
deployMode match {
3737
case BACKEND_MINIKUBE => MinikubeTestBackend
38-
case BACKEND_CLOUD => new KubeConfigBackend(null)
39-
case BACKEND_CLOUD_URL => CloudTestBackend
38+
case BACKEND_CLOUD => new KubeConfigBackend(System.getProperty(CONFIG_KEY_KUBE_CONFIG_CONTEXT))
4039
case BACKEND_DOCKER_FOR_DESKTOP => DockerForDesktopBackend
4140
case _ => throw new IllegalArgumentException("Invalid " +
4241
CONFIG_KEY_DEPLOY_MODE + ": " + deployMode)

resource-managers/kubernetes/integration-tests/src/test/scala/org/apache/spark/deploy/k8s/integrationtest/backend/cloud/CloudTestBackend.scala

Lines changed: 0 additions & 40 deletions
This file was deleted.

0 commit comments

Comments
 (0)