Interactive Kubernetes Dashboards with MDX

Building dynamic, interactive documentation and dashboards using MDX components for Kubernetes monitoring and management

Interactive Kubernetes Dashboards with MDX 📊

MDX (Markdown + JSX) has revolutionized how we create technical documentation and interactive content. When combined with Kubernetes monitoring and management, it becomes a powerful tool for creating dynamic, engaging technical content that goes beyond static documentation.

Why MDX for Kubernetes Content?

Traditional Markdown is great for static documentation, but Kubernetes content often benefits from:

  • Interactive code examples that users can run
  • Live configuration snippets with syntax highlighting
  • Dynamic charts and graphs showing cluster metrics
  • Embedded terminal sessions for hands-on learning
  • Real-time status displays for cluster health

MDX makes all of this possible by allowing us to embed React components directly in our Markdown content.

Setting Up MDX with Astro

This blog uses @astrojs/mdx for seamless MDX support. Here’s how we configure it:

// astro.config.mjs
import { defineConfig } from 'astro/config';
import mdx from '@astrojs/mdx';

export default defineConfig({
  integrations: [mdx()],
  markdown: {
    shikiConfig: {
      theme: 'github-dark',
      wrap: true
    }
  }
});

Interactive Components for K8s Content

Code Block with Copy Functionality

Here’s how you can create interactive code blocks for Kubernetes manifests:

📋 Copy YAML to Clipboard

Live Configuration Examples

# Interactive Kubernetes Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.21
        ports:
        - containerPort: 80
        resources:
          requests:
            memory: "64Mi"
            cpu: "250m"
          limits:
            memory: "128Mi"
            cpu: "500m"

Interactive Metrics Dashboard

Imagine embedding live Prometheus metrics directly in your documentation:

// This would be a React component in a real implementation
function ClusterMetrics() {
  const [metrics, setMetrics] = useState(null);
  
  useEffect(() => {
    // Fetch live metrics from Prometheus API
    fetch('/api/metrics/cluster')
      .then(res => res.json())
      .then(setMetrics);
  }, []);
  
  return (
    <div className="metrics-dashboard">
      <h3>Cluster Health</h3>
      <div className="metric-grid">
        <MetricCard 
          title="CPU Usage" 
          value={metrics?.cpu || 'Loading...'} 
          status="healthy" 
        />
        <MetricCard 
          title="Memory Usage" 
          value={metrics?.memory || 'Loading...'} 
          status="warning" 
        />
        <MetricCard 
          title="Pod Count" 
          value={metrics?.pods || 'Loading...'} 
          status="healthy" 
        />
      </div>
    </div>
  );
}

Advanced MDX Patterns

Custom Kubernetes Components

// components/K8sResource.jsx
export function K8sResource({ kind, name, namespace, children }) {
  return (
    <div className="k8s-resource">
      <div className="resource-header">
        <span className="kind">{kind}</span>
        <span className="name">{name}</span>
        {namespace && <span className="namespace">{namespace}</span>}
      </div>
      <div className="resource-content">
        {children}
      </div>
    </div>
  );
}

// Usage in MDX
<K8sResource kind="Deployment" name="web-app" namespace="production">
  This deployment manages the web application pods...
</K8sResource>

Interactive Terminal Sessions

// components/Terminal.jsx
export function Terminal({ commands, output }) {
  const [currentCommand, setCurrentCommand] = useState(0);
  
  return (
    <div className="terminal">
      <div className="terminal-header">
        <span className="terminal-title">kubectl</span>
      </div>
      <div className="terminal-body">
        {commands.map((cmd, index) => (
          <div key={index} className="command-line">
            <span className="prompt">$</span>
            <span className="command">{cmd}</span>
            {index <= currentCommand && (
              <div className="output">{output[index]}</div>
            )}
          </div>
        ))}
      </div>
    </div>
  );
}

Real-World Examples

Cluster Status Dashboard

Here’s how you might create an interactive cluster status page:

