<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Nadav Erell</title>
    <description>The latest articles on DEV Community by Nadav Erell (@nadaverell).</description>
    <link>https://dev.to/nadaverell</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3749337%2F54a4d440-7b70-474c-babc-869b6a2cc576.png</url>
      <title>DEV Community: Nadav Erell</title>
      <link>https://dev.to/nadaverell</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/nadaverell"/>
    <language>en</language>
    <item>
      <title>Kubernetes 1.37 Breaking Changes: What to Check Before You Upgrade</title>
      <dc:creator>Nadav Erell</dc:creator>
      <pubDate>Fri, 28 Aug 2026 13:57:52 +0000</pubDate>
      <link>https://dev.to/nadaverell/kubernetes-137-breaking-changes-what-to-check-before-you-upgrade-1lgk</link>
      <guid>https://dev.to/nadaverell/kubernetes-137-breaking-changes-what-to-check-before-you-upgrade-1lgk</guid>
      <description>&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# kubelet configuration - added for sidecar support, harmless ever since&lt;/span&gt;
&lt;span class="na"&gt;featureGates&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;SidecarContainers&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Harmless until Kubernetes 1.37. The feature went GA in 1.33 and the gate has been a no-op even longer - and 1.37 removes it. A kubelet that finds a removed gate in its config doesn't warn, it refuses to start. On upgrade day that looks like new nodes going NotReady over a line nobody has touched since it was added. The same applies to a control-plane component carrying it in &lt;code&gt;--feature-gates&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;SidecarContainers is one of 25 gates removed in 1.37. Another 13 get locked to fixed values, and an explicit setting that contradicts a locked default fails the same way.&lt;/p&gt;

&lt;p&gt;Kubernetes 1.37 was &lt;a href="https://github.com/kubernetes/kubernetes/releases/tag/v1.37.0" rel="noopener noreferrer"&gt;released on August 26, 2026&lt;/a&gt;. The gate removals are the sharpest edge, but not the only one: the release also drops 18 kubelet flags, kubeadm's v1beta3 config format, and an alpha scheduling API, removes a batch of metrics, changes what &lt;code&gt;eventRecordQPS: 0&lt;/code&gt; means, and starts the kube-proxy move from iptables to nftables. The feature side of the release - KYAML output for kubectl, pod-level resources, and DRA device taints and tolerations going stable, among the 16 graduations - is covered in &lt;a href="https://kubernetes.io/blog/2026/08/26/kubernetes-v1-37-release/" rel="noopener noreferrer"&gt;the official v1.37 announcement&lt;/a&gt;; this post is about the upgrade side. All of it is in &lt;a href="https://github.com/kubernetes/kubernetes/blob/release-1.37/CHANGELOG/CHANGELOG-1.37.md" rel="noopener noreferrer"&gt;the changelog&lt;/a&gt;. The work is figuring out which of it exists in &lt;em&gt;your&lt;/em&gt; cluster.&lt;/p&gt;

&lt;p&gt;This post walks through each change and how to check for it by hand. If you'd rather not do that, &lt;a href="https://radarhq.io" rel="noopener noreferrer"&gt;Radar&lt;/a&gt; has a dedicated view for exactly this - Upgrade impact - which runs every one of these checks against your live cluster and reports what it found per change (how to run it). Here it is on a GKE cluster:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F82qwlrv2gd6kz17hvco1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F82qwlrv2gd6kz17hvco1.png" alt="Radar's Upgrade impact view on a GKE cluster targeting Kubernetes 1.37: Admission webhook readiness, CRD conversion webhook readiness, and Node drain feasibility rows marked Blocked, plus the expanded kube-proxy mode transition check showing the finding 'Linux proxy mode is not explicit' with its impact, remediation, and the kube-system/kube-proxy DaemonSet as evidence" width="800" height="424"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What breaks in Kubernetes 1.37
&lt;/h2&gt;

&lt;p&gt;The short version:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Change in 1.37&lt;/th&gt;
&lt;th&gt;What happens on upgrade&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;25 feature gates removed, 13 locked to defaults&lt;/td&gt;
&lt;td&gt;Component rejects the setting and fails to start&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;--concurrent-service-syncs&lt;/code&gt;, &lt;code&gt;PodGroupWorkloadExists&lt;/code&gt; admission plugin removed&lt;/td&gt;
&lt;td&gt;Component fails to start&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;18 kubelet cAdvisor flags removed&lt;/td&gt;
&lt;td&gt;Kubelet fails to start&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Static Pods referencing Secrets or ConfigMaps&lt;/td&gt;
&lt;td&gt;The static Pod cannot start&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;scheduling.k8s.io/v1alpha2&lt;/code&gt; Workload and PodGroup dropped&lt;/td&gt;
&lt;td&gt;Stored objects must be deleted before the upgrade&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;kubeadm v1beta3 configuration API removed&lt;/td&gt;
&lt;td&gt;kubeadm rejects the stored config&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;eventRecordQPS: 0&lt;/code&gt; semantics change&lt;/td&gt;
&lt;td&gt;Event rate limit silently lifts from 5/s to unlimited&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SELinux mount-time labeling expands&lt;/td&gt;
&lt;td&gt;Conflicting labels on shared volumes can leave Pods in ContainerCreating&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;API-server, DRA, and cAdvisor metric changes&lt;/td&gt;
&lt;td&gt;Alerts and dashboards silently stop matching data&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;kube-proxy implicit mode&lt;/td&gt;
&lt;td&gt;Warnings start in 1.37; the Linux default flips to nftables in 1.40&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The first six rows are the ones to clear before upgrading: they can keep a component from starting or stop the upgrade itself. The rest change runtime behavior or monitoring, or set up work for 1.40.&lt;/p&gt;

