Kubernetes
Core pluginmarmotdata/kubernetes
Discover namespaces, services, workloads, and cron jobs from self-managed Kubernetes clusters
The Kubernetes plugin discovers namespaces, services, deployments, stateful sets, cron jobs, and pods from Kubernetes clusters. Each resource kind can be toggled on or off, and discovery can be scoped to specific namespaces or a label selector.
Discovered resources are linked together: namespaces contain their resources, services link to the deployments and stateful sets they expose (matched by selector), and workloads link to their pods (matched by owner references). Cron jobs come with run history built from their recent job runs, so the catalog shows whether the nightly pipeline actually succeeded. When cluster_name is set, a Cluster asset is created as the root of the tree.
Pods are not discovered by default because they are short-lived and can flood the catalog; enable discover_pods when pod-level visibility is worth the churn. One-off Jobs are never cataloged for the same reason; only jobs owned by a cron job are used, as run history.
Prerequisites
The plugin needs read access to the resources it discovers. When running inside a cluster, bind a role like this to the service account Marmot runs as:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: marmot-discovery
rules:
- apiGroups: [""]
resources: ["namespaces", "services", "pods"]
verbs: ["get", "list"]
- apiGroups: ["apps"]
resources: ["deployments", "statefulsets", "replicasets"]
verbs: ["get", "list"]
- apiGroups: ["batch"]
resources: ["cronjobs", "jobs"]
verbs: ["get", "list"]
This plugin is for self-managed and on-prem clusters. For managed clusters that authenticate with cloud IAM, use the dedicated plugins, which reuse this plugin's discovery engine:
- Amazon EKS: the EKS plugin
- Google GKE: the GKE plugin
The plugin supports three authentication methods:
- In-cluster: when Marmot runs inside Kubernetes and no connection settings are provided, the pod's service account is used automatically. The projected token is rotated automatically, so there is nothing to refresh.
- Kubeconfig:
$KUBECONFIGor~/.kube/configis used when Marmot runs somewhere kubectl already works. Setkubeconfig_pathandcontextto pick a specific file and context. - Direct token: set
host,token, andca_certificateto connect to any cluster with a service account token.
Connecting with a service account token
Create a service account bound to the read-only role above and mint a token for it:
kubectl create serviceaccount marmot-discovery
kubectl create clusterrolebinding marmot-discovery \
--clusterrole=marmot-discovery --serviceaccount=default:marmot-discovery
kubectl create token marmot-discovery --duration=48h
kubectl create token mints a time-bounded token, and the API server caps the lifetime (often 48h) regardless of the --duration you request, so a scheduled ingest will start failing once it expires. For unattended discovery, prefer in-cluster auth (its token is rotated automatically), or rotate the token on a schedule. A long-lived token can be created with a kubernetes.io/service-account-token Secret, but that is discouraged upstream and disabled on some clusters.
Then give the plugin the cluster endpoint, the token, and the cluster's CA certificate. The connection fields go in the same config as the discovery options, not a separate file:
host: "https://mycluster.example.com:6443"
token: "${K8S_SA_TOKEN}"
ca_certificate: |
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
cluster_name: "prod"
namespaces:
- "payments"
- "orders"
discover_pods: false
tags:
- "kubernetes"
- "${labels.team}"
In the UI
Point-and-click, no config file needed.
- 1 Open
Runs→Create Pipeline - 2 Pick Kubernetes from the plugin list.
- 3 Fill in the wizard, set a schedule, save.
With the CLI
Save a YAML config, then run marmot ingest.
name: my-kubernetes-pipeline
runs:
- kubernetes:
# No required fields — see the Configuration tab.marmot ingest -c ingest.yaml Not using plugins? Other ways to populate Marmot
Configuration
20 top-level fields.
tags multiselect Tags to apply to discovered assets
external_links object[] External links to show on all assets
name string Display name for the link
icon string Icon identifier for the link
url string URL to the external resource
filter object Filter discovered assets by name (regex)
include multiselect Include patterns for resource names (regex)
exclude multiselect Exclude patterns for resource names (regex)
cluster_name string Cluster name to prefix asset names with
namespaces multiselect Namespaces to discover. Empty or ["*"] means all namespaces
exclude_namespaces multiselect Namespaces to skip when discovering all namespaces
["kube-system","kube-public","kube-node-lease"] label_selector string Only discover namespaced resources matching this label selector (e.g. team=data)
discover_namespaces bool Discover namespaces
true discover_services bool Discover services
true discover_deployments bool Discover deployments
true discover_statefulsets bool Discover stateful sets
true discover_cronjobs bool Discover cron jobs, with their recent job runs as run history
true discover_pods bool Discover pods. Off by default because pods are short-lived and can flood the catalog
false labels_to_metadata bool Include resource labels in asset metadata
true annotations_to_metadata bool Include resource annotations in asset metadata
false kubeconfig_path string Kubeconfig path. Defaults to in-cluster, then $KUBECONFIG
context string Kubeconfig context. Defaults to the current context
host string API server URL for direct token authentication
token password Bearer token, typically a service account token
ca_certificate string PEM-encoded CA certificate of the API server
Assets Emitted
Metadata fields this plugin attaches to each discovered asset.
Cluster
ClusterFieldsClusterFields represents Kubernetes cluster metadata fields
cluster stringConfigured cluster name
kubernetes_version stringKubernetes server version
platform stringServer platform (e.g. linux/amd64)
Namespace
NamespaceFieldsNamespaceFields represents Kubernetes namespace metadata fields
namespace stringNamespace name
phase stringNamespace lifecycle phase (Active, Terminating)
cluster stringConfigured cluster name
created_at stringResource creation timestamp
labels objectResource labels
annotations objectResource annotations
Service
ServiceFieldsServiceFields represents Kubernetes service metadata fields
namespace stringNamespace the service lives in
service_type stringService type (ClusterIP, NodePort, LoadBalancer, ExternalName)
cluster_ip stringCluster IP address (None for headless services)
external_name stringExternal DNS name for ExternalName services
ports stringExposed ports (name:port/protocol, comma-separated)
selector stringPod selector labels (key=value, comma-separated)
load_balancer_hosts stringLoad balancer ingress hostnames and IPs
Deployment
DeploymentFieldsDeploymentFields represents Kubernetes deployment metadata fields
namespace stringNamespace the deployment lives in
replicas intDesired replica count
ready_replicas intNumber of ready replicas
available_replicas intNumber of available replicas
updated_replicas intNumber of replicas updated to the latest pod template
strategy stringRollout strategy (RollingUpdate, Recreate)
paused boolWhether rollouts are paused
images stringContainer images (comma-separated)
container_count intNumber of containers in the pod template
service_account stringService account the pods run as
Stateful Set
StatefulSetFieldsStatefulSetFields represents Kubernetes stateful set metadata fields
namespace stringNamespace the stateful set lives in
replicas intDesired replica count
ready_replicas intNumber of ready replicas
updated_replicas intNumber of replicas updated to the latest pod template
strategy stringUpdate strategy (RollingUpdate, OnDelete)
headless_service stringHeadless service governing the stateful set
images stringContainer images (comma-separated)
container_count intNumber of containers in the pod template
service_account stringService account the pods run as
volume_claims stringVolume claim templates (name:size/storageClass, comma-separated)
Cron Job
CronJobFieldsCronJobFields represents Kubernetes cron job metadata fields
namespace stringNamespace the cron job lives in
schedule stringCron schedule expression
timezone stringTime zone the schedule is evaluated in
suspended boolWhether the cron job is suspended
concurrency_policy stringConcurrency policy (Allow, Forbid, Replace)
images stringContainer images (comma-separated)
last_schedule_time stringWhen the cron job last fired
last_successful_time stringWhen the cron job last completed successfully
Pod
PodFieldsPodFields represents Kubernetes pod metadata fields
namespace stringNamespace the pod lives in
phase stringPod lifecycle phase (Pending, Running, Succeeded, Failed)
node stringNode the pod is scheduled on
images stringContainer images (comma-separated)
qos_class stringQuality of service class (Guaranteed, Burstable, BestEffort)
service_account stringService account the pod runs as
restart_count intTotal container restarts
owner_kind stringKind of the controlling owner (ReplicaSet, StatefulSet, DaemonSet, Job)
owner_name stringName of the controlling owner