Skip to main content

Overview

Make your data available to the Kubernetes cluster so it can be used for training and evaluation. Whether your client runs on Azure, AWS, Google Cloud, or a local Minikube setup, the process of ingesting datasets works the same way. The data ingestor is a lightweight service that bridges your raw data and the cluster’s persistent storage. Every supported task has a dataset template — the folder layout, the labels CSV and a ready-to-edit ingest.yaml — that you lay your own data out against. By containerizing the ingestion step, the ingestor validates data format and schema, enforces consistency, and transfers the dataset securely into cluster’s SQL storage where it becomes accessible to all training and evaluation jobs. This guide covers:
  • Laying your data out to match the dataset template for your task (tabular, images, text, time series)
  • Deploying the data ingestor for training and test data using Kubernetes
  • Managing datasets through the tracebloc interface
IMPORTANT Make sure that the data format and ML task is supported and that data standards are met by reviewing the docs. You must run the process twice, once to ingest training and once to ingest testing data.

Setup options

You can ingest data into your client in two ways:
  • Declarative YAML (recommended, simpler) — describe your dataset in ~8 lines of ingest.yaml, then helm install. No Dockerfile, no custom Python script. The official ingestor image runs it for you. Use this for any dataset that fits a supported category.
  • Custom Python script + Kubernetes Job (advanced) — install the tracebloc-ingestor Python package, write a short ingestion script against it, build and push a Docker image, then kubectl apply an ingestor-job.yaml. Use this when the declarative schema can’t express what your data needs — e.g. non-trivial preprocessing, a custom validator, or a BaseProcessor subclass.
