Docs Home
Viewing docs for
Self-ManagedNot available for BYOC

Installing Fluss

On this page

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:

Setup nameTargetsDefault Install pathWhat it enables
metrics-prometheusFluss server/opt/fluss/plugins/prometheus/Prometheus metrics reporter
fs-s3Fluss server + client/opt/fluss/plugins/s3/(server) / <flink-home>/lib/fluss-fs-s3/ (client)Amazon S3 (and S3-compatible) remote storage
fs-azureFluss server + client/opt/fluss/plugins/azure/ (server) / <flink-home>/lib/fluss-fs-azure/ (client)Azure Blob Storage (ADLS Gen2) remote storage
lake-iceberg-s3Fluss server + client/opt/fluss/plugins/iceberg/(server) / <flink-home>/lib/fluss-lake-iceberg-s3/ (client)Iceberg lake format on S3 (Hadoop and REST catalogs, e.g. Polaris)
lake-iceberg-absFluss server + client/opt/fluss/plugins/iceberg/(server) / <flink-home>/lib/fluss-lake-iceberg-abs/ (client)Iceberg lake format with Hadoop catalog on Azure Blob Storage (ADLS Gen2)
flink-connectorClient only<flink-home>/lib/fluss-flink-connector/The Fluss Flink connector JAR
lake-tiering-serviceClient only<flink-home>/lib/fluss-lake-tiering-service/The fluss-flink-tiering job binary used by the Flink-side tiering service

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):

BASH
1docker run --rm \
2registry.ververica.cloud/platform-images/fluss:0.9.1-vv-2
3  /opt/fluss/bin/setup/install.sh list

How 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.

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.

YAML
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: prometheus

Use the same image tag as your main Fluss deployment.

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:

YAML
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: s3

The 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:

BASH
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:

YAML
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-settings

Apply 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:

YAML
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-s3
BASH
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 build

For 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.

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:

TEXT
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 -- -q

Build and push to your registry, then reference your custom image in values.yaml:

YAML
1fluss:
2  image:
3    registry: <YOUR_REGISTRY>
4    repository: <YOUR_REPO>/fluss
5    tag: <YOUR_TAG>
6    pullSecrets:
7      - registry-credentials

With 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.

TEXT
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>...]
FlagDescription
listPrint all available setup names grouped by target (Fluss setups: / Client setups:). Each line shows the setup name padded to 30 characters followed by its default output path.
fluss <setup-name>Install the setup's server-side JARs into /opt/fluss/plugins/<setup-dir>/.
client <setup-name>Install the setup's client-side JARs into a classpath directory (Flink lib, Java SDK app classpath, etc.).
--output-dir <dir>Override the default output directory.
--forceDelete and recreate the output directory if it already exists.
--flink-home <dir>Flink installation root (used by client subcommand; falls back to $FLINK_HOME if set).
-- <maven-args>Extra arguments passed to Maven (e.g. -s /path/to/settings.xml, -q).

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:

BASH
1kubectl logs -n <NAMESPACE> <POD_NAME> -c install-setups

Common 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:

BASH
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

Was this helpful?