Integrate the REST Submitter¶
By default, the Spark Operator invokes the spark-submit CLI for each Spark application
submission. Each invocation starts two JVM processes in the controller pod. Those processes use
the pod’s limited CPU and memory, so a burst of applications can increase submission latency.
With REST submission, the operator sends a request for each application to a separate service.
The service creates the driver pod through the Kubernetes API without starting spark-submit in
the controller pod. This avoids CLI startup overhead and can start applications faster. The service
can also scale horizontally to handle bursts, leaving more controller resources for
SparkApplication lifecycle management. For more details about the service, see the
submitter documentation.
This guide walks you through deploying the REST submitter service and integrating it with the Spark Operator.
Note
REST submission is an alpha feature. Enable the RestSubmitter feature gate to use it.
Prerequisites¶
Complete the Getting Started prerequisites. If the operator is already installed, have its Helm release name and current values file ready. You can also enable REST submission when installing the operator for the first time.
Installation¶
In these examples, each Helm release has the same name as its namespace: spark-operator or
spark-submitter. Adjust the names to match your installation.
Deploy the submitter service¶
The chart installs a submitter Deployment, Service, ServiceAccount, and RBAC. It starts one pod by
default. Increase replicas and enable a PodDisruptionBudget if you need multiple pods.
Clone the submitter repository to get its Helm chart. Run the remaining commands from the clone’s parent directory:
git clone https://github.com/venkomirisetti/k8s-spark-submitter.git
Save the following as submitter-values.yaml:
image:
tag: "<submitter-image-tag>"
volumeMounts:
- name: submitter-tmp
mountPath: /tmp
volumes:
- name: submitter-tmp
emptyDir: {}
Set the values for your installation:
Value |
What to set |
|---|---|
|
Choose a tag from the submitter images that matches the Spark version in your operator image and supports your cluster’s node architecture. Set |
|
Keep the writable |
|
List the namespaces where the submitter may create driver resources. If omitted, the chart grants cluster-wide RBAC. See the submitter RBAC settings. |
Install the chart:
helm install spark-submitter ./k8s-spark-submitter/charts/spark-submitter \
--namespace spark-submitter \
--create-namespace \
--values submitter-values.yaml
For an existing submitter release, use helm upgrade instead. Check that the deployment is ready
before configuring the operator:
kubectl -n spark-submitter rollout status deployment/spark-submitter
Enable REST submission in the operator¶
The operator needs the submitter’s full Service URL. Add these settings to your operator values
file, called operator-values.yaml here. Keep any other enabled feature gates in
controller.featureGates:
controller:
featureGates:
- name: RestSubmitter
enabled: true
submitter:
serviceUrl: http://spark-submitter-svc.spark-submitter.svc.cluster.local:8080/api/v1/spark-submit
Set submitter.serviceUrl to the full submit endpoint URL for your submitter Service. The
operator chart values
list optional startup timeout, request timeout, and retry settings.
For an existing operator release, upgrade it with its complete values file:
helm upgrade spark-operator spark-operator/spark-operator \
--namespace spark-operator \
--values operator-values.yaml
For a new operator installation, follow Getting Started
and pass --values operator-values.yaml to helm install. The controller must be able to reach the
submitter Service when it starts. Check the release and controller deployment:
helm status --namespace spark-operator spark-operator
kubectl -n spark-operator rollout status deployment/spark-operator-controller
kubectl -n spark-operator logs deployment/spark-operator-controller | \
grep 'Using REST submitter service'
The log line confirms that the controller selected REST submission. To verify a submission, run a
SparkApplication as described in Getting Started
and check its status. Application manifests and lifecycle management stay the same.
Enable mTLS¶
By default, the operator and submitter communicate over HTTP. Both support mTLS, but the operator
chart does not expose the controller’s TLS flags. To enable mTLS, mount certificates in both pods,
pass the TLS flags to the controller, and change submitter.serviceUrl to HTTPS.
Required certificates¶
Component |
Certificate and key |
Trusted CA |
|---|---|---|
REST submitter |
Server certificate and private key |
CA that signed the operator’s client certificate |
Operator |
Client certificate and private key |
CA that signed the submitter’s server certificate |
The server certificate must include the DNS name in submitter.serviceUrl, such as
spark-submitter-svc.spark-submitter.svc.cluster.local. The server key must be in PKCS#8 PEM
format.
Create and mount Kubernetes Secrets¶
Create spark-submitter-tls in the submitter namespace for the server certificate and
spark-submitter-client-tls in the operator namespace for the client certificate. If you use
cert-manager, add two Certificate resources with these Secret names, using the operator chart’s
existing webhook certificate configuration
as a reference. Set spec.privateKey.encoding: PKCS8 for the server certificate. Otherwise, create
the Secrets from your certificate files using the commands below. Replace the /path/to/ paths
with your certificate file paths:
kubectl -n spark-submitter create secret generic spark-submitter-tls \
--from-file=tls.crt=/path/to/server.crt \
--from-file=tls.key=/path/to/server.key \
--from-file=ca.crt=/path/to/client-ca.crt
kubectl -n spark-operator create secret generic spark-submitter-client-tls \
--from-file=tls.crt=/path/to/client.crt \
--from-file=tls.key=/path/to/client.key \
--from-file=ca.crt=/path/to/server-ca.crt
Mount the server Secret in the submitter pod. In submitter-values.yaml, keep the existing /tmp
mount:
volumeMounts:
- name: submitter-tmp
mountPath: /tmp
- name: submitter-tls
mountPath: /etc/submitter-tls
readOnly: true
volumes:
- name: submitter-tmp
emptyDir: {}
- name: submitter-tls
secret:
secretName: spark-submitter-tls
Mount the client Secret in the controller pod. In operator-values.yaml, keep the existing /tmp
mount:
controller:
volumeMounts:
- name: tmp
mountPath: /tmp
readOnly: false
- name: submitter-client-tls
mountPath: /etc/submitter-client-tls
readOnly: true
volumes:
- name: tmp
emptyDir:
sizeLimit: 1Gi
- name: submitter-client-tls
secret:
secretName: spark-submitter-client-tls
If the CA files are stored separately, mount them too and update the CA paths in the next step.
Configure the submitter and operator¶
Set the submitter’s certificate paths in submitter-values.yaml:
tls:
enabled: true
certPath: /etc/submitter-tls/tls.crt
keyPath: /etc/submitter-tls/tls.key
caCertPath: /etc/submitter-tls/ca.crt
Configure the controller deployment to pass these arguments through your deployment tooling:
--submitter-tls-enabled=true
--submitter-tls-cert-file=/etc/submitter-client-tls/tls.crt
--submitter-tls-key-file=/etc/submitter-client-tls/tls.key
--submitter-tls-ca-file=/etc/submitter-client-tls/ca.crt
Once the controller has these arguments, set submitter.serviceUrl in operator-values.yaml to
the HTTPS endpoint:
submitter:
serviceUrl: https://spark-submitter-svc.spark-submitter.svc.cluster.local:8080/api/v1/spark-submit
Note
If your environment already provides the certificates, skip Secret creation. If the files are already mounted in the pods, skip the mount steps too. Set the paths above to the files in your pods.
Submitter metrics¶
The submitter service emits these metrics for Spark application submission requests:
Metric |
Description |
|---|---|
|
Successful submission requests |
|
Failed submission requests |
|
Submission requests currently being processed |
|
Submission request latency in seconds |
For Prometheus discovery through pod annotations, use these values in submitter-values.yaml:
probePort: 8081
prometheus:
metrics:
enable: true
Set the Prometheus scrape target for each submitter pod to
http://<submitter-pod-ip>:<probePort>/metrics.