Start with the declarative method below. Drop down to the custom-script flow only if you need it. Describe your dataset in ~8 lines of YAML, then helm install. The official ingestor image (published as ghcr.io/tracebloc/ingestor) runs it. No Dockerfile, no Python script.
Before you run any commands in this section: if you installed the client via the one-liner (curl -fsSL https://tracebloc.io/i.sh | bash), every later helm upgrade <workspace> tracebloc/client … must include --reset-then-reuse-values, otherwise the upgrade drops the values the installer applied and breaks the workspace:
Append --version <version-number> to pin a specific chart version. This caveat only affects upgrades of the parent tracebloc/client chart, not the helm install tracebloc/ingestor runs below.

1. Add the chart repo (one-time)

The tracebloc/client parent chart bootstraps the cluster (jobs-manager, MySQL, RBAC). The tracebloc/ingestor subchart submits per-dataset ingestion runs against it.

2. Stage your data on the cluster’s shared PVC

The chart doesn’t transport data into the cluster — it points at data already accessible to the cluster’s shared PVC (client-pvc by default, mounted at /data/shared/ inside the ingestor Pod). Before installing, get your raw files there. For a single-node workspace (the default install), the PVC is backed by a host directory the installer created at ~/.tracebloc/<workspace>/data/. Drop your files into a per-dataset subdirectory:
Inside the ingestor Pod those files appear at /data/shared/<prefix>/... — that’s what you’ll put in ingest.yaml below.
For multi-node or EKS deployments where the PVC isn’t backed by a local host path, use a throwaway kubectl cp Pod or a cloud-storage init container instead. See the client ingestor README for those recipes.

3. Write your ingest.yaml

The example below is for image_classification. Other tasks require different fields — e.g. tabular_classification has no images: and instead needs a typed schema: block. Don’t copy this one blindly; open the dataset template for your task — one page per task with the folder layout, the CSV columns, a ready-to-edit ingest.yaml and the checks the ingestor runs — and edit from there.
The top-level shape (apiVersion, kind, category, table, intent, label) is the same for every category; the category field picks the validator set, file-extension defaults, and column conventions. The data-source fields (csv:, images:, schema:, …) vary per category. The paths are paths inside the ingestor Pod, which is the PVC mount you populated in step 2.

4. Install once per dataset

The ingestor runs once: validates your data, copies files into the destination directory on the PVC, inserts rows into MySQL, sends metadata to the tracebloc backend, then exits. Run it twice per dataset — once with intent: train, once with intent: test — using distinct table: names. The example below shows both releases:
Each helm install is a separate release (the first argument is the release name), so the two runs don’t collide. The ingestor Pod picks up CLIENT_ID / CLIENT_PASSWORD automatically from the Kubernetes Secret the parent tracebloc/client chart created in <workspace> at install time — you don’t pass credentials on the helm install command.
Validation error like '<your_category>' is not one of [...] or Additional properties are not allowed (<field> was unexpected)? This comes from the cluster’s jobs-manager validating against its own bundled schema at submit time — the deployed schema is older than the ingestor image you’re installing. helm repo update won’t fix it (that only refreshes the local chart index, not the running server). The fix is on the cluster side: upgrade the parent chart so jobs-manager redeploys with the current schema.
Then re-run the helm install command above.
Full chart docs (data-staging recipe, schema, every category, update model, verification, override knobs) → client ingestor README.

Custom Python script (advanced)

Use this flow when the declarative schema can’t express what your data needs — typically when you have non-trivial preprocessing logic, a custom validator, or a BaseProcessor subclass. The sections below — Quick Setup and Detailed Setup — both describe this advanced path.

Quick Setup

Use this quick setup if you already have an ingestor configured and just want to switch datasets or toggle between training and testing. If you are setting up for the first time, go to the next section for the detailed walkthrough.

Steps

  1. Edit your ingestion script (the one you wrote in Configure a script below)
  • Update csv options and data_path
  • Only for tabular data: Update schema
  • Set schema and CSVIngestor()parameters like category, intent, label_column, etc. to match data type, task and train/test purpose
  1. Build and push docker image:
Make sure Docker is running on your system (e.g. by starting Docker Desktop), then execute the following command:
  1. Edit ingestor-job.yaml:
  • metadata.name: Unique job name (e.g. ingestor-job-train and ingestor-job-test)
  • image: The tag you built and pushed
  • LABEL_FILE: Path inside the pod to the labels CSV, under the PVC mount (e.g. /data/shared/labels.csv). For tabular data, this is the same file that contains both labels and features.
  • TABLE_NAME: Unique table name (no spaces, one per dataset). Title is optional
  • SRC_PATH: Root of the mounted dataset directory inside the pod (/data/shared, backed by ~/.tracebloc/<workspace>/data on the client host)
  1. Deploy to Kubernetes

Detailed Setup

1. Configure a script

This section walks you through the step-by-step setup of a data ingestor. You will install the ingestor package, lay your data out against the dataset template for your task, and write a short ingestion script that matches it. Follow this guide if you are setting up an ingestor for the first time or need full control beyond the quick setup.

Install the ingestor package

The ingestion library is published on PyPI as tracebloc-ingestor (import name tracebloc_ingestor). It is the same code the official ingestor image runs, so a script written against it behaves exactly like the declarative path. It needs Python 3.11 or newer:
IMPORTANT: Datasets must be cleaned and preprocessed before ingestion. Participants cannot view, clean or fix raw data, so model performance will only be as good as the data you provide.

Pick the dataset template for your task

Open the dataset template for your task. It gives you the folder layout and the labels CSV the ingestor expects — lay your data out the same way, then set the matching category and data_format in your script. The rows below cover the most common tasks; every other task on the templates index works the same way, and its TaskCategory constant is the upper-cased category identifier from its page (for example keypoint_detectionTaskCategory.KEYPOINT_DETECTION).

High Level Script Structure

Every ingestion script follows the same structure — save it as ingestor.py next to your Dockerfile:
Both Database, APIClient and other values are configured automatically from the environment variables defined in ingestor_job.yaml.
  • config.LABEL_FILE: Path to local csv label file
  • config.BATCH_SIZE: Batch size used during ingestion

Customize the script

The structure above is a starting point, but every dataset has its own format and labels. In this step you adapt the script to your data by tuning CSV ingestion options and setting the ingestor parameters (category, label column, intent, data path and schema). The following example shows how to ingest a tabular dataset, but the setup works the same way for image or text data.

Needed for Tabular Data: Define Schema

Define the dataset schema as a Python dictionary, mapping each column to its SQL type and constraints. Do not include IDs or the label column into the schema.

Needed for Image Classification Data: Define Image Options

Define image size and file extension.

Needed for Object Detection Data: Define Image Options

Define file extension.

Needed for Text Data: Define File Extension

Define file extensions.

Set CSV ingestion options

Customize parsing, memory handling, and data cleaning with the csv_options dictionary:

Set Up the Ingestor

Define the Ingestor instance with the required configuration. See the tabular data example below:
Specify:
  • category, choose the ML task type (TABULAR_CLASSIFICATION, IMAGE_CLASSIFICATION, OBJECT_DETECTION)
  • label_column, target column or class labels
  • intent, set as TRAIN or TEST depending on dataset purpose
  • include file_options or schema depending on the data type
Other data types work similarly — follow the same configuration pattern with the category, data_format and options for your task from the table above.

2. Build Docker Image

With your script configured, the next step is to package it into a Docker image so it can run inside the Kubernetes cluster.

Docker Hub Setup (first-time users)

The cluster pulls your ingestor image from a public Docker registry, so you need an account before you can push. If you already have one, skip to Write the Dockerfile.
  1. Create a Docker Hub account at hub.docker.com/signup and verify your email.
  2. Log in from your terminal so the docker push command can authenticate:
  3. Push the data ingestor image to your account using the build/push commands in the next section. The image name takes the form <your-docker-username>/<image-name>:<tag> — the username segment must match the account you just created.
  4. Make the image public so the cluster can pull it without credentials: Keeping the image private is also fine, but then you must create a Kubernetes imagePullSecret named regcred in the client namespace (the ingestor-job.yaml already references it).

Place data files on the client host

Datasets are not baked into the Docker image. They live on the client host in the per-workspace data directory and are mounted into the ingestor pod through the shared PVC (client-pvc/data/shared). Copy your dataset into the client’s data directory, where <workspace> is the workspace name you chose during client install (which is also the Helm release name and the Kubernetes namespace — the chart uses the same value for all three). The directory ~/.tracebloc/<workspace>/data/ is created automatically by the installer; just drop your files into it:
Inside the ingestor pod this directory is mounted at /data/shared, so the same files appear as /data/shared/images/... and /data/shared/labels.csv. Set SRC_PATH and LABEL_FILE in ingestor-job.yaml to point at those in-pod paths (see Configure Kubernetes below). For tabular data the same rule applies — drop the single labels.csv (with features and labels) into ~/.tracebloc/<workspace>/data/.

Write the Dockerfile

The Dockerfile only needs to install the ingestor package and copy in your script — the dataset is mounted at runtime, so do not COPY data into the image:
If the cluster enforces the restricted Pod Security Standard (see Run as non-root below), also add a non-root user to the Dockerfile, before the # Set the entrypoint line:

Build Docker Image

You need a docker user and password to proceed with the next step. Cloud platforms run a mix of x86 and ARM nodes (e.g. AWS Graviton, Azure Ampere, GCP Tau T2A). Building a multi-arch image with --platform linux/amd64,linux/arm64 guarantees the image runs on either, particularly if you build on Apple Silicon (M1/M2) or other ARM-based systems. Build and push the image with a single command:

3. Configure Kubernetes

With the image generated and pushed to the registry, edit ingestor-job.yaml with your settings:
Specify:
  • JOBNAME, to distinguish between train and test data jobs.
  • NAMESPACE, use the same as your client.
  • image, your Docker image (imagePullPolicy: Always for DockerHub, IfNotPresent for local)
  • CLIENT_ID, CLIENT_PASSWORD from the tracebloc client view
  • TABLE_NAME, unique per dataset, train and test use different names, no spaces. Different names for train and test data is mandatory
  • LABEL_FILE, path inside the ingestor pod (under /data/shared) to the CSV with file paths and labels — must match the location of the file you placed in ~/.tracebloc/<workspace>/data/
  • SRC_PATH, root inside the pod where the dataset directory is mounted (/data/shared)
  • BATCH_SIZE is the number of entries sent to the server per request. Optional — defaults to 4000. Keep it consistent across data types. It depends on available CPU memory, not for example image size. Too large can exhaust memory. It was tested up to 10,000, but 5,000 is a safe default for most systems.
  • LOG_LEVEL, “WARNING” for all warnings and errors, “INFO” for all logs, “ERROR” for errors only

4. Deploy

Run the ingestor as a Kubernetes Job:
This will start a pod, run the ingestion process once, and once complete you can delete the job. IMPORTANT: You must run this process twice — once for training data and once for test data. Use different JOBNAME and TABLE_NAME values for each run (e.g. ingestor-job-train / ingestor-job-test), and set intent to TRAIN or TEST accordingly in your ingestion script.

Run as non-root

If the namespace enforces the restricted Pod Security Standard, kubectl apply will be admitted but the pod will be rejected with a warning like:
Two changes are needed: 1. Add a securityContext block to the container in ingestor-job.yaml (already shown in the YAML above):
2. Run the container as a non-root user. Add the following to the Dockerfile before the # Set the entrypoint line so the image ships with a UID that satisfies runAsNonRoot: true:
Rebuild and push the image, then re-apply the job. The data ingestor always runs a validation step before ingestion and moving files.

Verify Deployment

Verify if jobs and pods are deployed successfully and running:
Look for “All records processed successfully” in the logs.

Dataset Management Interface

View your datasets at ai.tracebloc.io/data after successful deployment. Interface displays:
  • Dataset name, ID, and record count
  • Data type (Tabular, Image, Text) and purpose (Training/Testing)
  • Namespace and GPU requirements

Best Practices

  • Deploy jobs for training and testing simultaneously using different job names
  • Use consistent, descriptive table names (e.g., insurance-claims-train, insurance-claims-test)
  • Validate data schemas before deployment to prevent ingestion failures
  • Clean data before ingestion - Participants cannot view, clean, or fix raw data, so model performance depends entirely on the quality of data you provide

Troubleshooting

Recommended for debugging: Use k9s, a terminal-based Kubernetes dashboard, to monitor jobs, pods, and logs in real time. Run k9s -n <workspace> to get a live view of resources, switch between them instantly, and inspect logs or events with a few keystrokes. Compared to kubectl, it is faster and more convenient. Stale Kubernetes Job preventing new Job execution:
Storage Issues:

Next Steps


Need Help?