Docs Home
Viewing docs for
Self-ManagedNot available for BYOC

Platform-Wide Deployment Defaults

On this page

This section explains how to set deployment and session cluster defaults for an entire Ververica Platform installation through Helm values, so that every deployment created afterwards inherits them without per-deployment configuration.

Namespace-level defaults, configured in the UI under Configurations and the Deployment Defaults tab, are described in Defaults. Use platform-wide defaults when a setting must apply to every namespace in the installation and must be part of the install manifest rather than applied after installation.

Available Values

All platform-wide default blocks are set under the vvp-appmanager key in values.yaml. Each block is a YAML string, so it is written with the |- block scalar.

ValueApplies toAccepts
globalDeploymentDefaultsstreaming and batch deploymentsflinkConfiguration, kubernetes.pods, resources, upgradeStrategy
flinkConfigurationStreamstreaming deploymentsFlink configuration keys only
flinkConfigurationBatchbatch deploymentsFlink configuration keys only
globalSessionClusterDefaultssession clustersflinkConfiguration, kubernetes.pods

Restate the Platform Volume Mounts When You Set volumeMounts

systemDeploymentDefaults mounts three directories that Flink requires at runtime:

VolumeMount pathPurpose
flink-logs/opt/flink/logJobManager and TaskManager logs, including the JVM garbage collection log
flink-tmp-dir/opt/flink/flink-tmp-dirTemporary working directory
flink-sts-dir/flink/sts-secrets/sts-credentialBlob storage session credentials

kubernetes.pods.volumeMounts replaces this list rather than merging with it. Setting volumeMounts in globalDeploymentDefaults therefore removes all three mounts from every Flink pod unless you restate them.

Every volumeMounts list on this page therefore includes the three platform mounts alongside the mount being added. Reuse this block whenever you set volumeMounts:

YAML
1- name: flink-logs
2  volume:
3    name: flink-logs
4    emptyDir: {}
5  volumeMount:
6    name: flink-logs
7    mountPath: /opt/flink/log
8- name: flink-tmp-dir
9  volume:
10    name: flink-tmp-dir
11    emptyDir: {}
12  volumeMount:
13    name: flink-tmp-dir
14    mountPath: /opt/flink/flink-tmp-dir
15- name: flink-sts-dir
16  volume:
17    name: flink-sts-dir
18    emptyDir: {}
19  volumeMount:
20    name: flink-sts-dir
21    mountPath: /flink/sts-secrets/sts-credential

To confirm the mounts survived, read them back from a running Flink pod rather than from the values file:

BASH
1kubectl get pod <JOBMANAGER_POD> -n <FLINK_NAMESPACE> \
2  -o jsonpath='{range .spec.containers[0].volumeMounts[*]}{.mountPath}{"\n"}{end}'

/opt/flink/log, /opt/flink/flink-tmp-dir, and /flink/sts-secrets/sts-credential must all appear.

Streaming and Batch Halves

globalDeploymentDefaults has two top-level keys:

  • spec applies to streaming deployments.
  • batchSpec applies to deployments that set batchMode: true.

The shipped default contains spec only. Batch deployments inherit nothing from this block until batchSpec is added. If batch workloads require the same resources, Flink configuration, or volume mounts as streaming workloads, define both keys.

The spec key is required. A block that contains only batchSpec is rejected at startup, and AppManager reports that vvp.globalDeploymentDefaults.spec must not be null.

YAML
1vvp-appmanager:
2  globalDeploymentDefaults: |-
3    spec:                     # streaming deployments
4      template:
5        spec:
6          resources:
7            jobmanager:
8              cpu: 1
9              memory: 1Gi
10            taskmanager:
11              cpu: 1
12              memory: 2Gi
13      upgradeStrategy:
14        kind: STATELESS
15    batchSpec:                # batch deployments
16      template:
17        spec:
18          resources:
19            jobmanager:
20              cpu: 1
21              memory: 1Gi
22            taskmanager:
23              cpu: 1
24              memory: 2Gi

Example: Trust a Private Certificate Authority

This example delivers a private certificate authority trust store to every JobManager and TaskManager in the installation. It is the recommended way to reach services that present certificates signed by an internal authority, such as object storage over HTTPS, Kafka over SASL_SSL, or a schema registry.

Two things are required, and both are set in the same block:

  1. kubernetes.pods.volumeMounts mounts the trust store into the pod.
  2. flinkConfiguration tells the JVM to use it.

Mounting the file without setting the JVM options leaves the pod with a trust store it never reads, and connections fail with a PKIX path validation error.

Step 1: Create the Trust Store Secret