&lt;h2&gt;
  
  
  Feature gates, component flags, and kubeadm config removed in 1.37
&lt;/h2&gt;

&lt;p&gt;Start with the gates, because they're the likeliest thing to actually be in your cluster. 1.37 removes 25 feature gates and locks 13 more to their defaults; the exact diff is in the official &lt;a href="https://github.com/kubernetes/kubernetes/blob/release-1.37/test/compatibility_lifecycle/reference/versioned_feature_list.yaml" rel="noopener noreferrer"&gt;feature lifecycle lists&lt;/a&gt;. A component started with a removed gate, or a locked gate set to a non-default value, refuses to start.&lt;/p&gt;

&lt;p&gt;The removed set includes gates people actually set by hand: SidecarContainers, &lt;code&gt;JobSuccessPolicy&lt;/code&gt;, &lt;code&gt;PodLifecycleSleepAction&lt;/code&gt;, &lt;code&gt;SchedulerQueueingHints&lt;/code&gt;. These sit in &lt;code&gt;--feature-gates&lt;/code&gt; arguments and kubelet &lt;code&gt;featureGates&lt;/code&gt; blocks for years because nothing ever complains about them. Until the release that removes them.&lt;/p&gt;

&lt;p&gt;To check a node by hand, read its effective kubelet config through the API:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get &lt;span class="nt"&gt;--raw&lt;/span&gt; &lt;span class="s2"&gt;"/api/v1/nodes/&lt;/span&gt;&lt;span class="nv"&gt;$NODE&lt;/span&gt;&lt;span class="s2"&gt;/proxy/configz"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  | jq &lt;span class="s1"&gt;'.kubeletconfig | {featureGates, eventRecordQPS}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Two more removals fail the same way: kube-controller-manager's &lt;code&gt;--concurrent-service-syncs&lt;/code&gt; flag, and the &lt;code&gt;PodGroupWorkloadExists&lt;/code&gt; admission plugin. The plugin is rejected whether it appears in &lt;code&gt;--enable-admission-plugins&lt;/code&gt; or &lt;code&gt;--disable-admission-plugins&lt;/code&gt; - yes, &lt;em&gt;disabling&lt;/em&gt; a plugin that no longer exists also keeps the API server from starting.&lt;/p&gt;

&lt;p&gt;One removed gate carries a behavior change with it: &lt;code&gt;PreventStaticPodAPIReferences&lt;/code&gt; is gone, and with it the opt-out that let static Pods reference Secrets and ConfigMaps. A static Pod that still does gets its node configuration rejected on 1.37 and cannot start.&lt;/p&gt;

&lt;p&gt;In Radar's Upgrade impact report, the gate check reads every node's configz and every control-plane Pod's arguments (including split &lt;code&gt;command&lt;/code&gt;/&lt;code&gt;args&lt;/code&gt; forms) and names the exact gate on the exact node.&lt;/p&gt;

&lt;h3&gt;
  
  
  18 kubelet cAdvisor flags are removed
&lt;/h3&gt;

&lt;p&gt;The kubelet loses 18 cAdvisor flags on top of that (&lt;code&gt;--enable-load-reader&lt;/code&gt;, &lt;code&gt;--containerd&lt;/code&gt;, the whole &lt;code&gt;--storage-driver-*&lt;/code&gt; family; &lt;code&gt;--housekeeping-interval&lt;/code&gt; survives). These are harder to audit than the gates. They live in systemd units and bootstrap scripts on the node itself, where no Kubernetes API can see them, so checking by hand means a pass over every node's kubelet startup arguments.&lt;/p&gt;

&lt;p&gt;Radar can't see your systemd units either - nothing with only API access can - so instead of pretending the check passed, it hands you the list of 18 flags to grep for on your nodes.&lt;/p&gt;

&lt;h3&gt;
  
  
  kubeadm v1beta3 is gone
&lt;/h3&gt;

&lt;p&gt;On kubeadm clusters, the v1beta3 config format is gone too. If &lt;code&gt;kubeadm-config&lt;/code&gt; in kube-system still holds v1beta3 documents, run &lt;code&gt;kubeadm config migrate&lt;/code&gt; with a pre-1.37 binary &lt;em&gt;before&lt;/em&gt; upgrading; kubeadm 1.37 won't accept the old format even to migrate it. The &lt;code&gt;PublicKeysECDSA&lt;/code&gt; and &lt;code&gt;NodeLocalCRISocket&lt;/code&gt; kubeadm gates go with it.&lt;/p&gt;

&lt;h2&gt;
  
  
  scheduling.k8s.io/v1alpha2: delete stored objects before you upgrade
&lt;/h2&gt;

&lt;p&gt;If you never enabled the alpha scheduling gates, skip this section. It doesn't apply to you.&lt;/p&gt;

