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.
This page covers namespace-level annotations for Flink deployment pods. To attach annotations to Ververica Platform component pods (Gateway, AppManager, and so on), see Custom Pod Annotations. To customize annotations for a single deployment only, see Pod-Level Customization.
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:
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:
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:
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's pods:
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:
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:
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:
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:
Inspect the running pod'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>
Compare the annotation value against the namespace configuration to determine which scope supplied the value.
If the namespace value should take precedence, remove or rename the corresponding annotation key in the deployment's pod template underspec.template.spec.kubernetes.jobManagerPodTemplate.metadata.annotationsortaskManagerPodTemplate.metadata.annotations.
If the annotation key matches a platform-reserved annotation, the platform value takes precedence over all user-supplied values regardless of scope. Use a distinct annotation key to avoid this conflict.