Create a Java trust store containing the certificate authority, and store it in a Secret in the namespace where Flink pods run. The platform references this Secret; it does not create it.

BASH
1keytool -importcert -noprompt -trustcacerts \
2  -alias internal-ca \
3  -file internal-ca.pem \
4  -keystore truststore.jks \
5  -storepass changeit
6
7kubectl create secret generic flink-truststore \
8  --from-file=truststore.jks=truststore.jks \
9  --namespace <FLINK_NAMESPACE>

Step 2: Reference It in the Deployment Defaults

YAML
1vvp-appmanager:
2  globalDeploymentDefaults: |-
3    spec:
4      template:
5        spec:
6          flinkConfiguration:
7            env.java.opts.jobmanager: "-Djavax.net.ssl.trustStore=/certs/truststore.jks -Djavax.net.ssl.trustStorePassword=changeit"
8            env.java.opts.taskmanager: "-Djavax.net.ssl.trustStore=/certs/truststore.jks -Djavax.net.ssl.trustStorePassword=changeit"
9          kubernetes:
10            pods:
11              volumeMounts:
12                - name: flink-ca
13                  volume:
14                    name: flink-ca
15                    secret:
16                      secretName: flink-truststore
17                  volumeMount:
18                    name: flink-ca
19                    mountPath: /certs
20                    readOnly: true
21                - name: flink-logs
22                  volume:
23                    name: flink-logs
24                    emptyDir: {}
25                  volumeMount:
26                    name: flink-logs
27                    mountPath: /opt/flink/log
28                - name: flink-tmp-dir
29                  volume:
30                    name: flink-tmp-dir
31                    emptyDir: {}
32                  volumeMount:
33                    name: flink-tmp-dir
34                    mountPath: /opt/flink/flink-tmp-dir
35                - name: flink-sts-dir
36                  volume:
37                    name: flink-sts-dir
38                    emptyDir: {}
39                  volumeMount:
40                    name: flink-sts-dir
41                    mountPath: /flink/sts-secrets/sts-credential
42      upgradeStrategy:
43        kind: STATELESS
44    batchSpec:
45      template:
46        spec:
47          flinkConfiguration:
48            env.java.opts.jobmanager: "-Djavax.net.ssl.trustStore=/certs/truststore.jks -Djavax.net.ssl.trustStorePassword=changeit"
49            env.java.opts.taskmanager: "-Djavax.net.ssl.trustStore=/certs/truststore.jks -Djavax.net.ssl.trustStorePassword=changeit"
50          kubernetes:
51            pods:
52              volumeMounts:
53                - name: flink-ca
54                  volume:
55                    name: flink-ca
56                    secret:
57                      secretName: flink-truststore
58                  volumeMount:
59                    name: flink-ca
60                    mountPath: /certs
61                    readOnly: true
62                - name: flink-logs
63                  volume:
64                    name: flink-logs
65                    emptyDir: {}
66                  volumeMount:
67                    name: flink-logs
68                    mountPath: /opt/flink/log
69                - name: flink-tmp-dir
70                  volume:
71                    name: flink-tmp-dir
72                    emptyDir: {}
73                  volumeMount:
74                    name: flink-tmp-dir
75                    mountPath: /opt/flink/flink-tmp-dir
76                - name: flink-sts-dir
77                  volume:
78                    name: flink-sts-dir
79                    emptyDir: {}
80                  volumeMount:
81                    name: flink-sts-dir
82                    mountPath: /flink/sts-secrets/sts-credential

Step 3: Apply and Restart AppManager

BASH
1helm upgrade --install <RELEASE_NAME> \
2  oci://registry.ververica.cloud/platform-charts/ververica-platform \
3  --version 3.1.2 \
4  --namespace vvp-system \
5  --values values.yaml

The value is read when AppManager starts and applies to deployments created afterwards. Existing deployments keep the configuration they were created with.

Step 4: Verify

Create a deployment that sets no flinkConfiguration and no kubernetes block of its own, so that anything present in the pod must have been inherited. Then confirm the trust store is present inside the container:

BASH
1kubectl exec -n <FLINK_NAMESPACE> <JOBMANAGER_POD> -c flink-main-container -- ls -l /certs

Confirm the JVM options reached the effective configuration:

BASH
1kubectl exec -n <FLINK_NAMESPACE> <JOBMANAGER_POD> -c flink-main-container -- \
2  grep trustStore /opt/flink/conf/flink-conf.yaml

If the mount is present and the JVM options are set, the JobManager log contains no PKIX path building failed entries.

Example: Kafka over SASL_SSL

With the trust store from the previous example in place, a Flink SQL table reaches Kafka over SASL_SSL by referencing the mounted path.