&lt;p&gt;For everyone else: 1.37 stops serving &lt;code&gt;scheduling.k8s.io/v1alpha2&lt;/code&gt;, the alpha gang-scheduling API, as Workload and PodGroup &lt;a href="https://github.com/kubernetes/kubernetes/pull/140184" rel="noopener noreferrer"&gt;promote to v1beta1&lt;/a&gt;. The trap is the order of operations. Delete the stored v1alpha2 objects &lt;em&gt;before&lt;/em&gt; the upgrade, then recreate them as v1beta1 after the control plane reaches 1.37 - and expect to update the manifests to the v1beta1 schema, not just the apiVersion line. Upgrade first and the stored objects block you. Recreate too early and v1beta1 isn't served yet.&lt;/p&gt;

&lt;p&gt;Worth saying clearly: this is the only served API that 1.37 removes. Deployments, StatefulSets, Services - manifests that were valid on 1.36 remain valid on 1.37. (kubeadm's v1beta3 above is a config-file format, not an API the cluster serves.)&lt;/p&gt;

&lt;h2&gt;
  
  
  eventRecordQPS: 0 now means unlimited
&lt;/h2&gt;

&lt;p&gt;This one changes silently, which is why I'd check it even if you're confident about everything else.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# kubelet configuration, valid on 1.36 and 1.37 - with different meanings&lt;/span&gt;
&lt;span class="na"&gt;eventRecordQPS&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On 1.36, that zero doesn't mean what it looks like: it reaches client-go, which quietly substitutes its own fallback of 5 events per second. On 1.37, zero means zero throttling. The kubelet starts fine. Nothing warns. Every node carrying the setting just starts recording events as fast as it produces them. This was the one that surprised us most going through the changelog - nothing in the kubelet's own configuration surface hints that the zero was being overridden downstream.&lt;/p&gt;

&lt;p&gt;The upstream recommendation is an explicit 50, the normal kubelet default - or 5, if you were deliberately relying on the old fallback. The &lt;code&gt;configz&lt;/code&gt; command above shows the live value per node, and Radar flags every node whose effective config carries the setting.&lt;/p&gt;

&lt;h2&gt;
  
  
  Removed metrics: cAdvisor series, DRA renames, API-server cache stats
&lt;/h2&gt;

&lt;p&gt;None of the metric changes will block your upgrade. What they'll do is quietly break the dashboards and alerts you'd use to notice everything else on this page.&lt;/p&gt;

&lt;p&gt;1.37 replaces the API-server cache-list metrics with &lt;code&gt;apiserver_storage_list_*{storage="watchcache"}&lt;/code&gt; equivalents, renames DRA metrics, and drops several cAdvisor series: &lt;code&gt;container_cpu_load_average_10s&lt;/code&gt;, &lt;code&gt;container_cpu_load_d_average_10s&lt;/code&gt;, &lt;code&gt;container_tasks_state&lt;/code&gt;, the custom &lt;code&gt;container_application_*&lt;/code&gt; metrics, and &lt;code&gt;userDefinedMetrics&lt;/code&gt; in the kubelet's &lt;code&gt;/stats/summary&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The failure mode is silence. A PrometheusRule referencing a removed metric doesn't error; the expression just stops matching series, and the alert can never fire again. Grep your rules for the removed cAdvisor and cache-list names; the DRA renames are in the changelog:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get prometheusrules &lt;span class="nt"&gt;-A&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; yaml &lt;span class="se"&gt;\&lt;/span&gt;
  | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-nE&lt;/span&gt; &lt;span class="s1"&gt;'container_tasks_state|container_cpu_load(_d)?_average_10s|container_application_|apiserver_cache_list_'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Radar runs the same check against every PrometheusRule expression in the cluster and points at the exact expression and metric token. Where upstream removed a metric without a replacement, the finding says so rather than inventing one.&lt;/p&gt;

&lt;h2&gt;
  
  
  kube-proxy mode: warnings in 1.37, nftables default in 1.40
&lt;/h2&gt;

&lt;p&gt;Nothing about how kube-proxy moves traffic changes in 1.37. What starts is the countdown: the implicit Linux default flips from iptables to nftables in 1.40 (&lt;a href="https://github.com/kubernetes/enhancements/tree/master/keps/sig-network/5343-nftables-to-default" rel="noopener noreferrer"&gt;KEP-5343&lt;/a&gt;), and IPVS mode begins a staged deprecation - expected disabled by default in 1.40 and removed in 1.43 (&lt;a href="https://github.com/kubernetes/enhancements/tree/master/keps/sig-network/5495-deprecate-ipvs-mode-in-kube-proxy" rel="noopener noreferrer"&gt;KEP-5495&lt;/a&gt;). So 1.37 starts warning wherever the proxy mode is implicit.&lt;/p&gt;

&lt;p&gt;That's the finding expanded in the screenshot at the top - "Linux proxy mode is not explicit", on the kube-system/kube-proxy DaemonSet, with both KEPs linked. The fix is one line: set the mode explicitly, iptables or nftables, after validating whichever backend you pick. Set it now and there's nothing left to do when 1.40 arrives.&lt;/p&gt;

&lt;h2&gt;
  
  
  SELinux mount-time labeling applies to more volumes
&lt;/h2&gt;

&lt;p&gt;This one only matters on SELinux-enforcing nodes. 1.37 makes more volume shapes eligible for mount-time labeling instead of recursive relabeling. Mounts get faster. But a volume shared by Pods with conflicting SELinux labels stops being slow-but-tolerated: the kubelet can mount it with only one context, and a Pod requesting a different label can hang in ContainerCreating.&lt;/p&gt;

&lt;p&gt;The knobs are explicit. Align the SELinux label across every Pod sharing a volume, or set &lt;code&gt;seLinuxChangePolicy: Recursive&lt;/code&gt; in the Pod's &lt;code&gt;securityContext&lt;/code&gt; to keep the old behavior for that Pod. You can also defer the whole transition by setting the SELinuxMount feature gate to false on every kubelet, but that opt-out works for 1.37 only; the gate is expected to lock enabled in 1.38.&lt;/p&gt;

&lt;p&gt;Radar warns on conflicts it can actually observe (kubelet mismatch metrics, SELinuxLabelConflict Events) and flags shared-volume setups that could conflict for review.&lt;/p&gt;

&lt;h2&gt;
  
  
  Upgrade impact: check your cluster for 1.37 in one command
&lt;/h2&gt;

&lt;p&gt;Everything above is public knowledge - most of this list came out of the changelog pass we did while updating Radar's checks for 1.37. What no changelog can tell you is whether &lt;em&gt;your&lt;/em&gt; cluster has any of it: a locked gate in one node pool's kubelet config, a v1alpha2 object left over from an experiment, or a &lt;code&gt;container_tasks_state&lt;/code&gt; alert nobody has looked at in two years.&lt;/p&gt;

&lt;p&gt;That's what the Upgrade impact view is for. It ships in &lt;a href="https://github.com/skyhook-io/radar" rel="noopener noreferrer"&gt;open-source Radar&lt;/a&gt;, with the check catalog updated for 1.37:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-fsSL&lt;/span&gt; https://get.radarhq.io | sh &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; radar
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then open Checks in the sidebar, switch to the Upgrade impact tab, pick 1.37 as the target, and find out whether &lt;code&gt;SidecarContainers: true&lt;/code&gt; is still set somewhere in your fleet.&lt;/p&gt;

&lt;p&gt;A few things about how the report behaves, because they decide whether you can act on it without re-verifying everything yourself.&lt;/p&gt;

&lt;h3&gt;
  
  
  Radar checks the upgrade path, not just the target
&lt;/h3&gt;

&lt;p&gt;Each check is bound to the release that makes it relevant, and only the ones your upgrade path crosses run. A cluster on 1.35 targeting 1.37 gets the 1.36 boundary checked too; a cluster already on 1.37 isn't nagged about gates it can no longer have. The release-specific checks land on top of the standing ones in the screenshot: admission webhook readiness, CRD conversion webhook readiness, node drain feasibility, removed API usage.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fuugajdo2tonoey15nxro.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fuugajdo2tonoey15nxro.png" alt="Release-path gating: a cluster on 1.35 targeting 1.37 runs the 1.36 and 1.37 check groups, while the 1.38 group is skipped as beyond the target" width="799" height="285"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Every finding includes its evidence
&lt;/h3&gt;

&lt;p&gt;Not "you may be affected by the cAdvisor removals" but the specific field on the specific object: a configz path, a container argument, a stored object's &lt;code&gt;apiVersion&lt;/code&gt;, an expression inside a PrometheusRule. A blocker means Radar actually observed configuration or stored API that will reject startup or the upgrade. Warnings cover observed behavioral and monitoring impact. Review is everything that needs a human: the kubelet flags Radar can't read, the transitions you have to schedule.&lt;/p&gt;

&lt;h3&gt;
  
  
  Unknown is not green
&lt;/h3&gt;

&lt;p&gt;"Couldn't check" is never reported as a pass. When Radar can't inspect a surface, the result is Unknown, not green. On the GKE cluster in the screenshot, control-plane checks that need mirror Pods come back N/A, provider-managed: Google owns that surface, and you couldn't fix a finding there anyway. The same absence on a self-managed cluster is Unknown, because there the surface is yours. It's the same reasoning that shaped &lt;a href="https://radarhq.io/blog/kubernetes-network-reachability" rel="noopener noreferrer"&gt;Reachability's verdict semantics&lt;/a&gt;, and it's why the kubelet-flags check above gives you a grep list instead of a checkmark.&lt;/p&gt;

&lt;p&gt;One more note for GKE, EKS, and AKS: on release channels, the control plane moves to 1.37 on the provider's schedule over the coming months, not yours. The provider-managed rows are their problem. The kubelet config, the workloads, the PrometheusRules, and the kube-proxy mode are still yours.&lt;/p&gt;

&lt;h2&gt;
  
  
  Scripting it: the headless scan and MCP
&lt;/h2&gt;

&lt;p&gt;If you'd rather stay in the terminal, the same scan is an HTTP endpoint on the same binary. This installs Radar, starts it headless against your current kubectl context, and prints every non-passing check for the 1.37 path:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-fsSL&lt;/span&gt; https://get.radarhq.io | sh   &lt;span class="c"&gt;# skip if already installed&lt;/span&gt;
radar &lt;span class="nt"&gt;--no-browser&lt;/span&gt; &amp;amp;
curl &lt;span class="nt"&gt;-sf&lt;/span&gt; &lt;span class="nt"&gt;--retry&lt;/span&gt; 40 &lt;span class="nt"&gt;--retry-delay&lt;/span&gt; 3 &lt;span class="nt"&gt;--retry-all-errors&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="s2"&gt;"http://localhost:9280/api/upgrade-readiness?target=1.37"&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; scan.json
jq &lt;span class="nt"&gt;-r&lt;/span&gt; &lt;span class="s1"&gt;'"\(.currentVersion) -&amp;gt; \(.targetVersion)  verdict: \(.verdict)  (\(.summary.blocked) blocked, \(.summary.warnings) warnings, \(.summary.reviews) review)",
  (.checks[] | select(.status | IN("passed","not_applicable") | not)
    | "[\(.status)] \(.title) - \(.summary)")'&lt;/span&gt; scan.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The retries cover startup and the first cache sync. Drop the &lt;code&gt;target&lt;/code&gt; parameter to scan against whatever your cluster's next minor is. The full report - evidence paths, remediation, upstream references - lands in &lt;code&gt;scan.json&lt;/code&gt;, and the process you just started is also the full UI at &lt;a href="http://localhost:9280" rel="noopener noreferrer"&gt;localhost:9280&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The same scan is exposed over MCP, so an AI agent can run the readiness pass and read the same evidence-backed findings (&lt;a href="https://radarhq.io/blog/mcp-for-kubernetes-live-cluster-context-for-ai-tools" rel="noopener noreferrer"&gt;MCP for Kubernetes&lt;/a&gt; covers the pattern). The &lt;a href="https://radarhq.io/docs/features/upgrade-impact" rel="noopener noreferrer"&gt;upgrade impact docs&lt;/a&gt; have the full check catalog, coverage semantics, and the read-only RBAC Radar needs.&lt;/p&gt;

&lt;p&gt;However you run the checks, run them before the control plane moves. Many of these issues are quick fixes once you know where they are - a kubelet setting, a deleted object, an updated expression. The expensive version is discovering the same list on upgrade day, one NotReady node at a time.&lt;/p&gt;

</description>
      <category>kubernetes</category>
      <category>devops</category>
      <category>sre</category>
      <category>opensource</category>
    </item>
    <item>
      <title>[Boost]</title>
      <dc:creator>Nadav Erell</dc:creator>
      <pubDate>Mon, 17 Aug 2026 08:23:23 +0000</pubDate>
      <link>https://dev.to/nadaverell/-4k2p</link>
      <guid>https://dev.to/nadaverell/-4k2p</guid>
      <description>&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/dovzhikova/the-3am-test-autonomy-levels-for-ai-agents-in-kubernetes-operations-hn" class="crayons-story__hidden-navigation-link"&gt;The 3am Test: Autonomy Levels for AI Agents in Kubernetes Operations&lt;/a&gt;


  &lt;div class="crayons-story__body crayons-story__body-full_post"&gt;
    &lt;div class="crayons-story__top"&gt;
      &lt;div class="crayons-story__meta"&gt;
        &lt;div class="crayons-story__author-pic"&gt;

          &lt;a href="/dovzhikova" class="crayons-avatar  crayons-avatar--l  "&gt;
            &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3804277%2F285f8524-816a-4304-bdac-daef0c674515.jpeg" alt="dovzhikova profile" class="crayons-avatar__image" width="460" height="460"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/dovzhikova" class="crayons-story__secondary fw-medium m:hidden"&gt;
              Daria Dovzhikova
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                Daria Dovzhikova
                
                
              
              &lt;div id="story-author-preview-content-4388292" class="profile-preview-card__content crayons-dropdown branded-7 p-4 pt-0"&gt;
                &lt;div class="gap-4 grid"&gt;
                  &lt;div class="-mt-4"&gt;
                    &lt;a href="/dovzhikova" class="flex"&gt;
                      &lt;span class="crayons-avatar crayons-avatar--xl mr-2 shrink-0"&gt;
                        &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3804277%2F285f8524-816a-4304-bdac-daef0c674515.jpeg" class="crayons-avatar__image" alt="" width="460" height="460"&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;Daria Dovzhikova&lt;/span&gt;
                    &lt;/a&gt;
                  &lt;/div&gt;
                  &lt;div class="print-hidden"&gt;
                    
                      Follow
                    
                  &lt;/div&gt;
                  &lt;div class="author-preview-metadata-container"&gt;&lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;

          &lt;/div&gt;
          &lt;a href="https://dev.to/dovzhikova/the-3am-test-autonomy-levels-for-ai-agents-in-kubernetes-operations-hn" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;Aug 13&lt;/time&gt;&lt;span class="time-ago-indicator-initial-placeholder"&gt;&lt;/span&gt;&lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;

    &lt;/div&gt;

    &lt;div class="crayons-story__indention"&gt;
      &lt;h2 class="crayons-story__title crayons-story__title-full_post"&gt;
        &lt;a href="https://dev.to/dovzhikova/the-3am-test-autonomy-levels-for-ai-agents-in-kubernetes-operations-hn" id="article-link-4388292"&gt;
          The 3am Test: Autonomy Levels for AI Agents in Kubernetes Operations
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/kubernetes"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;kubernetes&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/ai"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;ai&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/devops"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;devops&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/sre"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;sre&lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="crayons-story__bottom"&gt;
        &lt;div class="crayons-story__details"&gt;
            &lt;a href="https://dev.to/dovzhikova/the-3am-test-autonomy-levels-for-ai-agents-in-kubernetes-operations-hn#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              

              1&lt;span class="hidden s:inline"&gt;&amp;nbsp;comment&lt;/span&gt;
            &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="crayons-story__save"&gt;
          &lt;small class="crayons-story__tertiary fs-xs mr-2"&gt;
            1 min read
          &lt;/small&gt;
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;


</description>
    </item>
    <item>
      <title>Are AI agents going to kill dashboards?

Let me know what you think.</title>
      <dc:creator>Nadav Erell</dc:creator>
      <pubDate>Tue, 28 Jul 2026 18:48:15 +0000</pubDate>
      <link>https://dev.to/nadaverell/are-ai-agents-going-to-kill-dashboardslet-me-know-what-you-think-2pi7</link>
      <guid>https://dev.to/nadaverell/are-ai-agents-going-to-kill-dashboardslet-me-know-what-you-think-2pi7</guid>
      <description>&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/dovzhikova/we-build-a-kubernetes-dashboard-ai-agents-might-make-it-obsolete-4cm4" class="crayons-story__hidden-navigation-link"&gt;We Build a Kubernetes Dashboard. AI Agents Might Make It Obsolete.&lt;/a&gt;


  &lt;div class="crayons-story__body crayons-story__body-full_post"&gt;
    &lt;div class="crayons-story__top"&gt;
      &lt;div class="crayons-story__meta"&gt;
        &lt;div class="crayons-story__author-pic"&gt;

          &lt;a href="/dovzhikova" class="crayons-avatar  crayons-avatar--l  "&gt;
            &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3804277%2F285f8524-816a-4304-bdac-daef0c674515.jpeg" alt="dovzhikova profile" class="crayons-avatar__image" width="460" height="460"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/dovzhikova" class="crayons-story__secondary fw-medium m:hidden"&gt;
              Daria Dovzhikova
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                Daria Dovzhikova
                
                
              
              &lt;div id="story-author-preview-content-4255196" class="profile-preview-card__content crayons-dropdown branded-7 p-4 pt-0"&gt;
                &lt;div class="gap-4 grid"&gt;
                  &lt;div class="-mt-4"&gt;
                    &lt;a href="/dovzhikova" class="flex"&gt;
                      &lt;span class="crayons-avatar crayons-avatar--xl mr-2 shrink-0"&gt;
                        &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3804277%2F285f8524-816a-4304-bdac-daef0c674515.jpeg" class="crayons-avatar__image" alt="" width="460" height="460"&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;Daria Dovzhikova&lt;/span&gt;
                    &lt;/a&gt;
                  &lt;/div&gt;
                  &lt;div class="print-hidden"&gt;
                    
                      Follow
                    
                  &lt;/div&gt;
                  &lt;div class="author-preview-metadata-container"&gt;&lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;

          &lt;/div&gt;
          &lt;a href="https://dev.to/dovzhikova/we-build-a-kubernetes-dashboard-ai-agents-might-make-it-obsolete-4cm4" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;Jul 28&lt;/time&gt;&lt;span class="time-ago-indicator-initial-placeholder"&gt;&lt;/span&gt;&lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;

    &lt;/div&gt;

    &lt;div class="crayons-story__indention"&gt;
      &lt;h2 class="crayons-story__title crayons-story__title-full_post"&gt;
        &lt;a href="https://dev.to/dovzhikova/we-build-a-kubernetes-dashboard-ai-agents-might-make-it-obsolete-4cm4" id="article-link-4255196"&gt;
          We Build a Kubernetes Dashboard. AI Agents Might Make It Obsolete.
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/kubernetes"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;kubernetes&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/devops"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;devops&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/ai"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;ai&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/opensource"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;opensource&lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="crayons-story__bottom"&gt;
        &lt;div class="crayons-story__details"&gt;
          &lt;a href="https://dev.to/dovzhikova/we-build-a-kubernetes-dashboard-ai-agents-might-make-it-obsolete-4cm4" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left"&gt;
            &lt;div class="multiple_reactions_aggregate"&gt;
              &lt;span class="multiple_reactions_icons_container"&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/exploding-head-daceb38d627e6ae9b730f36a1e390fca556a4289d5a41abb2c35068ad3e2c4b5.svg" width="24" height="24"&gt;
                  &lt;/span&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/multi-unicorn-b44d6f8c23cdd00964192bedc38af3e82463978aa611b4365bd33a0f1f4f3e97.svg" width="24" height="24"&gt;
                  &lt;/span&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/sparkle-heart-5f9bee3767e18deb1bb725290cb151c25234768a0e9a2bd39370c382d02920cf.svg" width="24" height="24"&gt;
                  &lt;/span&gt;
              &lt;/span&gt;
              &lt;span class="aggregate_reactions_counter"&gt;11&lt;span class="hidden s:inline"&gt;&amp;nbsp;reactions&lt;/span&gt;&lt;/span&gt;
            &lt;/div&gt;
          &lt;/a&gt;
            &lt;a href="https://dev.to/dovzhikova/we-build-a-kubernetes-dashboard-ai-agents-might-make-it-obsolete-4cm4#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              

              &lt;span class="hidden s:inline"&gt;Add&amp;nbsp;Comment&lt;/span&gt;
            &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="crayons-story__save"&gt;
          &lt;small class="crayons-story__tertiary fs-xs mr-2"&gt;
            8 min read
          &lt;/small&gt;
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;


</description>
      <category>agents</category>
      <category>ai</category>
      <category>kubernetes</category>
      <category>software</category>
    </item>
    <item>
      <title>DevOps engineers and anyone using Kubernetes - how are you connecting your agents to your production clusters?</title>
      <dc:creator>Nadav Erell</dc:creator>
      <pubDate>Tue, 21 Jul 2026 10:19:16 +0000</pubDate>
      <link>https://dev.to/nadaverell/devops-engineers-and-anyone-using-kubernetes-how-are-you-connecting-your-agents-to-your-4pkf</link>
      <guid>https://dev.to/nadaverell/devops-engineers-and-anyone-using-kubernetes-how-are-you-connecting-your-agents-to-your-4pkf</guid>
      <description>&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/dovzhikova/we-benchmarked-an-ai-agent-on-52-broken-clusters-kubectl-vs-a-kubernetes-mcp-server-2843" class="crayons-story__hidden-navigation-link"&gt;We benchmarked an AI agent on 52 broken clusters: kubectl vs a Kubernetes MCP server&lt;/a&gt;


  &lt;div class="crayons-story__body crayons-story__body-full_post"&gt;
    &lt;div class="crayons-story__top"&gt;
      &lt;div class="crayons-story__meta"&gt;
        &lt;div class="crayons-story__author-pic"&gt;

          &lt;a href="/dovzhikova" class="crayons-avatar  crayons-avatar--l  "&gt;
            &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3804277%2F285f8524-816a-4304-bdac-daef0c674515.jpeg" alt="dovzhikova profile" class="crayons-avatar__image" width="460" height="460"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/dovzhikova" class="crayons-story__secondary fw-medium m:hidden"&gt;
              Daria Dovzhikova
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                Daria Dovzhikova
                
                
              
              &lt;div id="story-author-preview-content-4195488" class="profile-preview-card__content crayons-dropdown branded-7 p-4 pt-0"&gt;
                &lt;div class="gap-4 grid"&gt;
                  &lt;div class="-mt-4"&gt;
                    &lt;a href="/dovzhikova" class="flex"&gt;
                      &lt;span class="crayons-avatar crayons-avatar--xl mr-2 shrink-0"&gt;
                        &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3804277%2F285f8524-816a-4304-bdac-daef0c674515.jpeg" class="crayons-avatar__image" alt="" width="460" height="460"&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;Daria Dovzhikova&lt;/span&gt;
                    &lt;/a&gt;
                  &lt;/div&gt;
                  &lt;div class="print-hidden"&gt;
                    
                      Follow
                    
                  &lt;/div&gt;
                  &lt;div class="author-preview-metadata-container"&gt;&lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;

          &lt;/div&gt;
          &lt;a href="https://dev.to/dovzhikova/we-benchmarked-an-ai-agent-on-52-broken-clusters-kubectl-vs-a-kubernetes-mcp-server-2843" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;Jul 21&lt;/time&gt;&lt;span class="time-ago-indicator-initial-placeholder"&gt;&lt;/span&gt;&lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;

    &lt;/div&gt;

    &lt;div class="crayons-story__indention"&gt;
      &lt;h2 class="crayons-story__title crayons-story__title-full_post"&gt;
        &lt;a href="https://dev.to/dovzhikova/we-benchmarked-an-ai-agent-on-52-broken-clusters-kubectl-vs-a-kubernetes-mcp-server-2843" id="article-link-4195488"&gt;
          We benchmarked an AI agent on 52 broken clusters: kubectl vs a Kubernetes MCP server
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/kubernetes"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;kubernetes&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/ai"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;ai&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/mcp"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;mcp&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/devops"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;devops&lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="crayons-story__bottom"&gt;
        &lt;div class="crayons-story__details"&gt;
          &lt;a href="https://dev.to/dovzhikova/we-benchmarked-an-ai-agent-on-52-broken-clusters-kubectl-vs-a-kubernetes-mcp-server-2843" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left"&gt;
            &lt;div class="multiple_reactions_aggregate"&gt;
              &lt;span class="multiple_reactions_icons_container"&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/exploding-head-daceb38d627e6ae9b730f36a1e390fca556a4289d5a41abb2c35068ad3e2c4b5.svg" width="24" height="24"&gt;
                  &lt;/span&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/multi-unicorn-b44d6f8c23cdd00964192bedc38af3e82463978aa611b4365bd33a0f1f4f3e97.svg" width="24" height="24"&gt;
                  &lt;/span&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/sparkle-heart-5f9bee3767e18deb1bb725290cb151c25234768a0e9a2bd39370c382d02920cf.svg" width="24" height="24"&gt;
                  &lt;/span&gt;
              &lt;/span&gt;
              &lt;span class="aggregate_reactions_counter"&gt;11&lt;span class="hidden s:inline"&gt;&amp;nbsp;reactions&lt;/span&gt;&lt;/span&gt;
            &lt;/div&gt;
          &lt;/a&gt;
            &lt;a href="https://dev.to/dovzhikova/we-benchmarked-an-ai-agent-on-52-broken-clusters-kubectl-vs-a-kubernetes-mcp-server-2843#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              

              10&lt;span class="hidden s:inline"&gt;&amp;nbsp;comments&lt;/span&gt;
            &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="crayons-story__save"&gt;
          &lt;small class="crayons-story__tertiary fs-xs mr-2"&gt;
            4 min read
          &lt;/small&gt;
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;


</description>
      <category>agents</category>
      <category>devops</category>
      <category>discuss</category>
      <category>kubernetes</category>
    </item>
    <item>
      <title>Why we stopped using Lens and built a new OSS K8s IDE/Dashboard</title>
      <dc:creator>Nadav Erell</dc:creator>
      <pubDate>Thu, 05 Feb 2026 19:22:40 +0000</pubDate>
      <link>https://dev.to/nadaverell/why-we-stopped-using-lens-and-built-a-new-oss-k8s-idedashboard-ain</link>
      <guid>https://dev.to/nadaverell/why-we-stopped-using-lens-and-built-a-new-oss-k8s-idedashboard-ain</guid>
      <description>&lt;p&gt;And why you should take 15 seconds to try it yourself :)&lt;/p&gt;

