<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/">
    <channel>
        <title>Elastic Observability Labs - Articles by Peter Simkins</title>
        <link>https://www.elastic.co/observability-labs</link>
        <description>Trusted security news &amp; research from the team at Elastic.</description>
        <lastBuildDate>Wed, 22 Jul 2026 17:07:31 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>Elastic Observability Labs - Articles by Peter Simkins</title>
            <url>https://www.elastic.co/observability-labs/assets/observability-labs-thumbnail.png</url>
            <link>https://www.elastic.co/observability-labs</link>
        </image>
        <copyright>© 2026. Elasticsearch B.V. All Rights Reserved</copyright>
        <item>
            <title><![CDATA[Migrate your Grafana Kubernetes dashboard to Elastic Observability: same PromQL, 30x faster queries]]></title>
            <link>https://www.elastic.co/observability-labs/blog/grafana-elastic-kubernetes-dashboard-migration</link>
            <guid isPermaLink="false">grafana-elastic-kubernetes-dashboard-migration</guid>
            <pubDate>Wed, 22 Jul 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Take a real Grafana Kubernetes dashboard covering pod CPU, memory, node pressure, and restart counts, then migrate it into Elastic Observability with native PromQL in under an hour.]]></description>
            <content:encoded><![CDATA[<p>Elasticsearch now runs PromQL natively. Migrate a Grafana <strong>Kubernetes / Views / Global</strong> dashboard into <a href="https://www.elastic.co/docs/solutions/observability">Elastic Observability</a> with the <a href="https://github.com/elastic/observability-migration-platform">Observability Migration Platform</a>. The sample board covers pod CPU, working set memory, throttling signals, and container restart counts. With Kubernetes metrics already in Elasticsearch, the translation, validation, and upload steps typically fit in under an hour.</p>
<p>The migration tool keeps panel queries in PromQL instead of rewriting them into a new dialect, validates them when you pass <code>--validate</code>, and uploads compiled dashboards to Kibana. You still review the migration report and enable alerts on your schedule.</p>
<h2>Sample Grafana Kubernetes dashboard used in this migration</h2>
<p>The walkthrough uses <strong>Kubernetes / Views / Global</strong>, a community-style Grafana dashboard in the migration repository. It includes the signals operators check during an incident: namespace CPU and memory, throttling pressure, and restart counts.</p>
<p>Below are representative PromQL queries from the source dashboard:</p>
<pre><code class="language-promql"># Pod / container CPU by namespace
sum(rate(container_cpu_usage_seconds_total{image!=&quot;&quot;, cluster=&quot;$cluster&quot;}[$__rate_interval])) by (namespace)
</code></pre>
<pre><code class="language-promql"># Memory working set by namespace
sum(container_memory_working_set_bytes{image!=&quot;&quot;, cluster=&quot;$cluster&quot;}) by (namespace)
</code></pre>
<pre><code class="language-promql"># Node / CPU pressure style signal: throttled seconds
sum(rate(container_cpu_cfs_throttled_seconds_total{image!=&quot;&quot;, cluster=&quot;$cluster&quot;}[$__rate_interval])) by (namespace) &gt; 0
</code></pre>
<pre><code class="language-promql"># Container restart counts
sum(increase(kube_pod_container_status_restarts_total{cluster=&quot;$cluster&quot;}[$__rate_interval])) by (namespace) &gt; 0
</code></pre>
<p>If this board translates cleanly, most production Grafana Kubernetes folders are worth testing with the same workflow.</p>
<h2>Why Grafana-to-Elastic migration is faster now</h2>
<p>The migration platform automates the query translation and panel rebuilds that used to dominate Grafana moves. Native <a href="https://www.elastic.co/observability-labs/blog/prometheus-remote-write-elasticsearch">Prometheus Remote Write</a> and <a href="https://www.elastic.co/observability-labs/blog/elasticsearch-supports-promql">PromQL in Kibana</a> let you keep the dialect your on-call team already uses. The <code>--native-promql</code> flag passes PromQL through unchanged. See <a href="https://www.elastic.co/observability-labs/blog/prometheus-metrics-elasticsearch-faster-cheaper-datadog">Elasticsearch as a metrics engine</a> for storage and query context.</p>
<h2>Prerequisites</h2>
<p>You need an <a href="https://www.elastic.co/docs/solutions/observability/get-started">Elastic Observability Serverless</a> project, a <a href="https://www.elastic.co/docs/deploy-manage/api-keys/serverless-project-api-keys">project API key</a>, and the migration CLI installed from the <a href="https://github.com/elastic/observability-migration-platform">observability-migration-platform</a> repository.</p>
<p>Export your endpoints and API key:</p>
<pre><code class="language-bash">export ELASTICSEARCH_ENDPOINT=&quot;https://YOUR_ES_ENDPOINT&quot;
export KIBANA_ENDPOINT=&quot;https://YOUR_KIBANA_ENDPOINT&quot;
export KEY=&quot;YOUR_API_KEY&quot;
</code></pre>
<p>Install the CLI and confirm the toolchain:</p>
<pre><code class="language-bash">python3 -m venv .venv
.venv/bin/pip install &quot;.[all]&quot;
.venv/bin/obs-migrate doctor
</code></pre>
<p>The <code>doctor</code> command checks compile and lint dependencies. Resolve any errors before you migrate production dashboards. Pin a release tag if you plan to run this in CI.</p>
<h2>How do you get Kubernetes metrics into Elasticsearch?</h2>
<p>Empty panels after upload usually mean Elasticsearch does not yet have the series the PromQL references. Make sure to confirm ingest before you run the migration.</p>
<p>There are two common paths to do so:</p>
<ol>
<li><a href="https://www.elastic.co/observability-labs/blog/prometheus-remote-write-elasticsearch">Prometheus Remote Write into Elasticsearch</a> from kube-state-metrics, cAdvisor or kubelet metrics, and node exporters.</li>
<li>OpenTelemetry into managed OTLP for Kubernetes receivers, then explore in Discover.</li>
</ol>
<p>Test with a query such as <code>sum(rate(container_cpu_usage_seconds_total[5m])) by (namespace)</code> against Elastic. If that returns data, continue. If it does not, fix ingest first.</p>
<p><img src="https://www.elastic.co/observability-labs/assets/images/grafana-elastic-kubernetes-dashboard-migration/metrics-exploration.jpg" alt="Kubernetes metrics exploration in Discover with live CPU and memory charts" /></p>
<h2>Run the Grafana dashboard migration CLI</h2>
<p>Export your Grafana dashboard JSON, or copy the sample <code>k8s-views-global.json</code> from <code>infra/grafana/dashboards/</code> in the migration repo. Place files in a directory such as <code>./grafana_k8s_exports/</code>.</p>
<p>Run the migration from that directory:</p>
<pre><code class="language-bash">grafana-migrate \
  --source files \
  --input-dir ./grafana_k8s_exports \
  --output-dir ./migration_output \
  --assets all \
  --native-promql \
  --data-view &quot;metrics-*&quot; \
  --esql-index &quot;metrics-*&quot; \
  --upload \
  --kibana-url &quot;$KIBANA_ENDPOINT&quot; \
  --kibana-api-key &quot;$KEY&quot; \
  --ensure-data-views \
  --create-alert-rules \
  --validate \
  --es-url &quot;$ELASTICSEARCH_ENDPOINT&quot; \
  --es-api-key &quot;$KEY&quot;
</code></pre>
<p>These flags matter for Kubernetes boards:</p>
<ul>
<li><code>--native-promql</code> keeps pod CPU, memory, throttling, and restart queries in PromQL</li>
<li><code>--assets all</code> includes dashboards and Grafana PromQL alert definitions when present</li>
<li><code>--validate</code> runs emitted queries against Elasticsearch before upload</li>
<li><code>--create-alert-rules</code> creates Kibana rules in a disabled state</li>
</ul>
<p>The unified CLI performs the same work:</p>
<pre><code class="language-bash">obs-migrate migrate \
  --source grafana \
  --input-mode files \
  --input-dir ./grafana_k8s_exports \
  --output-dir ./migration_output \
  --assets all \
  --native-promql \
  --data-view &quot;metrics-*&quot; \
  --validate \
  --es-url &quot;$ELASTICSEARCH_ENDPOINT&quot; \
  --es-api-key &quot;$KEY&quot; \
  --kibana-url &quot;$KIBANA_ENDPOINT&quot; \
  --kibana-api-key &quot;$KEY&quot; \
  --upload \
  --create-alert-rules
</code></pre>
<p><img src="https://www.elastic.co/observability-labs/assets/images/grafana-elastic-kubernetes-dashboard-migration/migration-flow.png" alt="End-to-end Observability Migration Platform flow from Grafana extract through translate, validate, compile, and upload to Kibana" /></p>
<h2>Validate the migrated Grafana dashboard in Kibana</h2>
<p>Open Kibana → <strong>Dashboards</strong> and locate <strong>Kubernetes / Views / Global</strong>. Confirm that namespace or pod CPU utilization, memory working set panels, throttling or pressure widgets, and restart charts return data for your selected time range.</p>
<p>If you migrated alerts, open <strong>Observability → Rules</strong>. Imported rules remain disabled until you enable them after reviewing thresholds.</p>
<p><img src="https://www.elastic.co/observability-labs/assets/images/grafana-elastic-kubernetes-dashboard-migration/kibana-k8s-overview.jpg" alt="Kubernetes overview dashboard in Kibana with cluster and node CPU, memory, and readiness views after Grafana migration" /></p>
<p>The CLI also writes local artifacts under <code>./migration_output/</code>:</p>
<ul>
<li><code>dashboards/yaml/</code> contains the translated dashboard definition.</li>
<li><code>dashboards/migration_report.json</code> lists panels that translated automatically and panels flagged for manual review.</li>
<li><code>alerts/</code> contains alert translations when alert definitions were included in the export.</li>
</ul>
<h2>What do you do when Grafana panels don't migrate automatically?</h2>
<p>The Observability Migration Platform flags PromQL expressions that do not translate automatically. Hard joins, unusual arithmetic, and a few Alertmanager-era edge cases appear as manual-review entries in the migration report rather than as silently broken charts.</p>
<table>
<thead>
<tr>
<th>Result</th>
<th>Recommended action</th>
</tr>
</thead>
<tbody>
<tr>
<td>Panel returns data</td>
<td>Accept the translation and continue</td>
</tr>
<tr>
<td>Panel is empty</td>
<td>Confirm metric names exist in <code>metrics-*</code>, then widen or shift the time range</td>
</tr>
<tr>
<td>Manual-review marker</td>
<td>Open the original PromQL and simplify or redesign the panel</td>
</tr>
<tr>
<td>Alert never fires</td>
<td>Confirm the rule is enabled and thresholds match your environment</td>
</tr>
</tbody>
</table>
<p>This path migrates Grafana PromQL dashboards and Grafana unified PromQL alert definitions into Kibana. It does not ingest a raw <code>alertmanager.yml</code>. The goal is to keep the PromQL your pager already trusts instead of rebuilding the Kubernetes board from zero.</p>
<h2>Related guides</h2>
<p>For platform-level context, see <a href="https://www.elastic.co/observability-labs/blog/migrate-datadog-grafana-dashboards-alerts-to-kibana">Migrating Datadog and Grafana dashboards and alerts to Kibana</a>. Review <a href="https://github.com/elastic/observability-migration-platform/blob/main/docs/known-limitations.md">known limitations</a> before you migrate every production folder.</p>
]]></content:encoded>
            <category>observability-labs</category>
            <enclosure url="https://www.elastic.co/observability-labs/assets/images/grafana-elastic-kubernetes-dashboard-migration/header.jpg" length="0" type="image/jpg"/>
        </item>
    </channel>
</rss>