SQL
1CREATE TABLE orders (
2  id INT,
3  amount INT
4) WITH (
5  'connector' = 'kafka',
6  'topic' = 'orders',
7  'format' = 'json',
8  'properties.bootstrap.servers' = 'kafka.example.internal:9094',
9  'properties.security.protocol' = 'SASL_SSL',
10  'properties.sasl.mechanism' = 'PLAIN',
11  'properties.sasl.jaas.config' = 'org.apache.flink.kafka.shaded.org.apache.kafka.common.security.plain.PlainLoginModule required username="flinkuser" password="<PASSWORD>";',
12  'properties.ssl.truststore.location' = '/certs/truststore.jks',
13  'properties.ssl.truststore.password' = 'changeit',
14  'properties.ssl.endpoint.identification.algorithm' = 'HTTPS'
15);

Session Cluster Defaults

globalSessionClusterDefaults applies to session clusters. Unlike the deployment block, it has a single spec key and no batch half.

YAML
1vvp-appmanager:
2  globalSessionClusterDefaults: |-
3    spec:
4      flinkConfiguration:
5        env.java.opts.jobmanager: "-Djavax.net.ssl.trustStore=/certs/truststore.jks -Djavax.net.ssl.trustStorePassword=changeit"
6      kubernetes:
7        pods:
8          volumeMounts:
9            - name: flink-ca
10              volume:
11                name: flink-ca
12                secret:
13                  secretName: flink-truststore
14              volumeMount:
15                name: flink-ca
16                mountPath: /certs
17                readOnly: true
18            - name: flink-logs
19              volume:
20                name: flink-logs
21                emptyDir: {}
22              volumeMount:
23                name: flink-logs
24                mountPath: /opt/flink/log
25            - name: flink-tmp-dir
26              volume:
27                name: flink-tmp-dir
28                emptyDir: {}
29              volumeMount:
30                name: flink-tmp-dir
31                mountPath: /opt/flink/flink-tmp-dir
32            - name: flink-sts-dir
33              volume:
34                name: flink-sts-dir
35                emptyDir: {}
36              volumeMount:
37                name: flink-sts-dir
38                mountPath: /flink/sts-secrets/sts-credential

Session cluster defaults are applied when the session cluster is created. Changing the value affects session clusters created afterwards, and existing session clusters keep the configuration they were created with. To apply a changed default to a running session cluster, recreate it.

Precedence

Settings are resolved from the broadest scope to the most specific. A more specific layer overrides a less specific one:

  1. globalDeploymentDefaults (spec or batchSpec), from Helm values
  2. flinkConfigurationStream and flinkConfigurationBatch, from Helm values
  3. Namespace-level defaults, set through the UI or the API
  4. The deployment's own specification

Two behaviors are worth noting when the same setting is defined at more than one layer:

  • flinkConfiguration merges across layers. Keys from a broader layer that the narrower layer does not set are retained.
  • kubernetes.pods.volumeMounts and resources replace. The narrower layer's value is used in full, and the broader layer's value is discarded.

Flink configuration keys can be set either in globalDeploymentDefaults.spec.template.spec.flinkConfiguration or in flinkConfigurationStream and flinkConfigurationBatch. The blocks differ in two ways:

  • globalDeploymentDefaults also accepts kubernetes.pods, resources, and upgradeStrategy. The flinkConfiguration* blocks accept Flink configuration keys only.
  • The flinkConfiguration* blocks ship with platform-tuned content, including the checkpointing interval, high availability, the metrics reporters and their factory classes, and leader election timings. Overriding either block replaces all of it.

Because overriding a value replaces the whole block, setting Flink configuration in globalDeploymentDefaults is the safer option: the shipped content of that block is limited to resources and upgradeStrategy, which are straightforward to restate. Overriding flinkConfigurationStream requires reproducing every shipped key that is still needed, and omitting the metrics reporter keys stops metrics from being served.

Verifying the Effective Defaults

Read the effective platform-wide defaults back from the API rather than inspecting the values file, so that the running configuration is confirmed:

BASH
1curl -s \
2  -H "Authorization: Bearer <API_TOKEN>" \
3  -H "workspace: <WORKSPACE>" \
4  https://<PLATFORM_HOST>/api/v1/global-deployment-defaults

To read the namespace-level defaults for a deployment type:

BASH
1curl -s \
2  -H "Authorization: Bearer <API_TOKEN>" \
3  -H "workspace: <WORKSPACE>" \
4  https://<PLATFORM_HOST>/api/v1/namespaces/<NAMESPACE>/deployment-defaults/STREAM
Was this helpful?