入门
有关如何使用、组合和使用 SparkApplication
的更详细指南,请参阅用户指南。如果您正在 Google Kubernetes Engine 上运行 Apache Spark 的 Kubernetes Operator,并且希望使用 Google Cloud Storage (GCS) 和/或 BigQuery 读取/写入数据,也请参阅GCP 指南。本指南的其余部分将简称为 operator。
先决条件
- Helm >= 3
- Kubernetes >= 1.16
安装
添加 Helm Repo
helm repo add spark-operator https://kubeflow.github.io/spark-operator
helm repo update
有关命令文档,请参阅 helm repo。
安装 Chart
helm install [RELEASE_NAME] spark-operator/spark-operator
例如,如果您想在 spark-operator
命名空间中创建一个名为 spark-operator
的发布
helm install spark-operator spark-operator/spark-operator \
--namespace spark-operator \
--create-namespace
有关命令文档,请参阅 helm install。
安装 Chart 将创建 spark-operator
命名空间(如果不存在),并且 helm 将为 operator 设置 RBAC 以在该命名空间中运行。它还会在 default
命名空间中为您的 Spark 应用程序的 driver pod 设置 RBAC,以便能够操作 executor pod。此外,Chart 将在 spark-operator
命名空间中创建一个 Deployment。默认情况下,Chart 不启用用于 Spark pod 定制的Mutating Admission Webhook。启用时,将为此目的创建一个 webhook 服务和一个存储 x509 证书的 Secret,名为 spark-webhook-certs
。要在 Kubernetes 集群上安装启用 mutating admission webhook 的 operator,请使用 webhook.enable=true
标志安装 Chart
helm install my-release spark-operator/spark-operator \
--namespace spark-operator \
--create-namespace \
--set webhook.enable=true
如果您想将 Chart 部署到 GKE 集群,则需要首先授予自己 cluster-admin 权限,然后才能在 1.6 及更高版本的 GKE 集群上创建自定义角色和角色绑定。在 GKE 上安装 Chart 之前运行以下命令
kubectl create clusterrolebinding <user>-cluster-admin-binding --clusterrole=cluster-admin --user=<user>@<domain>
现在,您应该可以通过检查 Helm 发布的状态来查看在集群中运行的 operator。
helm status --namespace spark-operator my-release
升级 Chart
helm upgrade [RELEASE_NAME] spark-operator/spark-operator [flags]
有关命令文档,请参阅 helm upgrade。
卸载 Chart
helm uninstall [RELEASE_NAME]
这将删除与 Chart 相关的所有 Kubernetes 资源并删除发布,但 crds
除外,这些需要手动删除。
有关命令文档,请参阅 helm uninstall。
运行示例
要运行 Spark PI 示例,请运行以下命令
kubectl apply -f examples/spark-pi.yaml
请注意,spark-pi.yaml
配置 driver pod 使用 spark
服务帐户与 Kubernetes API 服务器通信。您可能需要先将其替换为适当的服务帐户,然后再提交 job。如果您使用 Helm Chart 安装了 operator 并覆盖了 spark.jobNamespaces
,则服务帐户名称将以 -spark
结尾,并以 Helm 发布名称开头。例如,如果您希望 Spark job 在名为 test-ns
的命名空间中运行,请先确保该命名空间已存在,然后使用以下命令安装 Chart
helm install my-release spark-operator/spark-operator --namespace spark-operator --set "spark.jobNamespaces={test-ns}"
然后 Chart 将在该命名空间中为您的 Spark job 设置一个服务帐户。
有关默认 Spark Job 命名空间行为的详细信息,请参阅Spark Job 命名空间部分。
运行上述命令将创建一个名为 spark-pi
的 SparkApplication
对象。通过运行以下命令检查该对象
kubectl get sparkapplication spark-pi -o=yaml
这将显示类似以下内容
apiVersion: sparkoperator.k8s.io/v1beta2
kind: SparkApplication
metadata:
...
spec:
deps: {}
driver:
coreLimit: 1200m
cores: 1
labels:
version: 2.3.0
memory: 512m
serviceAccount: spark
executor:
cores: 1
instances: 1
labels:
version: 2.3.0
memory: 512m
image: gcr.io/ynli-k8s/spark:v3.1.1
mainApplicationFile: local:///opt/spark/examples/jars/spark-examples_2.12-3.1.1.jar
mainClass: org.apache.spark.examples.SparkPi
mode: cluster
restartPolicy:
type: OnFailure
onFailureRetries: 3
onFailureRetryInterval: 10
onSubmissionFailureRetries: 5
onSubmissionFailureRetryInterval: 20
type: Scala
status:
sparkApplicationId: spark-5f4ba921c85ff3f1cb04bef324f9154c9
applicationState:
state: COMPLETED
completionTime: 2018-02-20T23:33:55Z
driverInfo:
podName: spark-pi-83ba921c85ff3f1cb04bef324f9154c9-driver
webUIAddress: 35.192.234.248:31064
webUIPort: 31064
webUIServiceName: spark-pi-2402118027-ui-svc
webUIIngressName: spark-pi-ui-ingress
webUIIngressAddress: spark-pi.ingress.cluster.com
executorState:
spark-pi-83ba921c85ff3f1cb04bef324f9154c9-exec-1: COMPLETED
LastSubmissionAttemptTime: 2018-02-20T23:32:27Z
要检查 SparkApplication
对象的事件,请运行以下命令
kubectl describe sparkapplication spark-pi
这将显示类似以下内容的事件
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal SparkApplicationAdded 5m spark-operator SparkApplication spark-pi was added, enqueued it for submission
Normal SparkApplicationTerminated 4m spark-operator SparkApplication spark-pi terminated with state: COMPLETED
operator 在接收到指示 SparkApplication
对象已添加的事件后,将提交 Spark Pi 示例运行。
配置
operator 通常使用 Helm Chart 进行部署和运行。但是,用户仍然可以在 Kubernetes 集群外部运行它,并通过指定 kubeconfig
的路径使其与集群的 Kubernetes API 服务器通信,这可以通过使用 -kubeconfig
标志来实现。
operator 在 SparkApplication
控制器中使用多个 worker。worker 线程的数量通过命令行标志 -controller-threads
控制,默认值为 10。
operator 启用缓存重新同步,因此 operator 使用的 informer 会定期重新列出其管理的现有对象并重新触发资源事件。重新同步间隔(以秒为单位)可以使用标志 -resync-interval
配置,默认值为 30 秒。
默认情况下,operator 将为其管理的自定义资源安装 CustomResourceDefinitions。可以通过设置标志 -install-crds=false
来禁用此功能,在这种情况下,可以使用 kubectl apply -f manifest/spark-operator-crds.yaml
手动安装 CustomResourceDefinitions。
mutating admission webhook 是一个可选组件,可以使用标志 -enable-webhook
启用或禁用,该标志默认为 false
。
默认情况下,operator 将管理整个集群中托管 CRD 类型的自定义资源对象。可以使用标志 -namespace=<namespace>
将其配置为仅管理特定命名空间中的自定义资源对象
升级
要升级 operator,例如使用带有新标签的较新版本容器镜像,请使用更新的 Helm 发布参数运行以下命令
helm upgrade <YOUR-HELM-RELEASE-NAME> --set image.repository=org/image --set image.tag=newTag
有关 helm upgrade
的更多详细信息,请参阅 Helm 文档。
关于 Spark Job 命名空间
Spark Job Namespaces 值定义了可以部署 SparkApplications
的命名空间。Spark Job Namespaces 的 Helm Chart 值是 spark.jobNamespaces
,其默认值是 []
。当命名空间列表为空时,Helm Chart 将在部署 spark-operator
的命名空间中创建一个服务帐户。
如果您使用 Helm Chart 安装了 operator 并将 spark.jobNamespaces
覆盖为其他预先存在的命名空间,则 Helm Chart 将在指定的命名空间中创建必要的服务帐户和 RBAC。
Spark Operator 使用 Spark Job 命名空间来识别和过滤与 SparkApplication
CRD 相关的事件。如果您为 Spark Jobs 指定了命名空间,然后将 SparkApplication
资源提交到另一个命名空间,Spark Operator 将过滤掉该事件,并且资源将不会部署。如果您未指定命名空间,Spark Operator 将仅看到 Spark Operator 命名空间的 SparkApplication
事件。
关于 Driver Pod 的 Service Account
Spark driver pod 需要在 pod 所在的命名空间中有一个 Kubernetes 服务帐户,该帐户具有创建、获取、列出和删除 executor pod 的权限,以及创建 driver 的 Kubernetes 无头服务的权限。如果 pod 所在命名空间中的默认服务帐户没有所需的权限,driver 将失败并退出。要在命名空间中提交并运行 SparkApplication
,请确保该命名空间中存在具有所需权限的服务帐户,并将 .spec.driver.serviceAccount
设置为该服务帐户的名称。有关创建名为 spark-operator-spark
的 driver 服务帐户以及为其赋予所需权限的 RBAC 角色绑定的示例 RBAC 设置,请参阅 spark-rbac.yaml。
关于 Executor Pod 的 Service Account
Spark executor pod 可以在 pod 命名空间中配置一个 Kubernetes 服务帐户。要在命名空间中提交并运行 SparkApplication
,请确保该命名空间中存在具有所需权限的服务帐户,并将 .spec.executor.serviceAccount
设置为该服务帐户的名称。
启用向 Prometheus 导出指标
operator 通过指标端点暴露一组指标供 Prometheus
抓取。Helm Chart 默认安装 operator 时启用指标(-enable-metrics=true
)以及 Prometheus 用于抓取指标端点的其他注解。如果启用了 podMonitor.enable
,Helm Chart 将为 operator 的 pod 提交一个 pod 监控器。要安装未启用指标的 operator,请在 helm install
期间传递适当的标志
helm install my-release spark-operator/spark-operator \
--namespace spark-operator \
--create-namespace \
--set metrics.enable=false
如果启用,operator 将生成以下指标
Spark Application 指标
指标 | 描述 |
---|---|
spark_application_count | Operator 处理的 SparkApplication 总数。 |
spark_application_submit_count | Operator 通过 spark-submit 提交的 SparkApplication 总数。 |
spark_application_success_count | 成功完成的 SparkApplication 总数。 |
spark_application_failure_count | 未能完成的 SparkApplication 总数。 |
spark_application_running_count | 当前正在运行的 SparkApplication 总数。 |
spark_application_success_execution_time_seconds | 成功应用程序的执行时间。 |
spark_application_failure_execution_time_seconds | 失败应用程序的执行时间。 |
spark_application_start_latency_seconds | SparkApplication 的启动延迟,类型为 Prometheus Summary。 |
spark_application_start_latency_seconds | SparkApplication 的启动延迟,类型为 Prometheus Histogram。 |
spark_executor_success_count | 成功完成的 Spark Executor 总数。 |
spark_executor_failure_count | 失败的 Spark Executor 总数。 |
spark_executor_running_count | 当前正在运行的 Spark Executor 总数。 |
工作队列指标
指标 | 描述 |
---|---|
workqueue_depth | 工作队列当前深度 |
workqueue_adds_total | 工作队列处理的添加总数 |
workqueue_queue_duration_seconds_bucket | 项目在被请求之前在工作队列中停留的秒数 |
workqueue_work_duration_seconds_bucket | 处理工作队列中一个项目所需的秒数 |
workqueue_retries_total | 工作队列处理的重试总数 |
workqueue_unfinished_work_seconds | 未完成工作的秒数 |
workqueue_longest_running_processor_seconds | 最长运行处理器的秒数 |
以下是 operator 支持的所有指标配置列表
-enable-metrics=true
-metrics-port=10254
-metrics-endpoint=/metrics
-metrics-prefix=myServiceName
-metrics-label=label1Key
-metrics-label=label2Key
除 -enable-metrics
外,所有配置都是可选的。如果指定了端口和/或端点,请确保更新 spark-operator-with-metrics.yaml
中的注解 prometheus.io/port
、prometheus.io/path
和 containerPort
。
关于 metrics-labels
的注意事项:在 Prometheus
中,每个唯一的键值标签对组合代表一个新的时间序列,这会极大地增加存储的数据量。因此,标签不应用于存储具有高基数且可能具有大或无界值范围的维度。
此外,这些指标是 operator 当前运行的最佳努力,并将在 operator 重启时重置。此外,其中一些指标是通过监听 driver/executor 的 pod 状态更新生成的,在 operator 外部删除 pod 可能会导致其中一些指标的值不正确。
Driver UI 访问和 Ingress
默认情况下,operator 通过创建类型为 ClusterIP
的服务来暴露 Spark UI,使其可访问。这只能从集群内部访问。
operator 还支持为 UI 创建一个可选的 Ingress。这可以通过设置 ingress-url-format
命令行标志来启用。ingress-url-format
应该是一个模板,如 {{$appName}}.{ingress_suffix}/{{$appNamespace}}/{{$appName}}
。{ingress_suffix}
应由用户替换以指示集群的 ingress url,operator 将用适当的值替换 {{$appName}}
和 {{$appNamespace}}
。请注意,Ingress 支持要求正确设置集群的 ingress url 路由。例如,如果 ingress-url-format
是 {{$appName}}.ingress.cluster.com
,则要求任何 *ingress.cluster.com
都应路由到 K8s 集群上的 ingress 控制器。
operator 还将集群内部可访问的 WebUIAddress
和 WebUIIngressAddress
都作为 SparkApplication
的 DriverInfo
字段的一部分进行设置。
operator 生成的 ingress 资源旨在与 Ingress NGINX Controller 一起使用。将此包含在您的应用程序规范中,以确保控制器识别 ingress 并为您的 Spark UI 提供适当的路由。
spec:
sparkUIOptions:
ingressAnnotations:
kubernetes.io/ingress.class: nginx
关于 Mutating Admission Webhook
Apache Spark 的 Kubernetes Operator 带有一个可选的 mutating admission webhook,用于根据 SparkApplication
对象中的规范自定义 Spark driver 和 executor pod,例如挂载用户指定的 ConfigMap 和卷,设置 pod affinity/anti-affinity 以及添加容忍度。
webhook 需要一个 X509 证书用于 Kubernetes API 服务器和在 operator 内部运行的 webhook 服务器之间的 pod admission 请求和响应的 TLS 连接。为此,webhook 服务器必须能够访问证书和密钥文件。这些证书的位置是可配置的,并将在可配置的时间间隔内重新加载。Spark 的 Kubernetes Operator 附带一个工具 hack/gencerts.sh
,用于生成 CA 和服务器证书,并将证书和密钥文件放入名为 spark-webhook-certs
的 Secret 中,该 Secret 位于 spark-operator
命名空间。此 Secret 将被挂载到 operator pod 中。
运行以下命令使用批处理 Job 创建包含证书和密钥文件的 Secret,并安装带有 mutating admission webhook 的 operator Deployment
kubectl apply -f manifest/spark-operator-with-webhook.yaml
这将在 spark-operator
命名空间中为 webhook 创建一个名为 sparkoperator
的 Deployment 和一个名为 spark-webhook
的 Service。
在私有 GKE 或 EKS 集群上使用 Mutating Admission Webhook
如果您正在启用私有集群设置的 GKE 集群上部署 operator,或者在企业 AWS EKS 集群上并希望部署带有 Mutating Admission Webhook 的集群,则请确保将 webhookPort
更改为 443
。或者,您可以选择允许连接到默认端口 (8080)。
默认情况下,防火墙规则限制您的集群主节点仅能通过端口 443 (HTTPS) 和 10250 (kubelet) 发起与节点的 TCP 连接。对于某些 Kubernetes 功能,您可能需要添加防火墙规则以允许在附加端口上访问。例如,在 Kubernetes 1.9 及更早版本中,
kubectl top
访问 heapster,这需要一个防火墙规则来允许在端口 8080 上进行 TCP 连接。要授予此类访问权限,您可以添加防火墙规则。对于 GCP,请参阅此链接
要使用自定义端口安装 operator,请在 helm install
期间传递适当的标志
helm install my-release spark-operator/spark-operator \
--namespace spark-operator \
--create-namespace \
--set "spark.jobNamespaces={spark}" \
--set webhook.enable=true \
--set webhook.port=443