&lt;h3&gt;
  
  
  The "Good Old Days" of K8s Debugging
&lt;/h3&gt;

&lt;p&gt;If you've been working with Kubernetes for a few years, you probably remember when &lt;strong&gt;Lens&lt;/strong&gt; was the undisputed king of local development. It was fast, it was free, and it just worked. It was just so nice to not have to &lt;em&gt;always&lt;/em&gt; resort to plain &lt;code&gt;kubectl&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;Of course, things haven't stayed that way...&lt;/p&gt;

&lt;p&gt;Lens got acquired and is no longer open source. It also got bloated and slow, and requires you to log in. &lt;/p&gt;

&lt;p&gt;Alternatives and forks like &lt;strong&gt;Freelens&lt;/strong&gt; and &lt;strong&gt;Headlamp&lt;/strong&gt; exist, but they're just... ok. Not very feature rich, somewhat plain UI, awkward setup.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;K9s&lt;/strong&gt; is great sometimes, for some people... but the terminal experience is not for everyone, and it's still limiting for lots of things.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Kubernetes Dashboard&lt;/strong&gt; was another option that got some traction as an official tool, but it was never exceptional, and now that's shut down too.&lt;/p&gt;

&lt;p&gt;So our team at Skyhook got frustrated and one day asked: what if we just built the tool we ourselves would want to use? We've already been doing related pieces of this as part of the main Skyhook platform.&lt;/p&gt;

