Backstage Kubernetes brings your cluster view into the Backstage catalog. It is built for service owners. You can check the health of a service in one place across many clusters. The plugin highlights problems and lets you drill into deployments and pods for that service.
It connects to Kubernetes through the API and works with any cloud provider or managed platform.Use it to watch rollouts during a release. See errors sooner and reduce context switching. Bring runtime details next to docs, APIs, and ownership so teams can act faster.
For most teams the value is a clear picture of what is running, where it runs, and whether it is healthy.
Installation Instructions
These instructions apply to self-hosted Backstage only. To use this plugin on Roadie, visit the docs.
Install the frontend package
- Add the plugin to the app package
yarn add --cwd packages/app @backstage/plugin-kubernetes
- If you use the new frontend system then add the plugin to your app features
Edit packages/app/src/App.tsx
import { createApp } from '@backstage/app-defaults';
import kubernetesPlugin from '@backstage/plugin-kubernetes/alpha';
export const app = createApp({
features: [
kubernetesPlugin,
],
});
- If you use the classic frontend system then add the Kubernetes tab to the entity page
Edit packages/app/src/components/catalog/EntityPage.tsx
import React from 'react';
import { EntityLayout } from '@backstage/plugin-catalog';
import {
EntityKubernetesContent,
isKubernetesAvailable,
} from '@backstage/plugin-kubernetes';
const serviceEntityPage = (
<EntityLayout>
{/* other tabs */}
<EntityLayout.Route
path="/kubernetes"
title="Kubernetes"
if={isKubernetesAvailable}
>
<EntityKubernetesContent
// optional
refreshIntervalMs={30000}
/>
</EntityLayout.Route>
</EntityLayout>
);
export default serviceEntityPage;
- If you use the classic frontend system and your app defines custom APIs then register the Kubernetes APIs
Edit packages/app/src/apis.ts
import {
createApiFactory,
discoveryApiRef,
fetchApiRef,
} from '@backstage/core-plugin-api';
import {
kubernetesApiRef,
KubernetesBackendClient,
kubernetesAuthProvidersApiRef,
KubernetesAuthProviders,
kubernetesProxyApiRef,
KubernetesProxyClient,
} from '@backstage/plugin-kubernetes';
export const apis = [
// other apis
createApiFactory({
api: kubernetesAuthProvidersApiRef,
deps: {
// Provide the auth providers your app supports
// You can omit any providers you do not use
// For example googleAuthApi microsoftAuthApi githubAuthApi gitlabAuthApi oktaAuthApi
} as any,
factory: deps => new KubernetesAuthProviders(deps as any),
}),
createApiFactory({
api: kubernetesApiRef,
deps: {
discoveryApi: discoveryApiRef,
fetchApi: fetchApiRef,
kubernetesAuthProvidersApi: kubernetesAuthProvidersApiRef,
},
factory: ({ discoveryApi, fetchApi, kubernetesAuthProvidersApi }) =>
new KubernetesBackendClient({
discoveryApi,
fetchApi,
kubernetesAuthProvidersApi,
}),
}),
createApiFactory({
api: kubernetesProxyApiRef,
deps: { kubernetesApi: kubernetesApiRef },
factory: ({ kubernetesApi }) =>
new KubernetesProxyClient({ kubernetesApi }),
}),
];
- If you use the new frontend system then enable the entity content extension
Edit app-config.yaml
app:
extensions:
- entity-content:kubernetes/kubernetes
You can change where the tab shows with a filter
app:
extensions:
- entity-content:kubernetes/kubernetes:
config:
filter: kind:component,resource
Install the backend package
New backend system
- Add the backend package
yarn add --cwd packages/backend @backstage/plugin-kubernetes-backend
- Register the backend plugin in your backend entry
Edit packages/backend/src/index.ts
import { createBackend } from '@backstage/backend-defaults';
const backend = createBackend();
// Kubernetes backend
backend.add(
import('@backstage/plugin-kubernetes-backend').then(m => m.kubernetesPlugin()),
);
backend.start();
Classic backend system
- Add the backend package
yarn add --cwd packages/backend @backstage/plugin-kubernetes-backend
- Create the plugin router
Create packages/backend/src/plugins/kubernetes.ts
import { createRouter } from '@backstage/plugin-kubernetes-backend';
import { Router } from 'express';
import { PluginEnvironment } from '../types';
export default async function createPlugin(
env: PluginEnvironment,
): Promise<Router> {
return await createRouter({
logger: env.logger,
config: env.config,
catalogApi: env.catalogClient,
discovery: env.discovery,
permissions: env.permissions,
httpAuth: env.httpAuth,
identity: env.identity,
});
}
- Mount the router
Edit packages/backend/src/index.ts
import kubernetes from './plugins/kubernetes';
// inside main bootstrap
const apiRouter = Router();
// other routers
apiRouter.use('/kubernetes', await kubernetes(env));
Configure clusters in app config
Add your clusters and service locator
Edit app-config.yaml
kubernetes:
serviceLocatorMethod:
type: multiTenant
clusterLocatorMethods:
- type: config
clusters:
- url: https://your-cluster.example.com
name: my-cluster
authProvider: serviceAccount
skipTLSVerify: false
serviceAccountToken:
$env: K8S_SERVICE_ACCOUNT_TOKEN
dashboardUrl: https://k8s-ui.example.com
# optional if your cluster does not have metrics server
skipMetricsLookup: false
Notes
- authProvider can be serviceAccount aws aks oidc azure google among others depending on your environment
- For local dev you can use localKubectlProxy in place of url
Annotate catalog entities
Add Kubernetes annotations to the catalog entity so the tab knows what to load
Use id match
apiVersion: backstage.io/v1alpha1
kind: Component
metadata:
name: my-service
annotations:
backstage.io/kubernetes-id: my-service
spec:
type: service
owner: team-a
lifecycle: production
Or use a label selector
apiVersion: backstage.io/v1alpha1
kind: Component
metadata:
name: my-service
annotations:
backstage.io/kubernetes-label-selector: 'app=my-service'
spec:
type: service
owner: team-a
lifecycle: production
Optional tweaks
Change the tab refresh interval in the classic frontend
<EntityKubernetesContent refreshIntervalMs={15000} />
Show the tab on more kinds in the new frontend system
app:
extensions:
- entity-content:kubernetes/kubernetes:
config:
filter: kind:component,api,resource,system
Where you should see the plugin
- In the classic frontend you will get a Kubernetes tab on the entity page at path catalog default component yourcomponent kubernetes when the entity passes the isKubernetesAvailable check
- In the new frontend system you will get a Kubernetes tab once the extension is enabled and the entity filter matches
Things to Know
The Backstage Kubernetes plugin has two separate components:
- frontend: it will take care of displaying the information to the user.
- backend: it will take care of connecting to the Kubernetes clusters and sending the information to the frontend.
After installing the plugins, you have to configure them in two steps:
- Allow the backend to collect objects from your Kubernetes cluster(s).
- Surfacing your Kubernetes objects in catalog entities
Configuring Kubernetes Clusters
Here is a complete example of a configuration entry:
### app-config.yaml
kubernetes:
serviceLocatorMethod: 'multiTenant'
clusterLocatorMethods:
- 'config'
clusters:
- url: http://127.0.0.1:9999
name: minikube
authProvider: 'serviceAccount'
serviceAccountToken:
$env: K8S_MINIKUBE_TOKEN
- url: http://127.0.0.2:9999
name: gke-cluster-1
authProvider: 'google'
You can find the complete list of fields in the the official Backstage documentation.
Using RBAC Authorization
The current RBAC permissions required are read-only cluster wide, for the following objects:
- pods
- services
- configmaps
- deployments
- replicasets
- horizontalpodautoscalers
- ingresses
An example of a Role to grant read access to pods:
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: default
name: pod-reader
rules:
- apiGroups: ['']
resources: ['pods']
verbs: ['get', 'watch', 'list']
Surfacing your Kubernetes components as part of an entity
There are two ways to surface your Kubernetes components as part of an entity.
NOTE: The label selector takes precedence over the annotation/service id.
Common backstage.io/kubernetes-id
label
The following annotation must be added so that Backstage can detect that an entity has Kubernetes components.
### catalog-info.yaml
metadata:
annotations:
'backstage.io/kubernetes-id': <ENTITY_NAME>
...
In order for your Kubernetes components to show up in the service catalog as a part of an entity, your Kubernetes components themselves can have the following label:
"metadata": {
"labels": {
"backstage.io/kubernetes-id": <ENTITY_NAME>
...
}
}
Label selector query annotation
Via a label selector, the user can identify a set of objects.
You can write your own custom label selector query that Backstage will use to
lookup the objects. You can read
Labels and Selectors documentation
for more info.
### catalog-info.yaml
annotations:
'backstage.io/kubernetes-label-selector': 'app=my-app,component=front-end'
Example of steps to follow
-
Get the Kubernetes master base url
kubectl cluster-info
-
Get the service account token
kubectl get secret $(kubectl get sa <SERVICE_ACCOUNT_NAME> -o=json \ | jq -r '.secrets[0].name') -o=json \ | jq -r '.data["token"]' \ | base64 --decode \ | pbcopy
-
Register existing component in Backstage
# catalog-info.yaml apiVersion: backstage.io/v1alpha1 kind: Component metadata: name: <ENTITY_NAME> annotations: 'backstage.io/kubernetes-id': <ENTITY_NAME> spec: type: service lifecycle: production owner: guest
-
Add or update
app-config.local.yaml
with the following:# app-config.local.yaml kubernetes: serviceLocatorMethod: 'multiTenant' clusterLocatorMethods: - 'config' clusters: - url: <KUBERNETES_MASTER_BASE_URL_FROM_STEP_1> name: minikube serviceAccountToken: <TOKEN_FROM_STEP_2> authProvider: 'serviceAccount'
Changelog
This changelog is produced from commits made to the Backstage Kubernetes plugin since 8 months ago, and based on the code located here. It may not contain information about all commits. Releases and version bumps are intentionally omitted. This changelog is generated by AI.
Breaking changes
- Update Kubernetes client library to 1.1.2 in the plugin dependency tree. This library is now ESM only. If you import it in custom code you may need to adjust your imports or build setup. See #28198 merged 5 months ago
Bug fixes
- Remove double padding on the Kubernetes entity page. Content now aligns with the entity page layout. See #30490 merged 2 months ago
Dependencies
Set up Backstage in minutes with Roadie
Focus on using Backstage, rather than building and maintaining it.