Integrações — JupyterLab
Integração com Spark
O chart tdp-jupyter integra-se com o Apache Spark via o mecanismo tdpSparkIntegration. Ao ativar a integração, um ConfigMap (tdp-jupyter-spark-integration) é criado com as configurações de spark-defaults.conf e um script auxiliar jupyter-spark-env.sh.
Os pods de notebooks montam esse ConfigMap em /opt/bitnami/spark/conf e executam o script no postStart, de modo que cada sessão Spark encontra o master correcto automaticamente.
Para o usuário final, a decisão principal é simples:
- usar PySpark local para testes rápidos e desenvolvimento;
- usar cluster Spark externo quando quiser distribuir processamento;
- usar Iceberg a partir do notebook apenas depois de a integração Spark e o catálogo Iceberg já estarem configurados no ambiente.
Modos de operação
| Modo | tdpSparkIntegration.enabled | Valor resolvido para spark.master | Uso típico |
|---|---|---|---|
| PySpark local | false | local[*] | Executa Spark dentro do próprio pod do notebook (padrão para desenvolvimento) |
| Cluster externo | true | spark://<release>-spark-master-svc.<namespace>.svc.cluster.local:7077 | Liga a um deployment Spark já existente |
O parâmetro spark.master no values.yaml fica vazio por padrão. O template escolhe o valor correcto em tempo de renderização com base em tdpSparkIntegration.enabled. É possível fornecer uma URL personalizada se necessário.
Componentes envolvidos
| Componente | Função |
|---|---|
templates/spark-integration-configmap.yaml | Renderiza as configurações Spark e o script auxiliar de ambiente |
singleuser.extraEnv | Define variáveis de ambiente Spark para cada pod de notebook |
singleuser.lifecycleHooks.postStart | Executa jupyter-spark-env.sh antes do JupyterLab iniciar |
singleuser.networkPolicy.egress | Permite que os pods de notebook alcancem o Spark master e serviços auxiliares |
Variáveis de ambiente injectadas nos pods de notebook
SPARK_HOME=/opt/bitnami/spark
PYTHONPATH=/opt/bitnami/spark/python:/opt/bitnami/spark/python/lib/py4j-0.10.9.7-src.zip
SPARK_CONF_DIR=/opt/bitnami/spark/conf
PYSPARK_PYTHON=/opt/conda/envs/py312/bin/python
PYSPARK_DRIVER_PYTHON=/opt/conda/envs/py312/bin/python
SPARK_MASTER_URL=<automático> # local[*] ou spark://... conforme tdpSparkIntegration.enabled
SPARK_DRIVER_PORT=2222
SPARK_BLOCKMANAGER_PORT=7777
Volumes montados nos pods de notebook
| Caminho | Tipo | Conteúdo |
|---|---|---|
/opt/bitnami/spark/conf | ConfigMap | spark-defaults.conf e scripts auxiliares |
/tmp/spark-local | emptyDir | Dados temporários e shuffle do Spark |
/tmp/spark-logs | emptyDir | Logs do driver Spark |
Como configurar
Modo 1 — PySpark local (padrão)
Não requer um cluster Spark externo. O Spark é executado dentro do pod do notebook com local[*]:
tdpSparkIntegration:
enabled: false
deploySparkCluster: false
configMap:
sparkConfig:
"spark.master": "" # resolve para local[*]
Teste num notebook:
from pyspark.sql import SparkSession
spark = SparkSession.builder.appName("Local PySpark").getOrCreate()
print(spark.sparkContext.master) # local[*]
Modo 2 — Cluster Spark externo
Liga os notebooks a um deployment Spark já existente no cluster Kubernetes:
tdpSparkIntegration:
enabled: true
deploySparkCluster: false # false = apontar para deployment existente
configMap:
sparkConfig:
"spark.kubernetes.namespace": "tdp-project" # opcional
"spark.master": "" # resolve para spark://<release>-spark-master-svc.<ns>:7077
"spark.driver.host": "" # deixe vazio para usar o serviço admin do notebook
"spark.executor.instances": "2"
"spark.executor.memory": "4g"
"spark.executor.cores": "3"
tdp-spark:
spark:
worker:
replicaCount: 2
resources:
limits:
cpu: 4
memory: 6Gi
Certifique-se de que o serviço Spark master é acessível a partir do namespace dos notebooks (ex.: tdp-spark-master-svc.tdp-project.svc.cluster.local:7077).
Considerações sobre NetworkPolicy
- Os pods de notebook adicionam uma regra de egress que corresponde a qualquer Spark master (
app.kubernetes.io/component: master,app.kubernetes.io/name: spark). - Se o chart Spark tiver a sua própria NetworkPolicy, permita ligações de entrada a partir do namespace dos notebooks.
Modo 3 — Cluster Spark integrado (opcional)
Define tdpSparkIntegration.deploySparkCluster: true para instalar o subchart tdp-spark juntamente com o JupyterHub:
tdpSparkIntegration:
enabled: true
deploySparkCluster: true
Ajuste os valores de stack/charts/tdp/tdp-spark conforme necessário.
Uso de Iceberg a partir do Jupyter
O suporte a Iceberg no Jupyter não é uma integração separada do chart tdp-jupyter. Na prática, ele acontece via Spark:
- o notebook liga-se ao Spark;
- o Spark precisa conhecer o catálogo Iceberg;
- o catálogo Iceberg precisa de acesso ao Hive Metastore e ao storage S3/MinIO.
Por isso:
- a configuração do Jupyter fica nesta página;
- a configuração do catálogo Iceberg fica em Integrações — Iceberg;
- a configuração do Spark fica em Integrações — Spark.
Não trate Iceberg como obrigatório para o Jupyter. Ele é apenas um cenário adicional para notebooks que precisem consultar ou manter tabelas Iceberg via Spark.
Instalar ou atualizar o JupyterHub
helm upgrade --install <release> \
oci://registry.tecnisys.com.br/tdp/charts/tdp-jupyter \
-n <namespace> \
-f values.yaml
Sempre que modificar ConfigMaps ou variáveis de ambiente, reinicie os pods de usuário (Stop Server → Start Server no JupyterHub) para que as novas configurações entrem em vigor.
Checklist de verificação
-
Pods em execução
Terminal inputkubectl get pods -n <namespace> | grep jupyter -
ConfigMap Spark criado
Terminal inputkubectl get configmap tdp-jupyter-spark-integration -n <namespace> -o yaml -
Conectividade de rede (a partir de um pod de notebook)
Terminal inputkubectl exec -n <namespace> <pod> -- \
curl -sv tdp-spark-master-svc.<namespace>.svc.cluster.local:7077
Testar a integração
Notebook de teste incluído no chart
O chart inclui um notebook de teste (tdp-jupyter-spark-test ConfigMap). Para o extrair:
kubectl get configmap tdp-jupyter-spark-test -n <namespace> \
-o jsonpath='{.data.spark-integration-test\.ipynb}' \
> spark-integration-test.ipynb