Namespace-Level Annotations
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:
| Scope | Source | Priority |
|---|---|---|
| Workspace | Workspace-level defaults | Lowest |
| Namespace | Namespace pod templates | Middle |
| Pod | Deployment-level pod template | Highest |
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:
spec:
kubernetes:
jobManagerPodTemplate:
metadata:
annotations:
prometheus.io/scrape: "true"
prometheus.io/port: "9249"
team: "data-engineering"
taskManagerPodTemplate:
metadata:
annotations:
prometheus.io/scrape: "true"
prometheus.io/port: "9249"
team: "data-engineering"
To apply this configuration, patch the namespace using the AppManager API:
curl -X PATCH \
https://<VVP_HOST>/api/v1/namespaces/<NAMESPACE> \
-H "Authorization: Bearer <API_TOKEN>" \
-H "Content-Type: application/json" \
-d '{
"spec": {
"kubernetes": {
"jobManagerPodTemplate": {
"metadata": {
"annotations": {
"prometheus.io/scrape": "true",
"prometheus.io/port": "9249",
"team": "data-engineering"
}
}
},
"taskManagerPodTemplate": {
"metadata": {
"annotations": {
"prometheus.io/scrape": "true",
"prometheus.io/port": "9249",
"team": "data-engineering"
}
}
}
}
}
}'
To verify that the annotations are present on a running deployment's pods:
kubectl -n <NAMESPACE> describe pod \
-l deploymentName=<DEPLOYMENT_NAME>,component=jobmanager \
| 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:
spec:
kubernetes:
jobManagerPodTemplate:
metadata:
annotations:
prometheus.io/scrape: "true"
prometheus.io/port: "9249"
datadog/env: "production"
taskManagerPodTemplate:
metadata:
annotations:
prometheus.io/scrape: "true"
prometheus.io/port: "9249"
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:
spec:
kubernetes:
jobManagerPodTemplate:
metadata:
annotations:
fluentbit.io/parser: "flink-json"
log-routing/destination: "namespace-log-sink"
taskManagerPodTemplate:
metadata:
annotations:
fluentbit.io/parser: "flink-json"
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:
| Scenario | Result |
|---|---|
| Namespace annotation key not set in deployment | Namespace value is applied |
| Namespace annotation key also set in deployment | Deployment 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:
-
Inspect the running pod's annotations:
kubectl -n <NAMESPACE> describe pod \
-l deploymentName=<DEPLOYMENT_NAME> \
| grep -A30 "Annotations:" -
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 under
spec.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.