&lt;p&gt;So without further ado:&lt;/p&gt;

&lt;h3&gt;
  
  
  Meet Radar
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://github.com/skyhook-io/radar" rel="noopener noreferrer"&gt;Radar&lt;/a&gt;&lt;/strong&gt; is our attempt to fix the local K8s development experience.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdwb6t9h9m9ooga34n6zu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdwb6t9h9m9ooga34n6zu.png" alt="Radar Main View" width="800" height="446"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We had a few design rules:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Local-First:&lt;/strong&gt; No cloud logins. No data leaving the machine.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Zero Config:&lt;/strong&gt; It uses your existing &lt;code&gt;~/.kube/config&lt;/code&gt;. It should just work.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fast:&lt;/strong&gt; We hate waiting on slow tools.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Real-Time:&lt;/strong&gt; No "Refresh" buttons. If a pod dies, I want to see it turn red instantly.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  How we built it (The Tech Stack)
&lt;/h3&gt;

&lt;p&gt;Instead of wrapping a heavy web app in Electron, we built Radar as a single &lt;strong&gt;Go binary&lt;/strong&gt; with a React frontend embedded inside (using &lt;code&gt;go:embed&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;To get that "instant" feel, we avoided the standard API polling. Instead, we use &lt;strong&gt;Kubernetes SharedInformers&lt;/strong&gt;—the same machinery that K8s controllers use internally.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We open a persistent connection to the API server.&lt;/li&gt;
&lt;li&gt;We watch for deltas (add/update/delete events).&lt;/li&gt;
&lt;li&gt;We push those changes to the browser frontend via &lt;strong&gt;Server-Sent Events (SSE)&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now everything is super fast, updates in real time. Just works.&lt;/p&gt;

&lt;h3&gt;
  
  
  Cool things you can do
&lt;/h3&gt;

&lt;p&gt;Beyond the table-stakes resource browsing, we added features specifically for the "what is going on?" debugging moments:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Topology Graph:&lt;/strong&gt; We use a structured DAG layout (not a bouncy physics graph) so you can actually see ownership chains and ingress paths.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GitOps Native:&lt;/strong&gt; If you use Flux or ArgoCD, Radar shows their sync status and common operations right alongside the workloads they manage. No plugins required.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Helm Dashboard:&lt;/strong&gt; View, manage, search and install new charts. See their health, upgrade versions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Network Visualization:&lt;/strong&gt; See real data flows across your microservices and in/out of your cluster, with support for Hubble (for Cilium) and Caretta.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Timeline:&lt;/strong&gt; Because sometimes you really need to track what happened, not just the current state. See events and resource changes over time, grouped by connected resources.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Image Filesystem Viewer:&lt;/strong&gt; A nice hidden gem - browse the files &lt;em&gt;inside&lt;/em&gt; a container image directly from the UI without &lt;code&gt;exec&lt;/code&gt;-ing in.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Try it out
&lt;/h3&gt;

&lt;p&gt;It’s open source (Apache 2.0), no surprises.&lt;/p&gt;

&lt;p&gt;Quick install (15 seconds to install and see live dashboard - yes we timed it):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-fsSL&lt;/span&gt; skyhook.io/get-radar.sh | bash &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; kubectl radar
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or install with brew, krew, scoop, or direct download - check out the repo: &lt;strong&gt;&lt;a href="https://github.com/skyhook-io/radar" rel="noopener noreferrer"&gt;github.com/skyhook-io/radar&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;We built this because we needed it, but we’re hoping it helps other devs who are tired of fighting their tools. Let me know what you think!&lt;/p&gt;

</description>
      <category>kubernetes</category>
      <category>devops</category>
      <category>opensource</category>
      <category>go</category>
    </item>
  </channel>
</rss>
