Kiali Service Mesh logo

Backstage Kiali Service Mesh Plugin

Created by Red Hat

Kiali is a console for the Istio service mesh. It shows how services talk to each other. It highlights health issues, errors, and config problems. It gives graphs, metrics, and validation so you can understand your mesh faster.

The Kiali Service Mesh plugin brings that view into Backstage. It surfaces mesh data for each catalog entity. You can open a Kiali tab in an entity to see overview by namespace with health, canary info, and Istio config warnings. It can also live as a full page when you want to browse the mesh across namespaces.Typical use cases include incident triage, release checks, and day two operations. Teams get one place to confirm traffic health next to code, pipelines, and docs. From cards you can jump into the full Kiali view when you need deeper graphs.

Installation Instructions

These instructions apply to self-hosted Backstage only.

Add the frontend package

Copy
yarn workspace app add @janus-idp/backstage-plugin-kiali

Add a Kiali page under the Catalog Entity view

Open packages app src components catalog EntityPage.tsx. Import the components.

Copy
// packages/app/src/components/catalog/EntityPage.tsx
import React from 'react';
import { EntityLayout } from '@backstage/plugin-catalog';
import { EntitySwitch, isComponentType } from '@backstage/plugin-catalog';
import { EntityKialiContent, isKialiAvailable } from '@janus-idp/backstage-plugin-kiali';

Add a new route so users can open Kiali for a service or component. Place this inside your EntityLayout with your other tabs.

Copy
// inside <EntityLayout>
<EntitySwitch>
  <EntitySwitch.Case if={isComponentType('service')}>
    <EntityLayout.Route path="/kiali" title="Kiali">
      <EntityKialiContent />
    </EntityLayout.Route>
  </EntitySwitch.Case>

  <EntitySwitch.Case if={isKialiAvailable}>
    <EntityLayout.Route path="/kiali" title="Kiali">
      <EntityKialiContent />
    </EntityLayout.Route>
  </EntitySwitch.Case>
</EntitySwitch>

You can also expose a standalone page if you want a top level route.

Copy
// packages/app/src/App.tsx
import React from 'react';
import { FlatRoutes, Route } from '@backstage/core-app-api';
import { KialiPage } from '@janus-idp/backstage-plugin-kiali';

export const AppRoutes = () => (
  <FlatRoutes>
    <Route path="/kiali" element={<KialiPage />} />
  </FlatRoutes>
);

Add a sidebar link if you created the top level page.

Copy
// packages/app/src/components/Root/Root.tsx
import { SidebarItem } from '@backstage/core-components';

// inside your <Sidebar>
<SidebarItem to="kiali" text="Kiali" />

Annotate catalog entities

Add annotations to each service that you want to link with Kiali. Set the namespace and app name that Kiali uses.

Copy
# catalog info file for a service entity
apiVersion: backstage.io/v1alpha1
kind: Component
metadata:
  name: payment-service
  annotations:
    kiali.io/namespace: payments
    kiali.io/app: payment-service
    kiali.io/cluster: dev
spec:
  type: service
  owner: team-payments
  lifecycle: production

For a single Kiali instance you can skip the cluster annotation. For multiple Kiali instances set the cluster value to match the backend config.

Configure the plugin in app config

Add the Kiali target or targets.

Single instance

Copy
# app-config.yaml
kiali:
  baseUrl: https://kiali.example.com

Multiple instances

Copy
# app-config.yaml
kiali:
  clusters:
    - name: dev
      baseUrl: https://kiali.dev.example.com
    - name: prod
      baseUrl: https://kiali.prod.example.com

If your Kiali needs auth through a token set it in the backend config section. Use environment variables for secrets.

Copy
# app-config.yaml
backend:
  reading:
    allow:
      - host: kiali.example.com
  auth:
    keys:
      - secret: ${BACKEND_SECRET}
kiali:
  baseUrl: https://kiali.example.com
  auth:
    type: bearer
    token: ${KIALI_TOKEN}

Install the backend using the new backend system

Add the package.

Copy
yarn workspace backend add @janus-idp/backstage-plugin-kiali-backend

Wire the module in the new backend entry point.

Copy
// packages/backend/src/index.ts
import { createBackend } from '@backstage/backend-defaults';
import { kialiPlugin } from '@janus-idp/backstage-plugin-kiali-backend';

const backend = createBackend();
backend.add(kialiPlugin());
backend.start();

This registers the Kiali backend plugin and exposes its routes under the default path that the module provides. You do not need to add a proxy rule by hand. The backend plugin reads the kiali config you added.

If you prefer an explicit mount path you can pass a path option when adding the plugin.

Copy
backend.add(kialiPlugin({ mountPoint: '/kiali' }));

Install the backend using the old backend system

Add the package.

Copy
yarn workspace backend add @janus-idp/backstage-plugin-kiali-backend

Create the plugin router file.

Copy
// packages/backend/src/plugins/kiali.ts
import { Router } from 'express';
import { PluginEnvironment } from '../types';
import { createRouter } from '@janus-idp/backstage-plugin-kiali-backend';

export default async function createPlugin(
  env: PluginEnvironment,
): Promise<Router> {
  return await createRouter({
    logger: env.logger,
    config: env.config,
    discovery: env.discovery,
    reader: env.reader,
  });
}

Mount the router in the backend index file.

Copy
// packages/backend/src/index.ts
import kiali from './plugins/kiali';
import { useHotMemoize } from './utils';

async function main() {
  const env = await createEnv('plugin');

  const apiRouter = Router();
  apiRouter.use(
    '/kiali',
    await useHotMemoize(module, () => kiali(env)),
  );

  // attach apiRouter to service
}

Optional proxy setup when you do not use the backend package

If you choose not to install the backend package you can proxy the Kiali API through the Backstage proxy. This is useful for quick tests.

Copy
# app-config.yaml
proxy:
  '/kiali':
    target: https://kiali.example.com
    headers:
      Authorization: Bearer ${KIALI_TOKEN}

Update the frontend plugin config to point to the proxy path.

Copy
kiali:
  baseUrl: /api/proxy/kiali

Environment variables

Set any secrets through your runtime environment.

Copy
export KIALI_TOKEN='your token'
export BACKEND_SECRET='your backend secret'

Summary of where things go

  • Frontend package added to the app workspace
  • Entity tab added in packages app src components catalog EntityPage.tsx
  • Optional top level page added in packages app src App.tsx and a sidebar link in Root.tsx
  • Backend module added to packages backend src index.ts for the new system
  • Or a router created under packages backend src plugins kiali.ts and mounted in packages backend src index.ts for the old system
  • Config placed in app config yaml under kiali and optional proxy sections

Set up Backstage in minutes with Roadie