Installing Fluss
On this page
- Overview
- Available Setups
- Single Setup
- Multiple setups in one init container
- Using a private Maven repository
- By default the installer resolves Fluss release JARs from Ververica's public JFrog repository (https://ververica.jfrog.io/artifactory/fluss-release) and transitive/upstream dependencies from Maven Central.
- Setups with a client target
- Alternatively, extract JARs locally using docker run and build them into a custom Flink image:
- Pre-baking Setups into a Custom Image
- Command Reference
- Troubleshooting
- Init container fails or hangs
- Setup directory not populated after pod start
- Further Reading
This document provides information for using the Fluss Setup installer tool within the Fluss Docker image to deploy server and client applications dynamically or with pre-backed images. It is written for operators deploying Fluss or Kubernetes.
Overview
The Fluss Docker image includes a self-contained installer called fluss-setup. This tool downloads and installs Fluss-related JAR components, including server-side classpath JARs for the Fluss server, classpath JARs for client applications such as Flink jobs and Java SDK applications, and runnable binaries like the lake-tiering job. This tool is Ververica-specific and is not part of upstream Apache Fluss.
Component setups might be pre-bundled in a given image build. The installer provides a consistent mechanism to ensure specific JARs are present regardless of what the base image includes. You can use the installer to install components on demand without building a custom image.
The installer uses an embedded Maven wrapper, so you do not need a separate Maven installation on the pod. A JDK and either curl or wget must be available. Both tools are already present in the Fluss Docker image.
Available Setups
The following setups ship with the installer:
The <setup-dir> name is fixed per setup (prometheus, s3, azure, iceberg) — Fluss's plugin loader picks JARs up from these directories at startup.
Server Install Targets
Setups that include a fluss-pom.xml file install into the Fluss server directory at /opt/fluss/plugins/<setup-dir>. You can execute this installation using the command install.sh fluss <setup-name>.
The <setup-dir> name is fixed for each setup, including prometheus, s3, azure, and iceberg. The Fluss plugin loader picks up JARs from these directories at startup.
Client Install Targets
Setups that include a client-pom.xml file installed into a client classpath directory. You can execute this installation using the command install.sh client <setup-name> .
When you set --flink-home or the $FLINK_HOME environment variable, the default output directory is <flink-home>/lib/fluss-<setup-name>/. For non-Flink clients, such as a Fluss Java SDK application, you must pass the --output-dir flag explicitly.
To list available setups, run the installer from the image locally (see Obtaining Registry Access.docx for credentials):
1docker run --rm \
2registry.ververica.cloud/platform-images/fluss:0.9.1-vv-2
3 /opt/fluss/bin/setup/install.sh listHow Setup Installation Works
he installer writes setup JARs to a shared emptyDir volume via an init container. The Fluss server container then mounts specific subdirectories from that volume into /opt/fluss/plugins/<setup-dir>/, where Fluss's plugin loader discovers them at startup.
The key relationship:
- The init container mounts each setup subdirectory individually from the emptyDir and writes JARs directly into those paths.
- The main container mounts the same subPaths to the same locations under /opt/fluss/plugins/.
- The subPath value matches the setup's directory name — these are fixed per setup and listed in the table above (e.g., prometheus, s3, azure, iceberg).
- The same init container and volume setup must be applied to both fluss.coordinator and fluss.tablet. Fluss loads plugins in both the coordinator server and tablet servers.
You must apply the same init container and volume configuration to both fluss.coordinator and fluss.tablet. Fluss loads plugins in both the coordinator server and tablet servers.
Installing Setups on Kubernetes
Single Setup
The example below installs the Prometheus metrics setup. You can replace metric-prometheus and prometheus with the setup name and the matching /opt/fluss/plugins/ subdirectory for your chosen setup.
1fluss:
2 coordinator:
3 extraVolumes:
4 - name: fluss-setups
5 emptyDir: {}
6 extraVolumeMounts:
7 - name: fluss-setups
8 mountPath: /opt/fluss/plugins/prometheus
9 subPath: prometheus
10 initContainers:
11 - name: install-setups
12 image: registry.ververica.cloud/platform-images/fluss:0.9.1-vv-2
13 command:
14 - "/bin/sh"
15 - "-c"
16 - |
17 set -e
18 /opt/fluss/bin/setup/install.sh fluss metrics-prometheus --force -- -q
19 volumeMounts:
20 - name: fluss-setups
21 mountPath: /opt/fluss/plugins/prometheus
22 subPath: prometheus
23 tablet:
24 extraVolumes:
25 - name: fluss-setups
26 emptyDir: {}
27 extraVolumeMounts:
28 - name: fluss-setups
29 mountPath: /opt/fluss/plugins/prometheus
30 subPath: prometheus
31 initContainers:
32 - name: install-setups
33 image: registry.ververica.cloud/platform-images/fluss:0.9.1-vv-2
34 command:
35 - "/bin/sh"
36 - "-c"
37 - |
38 set -e
39 /opt/fluss/bin/setup/install.sh fluss metrics-prometheus --force -- -q
40 volumeMounts:
41 - name: fluss-setups
42 mountPath: /opt/fluss/plugins/prometheus
43 subPath: prometheusUse the same image tag as your main Fluss deployment.
You must use the same image tag as your main Fluss deployment.
For the full set of configurable fields under fluss: ,you can refer to the Fluss Helm chart documentation.
Multiple setups in one init container
You can chain multiple install.sh calls in a single init container command. You must add one extraVolumeMounts entry and one volumeMounts entry for each setup:
1fluss:
2 coordinator:
3 extraVolumes:
4 - name: fluss-setups
5 emptyDir: {}
6 extraVolumeMounts:
7 - name: fluss-setups
8 mountPath: /opt/fluss/plugins/prometheus
9 subPath: prometheus
10 - name: fluss-setups
11 mountPath: /opt/fluss/plugins/s3
12 subPath: s3
13 initContainers:
14 - name: install-setups
15 image: registry.ververica.cloud/platform-images/fluss:0.9.1-vv-2
16 command:
17 - "/bin/sh"
18 - "-c"
19 - |
20 set -e
21 /opt/fluss/bin/setup/install.sh fluss metrics-prometheus --force -- -q
22 /opt/fluss/bin/setup/install.sh fluss fs-s3 --force -- -q
23 volumeMounts:
24 - name: fluss-setups
25 mountPath: /opt/fluss/plugins/prometheus
26 subPath: prometheus
27 - name: fluss-setups
28 mountPath: /opt/fluss/plugins/s3
29 subPath: s3
30 tablet:
31 extraVolumes:
32 - name: fluss-setups
33 emptyDir: {}
34 extraVolumeMounts:
35 - name: fluss-setups
36 mountPath: /opt/fluss/plugins/prometheus
37 subPath: prometheus
38 - name: fluss-setups
39 mountPath: /opt/fluss/plugins/s3
40 subPath: s3
41 initContainers:
42 - name: install-setups
43 image: registry.ververica.cloud/platform-images/fluss:0.9.1-vv-2
44 command:
45 - "/bin/sh"
46 - "-c"
47 - |
48 set -e
49 /opt/fluss/bin/setup/install.sh fluss metrics-prometheus --force -- -q
50 /opt/fluss/bin/setup/install.sh fluss fs-s3 --force -- -q
51 volumeMounts:
52 - name: fluss-setups
53 mountPath: /opt/fluss/plugins/prometheus
54 subPath: prometheus
55 - name: fluss-setups
56 mountPath: /opt/fluss/plugins/s3
57 subPath: s3The subPath value for each setup matches the directory name shown in the default path when you run the install.sh list command. For example, fs-s3 maps to default: /opt/fluss/plugins/s3, which means you use subPath : s3.
Using a private Maven repository
By default the installer resolves Fluss release JARs from Ververica's public JFrog repository (https://ververica.jfrog.io/artifactory/fluss-release) and transitive/upstream dependencies from Maven Central.
Create the ConfigMap:
1kubectl create configmap maven-settings \
2 --from-file=settings.xml=/path/to/your/settings.xml \
3 --namespace <NAMESPACE>You can reference the ConfigMap in the init container. The following example shows the configuration for one setup. You can extend the volumeMounts section to include additional setups:
1fluss:
2 coordinator:
3 extraVolumes:
4 - name: fluss-setups
5 emptyDir: {}
6 - name: maven-settings
7 configMap:
8 name: maven-settings
9 extraVolumeMounts:
10 - name: fluss-setups
11 mountPath: /opt/fluss/plugins/prometheus
12 subPath: prometheus
13 initContainers:
14 - name: install-setups
15 image: registry.ververica.cloud/platform-images/fluss:0.9.1-vv-2
16 command:
17 - "/bin/sh"
18 - "-c"
19 - |
20 set -e
21 /opt/fluss/bin/setup/install.sh fluss metrics-prometheus --force \
22 -- -s /maven-settings/settings.xml -q
23 volumeMounts:
24 - name: fluss-setups
25 mountPath: /opt/fluss/plugins/prometheus
26 subPath: prometheus
27 - name: maven-settings
28 mountPath: /maven-settingsApply the same pattern to the tablet block.
Setups with a client target
Setups with a client-pom.xml file install JARs into a client classpath directory. Some setups, including fs-s3, fs-azure, lake-iceberg-s3, and lake-iceberg-abs, ship both targets. This means they install both into the Fluss server using the fluss subcommand and into a client classpath using the client subcommand. Two setups are client-only: flink-connector (the Fluss Flink connector JAR) and lake-tiering-service (the lake-tiering job binary). You can run the install.sh list to see the full inventory.
The installer lives inside the Fluss Docker image, so you cannot invoke it directly on a Flink or Java SDK pod. To get client-side JARs onto a client pod, you can use the Fluss image as an init container that writes to a shared volume. The main container then mounts this shared volume on its classpath. The example below uses lake-iceberg-s3, but you can substitute any setup that features a client target:
1# On your FlinkDeployment or Flink pod spec:
2initContainers:
3 - name: install-fluss-setups
4 image: registry.ververica.cloud/platform-images/fluss:0.9.1-vv-2
5 command:
6 - "/bin/sh"
7 - "-c"
8 - |
9 set -e
10 /opt/fluss/bin/setup/install.sh client lake-iceberg-s3 \
11 --output-dir /flink-setups --force -- -q
12 volumeMounts:
13 - name: flink-setups
14 mountPath: /flink-setups
15volumes:
16 - name: flink-setups
17 emptyDir: {}
18# In the Flink container:
19volumeMounts:
20 - name: flink-setups
21 mountPath: /opt/flink/lib/fluss-lake-iceberg-s3Alternatively, extract JARs locally using docker run and build them into a custom Flink image:
1mkdir -p /tmp/flink-setups
2docker run --rm \
3 -v /tmp/flink-setups:/output \
4 registry.ververica.cloud/platform-images/fluss:0.9.1-vv-2 \
5 /opt/fluss/bin/setup/install.sh client lake-iceberg-s3 \
6 --output-dir /output/fluss-lake-iceberg-s3 --force -- -q # per-setup subdir, not the mount root (--force clears the target dir)
7# JARs are now in /tmp/flink-setups/fluss-lake-iceberg-s3/ — copy them into your Flink image buildFor a Flink session or application cluster where $FLINK_HOME is set, you can drop the --output-dir flag and pass --flink-home, or you can rely directly on the environment variable. The installer then writes to <flink-home>/lib/fluss-<setup-name>/ by default.
See Configuring Remote Storage for the Iceberg + S3 Helm values pattern on the Fluss server side, and Running Lakehouse (Iceberg) Jobs against Fluss › Flink-Classpath Plugins for the Flink-side classpath set used by the tiering service and union-read jobs.
Pre-baking Setups into a Custom Image
The init container approach downloads setups at each pod start. For environments where network egress is restricted or startup latency matters, build a custom image with setups pre-installed.
Extend the Fluss image in a Dockerfile:
1FROM registry.ververica.cloud/platform-images/fluss:0.9.1-vv-2
2RUN /opt/fluss/bin/setup/install.sh fluss metrics-prometheus -- -q && \
3 /opt/fluss/bin/setup/install.sh fluss fs-s3 -- -qBuild and push to your registry, then reference your custom image in values.yaml:
1fluss:
2 image:
3 registry: <YOUR_REGISTRY>
4 repository: <YOUR_REPO>/fluss
5 tag: <YOUR_TAG>
6 pullSecrets:
7 - registry-credentialsWith a pre-baked image, you do not need an init container or extra volume configuration for the pre-installed setups.
Command Reference
The installer is at /opt/fluss/bin/setup/install.sh inside the Docker image.
1install.sh list
2install.sh fluss <setup-name> [--output-dir <dir>] [--force] [-- <maven-args>...]
3install.sh client <setup-name> [--flink-home <dir>] [--output-dir <dir>] [--force] [-- <maven-args>...]Default output paths:
- fluss subcommand: /opt/fluss/plugins/<setup-dir>/ (this <setup-dir>comes from the setup's fluss-dir file).
- client subcommand: <flink-home>/lib/fluss-<setup-name> when --flink-home (or $FLINK_HOME) is set; otherwise --output-dir is required.
Troubleshooting
Init container fails or hangs
Check init container logs:
1kubectl logs -n <NAMESPACE> <POD_NAME> -c install-setupsCommon causes:
- Network policies might block outbound Maven traffic. The installer must reach Ververica's public JFrog (ververica.jfrog.io) and Maven Central on port 443, or your configured private repository. Check the egress rules for your cluster
- A missing or misconfigured settings.xml file. If you use a private repository, verify that you created the ConfigMap in the correct namespace and that the settings.xml path in the mount is correct.
- An incorrect image tag. The init container image must match your Fluss version. A mismatch might result in incompatible setup JARs.
Setup directory not populated after pod start
Verify the setup subdirectories are present on the pod:
1kubectl exec -n <NAMESPACE> coordinator-server-0 -- ls /opt/fluss/plugins/Each installed setup should appear as a subdirectory. If missing, check that the extraVolumeMounts subPath and mountPath in both the init container and main container match the setup's directory name from the table above.
--force required
If a previous installation left the setup directory behind (e.g., the init container was retried), the installer exits with an error unless --force is passed. Always include --force in init container commands.
Further Reading
- Deploying Fluss on Kubernetes — cluster setup prerequisite
- Apache Fluss Documentation — upstream reference
- Fluss Helm Chart Documentation— complete reference for all fluss: values