Docs Home
Viewing docs for
Self-ManagedNot available for BYOC

Namespace-Level Annotations

On this page

Namespace-level annotations are Kubernetes annotations defined at the namespace scope that Ververica Platform automatically applies to the pods of every Flink deployment running in that namespace. Defining annotations at this scope lets you enforce consistent metadata — such as observability labels or logging rules — across all deployments without touching individual deployment configurations.

How Namespace-Level Annotations Work

When a deployment starts, Ververica Platform assembles the final set of pod annotations by merging annotations from three scopes in order:

ScopeSourcePriority
WorkspaceWorkspace-level defaultsLowest
NamespaceNamespace pod templatesMiddle
PodDeployment-level pod templateHighest

A key defined at a higher-priority scope takes precedence over the same key defined at a lower-priority scope. Deployment-level annotations always override namespace-level annotations, which override workspace-level annotations.

Configure Namespace-Level Annotations

Namespace-level annotations are set in the namespace configuration under spec.kubernetes.jobManagerPodTemplate.metadata.annotations and spec.kubernetes.taskManagerPodTemplate.metadata.annotations.

The following example adds Prometheus scraping annotations to all JobManager and TaskManager pods in the namespace:

YAML
1spec:
2  kubernetes:
3    jobManagerPodTemplate:
4      metadata:
5        annotations:
6          prometheus.io/scrape: "true"
7          prometheus.io/port: "9249"
8          team: "data-engineering"
9    taskManagerPodTemplate:
10      metadata:
11        annotations:
12          prometheus.io/scrape: "true"
13          prometheus.io/port: "9249"
14          team: "data-engineering"

To apply this configuration, patch the namespace using the AppManager API:

BASH
1curl -X PATCH \
2  https://<VVP_HOST>/api/v1/namespaces/<NAMESPACE> \
3  -H "Authorization: Bearer <API_TOKEN>" \
4  -H "Content-Type: application/json" \
5  -d '{
6    "spec": {
7      "kubernetes": {
8        "jobManagerPodTemplate": {
9          "metadata": {
10            "annotations": {
11              "prometheus.io/scrape": "true",
12              "prometheus.io/port": "9249",
13              "team": "data-engineering"
14            }
15          }
16        },
17        "taskManagerPodTemplate": {
18          "metadata": {
19            "annotations": {
20              "prometheus.io/scrape": "true",
21              "prometheus.io/port": "9249",
22              "team": "data-engineering"
23            }
24          }
25        }
26      }
27    }
28  }'

To verify that the annotations are present on a running deployment&#x27;s pods:

BASH
1kubectl -n <NAMESPACE> describe pod \
2  -l deploymentName=<DEPLOYMENT_NAME>,component=jobmanager \
3  | grep -A20 "Annotations:"

Use Cases

Team-Level Observability

Apply Prometheus scraping or Datadog tagging annotations to all pods owned by a team, so every deployment automatically registers with the observability stack without requiring per-deployment configuration:

YAML
1spec:
2  kubernetes:
3    jobManagerPodTemplate:
4      metadata:
5        annotations:
6          prometheus.io/scrape: "true"
7          prometheus.io/port: "9249"
8          datadog/env: "production"
9    taskManagerPodTemplate:
10      metadata:
11        annotations:
12          prometheus.io/scrape: "true"
13          prometheus.io/port: "9249"
14          datadog/env: "production"

Namespace-Specific Logging Rules

Configure a log shipper such as Fluent Bit or Filebeat across all deployments in a namespace by attaching the required sidecar-injection or log-routing annotations at the namespace level:

YAML
1spec:
2  kubernetes:
3    jobManagerPodTemplate:
4      metadata:
5        annotations:
6          fluentbit.io/parser: "flink-json"
7          log-routing/destination: "namespace-log-sink"
8    taskManagerPodTemplate:
9      metadata:
10        annotations:
11          fluentbit.io/parser: "flink-json"
12          log-routing/destination: "namespace-log-sink"

Compatibility with Other Annotation Scopes

Namespace-level annotations coexist with workspace-level and deployment-level annotations. Keys that do not conflict are merged into the final pod metadata. When the same key appears at multiple scopes, the deployment-level value takes precedence.

The table below summarizes how a conflicting key is resolved:

ScenarioResult
Namespace annotation key not set in deploymentNamespace value is applied
Namespace annotation key also set in deploymentDeployment value is applied; namespace value is discarded

Troubleshooting

Annotation Not Applied Due to Override Conflicts

If an annotation you defined at the namespace level does not appear on a pod, an annotation with the same key is likely defined at the deployment level. The deployment-level value overrides the namespace-level value.

To diagnose the conflict:


  1. Inspect the running pod&#x27;s annotations:
    <code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">kubectl -n <NAMESPACE> describe pod \</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> -l deploymentName=<DEPLOYMENT_NAME> \</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> | grep -A30 "Annotations:"</span><br></span></code>

  2. Compare the annotation value against the namespace configuration to determine which scope supplied the value.

  3. If the namespace value should take precedence, remove or rename the corresponding annotation key in the deployment&#x27;s pod template under spec.template.spec.kubernetes.jobManagerPodTemplate.metadata.annotations or taskManagerPodTemplate.metadata.annotations.
Was this helpful?