// pages/cluster-status.mdx
import { ClusterOverview } from '../components/ClusterOverview';
import { NodeStatus } from '../components/NodeStatus';
import { PodMetrics } from '../components/PodMetrics';

# Cluster Status Dashboard

<ClusterOverview />

## Node Status

<NodeStatus />

## Pod Metrics

<PodMetrics />

Interactive Tutorial

// pages/k8s-tutorial.mdx
import { Step } from '../components/Step';
import { CodeBlock } from '../components/CodeBlock';

# Kubernetes Tutorial

<Step number={1} title="Create a Namespace">
  First, let's create a namespace for our application:
  
  <CodeBlock language="bash">
    kubectl create namespace my-app
  </CodeBlock>
</Step>

<Step number={2} title="Deploy an Application">
  Now let's deploy a simple nginx application:
  
  <CodeBlock language="yaml">
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: nginx
      namespace: my-app
    spec:
      replicas: 3
      selector:
        matchLabels:
          app: nginx
      template:
        metadata:
          labels:
            app: nginx
        spec:
          containers:
          - name: nginx
            image: nginx:1.21
            ports:
            - containerPort: 80
  </CodeBlock>
</Step>

Best Practices for K8s MDX Content

1. Component Reusability

Create reusable components for common Kubernetes patterns:

// components/K8sManifest.jsx
export function K8sManifest({ 
  title, 
  description, 
  yaml, 
  language = "yaml",
  showCopy = true 
}) {
  return (
    <div className="k8s-manifest">
      <h4>{title}</h4>
      <p>{description}</p>
      <CodeBlock 
        language={language} 
        code={yaml}
        showCopy={showCopy}
      />
    </div>
  );
}

2. Interactive Examples

Make your examples interactive and educational:

// components/InteractiveExample.jsx
export function InteractiveExample({ 
  title, 
  description, 
  initialCode, 
  expectedOutput 
}) {
  const [code, setCode] = useState(initialCode);
  const [output, setOutput] = useState('');
  
  const runCode = async () => {
    // Execute the code and show results
    const result = await executeKubectlCommand(code);
    setOutput(result);
  };
  
  return (
    <div className="interactive-example">
      <h4>{title}</h4>
      <p>{description}</p>
      <textarea 
        value={code} 
        onChange={(e) => setCode(e.target.value)}
        className="code-input"
      />
      <button onClick={runCode}>Run Command</button>
      {output && (
        <div className="output">
          <pre>{output}</pre>
        </div>
      )}
    </div>
  );
}

3. Progressive Disclosure

Use collapsible sections for complex configurations:

// components/CollapsibleSection.jsx
export function CollapsibleSection({ title, children, defaultOpen = false }) {
  const [isOpen, setIsOpen] = useState(defaultOpen);
  
  return (
    <div className="collapsible-section">
      <button 
        className="section-header"
        onClick={() => setIsOpen(!isOpen)}
      >
        <span>{title}</span>
        <span>{isOpen ? 'â–¼' : 'â–¶'}</span>
      </button>
      {isOpen && (
        <div className="section-content">
          {children}
        </div>
      )}
    </div>
  );
}

The Power of MDX for Technical Content

MDX transforms static documentation into interactive experiences:

  • Live code execution - Users can run commands directly in the browser
  • Dynamic content - Real-time data from your Kubernetes clusters
  • Interactive tutorials - Step-by-step guides with hands-on practice
  • Embedded tools - Terminal sessions, configuration editors, and more
  • Progressive disclosure - Complex information presented in digestible chunks

Getting Started

To start using MDX for your Kubernetes content:

  1. Install MDX support in your Astro project
  2. Create reusable components for common K8s patterns
  3. Build interactive examples that users can experiment with
  4. Integrate with monitoring tools for live data display
  5. Test thoroughly to ensure components work across different environments

The combination of MDX and Kubernetes content creates powerful, engaging documentation that goes far beyond traditional static pages. Your users will appreciate the interactive nature, and you’ll find it much easier to keep content up-to-date and relevant.

Ready to build your own interactive K8s documentation? Check out the MDX documentation and start experimenting with components!