KubExporter allows you to export resources from kubernetes as yaml/json files.
The configuration allows customization on which resources and which fields to exclude.
Download the latest binary from https://github.com/bakito/kubexporter/releases.
# Add the tap
brew tap bakito/tap
brew trust bakito/tap
# install kubexporter
brew install --cask kubexporterkubectl krew install exporter
kubectl exporter ...Export k8s cluster resources as YAML or JSON
Usage:
kubexporter [flags]
kubexporter [command]
Available Commands:
completion Generate the autocompletion script for the specified shell
decrypt Decrypt secrets in exported resource files
encrypt Encrypt secrets in exported resource files
help Help about any command
update-owner-references Update owner references of an export against the current cluster
Flags:
-a, --archive Create a tar.gz archive
--as string Username to impersonate for the operation. User could be a regular user or a service account in a namespace.
--as-group stringArray Group to impersonate for the operation, this flag can be repeated to specify multiple groups.
--as-uid string UID to impersonate for the operation.
--as-user-extra stringArray User extras to impersonate for the operation, this flag can be repeated to specify multiple values for the same key.
--certificate-authority string Path to a cert file for the certificate authority
-c, --clear-target Clear the target directory before exporting
--client-certificate string Path to a client certificate file for TLS
--client-key string Path to a client key file for TLS
--cluster string The name of the kubeconfig cluster to use
--config string config file
--context string The name of the kubeconfig context to use
--created-within duration The max allowed age duration for the resources
--disable-compression If true, opt-out of response compression for all requests to the server
-d, --exclude-defaults If enabled, default excludes will be applied. [apps.ControllerRevision, apps.ReplicaSet, batch.Job, Pod, ReplicationController, discovery.k8s.io.EndpointSlice, Endpoints, Event, events.k8s.io.Event, coordination.k8s.io.Lease, metrics.k8s.io.NodeMetrics, metrics.k8s.io.PodMetrics, ComponentStatus, Secret, LocalSubjectAccessReview, SelfSubjectAccessReview, SelfSubjectRulesReview, SubjectAccessReview, TokenReview, Binding]
-e, --exclude-kinds strings List all kinds to be excluded
-h, --help help for kubexporter
--include-cluster-resources Export cluster-scoped resources too, when a namespace filter is active
-i, --include-kinds strings List all kinds to be included
--insecure-skip-tls-verify If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure
--kubeconfig string Path to the kubeconfig file to use for CLI requests.
-l, --lists Export as lists instead of individual files
-n, --namespace strings A single namespace (default all)
--openreports OpenReports is enabled
--otlp-metrics OTLP Metrics are enabled
-o, --output string Output format. One of: (json, yaml, kyaml). (default "yaml")
-p, --progress string Progress mode bar|bubbles|simple|none (default "bar")
--proxy-url string Proxy URL to use for requests to the API server
-q, --quiet Output is prevented
--request-timeout string The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests. (default "0")
-s, --server string The address and port of the Kubernetes API server
--show-managed-fields If true, keep the managedFields when printing objects in JSON or YAML format.
--size Print the size of the exported files
--summary If enabled, a summary is printed
-t, --target string The target directory (default "exports")
--tls-server-name string Server name to use for server certificate validation. If it is not provided, the hostname used to contact the server is used
--token string Bearer token for authentication to the API server
--user string The name of the kubeconfig user to use
-v, --verbose Errors during export are listed in summary
--version version for kubexporter
-w, --worker int The number of parallel worker (default 1)
Use "kubexporter [command] --help" for more information about a command.
| bar | bubbles |
|---|---|
![]() |
![]() |
| simple | none |
|---|---|
![]() |
![]() |
KubExporter exports by default all resources and allows excluding unwanted resources. The benefit is that new custom resource definitions are automatically considered in the export.
Example configuration: config.yaml
Config Documentation:
# Excluded resources (struct)
excluded:
# List all kinds to be excluded ([]string)
kinds:
# List fields that should be removed for all resources before exported; slices are also traversed ([][]string)
fields:
# Kind specific excluded fields (map[string:[][]string])
kindFields:
# Allows to exclude single instances with certain field values (map[string:[]struct])
kindByField:
# List of fields to be preserved (struct)
preservedFields:
# Fields to be preserved ([][]string)
fields:
# Included resources (struct)
included:
# List all kinds to be included ([]string)
kinds:
# The max allowed age duration for the resources (int64)
createdWithin:
# Consider owner references for not excluded resources (bool)
considerOwnerReferences:
# Field masking config (struct)
masked:
# The replacement value for masked fields (string)
replacement:
# The checksum algorithm to use for masked fields md5|sha1|sha256 (default md5) (string)
checksum:
# The fields to mask for each kind (map[string:[][]string])
kindFields:
# Field encryption config (struct)
encrypted:
# The AES key to use for field encryption (string)
aesKey:
# The age public key for encryption (recipient) (string)
agePublicKey:
# The age identity for decryption (string or file path) (string)
ageIdentity:
# The fields to encrypt for each kind (map[string:[][]string])
kindFields:
# sort the slice field value before exporting (map[string:[][]string])
sortSlices:
# Custom resource file name template (string)
fileNameTemplate:
# Custom resource list file name template (string)
listFileNameTemplate:
# Export as lists instead of individual files (bool)
asLists:
# Kubernetes query page size (0 use default) (int)
queryPageSize:
# The target directory (string)
target:
# Clear the target directory before exporting (bool)
clearTarget:
# If enabled, a summary is printed (bool)
summary:
# Progress mode bar|bubbles|simple|none (string)
progress:
# A single namespace (default all) (string)
namespace:
# Multiple namespaces (joined with namespace, if both are set) ([]string)
namespaces:
# Export cluster-scoped resources too, when a namespace filter is active (bool)
includeClusterResources:
# The number of parallel worker (int)
worker:
# Create a tar.gz archive (bool)
archive:
# Number of days to keep old archives (int)
archiveRetentionDays:
# The target directory for the archive(default "exports") (string)
archiveTarget:
# S3 Configuration to upload the archive to an S3 compatible storage (struct)
s3:
# S3 Endpoint (string)
endpoint:
# Access key ID (string)
accessKeyID:
# Secret access key (string)
secretAccessKey:
# Session token (optional) (string)
token:
# Use HTTPS (default true) (bool)
secure:
# Bucket name (string)
bucket:
# Google storage bucket configuration (struct)
gcs:
# Bucket name (string)
bucket:
# Metrics configuration (struct)
metrics:
# OTel Metrics configuration (struct)
otlp:
# OTLP Metrics are enabled (bool)
enabled:
# OTLP Metrics endpoint (string)
endpoint:
# OTLP Metrics insecure (bool)
insecure:
# OpenReports configuration (struct)
openReports:
# OpenReports is enabled (bool)
enabled:
# Target namespace for Report (string)
namespace:
# Output is prevented (bool)
quiet:
# Errors during export are listed in summary (bool)
verbose:
# Print the size of the exported files (bool)
printSize:You can configure kubexporter to upload the created archive to an S3 compatible storage.
The following fields are available for S3 configuration:
endpoint: The S3 endpoint.accessKeyID: The access key ID.secretAccessKey: The secret access key.token: The session token (optional).secure: Set totruefor HTTPS,falsefor HTTP.bucket: The name of the S3 bucket.
Credentials must be provided in the config file. Environment variables are not automatically used if these fields are set (even if empty).
Example:
s3:
endpoint: <your-s3-endpoint>
accessKeyID: <your-access-key-id>
secretAccessKey: <your-secret-access-key>
token: <your-session-token> # Optional
secure: true # Use HTTPS (default)
bucket: <your-bucket-name>You can configure kubexporter to upload the created archive to a GCS bucket.
The following fields are available for GCS configuration:
bucket: The name of the GCS bucket.
Authentication to Google Cloud Storage is handled automatically via Application Default Credentials (ADC).
You can configure ADC in one of the following ways:
- Service Account Key File: Set the
GOOGLE_APPLICATION_CREDENTIALSenvironment variable to the path of the JSON file that contains your service account key.export GOOGLE_APPLICATION_CREDENTIALS="/path/to/your/keyfile.json"
- gcloud CLI: Authenticate with the gcloud CLI.
gcloud auth application-default login
- Workload Identity (Recommended for GKE): When running in a GKE cluster, the recommended way to authenticate is by using Workload Identity. This allows your Kubernetes pod to impersonate a Google Service Account without needing to handle service account keys.
Example:
gcs:
bucket: <your-bucket-name>kubexporter supports pushing metrics to OTel collectors.
metrics:
otlp:
enabled: true
endpoint: localhost:4317
insecure: true| Metric | Description |
|---|---|
| kubexporter.duration_seconds | Total export duration in seconds |
| kubexporter.errors | Number of errors encountered during export |
| kubexporter.exported_resources | Total number of exported resources |
| kubexporter.exported_size_bytes | Total size of exported resources in bytes |
| kubexporter.kinds | Number of kinds processed |
| kubexporter.namespaces | Number of namespaces containing exported resources |
| kubexporter.query_pages | Total number of query pages requested |
| kubexporter.resource.export_duration_seconds | Export duration per kind in seconds |
| kubexporter.resource.exported_instances | Number of exported resource instances per kind |
| kubexporter.resource.exported_size_bytes | Size of exported resources per kind in bytes |
| kubexporter.resource.instances | Number of resource instances found per kind |
| kubexporter.resource.query_duration_seconds | Query duration per kind in seconds |
| kubexporter.resource.query_pages | Number of query pages per kind |
A pre-configured Grafana sample dashboard is available at examples/grafana/dashboard.json.
OTLP Authentication headers can be defined via env variables with prefix KUBEXPORTER_METRICS_OTLP_HEADER_
E.g: KUBEXPORTER_METRICS_OTLP_HEADER_Authorization="Bearer <yourToken>
kubexporter can create OpenReports Report resources summarizing export results.
openReports:
enabled: true
namespace: defaultenabled: Enable OpenReports integration.namespace: Target namespace for theReportresource (required when enabled, unless running in a CronJob pod, where the pod's namespace is used automatically).
You can also enable OpenReports via CLI flag:
kubexporter --openreportsThe OpenReports CRDs must be installed in the target cluster before using this feature.
Install via Helm:
# Using the Helm repository
helm repo add openreports https://openreports.github.io/reports-api
helm upgrade --install openreports openreports/openreportsInstall via manifest:
kubectl apply -f https://github.com/openreports/reports-api/releases/latest/download/release.yamlThe service account or user running kubexporter needs permissions to create and update OpenReports resources.
For a namespaced Report:
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: kubexporter-openreports
namespace: default
rules:
- apiGroups: ["openreports.io"]
resources: ["reports"]
verbs: ["create", "update", "get"]
- apiGroups: [""]
resources: ["pods"]
verbs: ["get"]
- apiGroups: ["batch"]
resources: ["jobs"]
verbs: ["get"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: kubexporter-openreports
namespace: default
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: kubexporter-openreports
subjects:
- kind: ServiceAccount
name: <your-service-account>
namespace: defaultCronJob Owner Reference: When kubexporter runs inside a pod that belongs to a CronJob, it automatically adds an owner reference to that CronJob on the Report and uses the pod's namespace for the Report. The namespace configuration is not required in this case. If a different namespace is configured, an error is returned β the Report must be created in the same namespace as the running pod. This requires additional permissions to read Pods and Jobs, as shown above.
Allows updating Owner references against a running cluster.
kubexporter update-owner-references
FILE OWNER KIND OWNER NAME UID FROM UID TO
cert-manager/cilium.io.CiliumEndpoint.cert-manager-cainjector-7fd8f6bbbf-9nlf2.yaml Pod cert-manager-cainjector-7fd8f6bbbf-9nlf2 1d494969-hhhh-4c79-96d4-25d31c66c895 1d494969-db54-4c79-96d4-25d31c66c895
cert-manager/cilium.io.CiliumEndpoint.cert-manager-webhook-787cd749dc-7sfvq.yaml Pod cert-manager-webhook-787cd749dc-7sfvq-XXX eeeb48d9-751c-4aa9-9389-6aab845dba1e <NOT FOUND> Exported files with encrypted values can be decrypted with the decrypt command.
The decrypt command supports both age and AES encryption modes. Encrypted values are automatically detected
by their prefix (KUBEXPORTER_AGE@ for age, KUBEXPORTER_AES@ for AES).
Note: For encryption, age is preferred over AES when both keys are configured. For decryption, both age and AES keys can be provided simultaneously, allowing files with mixed encrypted values (some age, some AES) to be decrypted in a single pass.
Age encryption uses public-key cryptography. To encrypt, provide an age public key (recipient). To decrypt, provide the corresponding age identity.
Encrypt with age:
The age public key can be provided via --age-public-key flag, env variable KUBEXPORTER_AGE_PUBLIC_KEY, or from a
Kubernetes Secret:
kubexporter encrypt --age-public-key age1ql3z7hjy54pw3hyww5ayyfg7zqgvc7w3j2elw8zmrj2kg5sfn9aqmcac8p exports/Secret.my-secret.yaml
# Or from a Kubernetes Secret
kubexporter encrypt --age-public-key-secret-namespace default --age-public-key-secret-name kubexporter-age-key --age-public-key-secret-key public-key exports/Secret.my-secret.yamlDecrypt with age:
The age identity can be provided via --age-identity flag, env variable KUBEXPORTER_AGE_IDENTITY, or from a
Kubernetes Secret. The identity can be passed as a string or as a file path pointing to a file containing the
identity:
# Pass the identity string directly
kubexporter decrypt --age-identity "AGE-SECRET-KEY-1..." exports/Secret.my-secret.yaml
# Or pass a file path containing the identity
kubexporter decrypt --age-identity /path/to/age-identity.txt exports/Secret.my-secret.yaml
# Or from a Kubernetes Secret
kubexporter decrypt --age-identity-secret-namespace default --age-identity-secret-name kubexporter-age-key --age-identity-secret-key identity exports/Secret.my-secret.yamlThe AES key can be provided via arg --aes-key, env variable KUBEXPORTER_AES_KEY. If not provided the key can be
entered via password prompt.
The AES key can also be stored in a Kubernetes Secret:
kubexporter encrypt --aes-key-secret-namespace default --aes-key-secret-name kubexporter-key --aes-key-secret-key aes-key exports/Secret.my-secret.yaml
kubexporter decrypt --aes-key-secret-namespace default --aes-key-secret-name kubexporter-key --aes-key-secret-key aes-key exports/Secret.my-secret.yaml1 - n file paths are defined via command arguments.
kubexporter decrypt exports/argocd/Secret.argocd-secret.yaml
FILE NAMESPACE KIND NAME DECRYPTED FIELDS
exports/argocd/Secret.argocd-secret.yaml argocd Secret argocd-secret 5
kubexporter decrypt $(ls exports/argocd/Secret*)


