<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Engineering Archives | Clever Cloud</title>
	<atom:link href="https://www.clever.cloud/blog/category/engineering/feed/" rel="self" type="application/rss+xml" />
	<link>https://www.clever.cloud/blog/category/engineering/</link>
	<description>From Code to Product</description>
	<lastBuildDate>Tue, 01 Sep 2026 10:21:03 +0000</lastBuildDate>
	<language>en-GB</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	

<image>
	<url>https://cdn.clever-cloud.com/uploads/2023/03/cropped-cropped-favicon-32x32.png</url>
	<title>Engineering Archives | Clever Cloud</title>
	<link>https://www.clever.cloud/blog/category/engineering/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Compliance as code: moving our management system documentation into GitLab, from one month to 30 minutes</title>
		<link>https://www.clever.cloud/blog/engineering/2026/09/01/compliance-as-code-policy-documentation-gitlab/</link>
		
		<dc:creator><![CDATA[Darya Khendrik]]></dc:creator>
		<pubDate>Tue, 01 Sep 2026 10:21:03 +0000</pubDate>
				<category><![CDATA[Engineering]]></category>
		<guid isPermaLink="false">https://www.clever.cloud/?p=25344</guid>

					<description><![CDATA[<p><img width="2499" height="1109" src="https://cdn.clever-cloud.com/uploads/2026/08/2026-08-26-clever-cloud-banniere-blog-compliance-as-code-en.png" class="attachment-post-thumbnail size-post-thumbnail wp-post-image" alt="2026.08.26 Clever Cloud Bannière Blog Compliance as Code EN" decoding="async" fetchpriority="high" srcset="https://cdn.clever-cloud.com/uploads/2026/08/2026-08-26-clever-cloud-banniere-blog-compliance-as-code-en.png 2499w, https://cdn.clever-cloud.com/uploads/2026/08/2026-08-26-clever-cloud-banniere-blog-compliance-as-code-en-300x133.png 300w, https://cdn.clever-cloud.com/uploads/2026/08/2026-08-26-clever-cloud-banniere-blog-compliance-as-code-en-1024x454.png 1024w, https://cdn.clever-cloud.com/uploads/2026/08/2026-08-26-clever-cloud-banniere-blog-compliance-as-code-en-768x341.png 768w, https://cdn.clever-cloud.com/uploads/2026/08/2026-08-26-clever-cloud-banniere-blog-compliance-as-code-en-1536x682.png 1536w, https://cdn.clever-cloud.com/uploads/2026/08/2026-08-26-clever-cloud-banniere-blog-compliance-as-code-en-2048x909.png 2048w, https://cdn.clever-cloud.com/uploads/2026/08/2026-08-26-clever-cloud-banniere-blog-compliance-as-code-en-1368x607.png 1368w" sizes="(max-width: 2499px) 100vw, 2499px" /></p><!-- wp:paragraph -->
<p>A compliance manager's field report.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>When I joined Clever Cloud four years ago, I walked into a deeply technical culture: no collaborative suite, no conventional project management tool. Everything lives in GitLab, GitHub and terminals.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Running an integrated management system (ISO 9001, <a href="https://www.clever.cloud/iso-27001-security-by-default-at-clever-cloud/">ISO 27001</a>, <a href="https://www.clever.cloud/health-data-hosting/">HDS</a>, <a href="https://www.clever.cloud/compliance/">regulatory compliance</a>) is formalisation work: policies, procedures, security rules.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>So we started out the conventional way, on a collaborative suite.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Some of the habits that came with it quickly turned into a time sink. Version numbers tracked by hand in a spreadsheet. PDFs sent to the steering committee for sign-off. Signatures. Folders labelled "approved" and "in progress". Links breaking every time a format changed.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Human checks everywhere, so mistakes waiting to happen. And above all: developers never go into those tools. Their documentation sits in GitLab.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>So we made a simple call. The entire documentation set in Markdown, version-controlled in GitLab, in the same place as the technical documentation.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>What that changes in practice:</p>
<!-- /wp:paragraph -->

<!-- wp:list -->
<ul class="wp-block-list"><!-- wp:list-item -->
<li>a complete, native history: commits, diffs, authors</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>every change goes through a merge request, with at least one approval from a third party. Segregation of duties no longer rests on a declared process, it is carried by the tool</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>the technical population reads the policies all year round, not only at the annual awareness session (the new challenge is the non-technical profiles, who now learn GitLab during onboarding, as I did four years ago)</li>
<!-- /wp:list-item --></ul>
<!-- /wp:list -->

<!-- wp:paragraph -->
<p>Then we automated. A monthly script reads the platform changelogs, drafts the updates in the right places across the policies, and opens the merge requests. What is left for me is the review, then approval by whoever owns the subject. That is where the month becomes 30 minutes.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>And the real change is somewhere else. We no longer update documents for the audit, once a year. We update them at every actual change to the information system. In front of the auditor, the sources, the versions and the approvals are right there. Compliance becomes a measured state rather than a declared one.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>That is how I picture compliance as code from an integrated management system governance standpoint. What it changes at a deeper level is the tempo: compliance now moves at the speed of the information system, not at the speed of the audit calendar.</p>
<!-- /wp:paragraph -->]]></description>
										<content:encoded><![CDATA[<p><img width="2499" height="1109" src="https://cdn.clever-cloud.com/uploads/2026/08/2026-08-26-clever-cloud-banniere-blog-compliance-as-code-en.png" class="attachment-post-thumbnail size-post-thumbnail wp-post-image" alt="2026.08.26 Clever Cloud Bannière Blog Compliance as Code EN" decoding="async" srcset="https://cdn.clever-cloud.com/uploads/2026/08/2026-08-26-clever-cloud-banniere-blog-compliance-as-code-en.png 2499w, https://cdn.clever-cloud.com/uploads/2026/08/2026-08-26-clever-cloud-banniere-blog-compliance-as-code-en-300x133.png 300w, https://cdn.clever-cloud.com/uploads/2026/08/2026-08-26-clever-cloud-banniere-blog-compliance-as-code-en-1024x454.png 1024w, https://cdn.clever-cloud.com/uploads/2026/08/2026-08-26-clever-cloud-banniere-blog-compliance-as-code-en-768x341.png 768w, https://cdn.clever-cloud.com/uploads/2026/08/2026-08-26-clever-cloud-banniere-blog-compliance-as-code-en-1536x682.png 1536w, https://cdn.clever-cloud.com/uploads/2026/08/2026-08-26-clever-cloud-banniere-blog-compliance-as-code-en-2048x909.png 2048w, https://cdn.clever-cloud.com/uploads/2026/08/2026-08-26-clever-cloud-banniere-blog-compliance-as-code-en-1368x607.png 1368w" sizes="(max-width: 2499px) 100vw, 2499px" /></p><!-- wp:paragraph -->
<p>A compliance manager's field report.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>When I joined Clever Cloud four years ago, I walked into a deeply technical culture: no collaborative suite, no conventional project management tool. Everything lives in GitLab, GitHub and terminals.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Running an integrated management system (ISO 9001, <a href="https://www.clever.cloud/iso-27001-security-by-default-at-clever-cloud/">ISO 27001</a>, <a href="https://www.clever.cloud/health-data-hosting/">HDS</a>, <a href="https://www.clever.cloud/compliance/">regulatory compliance</a>) is formalisation work: policies, procedures, security rules.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>So we started out the conventional way, on a collaborative suite.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Some of the habits that came with it quickly turned into a time sink. Version numbers tracked by hand in a spreadsheet. PDFs sent to the steering committee for sign-off. Signatures. Folders labelled "approved" and "in progress". Links breaking every time a format changed.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Human checks everywhere, so mistakes waiting to happen. And above all: developers never go into those tools. Their documentation sits in GitLab.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>So we made a simple call. The entire documentation set in Markdown, version-controlled in GitLab, in the same place as the technical documentation.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>What that changes in practice:</p>
<!-- /wp:paragraph -->

<!-- wp:list -->
<ul class="wp-block-list"><!-- wp:list-item -->
<li>a complete, native history: commits, diffs, authors</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>every change goes through a merge request, with at least one approval from a third party. Segregation of duties no longer rests on a declared process, it is carried by the tool</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>the technical population reads the policies all year round, not only at the annual awareness session (the new challenge is the non-technical profiles, who now learn GitLab during onboarding, as I did four years ago)</li>
<!-- /wp:list-item --></ul>
<!-- /wp:list -->

<!-- wp:paragraph -->
<p>Then we automated. A monthly script reads the platform changelogs, drafts the updates in the right places across the policies, and opens the merge requests. What is left for me is the review, then approval by whoever owns the subject. That is where the month becomes 30 minutes.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>And the real change is somewhere else. We no longer update documents for the audit, once a year. We update them at every actual change to the information system. In front of the auditor, the sources, the versions and the approvals are right there. Compliance becomes a measured state rather than a declared one.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>That is how I picture compliance as code from an integrated management system governance standpoint. What it changes at a deeper level is the tempo: compliance now moves at the speed of the information system, not at the speed of the audit calendar.</p>
<!-- /wp:paragraph -->]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Managed Kubernetes: benefits, limitations and selection criteria</title>
		<link>https://www.clever.cloud/blog/features/2026/07/24/managed-kubernetes-benefits-limitations-and-selection-criteria/</link>
		
		<dc:creator><![CDATA[Marjorie Darrigade]]></dc:creator>
		<pubDate>Fri, 24 Jul 2026 11:13:45 +0000</pubDate>
				<category><![CDATA[Engineering]]></category>
		<category><![CDATA[Features]]></category>
		<category><![CDATA[Kubernetes]]></category>
		<category><![CDATA[managed services]]></category>
		<guid isPermaLink="false">https://www.clever.cloud/?p=25100</guid>

					<description><![CDATA[<p><img width="800" height="355" src="https://cdn.clever-cloud.com/uploads/2026/07/2026-07-24-clever-cloud-banniere-blog-kubem-eng.png" class="attachment-post-thumbnail size-post-thumbnail wp-post-image" alt="managed kubernetes" decoding="async" srcset="https://cdn.clever-cloud.com/uploads/2026/07/2026-07-24-clever-cloud-banniere-blog-kubem-eng.png 800w, https://cdn.clever-cloud.com/uploads/2026/07/2026-07-24-clever-cloud-banniere-blog-kubem-eng-300x133.png 300w, https://cdn.clever-cloud.com/uploads/2026/07/2026-07-24-clever-cloud-banniere-blog-kubem-eng-768x341.png 768w" sizes="(max-width: 800px) 100vw, 800px" /></p><!-- wp:paragraph -->
<p>workloads and node pools but does not administer the cluster’s critical infrastructure.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>The control plane consists of Kubernetes’ standard components: the API server, etcd (the datastore that stores the cluster’s state), the scheduler and the controller manager. If the control plane fails, workloads that are already running continue to operate, but the cluster can no longer be managed: no new deployments, no scaling, and no response to kubectl commands. Managed services remove responsibility for precisely this layer from engineering teams.</p>
<!-- /wp:paragraph -->

<!-- wp:spacer {"height":"15px"} -->
<div style="height:15px" aria-hidden="true" class="wp-block-spacer"></div>
<!-- /wp:spacer -->

<!-- wp:heading -->
<h2 class="wp-block-heading">Why is Kubernetes difficult to operate yourself?</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p><a href="https://www.clever.cloud/blog/engineering/2026/05/19/k8s-kubernetes-definition-standard/">Kubernetes</a> &nbsp;is a container orchestration standard, not a turnkey product. Deploying a cluster without a managed layer means handling:</p>
<!-- /wp:paragraph -->

<!-- wp:list -->
<ul class="wp-block-list"><!-- wp:list-item -->
<li>version upgrades (the Kubernetes project actively supports the three most recent minor releases);</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>internal TLS certificate rotation;</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>high availability of the control plane across multiple nodes;</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>backup and consistency of the etcd datastore;</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>security patches, often under tight time constraints.</li>
<!-- /wp:list-item --></ul>
<!-- /wp:list -->

<!-- wp:paragraph -->
<p>These tasks are repetitive, consume valuable engineering time, and are a frequent source of incidents when not performed correctly. Managed services are specifically designed to remove this operational burden from product teams.</p>
<!-- /wp:paragraph -->

<!-- wp:spacer {"height":"15px"} -->
<div style="height:15px" aria-hidden="true" class="wp-block-spacer"></div>
<!-- /wp:spacer -->

<!-- wp:heading -->
<h2 class="wp-block-heading">Use cases: when managed Kubernetes delivers value</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Kubernetes—whether managed or self-managed—becomes relevant in specific scenarios. It is not a systematic replacement for a <a href="https://www.clever.cloud/clever-cloud-paas/">PaaS</a>: the two approaches address different needs.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">Managed Kubernetes is well suited when:</h3>
<!-- /wp:heading -->

<!-- wp:list -->
<ul class="wp-block-list"><!-- wp:list-item -->
<li>the architecture includes multiple interdependent services requiring <a href="https://www.clever.cloud/blog/engineering/2026/07/03/kubernetes-orchestration-containers-what-is-it-for/">fine-grained orchestration</a> (rolling updates, resource management by namespace);</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>workloads are already built for Kubernetes and delivered as Helm charts or YAML manifests;</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>the team requires multi-cluster or hybrid environments (on-premises + cloud);</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>operating the control plane represents a real and measurable cost for SRE or DevOps teams.</li>
<!-- /wp:list-item --></ul>
<!-- /wp:list -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">A PaaS remains a better fit when:</h3>
<!-- /wp:heading -->

<!-- wp:list -->
<ul class="wp-block-list"><!-- wp:list-item -->
<li>the application deployment model (code push with platform-managed build and runtime) matches the way your team works;</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>you want to focus on application code without managing orchestration primitives (networking, scheduling, node management);</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>your applications do not require fine-grained control over workload placement or the cluster’s network topology.</li>
<!-- /wp:list-item --></ul>
<!-- /wp:list -->

<!-- wp:spacer {"height":"15px"} -->
<div style="height:15px" aria-hidden="true" class="wp-block-spacer"></div>
<!-- /wp:spacer -->

<!-- wp:heading -->
<h2 class="wp-block-heading">Comparison table: self-managed Kubernetes vs managed Kubernetes vs PaaS</h2>
<!-- /wp:heading -->

<!-- wp:spacer {"height":"25px"} -->
<div style="height:25px" aria-hidden="true" class="wp-block-spacer"></div>
<!-- /wp:spacer -->

<!-- wp:html -->
<style>
  .cc-table-wrap {
    width: 100%;
    overflow-x: auto;
  }

  .cc-table {
    width: 100%;
    min-width: 760px;
    border-collapse: collapse;
    table-layout: fixed;
    font-size: 17px;
    font-family: "Plus Jakarta Sans", "PlusJakartaSans", -apple-system,
      BlinkMacSystemFont, "Segoe UI", Roboto, Arial, sans-serif;
    color: #111827;
  }

  .cc-table th,
  .cc-table td {
    padding: 12px 16px;
    text-align: left;
    vertical-align: top;
    line-height: 1.6;
  }

  .cc-table thead th {
    font-weight: 700;
    text-align: center;
  }

  .cc-table tbody td:first-child {
    font-weight: 700;
  }

  .cc-table tbody tr + tr td,
  .cc-table tbody tr:first-child td {
    border-top: 1px solid #deddee;
  }

  .cc-table th + th,
  .cc-table td + td {
    border-left: 1px solid #deddee;
  }

  .cc-table th:nth-child(1),
  .cc-table td:nth-child(1) {
    width: 30%;
  }

  .cc-table th:nth-child(2),
  .cc-table td:nth-child(2),
  .cc-table th:nth-child(3),
  .cc-table td:nth-child(3),
  .cc-table th:nth-child(4),
  .cc-table td:nth-child(4) {
    width: 23.33%;
  }

  @media (max-width: 767px) {
    .cc-table {
      font-size: 15px;
    }

    .cc-table th,
    .cc-table td {
      padding: 10px 12px;
    }
  }
</style>

<div class="cc-table-wrap">
  <table class="cc-table">
    <thead>
      <tr>
        <th>Criteria</th>
        <th>Self-managed Kubernetes</th>
        <th>Managed Kubernetes</th>
        <th>PaaS</th>
      </tr>
    </thead>

    <tbody>
      <tr>
        <td>Control plane management</td>
        <td>Managed by the team</td>
        <td>Operated by the provider</td>
        <td>Not exposed</td>
      </tr>

      <tr>
        <td>kubectl / Helm compatibility</td>
        <td>Full</td>
        <td>Full (vanilla)</td>
        <td>Not applicable</td>
      </tr>

      <tr>
        <td>Architectural flexibility</td>
        <td>Maximum</td>
        <td>High</td>
        <td>Limited to PaaS primitives</td>
      </tr>

      <tr>
        <td>Operational overhead</td>
        <td>High</td>
        <td>Reduced</td>
        <td>Low</td>
      </tr>

      <tr>
        <td>Learning curve</td>
        <td>Steep</td>
        <td>Moderate</td>
        <td>Low</td>
      </tr>

      <tr>
        <td>Kubernetes updates</td>
        <td>Manual</td>
        <td>Handled by the provider</td>
        <td>Not applicable</td>
      </tr>

      <tr>
        <td>Infrastructure engineering cost</td>
        <td>High</td>
        <td>Reduced</td>
        <td>Minimal</td>
      </tr>

      <tr>
        <td>Workload portability</td>
        <td>Full</td>
        <td>Full (if vanilla)</td>
        <td>Depends on the PaaS</td>
      </tr>

      <tr>
        <td>Control plane SLA</td>
        <td>N/A<br>(self-operated)</td>
        <td>Varies by offering</td>
        <td>Varies</td>
      </tr>
    </tbody>
  </table>
</div>
<!-- /wp:html -->

<!-- wp:spacer {"height":"20px"} -->
<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>
<!-- /wp:spacer -->

<!-- wp:paragraph -->
<p><strong>Note:</strong> here, <em>vanilla</em> refers to a standard Kubernetes experience, with no changes to native Kubernetes behaviour and no proprietary tooling imposed.</p>
<!-- /wp:paragraph -->

<!-- wp:spacer {"height":"15px"} -->
<div style="height:15px" aria-hidden="true" class="wp-block-spacer"></div>
<!-- /wp:spacer -->

<!-- wp:heading -->
<h2 class="wp-block-heading">Common mistakes when choosing or adopting managed Kubernetes</h2>
<!-- /wp:heading -->

<!-- wp:acf/arguments {"name":"acf/arguments","data":{"items_0_title":"Confusing “managed” with “no operational responsibility”","_items_0_title":"field_638a066e4d2ec","items_0_short_description":"The provider manages the control plane. Node pools, network configuration, RBAC policies, resource limits and workload security remain the user’s responsibility. Managed Kubernetes reduces the operational burden; it does not eliminate it.","_items_0_short_description":"field_638a068d4d2ed","items_0_full_description":"","_items_0_full_description":"field_638a06af4d2ee","items_1_title":"Moving to Kubernetes by default without assessing actual requirements","_items_1_title":"field_638a066e4d2ec","items_1_short_description":"Kubernetes is often adopted because it has become the industry standard, not because it solves a specific problem. For lighter requirements, other distributions (such as \u003ca href=\u0022https://www.clever.cloud/blog/features/2026/05/28/k3s-vs-k8s-what-are-the-differences-and-which-one-should-you-choose-in-2026/\u0022\u003eK3s\u003c/a\u003e) are available and should be evaluated before deploying a full Kubernetes cluster. An application that fits a PaaS deployment model will often be better served by a PaaS: fewer orchestration primitives to manage for an equivalent production outcome.","_items_1_short_description":"field_638a068d4d2ed","items_1_full_description":"","_items_1_full_description":"field_638a06af4d2ee","items_2_title":"Ignoring the release policy","_items_2_title":"field_638a066e4d2ec","items_2_short_description":"The Kubernetes project supports the three most recent minor releases (the “n-2” policy). A cluster that is not kept up to date eventually falls out of support and no longer receives security patches. Verifying that a managed provider follows this policy (and how unsupported cluster versions are handled) is a selection criterion in its own right.","_items_2_short_description":"field_638a068d4d2ed","items_2_full_description":"","_items_2_full_description":"field_638a06af4d2ee","items_3_title":"Overlooking the risk of vendor lock-in","_items_3_title":"field_638a066e4d2ec","items_3_short_description":"Some managed offerings introduce proprietary abstractions (non-standard CRDs, exclusive networking integrations, provider-specific deployment tools) that make migration difficult. A vanilla offering, with no changes to Kubernetes’ native behaviour, ensures portability of existing manifests and workflows.","_items_3_short_description":"field_638a068d4d2ed","items_3_full_description":"","_items_3_full_description":"field_638a06af4d2ee","items_4_title":"Evaluating the service solely on its upfront price","_items_4_title":"field_638a066e4d2ec","items_4_short_description":"The real cost of a Kubernetes cluster includes the engineering time spent maintaining it. A managed service with a higher list price may have a lower total cost of ownership if it eliminates several days of operational work each month.","_items_4_short_description":"field_638a068d4d2ed","items_4_full_description":"","_items_4_full_description":"field_638a06af4d2ee","items":5,"_items":"field_638a065a4d2eb"},"mode":"auto"} /-->

<!-- wp:spacer {"height":"20px"} -->
<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>
<!-- /wp:spacer -->

<!-- wp:acf/avantages {"name":"acf/avantages","data":{"title":"Which option should you choose? \u003cbr\u003e\u003cb\u003eA decision guide\u003c/b\u003e","_title":"field_63878c81ae569","content":"","_content":"field_63878c9cae56a","main_picture":"","_main_picture":"field_63878cd5ae56b","advantages_collection_0_picto":"","_advantages_collection_0_picto":"field_6397417cac52f","advantages_collection_0_title":"Choose a PaaS if","_advantages_collection_0_title":"field_63878d1aae56d","advantages_collection_0_content":"ts deployment model matches the way your team works: you deliver code, while the platform handles builds, runtime and infrastructure. You retain control over your applications without managing Kubernetes orchestration primitives.","_advantages_collection_0_content":"field_63878d4dae56e","advantages_collection_0_link":"","_advantages_collection_0_link":"field_63878d66ae56f","advantages_collection_1_picto":"","_advantages_collection_1_picto":"field_6397417cac52f","advantages_collection_1_title":"Choose managed Kubernetes if","_advantages_collection_1_title":"field_63878d1aae56d","advantages_collection_1_content":"your architecture includes multiple interdependent services, distributed deployments or third-party software already packaged for Kubernetes. A managed service lets you keep your existing tools (kubectl, Helm, Terraform, GitOps) while delegating operation of the control plane.","_advantages_collection_1_content":"field_63878d4dae56e","advantages_collection_1_link":"","_advantages_collection_1_link":"field_63878d66ae56f","advantages_collection_2_picto":"","_advantages_collection_2_picto":"field_6397417cac52f","advantages_collection_2_title":"Choose self-managed Kubernetes if","_advantages_collection_2_title":"field_63878d1aae56d","advantages_collection_2_content":"you have highly specific infrastructure requirements (mandatory on-premises deployment, network configurations unavailable from cloud providers, or sovereignty requirements incompatible with third-party hosting).","_advantages_collection_2_content":"field_63878d4dae56e","advantages_collection_2_link":"","_advantages_collection_2_link":"field_63878d66ae56f","advantages_collection":3,"_advantages_collection":"field_63878cecae56c"},"mode":"auto"} /-->

<!-- wp:spacer {"height":"20px"} -->
<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>
<!-- /wp:spacer -->

<!-- wp:heading -->
<h2 class="wp-block-heading">Managed Kubernetes in Europe: which sovereignty criteria matter?</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>For organisations subject to the GDPR, sector-specific regulations (healthcare, public sector, defence) or data residency requirements, where the cluster is hosted is a compliance issue, not just a performance consideration.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Points to verify:</p>
<!-- /wp:paragraph -->

<!-- wp:list -->
<ul class="wp-block-list"><!-- wp:list-item -->
<li>physical location of the&nbsp; &nbsp; datacenters (country and applicable jurisdiction);</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>identity of the operator and the involvement of foreign subcontractors in the hosting chain;</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>infrastructure certifications (SecNumCloud, ISO 27001, HDS, depending on the provider and the offering);</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>potential access to data by non-European third parties, particularly under extraterritorial legislation.</li>
<!-- /wp:list-item --></ul>
<!-- /wp:list -->

<!-- wp:paragraph -->
<p>A managed Kubernetes service operated in France by a French provider addresses these requirements without requiring additional user-side configuration. This is the approach taken by <a href="https://www.clever.cloud/product/kubernetes/">Clever Kubernetes Engine (CKE)</a>, operated end to end in France by Clever Cloud, with no foreign hyperscaler involved in the hosting chain.</p>
<!-- /wp:paragraph -->

<!-- wp:spacer {"height":"20px"} -->
<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>
<!-- /wp:spacer -->

<!-- wp:heading -->
<h2 class="wp-block-heading">Key takeaways</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p><a href="https://www.clever.cloud/product/kubernetes/">Managed Kubernetes</a> is relevant when your organisation already relies on Kubernetes and maintaining the control plane represents a meaningful operational burden. It is not a universal solution: when a PaaS deployment model matches the way your team works, it often remains the most straightforward choice. For organisations with European sovereignty requirements, the choice of provider and hosting location is critical.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>The key selection criteria are: vanilla compatibility (no vendor lock-in), the release policy, a clear division of responsibilities between provider and user, and the overall cost model-list price plus internal engineering costs.</p>
<!-- /wp:paragraph -->

<!-- wp:spacer {"height":"150px"} -->
<div style="height:150px" aria-hidden="true" class="wp-block-spacer"></div>
<!-- /wp:spacer -->

<!-- wp:heading {"level":1,"style":{"typography":{"textAlign":"center"}}} -->
<h1 class="wp-block-heading has-text-align-center">FAQ</h1>
<!-- /wp:heading -->

<!-- wp:html -->
<div style="height: 1px; background-color: #DEDDEE; margin: 30px auto; width: 100%;"></div>
<!-- /wp:html -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">What is managed Kubernetes?</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>A service in which the cloud provider manages the Kubernetes control plane (provisioning, updates and availability). The user manages workloads and node pools, but not the cluster’s critical infrastructure.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">What is the difference between managed Kubernetes and a PaaS?</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>A PaaS handles the build, deployment and execution of what you deliver (source code or a container image) without requiring you to define the underlying orchestration. Managed Kubernetes retains the standard Kubernetes interface (kubectl, Helm and YAML manifests), allowing you to manage these primitives while delegating control plane operations to the provider. These are two distinct operational models that are complementary rather than interchangeable.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">Does managed Kubernetes create a risk of vendor lock-in?</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>It depends on the implementation. A <em>vanilla</em> offering (with no changes to Kubernetes’ native behaviour and no proprietary tooling imposed) allows workloads to be migrated without rewriting them. By contrast, non-standard CRDs or exclusive networking integrations can create dependency on a specific provider.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">Who is responsible for what in a managed Kubernetes cluster?</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>The provider manages the control plane: updates, availability and patching. The user remains responsible for node pools (sizing and scaling), workloads, application security and RBAC policies.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">How can I tell whether my organisation needs managed Kubernetes rather than a PaaS?</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>The key question is architectural complexity. If your applications require multi-service orchestration, advanced networking interactions or are already designed for Kubernetes, managed Kubernetes is appropriate. If you are deploying relatively standard services, a PaaS will usually be faster and less expensive to operate.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">Managed Kubernetes in France: what sovereign options are available?</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>In France, several providers offer managed Kubernetes on sovereign infrastructure, including Scaleway (Kubernetes Kapsule), OVHcloud (Managed Kubernetes Service) and Clever Cloud with CKE. Beyond location, the key differentiators are the actual level of sovereignty (operator, subcontractors involved in the hosting chain), vanilla compatibility and the shared responsibility model between provider and user.</p>
<!-- /wp:paragraph -->]]></description>
										<content:encoded><![CDATA[<p><img width="800" height="355" src="https://cdn.clever-cloud.com/uploads/2026/07/2026-07-24-clever-cloud-banniere-blog-kubem-eng.png" class="attachment-post-thumbnail size-post-thumbnail wp-post-image" alt="managed kubernetes" decoding="async" loading="lazy" srcset="https://cdn.clever-cloud.com/uploads/2026/07/2026-07-24-clever-cloud-banniere-blog-kubem-eng.png 800w, https://cdn.clever-cloud.com/uploads/2026/07/2026-07-24-clever-cloud-banniere-blog-kubem-eng-300x133.png 300w, https://cdn.clever-cloud.com/uploads/2026/07/2026-07-24-clever-cloud-banniere-blog-kubem-eng-768x341.png 768w" sizes="auto, (max-width: 800px) 100vw, 800px" /></p><!-- wp:paragraph -->
<p>workloads and node pools but does not administer the cluster’s critical infrastructure.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>The control plane consists of Kubernetes’ standard components: the API server, etcd (the datastore that stores the cluster’s state), the scheduler and the controller manager. If the control plane fails, workloads that are already running continue to operate, but the cluster can no longer be managed: no new deployments, no scaling, and no response to kubectl commands. Managed services remove responsibility for precisely this layer from engineering teams.</p>
<!-- /wp:paragraph -->

<!-- wp:spacer {"height":"15px"} -->
<div style="height:15px" aria-hidden="true" class="wp-block-spacer"></div>
<!-- /wp:spacer -->

<!-- wp:heading -->
<h2 class="wp-block-heading">Why is Kubernetes difficult to operate yourself?</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p><a href="https://www.clever.cloud/blog/engineering/2026/05/19/k8s-kubernetes-definition-standard/">Kubernetes</a> &nbsp;is a container orchestration standard, not a turnkey product. Deploying a cluster without a managed layer means handling:</p>
<!-- /wp:paragraph -->

<!-- wp:list -->
<ul class="wp-block-list"><!-- wp:list-item -->
<li>version upgrades (the Kubernetes project actively supports the three most recent minor releases);</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>internal TLS certificate rotation;</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>high availability of the control plane across multiple nodes;</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>backup and consistency of the etcd datastore;</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>security patches, often under tight time constraints.</li>
<!-- /wp:list-item --></ul>
<!-- /wp:list -->

<!-- wp:paragraph -->
<p>These tasks are repetitive, consume valuable engineering time, and are a frequent source of incidents when not performed correctly. Managed services are specifically designed to remove this operational burden from product teams.</p>
<!-- /wp:paragraph -->

<!-- wp:spacer {"height":"15px"} -->
<div style="height:15px" aria-hidden="true" class="wp-block-spacer"></div>
<!-- /wp:spacer -->

<!-- wp:heading -->
<h2 class="wp-block-heading">Use cases: when managed Kubernetes delivers value</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Kubernetes—whether managed or self-managed—becomes relevant in specific scenarios. It is not a systematic replacement for a <a href="https://www.clever.cloud/clever-cloud-paas/">PaaS</a>: the two approaches address different needs.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">Managed Kubernetes is well suited when:</h3>
<!-- /wp:heading -->

<!-- wp:list -->
<ul class="wp-block-list"><!-- wp:list-item -->
<li>the architecture includes multiple interdependent services requiring <a href="https://www.clever.cloud/blog/engineering/2026/07/03/kubernetes-orchestration-containers-what-is-it-for/">fine-grained orchestration</a> (rolling updates, resource management by namespace);</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>workloads are already built for Kubernetes and delivered as Helm charts or YAML manifests;</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>the team requires multi-cluster or hybrid environments (on-premises + cloud);</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>operating the control plane represents a real and measurable cost for SRE or DevOps teams.</li>
<!-- /wp:list-item --></ul>
<!-- /wp:list -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">A PaaS remains a better fit when:</h3>
<!-- /wp:heading -->

<!-- wp:list -->
<ul class="wp-block-list"><!-- wp:list-item -->
<li>the application deployment model (code push with platform-managed build and runtime) matches the way your team works;</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>you want to focus on application code without managing orchestration primitives (networking, scheduling, node management);</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>your applications do not require fine-grained control over workload placement or the cluster’s network topology.</li>
<!-- /wp:list-item --></ul>
<!-- /wp:list -->

<!-- wp:spacer {"height":"15px"} -->
<div style="height:15px" aria-hidden="true" class="wp-block-spacer"></div>
<!-- /wp:spacer -->

<!-- wp:heading -->
<h2 class="wp-block-heading">Comparison table: self-managed Kubernetes vs managed Kubernetes vs PaaS</h2>
<!-- /wp:heading -->

<!-- wp:spacer {"height":"25px"} -->
<div style="height:25px" aria-hidden="true" class="wp-block-spacer"></div>
<!-- /wp:spacer -->

<!-- wp:html -->
<style>
  .cc-table-wrap {
    width: 100%;
    overflow-x: auto;
  }

  .cc-table {
    width: 100%;
    min-width: 760px;
    border-collapse: collapse;
    table-layout: fixed;
    font-size: 17px;
    font-family: "Plus Jakarta Sans", "PlusJakartaSans", -apple-system,
      BlinkMacSystemFont, "Segoe UI", Roboto, Arial, sans-serif;
    color: #111827;
  }

  .cc-table th,
  .cc-table td {
    padding: 12px 16px;
    text-align: left;
    vertical-align: top;
    line-height: 1.6;
  }

  .cc-table thead th {
    font-weight: 700;
    text-align: center;
  }

  .cc-table tbody td:first-child {
    font-weight: 700;
  }

  .cc-table tbody tr + tr td,
  .cc-table tbody tr:first-child td {
    border-top: 1px solid #deddee;
  }

  .cc-table th + th,
  .cc-table td + td {
    border-left: 1px solid #deddee;
  }

  .cc-table th:nth-child(1),
  .cc-table td:nth-child(1) {
    width: 30%;
  }

  .cc-table th:nth-child(2),
  .cc-table td:nth-child(2),
  .cc-table th:nth-child(3),
  .cc-table td:nth-child(3),
  .cc-table th:nth-child(4),
  .cc-table td:nth-child(4) {
    width: 23.33%;
  }

  @media (max-width: 767px) {
    .cc-table {
      font-size: 15px;
    }

    .cc-table th,
    .cc-table td {
      padding: 10px 12px;
    }
  }
</style>

<div class="cc-table-wrap">
  <table class="cc-table">
    <thead>
      <tr>
        <th>Criteria</th>
        <th>Self-managed Kubernetes</th>
        <th>Managed Kubernetes</th>
        <th>PaaS</th>
      </tr>
    </thead>

    <tbody>
      <tr>
        <td>Control plane management</td>
        <td>Managed by the team</td>
        <td>Operated by the provider</td>
        <td>Not exposed</td>
      </tr>

      <tr>
        <td>kubectl / Helm compatibility</td>
        <td>Full</td>
        <td>Full (vanilla)</td>
        <td>Not applicable</td>
      </tr>

      <tr>
        <td>Architectural flexibility</td>
        <td>Maximum</td>
        <td>High</td>
        <td>Limited to PaaS primitives</td>
      </tr>

      <tr>
        <td>Operational overhead</td>
        <td>High</td>
        <td>Reduced</td>
        <td>Low</td>
      </tr>

      <tr>
        <td>Learning curve</td>
        <td>Steep</td>
        <td>Moderate</td>
        <td>Low</td>
      </tr>

      <tr>
        <td>Kubernetes updates</td>
        <td>Manual</td>
        <td>Handled by the provider</td>
        <td>Not applicable</td>
      </tr>

      <tr>
        <td>Infrastructure engineering cost</td>
        <td>High</td>
        <td>Reduced</td>
        <td>Minimal</td>
      </tr>

      <tr>
        <td>Workload portability</td>
        <td>Full</td>
        <td>Full (if vanilla)</td>
        <td>Depends on the PaaS</td>
      </tr>

      <tr>
        <td>Control plane SLA</td>
        <td>N/A<br>(self-operated)</td>
        <td>Varies by offering</td>
        <td>Varies</td>
      </tr>
    </tbody>
  </table>
</div>
<!-- /wp:html -->

<!-- wp:spacer {"height":"20px"} -->
<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>
<!-- /wp:spacer -->

<!-- wp:paragraph -->
<p><strong>Note:</strong> here, <em>vanilla</em> refers to a standard Kubernetes experience, with no changes to native Kubernetes behaviour and no proprietary tooling imposed.</p>
<!-- /wp:paragraph -->

<!-- wp:spacer {"height":"15px"} -->
<div style="height:15px" aria-hidden="true" class="wp-block-spacer"></div>
<!-- /wp:spacer -->

<!-- wp:heading -->
<h2 class="wp-block-heading">Common mistakes when choosing or adopting managed Kubernetes</h2>
<!-- /wp:heading -->

<!-- wp:acf/arguments {"name":"acf/arguments","data":{"items_0_title":"Confusing “managed” with “no operational responsibility”","_items_0_title":"field_638a066e4d2ec","items_0_short_description":"The provider manages the control plane. Node pools, network configuration, RBAC policies, resource limits and workload security remain the user’s responsibility. Managed Kubernetes reduces the operational burden; it does not eliminate it.","_items_0_short_description":"field_638a068d4d2ed","items_0_full_description":"","_items_0_full_description":"field_638a06af4d2ee","items_1_title":"Moving to Kubernetes by default without assessing actual requirements","_items_1_title":"field_638a066e4d2ec","items_1_short_description":"Kubernetes is often adopted because it has become the industry standard, not because it solves a specific problem. For lighter requirements, other distributions (such as \u003ca href=\u0022https://www.clever.cloud/blog/features/2026/05/28/k3s-vs-k8s-what-are-the-differences-and-which-one-should-you-choose-in-2026/\u0022\u003eK3s\u003c/a\u003e) are available and should be evaluated before deploying a full Kubernetes cluster. An application that fits a PaaS deployment model will often be better served by a PaaS: fewer orchestration primitives to manage for an equivalent production outcome.","_items_1_short_description":"field_638a068d4d2ed","items_1_full_description":"","_items_1_full_description":"field_638a06af4d2ee","items_2_title":"Ignoring the release policy","_items_2_title":"field_638a066e4d2ec","items_2_short_description":"The Kubernetes project supports the three most recent minor releases (the “n-2” policy). A cluster that is not kept up to date eventually falls out of support and no longer receives security patches. Verifying that a managed provider follows this policy (and how unsupported cluster versions are handled) is a selection criterion in its own right.","_items_2_short_description":"field_638a068d4d2ed","items_2_full_description":"","_items_2_full_description":"field_638a06af4d2ee","items_3_title":"Overlooking the risk of vendor lock-in","_items_3_title":"field_638a066e4d2ec","items_3_short_description":"Some managed offerings introduce proprietary abstractions (non-standard CRDs, exclusive networking integrations, provider-specific deployment tools) that make migration difficult. A vanilla offering, with no changes to Kubernetes’ native behaviour, ensures portability of existing manifests and workflows.","_items_3_short_description":"field_638a068d4d2ed","items_3_full_description":"","_items_3_full_description":"field_638a06af4d2ee","items_4_title":"Evaluating the service solely on its upfront price","_items_4_title":"field_638a066e4d2ec","items_4_short_description":"The real cost of a Kubernetes cluster includes the engineering time spent maintaining it. A managed service with a higher list price may have a lower total cost of ownership if it eliminates several days of operational work each month.","_items_4_short_description":"field_638a068d4d2ed","items_4_full_description":"","_items_4_full_description":"field_638a06af4d2ee","items":5,"_items":"field_638a065a4d2eb"},"mode":"auto"} /-->

<!-- wp:spacer {"height":"20px"} -->
<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>
<!-- /wp:spacer -->

<!-- wp:acf/avantages {"name":"acf/avantages","data":{"title":"Which option should you choose? \u003cbr\u003e\u003cb\u003eA decision guide\u003c/b\u003e","_title":"field_63878c81ae569","content":"","_content":"field_63878c9cae56a","main_picture":"","_main_picture":"field_63878cd5ae56b","advantages_collection_0_picto":"","_advantages_collection_0_picto":"field_6397417cac52f","advantages_collection_0_title":"Choose a PaaS if","_advantages_collection_0_title":"field_63878d1aae56d","advantages_collection_0_content":"ts deployment model matches the way your team works: you deliver code, while the platform handles builds, runtime and infrastructure. You retain control over your applications without managing Kubernetes orchestration primitives.","_advantages_collection_0_content":"field_63878d4dae56e","advantages_collection_0_link":"","_advantages_collection_0_link":"field_63878d66ae56f","advantages_collection_1_picto":"","_advantages_collection_1_picto":"field_6397417cac52f","advantages_collection_1_title":"Choose managed Kubernetes if","_advantages_collection_1_title":"field_63878d1aae56d","advantages_collection_1_content":"your architecture includes multiple interdependent services, distributed deployments or third-party software already packaged for Kubernetes. A managed service lets you keep your existing tools (kubectl, Helm, Terraform, GitOps) while delegating operation of the control plane.","_advantages_collection_1_content":"field_63878d4dae56e","advantages_collection_1_link":"","_advantages_collection_1_link":"field_63878d66ae56f","advantages_collection_2_picto":"","_advantages_collection_2_picto":"field_6397417cac52f","advantages_collection_2_title":"Choose self-managed Kubernetes if","_advantages_collection_2_title":"field_63878d1aae56d","advantages_collection_2_content":"you have highly specific infrastructure requirements (mandatory on-premises deployment, network configurations unavailable from cloud providers, or sovereignty requirements incompatible with third-party hosting).","_advantages_collection_2_content":"field_63878d4dae56e","advantages_collection_2_link":"","_advantages_collection_2_link":"field_63878d66ae56f","advantages_collection":3,"_advantages_collection":"field_63878cecae56c"},"mode":"auto"} /-->

<!-- wp:spacer {"height":"20px"} -->
<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>
<!-- /wp:spacer -->

<!-- wp:heading -->
<h2 class="wp-block-heading">Managed Kubernetes in Europe: which sovereignty criteria matter?</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>For organisations subject to the GDPR, sector-specific regulations (healthcare, public sector, defence) or data residency requirements, where the cluster is hosted is a compliance issue, not just a performance consideration.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Points to verify:</p>
<!-- /wp:paragraph -->

<!-- wp:list -->
<ul class="wp-block-list"><!-- wp:list-item -->
<li>physical location of the&nbsp; &nbsp; datacenters (country and applicable jurisdiction);</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>identity of the operator and the involvement of foreign subcontractors in the hosting chain;</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>infrastructure certifications (SecNumCloud, ISO 27001, HDS, depending on the provider and the offering);</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>potential access to data by non-European third parties, particularly under extraterritorial legislation.</li>
<!-- /wp:list-item --></ul>
<!-- /wp:list -->

<!-- wp:paragraph -->
<p>A managed Kubernetes service operated in France by a French provider addresses these requirements without requiring additional user-side configuration. This is the approach taken by <a href="https://www.clever.cloud/product/kubernetes/">Clever Kubernetes Engine (CKE)</a>, operated end to end in France by Clever Cloud, with no foreign hyperscaler involved in the hosting chain.</p>
<!-- /wp:paragraph -->

<!-- wp:spacer {"height":"20px"} -->
<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>
<!-- /wp:spacer -->

<!-- wp:heading -->
<h2 class="wp-block-heading">Key takeaways</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p><a href="https://www.clever.cloud/product/kubernetes/">Managed Kubernetes</a> is relevant when your organisation already relies on Kubernetes and maintaining the control plane represents a meaningful operational burden. It is not a universal solution: when a PaaS deployment model matches the way your team works, it often remains the most straightforward choice. For organisations with European sovereignty requirements, the choice of provider and hosting location is critical.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>The key selection criteria are: vanilla compatibility (no vendor lock-in), the release policy, a clear division of responsibilities between provider and user, and the overall cost model-list price plus internal engineering costs.</p>
<!-- /wp:paragraph -->

<!-- wp:spacer {"height":"150px"} -->
<div style="height:150px" aria-hidden="true" class="wp-block-spacer"></div>
<!-- /wp:spacer -->

<!-- wp:heading {"level":1,"style":{"typography":{"textAlign":"center"}}} -->
<h1 class="wp-block-heading has-text-align-center">FAQ</h1>
<!-- /wp:heading -->

<!-- wp:html -->
<div style="height: 1px; background-color: #DEDDEE; margin: 30px auto; width: 100%;"></div>
<!-- /wp:html -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">What is managed Kubernetes?</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>A service in which the cloud provider manages the Kubernetes control plane (provisioning, updates and availability). The user manages workloads and node pools, but not the cluster’s critical infrastructure.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">What is the difference between managed Kubernetes and a PaaS?</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>A PaaS handles the build, deployment and execution of what you deliver (source code or a container image) without requiring you to define the underlying orchestration. Managed Kubernetes retains the standard Kubernetes interface (kubectl, Helm and YAML manifests), allowing you to manage these primitives while delegating control plane operations to the provider. These are two distinct operational models that are complementary rather than interchangeable.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">Does managed Kubernetes create a risk of vendor lock-in?</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>It depends on the implementation. A <em>vanilla</em> offering (with no changes to Kubernetes’ native behaviour and no proprietary tooling imposed) allows workloads to be migrated without rewriting them. By contrast, non-standard CRDs or exclusive networking integrations can create dependency on a specific provider.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">Who is responsible for what in a managed Kubernetes cluster?</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>The provider manages the control plane: updates, availability and patching. The user remains responsible for node pools (sizing and scaling), workloads, application security and RBAC policies.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">How can I tell whether my organisation needs managed Kubernetes rather than a PaaS?</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>The key question is architectural complexity. If your applications require multi-service orchestration, advanced networking interactions or are already designed for Kubernetes, managed Kubernetes is appropriate. If you are deploying relatively standard services, a PaaS will usually be faster and less expensive to operate.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">Managed Kubernetes in France: what sovereign options are available?</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>In France, several providers offer managed Kubernetes on sovereign infrastructure, including Scaleway (Kubernetes Kapsule), OVHcloud (Managed Kubernetes Service) and Clever Cloud with CKE. Beyond location, the key differentiators are the actual level of sovereignty (operator, subcontractors involved in the hosting chain), vanilla compatibility and the shared responsibility model between provider and user.</p>
<!-- /wp:paragraph -->]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Kubernetes Cloud: What It Is, How It Works, and the Main Types of Offerings</title>
		<link>https://www.clever.cloud/blog/engineering/2026/07/24/kubernetes-cloud/</link>
		
		<dc:creator><![CDATA[Leo Le Levé Dandé]]></dc:creator>
		<pubDate>Fri, 24 Jul 2026 09:15:00 +0000</pubDate>
				<category><![CDATA[Engineering]]></category>
		<category><![CDATA[Kubernetes]]></category>
		<guid isPermaLink="false">https://www.clever.cloud/?p=25047</guid>

					<description><![CDATA[<p><img width="2499" height="1109" src="https://cdn.clever-cloud.com/uploads/2026/07/2026-07-22-clever-cloud-banniere-blog-k8s-en.png" class="attachment-post-thumbnail size-post-thumbnail wp-post-image" alt="2026.07.22 Clever Cloud Bannière Blog K8S EN" decoding="async" loading="lazy" srcset="https://cdn.clever-cloud.com/uploads/2026/07/2026-07-22-clever-cloud-banniere-blog-k8s-en.png 2499w, https://cdn.clever-cloud.com/uploads/2026/07/2026-07-22-clever-cloud-banniere-blog-k8s-en-300x133.png 300w, https://cdn.clever-cloud.com/uploads/2026/07/2026-07-22-clever-cloud-banniere-blog-k8s-en-1024x454.png 1024w, https://cdn.clever-cloud.com/uploads/2026/07/2026-07-22-clever-cloud-banniere-blog-k8s-en-768x341.png 768w, https://cdn.clever-cloud.com/uploads/2026/07/2026-07-22-clever-cloud-banniere-blog-k8s-en-1536x682.png 1536w, https://cdn.clever-cloud.com/uploads/2026/07/2026-07-22-clever-cloud-banniere-blog-k8s-en-2048x909.png 2048w, https://cdn.clever-cloud.com/uploads/2026/07/2026-07-22-clever-cloud-banniere-blog-k8s-en-1368x607.png 1368w" sizes="auto, (max-width: 2499px) 100vw, 2499px" /></p><!-- wp:paragraph -->
<p>Kubernetes is a container orchestrator; the cloud is where it most often runs. The term "Kubernetes cloud" therefore covers two related realities: running Kubernetes on cloud infrastructure, and relying on a managed Kubernetes service operated by a provider.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2 class="wp-block-heading">Kubernetes Is Not a Cloud</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p><a href="https://www.clever.cloud/fr/product/kubernetes/">Kubernetes</a> is an open source container orchestrator. <a href="https://www.clever.cloud/blog/engineering/2026/05/19/k8s-kubernetes-definition-standard/">How Kubernetes works</a> comes down to orchestrating containers spread across a set of machines: it schedules their placement, deploys them, supervises their lifecycle, and manages their scaling and network exposure. These containers are often built with Docker, and <a href="https://www.clever.cloud/blog/features/2026/05/22/kubernetes-vs-docker-differences-and-when-to-use-them/">the distinction between Kubernetes and Docker</a> is itself a common source of confusion.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>What Kubernetes does not do is provide the underlying machines, storage, and network. It needs infrastructure to run on, and that infrastructure can take several forms: physical servers (bare metal), virtual machines, a private cloud, or a public cloud. This is the layer a cloud provider supplies.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Hence a frequent confusion: comparing "Kubernetes" with "AWS", or Kubernetes with a cloud provider in general. The two sit at different layers. A cloud provider sells <a href="https://www.clever.cloud/infrastructure/">infrastructure</a> and often offers a managed Kubernetes on top of it. Kubernetes orchestrates the containers running on that infrastructure. You do not choose between Kubernetes and the cloud: you can run Kubernetes on a cloud, or use the managed Kubernetes that cloud offers.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>In other words, choosing an infrastructure and choosing who operates the cluster are two separate decisions. That is what shapes the types of offerings described below.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2 class="wp-block-heading">Running Kubernetes in the Cloud: Managed or Self-Managed</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Once that relationship is clear, two operating models appear. Either you install and operate Kubernetes yourself on machines rented from a cloud provider, or you use a managed service where the provider operates the control plane for you.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>The control plane is the dividing line between the two. It groups the components that drive the cluster: the apiserver, etcd (the datastore that holds the cluster state), the scheduler, and the controller-manager. Operating it yourself means handling version upgrades, which the Kubernetes project requires you to keep up with since it only supports its three most recent minor versions, internal TLS certificate rotation, high availability of these components across several nodes, etcd backup and consistency, and security patches under time pressure. A managed service takes this layer off your hands: you keep control of your workloads, your node pools, and their security, but no longer administer the cluster's critical infrastructure.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Not every need calls for a full cluster. Lighter distributions, <a href="https://www.clever.cloud/blog/features/2026/05/28/k3s-vs-k8s-what-are-the-differences-and-which-one-should-you-choose-in-2026/">such as K3s</a>, exist and are worth evaluating depending on the workload and the context. And Kubernetes, managed or not, is one operating model among others. A <a href="https://www.clever.cloud/clever-cloud-paas/">PaaS</a> follows a different one: you ship code, and the platform handles the build, execution, and scaling, without you having to operate an orchestrator. PaaS and Kubernetes meet different, complementary needs, and a single organization can use both.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2 class="wp-block-heading">The Three Types of Offerings for Running Kubernetes in the Cloud</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Offerings fall into three types, depending on whether you operate the cluster yourself or a provider does, and, in the latter case, on whether that provider is a global hyperscaler or a European player.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">Self-Managed on Cloud Infrastructure</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>You rent compute, storage, and network from a provider, then install and operate Kubernetes yourself. This approach gives the most complete control over the cluster and the underlying infrastructure, at the cost of the operational burden described above. It makes sense when specific infrastructure, network, or compliance constraints are not covered by the managed offerings available. It is also the approach of teams that want to keep a hand on every component of the cluster, from the container runtime to the scheduling and internal network configuration.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">Managed by a Hyperscaler</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>The large global cloud providers offer managed Kubernetes services: Amazon EKS, Google GKE, Microsoft AKS. The provider operates the control plane, and you deploy your workloads with the standard Kubernetes tooling. These offerings are tightly integrated with each provider's ecosystem, which is their strength when your other services already run there, and the point to watch if you ever consider moving away. Their operators, however, fall under non-European jurisdictions, including for the regions they run in Europe. These offerings therefore do not meet a European sovereignty requirement, a decisive criterion for certain sectors and certain types of data.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">Managed by a European Provider</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Several European providers offer managed Kubernetes on infrastructure located within the European Union. Location matters, but it does not make an offering sovereign. A datacenter sitting in Europe remains within reach of the US CLOUD Act if the company operating it answers to a foreign jurisdiction. What determines sovereignty is the <a href="https://www.clever.cloud/sovereign-cloud/">legal and capital control of the operator</a>, not where the servers sit.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>On this ground, several players offer managed Kubernetes: OVHcloud (Managed Kubernetes Service) and Scaleway (Kubernetes Kapsule). Clever Cloud offers <a href="https://www.clever.cloud/clever-kubernetes-engine/">Clever Kubernetes Engine</a>, a managed Kubernetes operated by a European company based in France. Beyond location, these offerings differ in their real level of sovereignty, which depends on the operator and its subcontracting chain, and in how well they fit the tools you already use. For a closer look, French managed Kubernetes offerings are covered in a dedicated article.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2 class="wp-block-heading">Kubernetes Cloud: Key Takeaways</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>"Kubernetes cloud" refers to running Kubernetes on cloud infrastructure, along with the managed services providers offer so you do not have to operate the cluster yourself. The line between self-managed and managed runs through the control plane, the layer a provider either takes on or does not. Three types of offerings then appear: self-managed on cloud infrastructure, managed by a hyperscaler, and managed by a European provider, bearing in mind that a European location alone is not enough to make an offering sovereign. Which one fits depends on your infrastructure constraints, the tooling already in place, and your requirements around data and sovereignty. It all comes down to one distinction: the cloud supplies the infrastructure, Kubernetes orchestrates what runs on it, and the managed model determines who, the provider or you, operates the cluster in between.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>What remains is to work out when a managed Kubernetes makes sense and how to choose one, and to clarify what a sovereign Kubernetes really means.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2 class="wp-block-heading">FAQ</h2>
<!-- /wp:heading -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">Is Kubernetes a cloud?</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>No. Kubernetes is a container orchestrator, not an infrastructure provider. A cloud supplies the servers, storage, and network; Kubernetes orchestrates the containers running on top of them. You can run it on a cloud, or use the managed Kubernetes service a cloud offers.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">Can you run Kubernetes outside the cloud, on bare metal or on-premises?</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Yes. Kubernetes is infrastructure-agnostic: it runs on physical servers, virtual machines, a private or public cloud, and on hybrid environments combining several of these. The cloud is the most common setting, not a requirement.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">Are "Kubernetes cloud" and "managed Kubernetes" the same thing?</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Not exactly. "Kubernetes cloud" broadly means running Kubernetes on cloud infrastructure, which covers both a cluster you operate yourself and a managed service. "Managed Kubernetes" specifically refers to the offering where a provider operates the control plane for you. Every managed Kubernetes is Kubernetes in the cloud, but the reverse is not always true.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">What is the difference between Kubernetes and a cloud provider like AWS?</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>They operate at different layers. AWS is a cloud provider: it sells infrastructure and offers, on top of it, a managed Kubernetes (Amazon EKS). Kubernetes is the orchestrator that drives the containers on that infrastructure. Setting them against each other is like confusing the warehouse with the system that organizes what goes into it.</p>
<!-- /wp:paragraph -->]]></description>
										<content:encoded><![CDATA[<p><img width="2499" height="1109" src="https://cdn.clever-cloud.com/uploads/2026/07/2026-07-22-clever-cloud-banniere-blog-k8s-en.png" class="attachment-post-thumbnail size-post-thumbnail wp-post-image" alt="2026.07.22 Clever Cloud Bannière Blog K8S EN" decoding="async" loading="lazy" srcset="https://cdn.clever-cloud.com/uploads/2026/07/2026-07-22-clever-cloud-banniere-blog-k8s-en.png 2499w, https://cdn.clever-cloud.com/uploads/2026/07/2026-07-22-clever-cloud-banniere-blog-k8s-en-300x133.png 300w, https://cdn.clever-cloud.com/uploads/2026/07/2026-07-22-clever-cloud-banniere-blog-k8s-en-1024x454.png 1024w, https://cdn.clever-cloud.com/uploads/2026/07/2026-07-22-clever-cloud-banniere-blog-k8s-en-768x341.png 768w, https://cdn.clever-cloud.com/uploads/2026/07/2026-07-22-clever-cloud-banniere-blog-k8s-en-1536x682.png 1536w, https://cdn.clever-cloud.com/uploads/2026/07/2026-07-22-clever-cloud-banniere-blog-k8s-en-2048x909.png 2048w, https://cdn.clever-cloud.com/uploads/2026/07/2026-07-22-clever-cloud-banniere-blog-k8s-en-1368x607.png 1368w" sizes="auto, (max-width: 2499px) 100vw, 2499px" /></p><!-- wp:paragraph -->
<p>Kubernetes is a container orchestrator; the cloud is where it most often runs. The term "Kubernetes cloud" therefore covers two related realities: running Kubernetes on cloud infrastructure, and relying on a managed Kubernetes service operated by a provider.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2 class="wp-block-heading">Kubernetes Is Not a Cloud</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p><a href="https://www.clever.cloud/fr/product/kubernetes/">Kubernetes</a> is an open source container orchestrator. <a href="https://www.clever.cloud/blog/engineering/2026/05/19/k8s-kubernetes-definition-standard/">How Kubernetes works</a> comes down to orchestrating containers spread across a set of machines: it schedules their placement, deploys them, supervises their lifecycle, and manages their scaling and network exposure. These containers are often built with Docker, and <a href="https://www.clever.cloud/blog/features/2026/05/22/kubernetes-vs-docker-differences-and-when-to-use-them/">the distinction between Kubernetes and Docker</a> is itself a common source of confusion.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>What Kubernetes does not do is provide the underlying machines, storage, and network. It needs infrastructure to run on, and that infrastructure can take several forms: physical servers (bare metal), virtual machines, a private cloud, or a public cloud. This is the layer a cloud provider supplies.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Hence a frequent confusion: comparing "Kubernetes" with "AWS", or Kubernetes with a cloud provider in general. The two sit at different layers. A cloud provider sells <a href="https://www.clever.cloud/infrastructure/">infrastructure</a> and often offers a managed Kubernetes on top of it. Kubernetes orchestrates the containers running on that infrastructure. You do not choose between Kubernetes and the cloud: you can run Kubernetes on a cloud, or use the managed Kubernetes that cloud offers.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>In other words, choosing an infrastructure and choosing who operates the cluster are two separate decisions. That is what shapes the types of offerings described below.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2 class="wp-block-heading">Running Kubernetes in the Cloud: Managed or Self-Managed</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Once that relationship is clear, two operating models appear. Either you install and operate Kubernetes yourself on machines rented from a cloud provider, or you use a managed service where the provider operates the control plane for you.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>The control plane is the dividing line between the two. It groups the components that drive the cluster: the apiserver, etcd (the datastore that holds the cluster state), the scheduler, and the controller-manager. Operating it yourself means handling version upgrades, which the Kubernetes project requires you to keep up with since it only supports its three most recent minor versions, internal TLS certificate rotation, high availability of these components across several nodes, etcd backup and consistency, and security patches under time pressure. A managed service takes this layer off your hands: you keep control of your workloads, your node pools, and their security, but no longer administer the cluster's critical infrastructure.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Not every need calls for a full cluster. Lighter distributions, <a href="https://www.clever.cloud/blog/features/2026/05/28/k3s-vs-k8s-what-are-the-differences-and-which-one-should-you-choose-in-2026/">such as K3s</a>, exist and are worth evaluating depending on the workload and the context. And Kubernetes, managed or not, is one operating model among others. A <a href="https://www.clever.cloud/clever-cloud-paas/">PaaS</a> follows a different one: you ship code, and the platform handles the build, execution, and scaling, without you having to operate an orchestrator. PaaS and Kubernetes meet different, complementary needs, and a single organization can use both.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2 class="wp-block-heading">The Three Types of Offerings for Running Kubernetes in the Cloud</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Offerings fall into three types, depending on whether you operate the cluster yourself or a provider does, and, in the latter case, on whether that provider is a global hyperscaler or a European player.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">Self-Managed on Cloud Infrastructure</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>You rent compute, storage, and network from a provider, then install and operate Kubernetes yourself. This approach gives the most complete control over the cluster and the underlying infrastructure, at the cost of the operational burden described above. It makes sense when specific infrastructure, network, or compliance constraints are not covered by the managed offerings available. It is also the approach of teams that want to keep a hand on every component of the cluster, from the container runtime to the scheduling and internal network configuration.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">Managed by a Hyperscaler</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>The large global cloud providers offer managed Kubernetes services: Amazon EKS, Google GKE, Microsoft AKS. The provider operates the control plane, and you deploy your workloads with the standard Kubernetes tooling. These offerings are tightly integrated with each provider's ecosystem, which is their strength when your other services already run there, and the point to watch if you ever consider moving away. Their operators, however, fall under non-European jurisdictions, including for the regions they run in Europe. These offerings therefore do not meet a European sovereignty requirement, a decisive criterion for certain sectors and certain types of data.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">Managed by a European Provider</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Several European providers offer managed Kubernetes on infrastructure located within the European Union. Location matters, but it does not make an offering sovereign. A datacenter sitting in Europe remains within reach of the US CLOUD Act if the company operating it answers to a foreign jurisdiction. What determines sovereignty is the <a href="https://www.clever.cloud/sovereign-cloud/">legal and capital control of the operator</a>, not where the servers sit.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>On this ground, several players offer managed Kubernetes: OVHcloud (Managed Kubernetes Service) and Scaleway (Kubernetes Kapsule). Clever Cloud offers <a href="https://www.clever.cloud/clever-kubernetes-engine/">Clever Kubernetes Engine</a>, a managed Kubernetes operated by a European company based in France. Beyond location, these offerings differ in their real level of sovereignty, which depends on the operator and its subcontracting chain, and in how well they fit the tools you already use. For a closer look, French managed Kubernetes offerings are covered in a dedicated article.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2 class="wp-block-heading">Kubernetes Cloud: Key Takeaways</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>"Kubernetes cloud" refers to running Kubernetes on cloud infrastructure, along with the managed services providers offer so you do not have to operate the cluster yourself. The line between self-managed and managed runs through the control plane, the layer a provider either takes on or does not. Three types of offerings then appear: self-managed on cloud infrastructure, managed by a hyperscaler, and managed by a European provider, bearing in mind that a European location alone is not enough to make an offering sovereign. Which one fits depends on your infrastructure constraints, the tooling already in place, and your requirements around data and sovereignty. It all comes down to one distinction: the cloud supplies the infrastructure, Kubernetes orchestrates what runs on it, and the managed model determines who, the provider or you, operates the cluster in between.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>What remains is to work out when a managed Kubernetes makes sense and how to choose one, and to clarify what a sovereign Kubernetes really means.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2 class="wp-block-heading">FAQ</h2>
<!-- /wp:heading -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">Is Kubernetes a cloud?</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>No. Kubernetes is a container orchestrator, not an infrastructure provider. A cloud supplies the servers, storage, and network; Kubernetes orchestrates the containers running on top of them. You can run it on a cloud, or use the managed Kubernetes service a cloud offers.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">Can you run Kubernetes outside the cloud, on bare metal or on-premises?</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Yes. Kubernetes is infrastructure-agnostic: it runs on physical servers, virtual machines, a private or public cloud, and on hybrid environments combining several of these. The cloud is the most common setting, not a requirement.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">Are "Kubernetes cloud" and "managed Kubernetes" the same thing?</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Not exactly. "Kubernetes cloud" broadly means running Kubernetes on cloud infrastructure, which covers both a cluster you operate yourself and a managed service. "Managed Kubernetes" specifically refers to the offering where a provider operates the control plane for you. Every managed Kubernetes is Kubernetes in the cloud, but the reverse is not always true.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">What is the difference between Kubernetes and a cloud provider like AWS?</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>They operate at different layers. AWS is a cloud provider: it sells infrastructure and offers, on top of it, a managed Kubernetes (Amazon EKS). Kubernetes is the orchestrator that drives the containers on that infrastructure. Setting them against each other is like confusing the warehouse with the system that organizes what goes into it.</p>
<!-- /wp:paragraph -->]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Magnetar: a Rust Apache Pulsar client built for deterministic simulation</title>
		<link>https://www.clever.cloud/blog/engineering/2026/07/15/magnetar-rust-apache-pulsar-client-deterministic-simulation/</link>
		
		<dc:creator><![CDATA[Florentin Dubois]]></dc:creator>
		<pubDate>Wed, 15 Jul 2026 14:46:35 +0000</pubDate>
				<category><![CDATA[Engineering]]></category>
		<category><![CDATA[Pulsar]]></category>
		<category><![CDATA[Rust]]></category>
		<guid isPermaLink="false">https://www.clever.cloud/?p=24981</guid>

					<description><![CDATA[<p><img width="2400" height="1065" src="https://cdn.clever-cloud.com/uploads/2026/07/2026-07-15-clever-cloud-banniere-blog-magnetar-en.png" class="attachment-post-thumbnail size-post-thumbnail wp-post-image" alt="2026.07.15 Clever Cloud Bannière Blog Magnetar EN" decoding="async" loading="lazy" srcset="https://cdn.clever-cloud.com/uploads/2026/07/2026-07-15-clever-cloud-banniere-blog-magnetar-en.png 2400w, https://cdn.clever-cloud.com/uploads/2026/07/2026-07-15-clever-cloud-banniere-blog-magnetar-en-300x133.png 300w, https://cdn.clever-cloud.com/uploads/2026/07/2026-07-15-clever-cloud-banniere-blog-magnetar-en-1024x454.png 1024w, https://cdn.clever-cloud.com/uploads/2026/07/2026-07-15-clever-cloud-banniere-blog-magnetar-en-768x341.png 768w, https://cdn.clever-cloud.com/uploads/2026/07/2026-07-15-clever-cloud-banniere-blog-magnetar-en-1536x682.png 1536w, https://cdn.clever-cloud.com/uploads/2026/07/2026-07-15-clever-cloud-banniere-blog-magnetar-en-2048x909.png 2048w, https://cdn.clever-cloud.com/uploads/2026/07/2026-07-15-clever-cloud-banniere-blog-magnetar-en-1368x607.png 1368w" sizes="auto, (max-width: 2400px) 100vw, 2400px" /></p><!-- wp:paragraph -->
<p><a href="https://apple.github.io/foundationdb/testing.html">FoundationDB</a> made this idea famous. Instead of relying only on unit tests and real-cluster end-to-end tests, it runs distributed workloads inside a simulated world where time, network faults, process failures, and scheduling decisions can be explored and reproduced from a seed. <a href="https://github.com/tigerbeetle/tigerbeetle/blob/main/docs/TIGER_STYLE.md">TigerBeetle</a> pushed a complementary discipline: make invariants part of the code, assert the shape of the state continuously, and turn silent corruption into loud local failures.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>At Clever Cloud, we have been applying that direction to Rust infrastructure software. <a href="https://github.com/PierreZ/moonpool">Moonpool</a>, developed by Pierre Zemb, gives Rust systems a deterministic simulation environment where time, networking, tasks, randomness, and storage can be virtualized behind provider traits. <a href="https://github.com/CleverCloud/magnetar">Magnetar</a> is where we apply that approach to a client for <a href="https://pulsar.apache.org/">Apache Pulsar</a>. This is also the approach that we are taking in <a href="https://www.clever.cloud/blog/company/2026/07/01/sozu-2-1-0-udp-load-balancer-programmable-edge/">Sōzu</a>.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Magnetar is a from-scratch Apache Pulsar client driver in Rust. It is built around a sans-io protocol core, a production Tokio engine, and a Moonpool engine for deterministic simulation. This first public release is meant for engineers who want to try Magnetar, evaluate the architecture, compare behavior with existing Pulsar clients, and help shape a stronger Rust-native Pulsar ecosystem.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>The goal is not only to expose a Rust API around Pulsar. The goal is to build a client whose difficult behavior can be inspected, replayed, and made to fail before production gets the chance.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2 class="wp-block-heading">A Pulsar client is part of the distributed system</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>It is tempting to think about a client library as the easy side of a distributed system. The broker is where replication, storage, ownership, and coordination live. The client only connects, sends messages, receives messages, and acknowledges them.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>That view does not survive contact with a real Apache Pulsar client.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>A serious Pulsar client has to manage producers, consumers, readers, partitioned topics, multi-topic consumers, pattern subscriptions, transactions, schemas, authentication, proxy routing, broker lookup, cluster failover, reconnect, backoff, batching, chunking, ack grouping, unacked-message tracking, negative acknowledgements, retry-letter and dead-letter flows, observability, and a long list of Pulsar Improvement Proposals.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Many of the hard bugs are not about one command being encoded incorrectly. They are about time and ordering. A broker drops while a publish is in flight. A reconnect happens while a consumer has pending acknowledgements. A token refresh races with a session reset. A proxy lookup points to a new broker while the old connection is still draining. A topic migrates and the client must rebuild enough state to continue without pretending the old session still exists.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>That means a Pulsar client is not just a convenience wrapper around a socket. It is part of the distributed system. It owns state that has to remain coherent while the world around it changes.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>If that state is hidden inside runtime tasks, channel queues, implicit clocks, and timing accidents, then the client becomes hardest to reason about exactly when precision matters most. Magnetar starts from the opposite assumption: make the protocol state explicit, drive it through narrow boundaries, and keep the I/O outside.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2 class="wp-block-heading">From the Rust Pulsar ecosystem to Magnetar</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Magnetar comes from experience with the Rust Pulsar ecosystem, including maintaining and using <a href="https://github.com/streamnative/pulsar-rs">pulsar-rs</a>. That work matters. It gave Rust users an Apache Pulsar client and created the practical context in which the next generation of driver work could be evaluated.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Magnetar is not an article-length criticism of what existed before it. It is a continuation of the same ecosystem from a different architectural starting point. After spending time with real Pulsar usage, the shape of the next step became clearer: a Rust Pulsar driver should make the protocol/runtime boundary sharper, make difficult behavior reproducible, track parity explicitly, and make testability a first-class design constraint.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>That is why Magnetar does not begin with the public builder API. It begins with the protocol.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>The user-facing API matters, and the first release already exposes a broad surface. But for a distributed client, the deeper question is what happens underneath that API when the broker moves, the connection drops, the clock advances, a timeout fires, a subscription is rebuilt, or the same trace is replayed under a different runtime.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2 class="wp-block-heading">The sans-io core</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>The heart of Magnetar is <a href="https://github.com/CleverCloud/magnetar/tree/main/crates/magnetar-proto">magnetar-proto</a>. It is a synchronous protocol state machine. It has no sockets. It does not depend on Tokio. It does not spawn tasks. It does not use async. It does not read the host clock on the protocol hot path.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Its shape follows the same broad idea that made <a href="https://github.com/quinn-rs/quinn/tree/main/quinn-proto">quinn-proto</a> influential in the Rust networking world: feed bytes in, poll bytes out, poll semantic events, and ask the state machine when its next timer expires.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Conceptually, the interface looks like this:</p>
<!-- /wp:paragraph -->

<!-- wp:html -->
<div
  style="
    max-width: 780px;
    margin: 1.5rem auto;
    padding: 16px 20px;
    background: #0f172a;
    color: #e5eefc;
    border: 1px solid rgba(255, 255, 255, 0.08);
    border-radius: 12px;
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.08);
    font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI',
      Roboto, 'Helvetica Neue', Arial, sans-serif;
    font-size: 15px;
    line-height: 1.7;
  "
>
  <pre
    style="
      margin: 0;
      overflow-x: auto;
      white-space: pre-wrap;
      font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas,
        'Liberation Mono', 'Courier New', monospace;
    "
  ><code>&gt; connection.handle_bytes(now, bytes);

connection.poll_transmit(&amp;mut out);
connection.poll_event();
connection.poll_timeout();</code></pre>
</div>
<!-- /wp:html -->

<!-- wp:paragraph -->
<p>That small shape is a large architectural choice.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>handle_bytes lets an engine feed wire bytes into the state machine. poll_transmit drains outbound frames. poll_event yields semantic events that the runtime must react to, such as authentication challenges, lookup outcomes, checksum mismatches, reconnect signals, or protocol-level transitions. poll_timeout lets the runtime ask when to wake the state machine again.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>The state machine does not decide where bytes come from. It does not know whether the network is a real TCP stream, a TLS stream, a byte pipe inside a simulator, or a scripted broker in a differential harness. It does not decide what "now" means. The engine passes time in.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>The public traits in magnetar-proto follow the same rule. They are not runtime services hidden behind async callbacks. They are small protocol contracts at the points where the state machine needs a decision or a transformation: <a href="https://github.com/CleverCloud/magnetar/blob/main/crates/magnetar-proto/src/auth.rs">AuthProvider</a> produces authentication bytes, <a href="https://github.com/CleverCloud/magnetar/blob/main/crates/magnetar-proto/src/schema/mod.rs">Schema</a> defines encoding, decoding, schema data, and broker-resolved schema hooks, <a href="https://github.com/CleverCloud/magnetar/blob/main/crates/magnetar-proto/src/crypto.rs">MessageEncryptor and MessageDecryptor</a> describe payload crypto over bytes and message metadata, <a href="https://github.com/CleverCloud/magnetar/blob/main/crates/magnetar-proto/src/service_url.rs">ServiceUrlProvider</a> exposes the current service URL for failover, and <a href="https://github.com/CleverCloud/magnetar/blob/main/crates/magnetar-proto/src/health_probe.rs">HealthProbe</a> uses a poll-style contract instead of binding the protocol crate to an async runtime. The pattern is deliberate: the protocol core can ask for facts, bytes, or readiness, while the I/O, caching, refresh logic, network probes, and scheduler stay outside.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>This separation is not just a clean layering exercise. It is what makes the protocol testable without a broker, without a socket, and without an async runtime. A protocol bug can be reduced to a fixture: feed these bytes at this instant, poll these outputs, assert this event stream, and replay the same sequence again.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>For an Apache Pulsar client, that matters because the wire protocol is not only a happy path. It includes producer creation, consumer subscription, acks, nacks, transactions, broker errors, redirects, authentication challenges, topic migration, replicated-subscription markers, schema metadata, batching, chunking, and close paths. Each of these has state. Each state transition is easier to reason about when it is not mixed with socket reads, task scheduling, and runtime-specific wakeups.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2 class="wp-block-heading">No channels as an architectural constraint</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Magnetar also makes an unusual Rust async choice: channel primitives are banned from the workspace.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>The straightforward architecture for a network client is often producer future to channel, channel to driver task, driver task to channel, channel to consumer future. That can work, but it spreads state across queues and tasks. Backpressure becomes implicit. Close semantics become library-specific. Dropped futures can leave messages stranded in places that are hard to inspect. The debugging question becomes "where did this message go?"</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Magnetar uses a different pattern. State lives inside the protocol state machine and the runtime-owned shared connection. User-facing futures register wakers in slabs keyed by operation identifiers. The driver owns the I/O loop, feeds bytes into the state machine, drains outbound frames, and wakes the matching futures as outcomes arrive.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>This is not an aesthetic ban on channels. It is a way to keep ownership of state explicit. When the driver rebuilds producers after a reconnect, when a consumer waits for a message, when an ack outcome is delivered, or when a pending operation fails because a session is gone, the relevant state is in the state machine and can be inspected there.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>That design has trade-offs. It puts more pressure on the correctness of the state machine. It requires careful lock ordering. It requires reviewers to understand waker registration and wakeup paths. But it also makes the behavior much easier to simulate, replay, and compare across runtimes.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2 class="wp-block-heading">Two engines, one state machine</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Magnetar ships two engines that drive the same protocol core.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>The default engine is <a href="https://github.com/CleverCloud/magnetar/tree/main/crates/magnetar-runtime-tokio">magnetar-runtime-tokio</a>. It is the production execution path: TCP, TLS through tokio-rustls, driver tasks, real time, real sockets, and the public PulsarClient surface most users will reach first.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>The second engine is <a href="https://github.com/CleverCloud/magnetar/tree/main/crates/magnetar-runtime-moonpool">magnetar-runtime-moonpool</a>. It drives the same magnetar-proto::Connection state machine through Moonpool providers. Instead of baking in the runtime, Moonpool exposes provider traits for networking, time, task spawning, randomness, and storage. Under a production-style provider bundle, the engine can run against real I/O. Under simulation providers, those same categories can be virtualized.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>This is where deterministic simulation becomes practical. The client can be driven in a world where time advances under control, network delivery can be reordered or interrupted, tasks run under a deterministic scheduler, randomness is seeded, and failures can be replayed from the same seed.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Moonpool is not a mock. A mock usually replaces a component with simplified behavior. That is useful for many unit tests, but it is not the same thing as exercising a real client through hard interleavings.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Moonpool is also not a normal end-to-end test. An e2e test runs the real system, which is essential, but it usually runs with real time, real networking, and failures that are difficult to reproduce once the timing has moved on.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Moonpool sits in a different space. It keeps the client code close to the real execution path while virtualizing the providers that make distributed behavior hard to reproduce. The point is not to avoid e2e tests. The point is to add a regime where failures are not anecdotes. They become seeds.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Magnetar's Moonpool engine uses the same protocol state machine as the Tokio engine. The TLS path is also driven in a way that preserves the simulation boundary: instead of relying on tokio-rustls, the Moonpool engine drives rustls::ClientConnection over the byte pipe directly. That keeps TLS handshakes under the same deterministic control as the rest of the simulated network.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2 class="wp-block-heading">Differential testing: making the engines agree</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Two engines are useful only if they do not silently become two different clients.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Magnetar therefore includes a differential harness. It runs a trace, such as connect, open producer, send, subscribe, receive, ack, seek, and close, against both the Tokio and Moonpool engines, then compares the user-visible event streams.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>This matters because the Moonpool engine is used to find bugs that are difficult to expose with real time and real sockets. For that to be meaningful, the simulated engine must remain observationally aligned with the production engine at the user boundary.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>If Tokio and Moonpool drift, the simulator becomes less trustworthy. If the differential harness keeps them aligned, then a seed failure in the simulated world is much more likely to point at a real property of the client, not a separate test-only implementation.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>This is also why Magnetar's validation policy is strict about cross-runtime coverage. Behavioral changes are expected to exercise the sans-io layer, the Tokio runtime, the Moonpool runtime, differential equivalence, and the e2e surface when applicable. That is more work than adding one unit test. It is also the cost of making deterministic simulation a real engineering tool rather than a side experiment.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2 class="wp-block-heading">Java parity as a credibility contract</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Simulation is not a substitute for feature breadth. It is what makes feature breadth less fragile.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Apache Pulsar has a mature <a href="https://pulsar.apache.org/docs/">Java client</a>, and for many users that client defines what "a Pulsar client" means. Basic produce and consume are not enough. A credible client must cover the behaviors applications rely on: batching, compression, transactions, schemas, partitioned topics, multi-topic and pattern consumers, retries, dead-letter flows, authentication providers, proxy support, failover, admin operations, and the PIPs that shape modern Pulsar usage.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Magnetar tracks Java-client parity as a public contract. The <a href="https://github.com/CleverCloud/magnetar/blob/main/README.md">README</a> carries the parity matrix and the engine-by-engine status. The article does not need to reproduce that matrix, but the matrix itself is important. It gives users a way to evaluate the project as a Pulsar client, not as a narrow experiment around one happy path.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>This is the reason Magnetar's first public release is broader than a minimal demo. It includes the protocol foundation, the public facade, runtime engines, admin support, authentication providers, message crypto, CLI work, observability hooks, and a growing list of PIP surfaces.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>The exact reason for tracking parity is simple: users do not choose a client library only because its internal architecture is elegant. They choose it because it can represent the system they actually run. Architecture makes that surface maintainable. Parity makes it useful.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2 class="wp-block-heading">Beyond produce and consume</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>The phrase "Pulsar client" can hide a lot of surface area. From the outside, the first examples usually look small: build a client, create a producer, send a payload, subscribe with a consumer, receive a message, acknowledge it. Those examples are useful because they show the entry point. They are not enough to evaluate the client.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Real Pulsar applications depend on behaviors that only appear after the first demo works. A producer may need batching, compression, chunking, access modes, sequence ids, send timeouts, per-message properties, transactions, interceptors, and latency statistics. A consumer may need batch receive, cumulative acknowledgements, batch-index acknowledgements, nack backoff, ack timeout handling, retry topics, dead-letter topics, seek, pause/resume, subscription modes, and per-partition behavior. Applications with strict schemas need Avro, JSON, Protobuf, Protobuf-native, KeyValue, primitive schemas, and broker-side schema lookup semantics. Deployments with security requirements need token auth, mTLS, OAuth2, SASL, Kerberos/GSSAPI, Athenz, TLS provider choices, and a way to reason about crypto behavior without making every build drag every provider.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Those features are not independent checkboxes. They interact. Batching interacts with compression and send timeouts. Chunking interacts with sequence ids and redelivery. Transactions interact with acknowledgements. Reconnect interacts with producers, consumers, lookups, proxy routing, and failover. Observability has to describe the behavior without leaking secrets or flooding operators under churn.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>That is why Magnetar's feature work and architecture work are tied together. The more complete the surface becomes, the more important it is that the protocol state is explicit and that the runtime boundary is narrow. A broad client built on accidental state becomes harder to maintain as it becomes more useful. A broad client built on replayable state gives maintainers a better chance to keep feature growth from turning into hidden behavior.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2 class="wp-block-heading">Validation as architecture</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Magnetar's test strategy is intentionally layered because each layer catches a different class of bug.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>The sans-io layer lets protocol behavior be tested without sockets or async tasks. The <a href="https://github.com/CleverCloud/magnetar/blob/main/docs/testing.md">project testing documentation</a> currently records more than 270 unit tests in magnetar-proto. Those tests exercise the state machine directly: bytes in, events out, transmit buffers out, state transitions checked.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Runtime integration tests exercise the glue that pure protocol tests cannot cover. The Tokio engine and Moonpool engine each have their own integration surfaces, and the project enforces runtime parity so one engine does not quietly fall behind the other.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>The deterministic chaos pack targets the failure schedules that motivated the architecture in the first place: reconnect, failover, virtual-clock timers, TLS handshake ordering, in-flight publishes, broker migration, and adversarial network behavior. The <a href="https://github.com/CleverCloud/magnetar/blob/main/docs/moonpool-engine.md">Moonpool engine documentation</a> describes a daily Moonpool seed sweep with 128 freshly rolled random seeds in parallel. The number is less important than what it represents: the client is being driven through schedules that a human would not write by hand.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Differential equivalence tests compare the two runtime worlds. They ask a direct question: if the same trace is run through Tokio and Moonpool, does the user see the same behavior?</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>End-to-end tests still matter. They keep Magnetar honest against a real Apache Pulsar broker. Simulation can make failures reproducible, but it does not replace compatibility with the system users actually deploy.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Taken together, these layers are not ceremony. They are part of the architecture. The point is not to collect large test numbers. The point is to put validation pressure exactly where distributed clients fail: protocol state, runtime boundaries, reconnect logic, timing, equivalence, and real broker behavior.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2 class="wp-block-heading">What reproducibility changes in practice</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>The practical value of deterministic simulation is not that it makes tests more sophisticated. It changes the debugging loop.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>When a traditional end-to-end test fails because of timing, the first question is often whether the failure is reproducible at all. If it is not, engineers start adding sleeps, logs, larger timeouts, or retry loops. Some of those changes are useful. Many of them only move the failure somewhere else. The failure remains a story: "we saw it once in CI".</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>With a deterministic simulation, the failure should become an artifact. The artifact is a seed, a trace, and a state transition that can be replayed. The question changes from "can we make it happen again?" to "what invariant did this schedule violate?"</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>That difference matters for a client library. Client bugs often sit at the boundary between user code and the broker. They are easy to misattribute. A publish can fail because the broker closed the connection, because the client lost an outcome, because the reconnect path rebuilt the producer too late, because an ack was delivered to the wrong waiter, because a timeout fired against stale session state, or because the runtime task died after the protocol had already transitioned.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>If all of that behavior is spread across tasks, channels, timers, and sockets, a failure report is hard to compress. If the protocol state machine is explicit, the runtime boundary is narrow, and the same sequence can be replayed under controlled providers, the report can become much smaller: this seed, this trace, this event order, this invariant.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>That is why Magnetar treats reproducibility as part of the client design. The point is not only to catch more bugs. The point is to make the bugs that do appear cheaper to understand and safer to fix.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>It also changes code review. A reviewer can ask whether a behavior is covered at the right layer. Is this a pure protocol transition? Then the sans-io test should feed bytes and assert events. Is it runtime glue? Then Tokio and Moonpool need equivalent coverage. Is it an observable behavior shared by both engines? Then the differential harness should compare the event streams. Is it broker compatibility? Then an e2e test should touch a real Pulsar broker.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Those questions are more precise than "did we add tests?" They connect the test to the failure model.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2 class="wp-block-heading">What to inspect first</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>For engineers reading Magnetar for the first time, the best entry point is not a single file. It is the relationship between the documents and the code.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>The <a href="https://github.com/CleverCloud/magnetar/blob/main/README.md">README</a> gives the public surface: what the client exposes, which features are implemented, how the Java-client parity matrix is tracked, which PIPs are supported, and how the two engines are positioned. That is the user-facing contract.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>The <a href="https://github.com/CleverCloud/magnetar/blob/main/ARCHITECTURE.md">architecture document</a> explains the shape underneath that contract. It shows the crate topology, the dependency direction, the sans-io boundary, the driver loop, the event model, the producer and consumer paths, the runtime engines, TLS sites, schemas, PIP coverage, and the validation strategy. That is the system map.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>The <a href="https://github.com/CleverCloud/magnetar/tree/main/specs/adr">ADR series</a> explains why the system has this shape. <a href="https://github.com/CleverCloud/magnetar/blob/main/specs/adr/0004-sans-io-protocol-core.md">ADR-0004</a> records the sans-io split. <a href="https://github.com/CleverCloud/magnetar/blob/main/specs/adr/0003-no-channels-rule.md">ADR-0003</a> records the no-channels rule. <a href="https://github.com/CleverCloud/magnetar/blob/main/specs/adr/0011-clock-injection-sans-io.md">ADR-0011</a> records clock injection. <a href="https://github.com/CleverCloud/magnetar/blob/main/specs/adr/0010-v0-1-full-java-parity.md">ADR-0010</a> records the Java parity decision. <a href="https://github.com/CleverCloud/magnetar/blob/main/specs/adr/0019-engine-scope-and-moonpool-parity.md">ADR-0019</a> records how the production Tokio engine and the Moonpool engine relate to the parity goal. <a href="https://github.com/CleverCloud/magnetar/blob/main/specs/adr/0024-cross-runtime-test-and-coverage-policy.md">ADR-0024</a> records the cross-runtime testing policy.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>This matters because Magnetar is intentionally not only a code drop. It is a set of engineering decisions with a public audit trail. If you disagree with the design, the ADRs give you the right surface to discuss. If you want to contribute a feature, the parity matrix and validation policy tell you what "done" means. If you want to evaluate the simulation work, the <a href="https://github.com/CleverCloud/magnetar/blob/main/docs/moonpool-engine.md">Moonpool engine documentation</a> and the differential harness show how the same protocol core is driven in different worlds.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>The first release should therefore be read in two ways. As a Pulsar user, look at the client surface and the parity matrix. As a Rust infrastructure engineer, look at the state-machine boundary and the simulation strategy. The interesting part of Magnetar is that both views are meant to reinforce each other.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2 class="wp-block-heading">What the first public release gives you</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>This first public release is a technical entry point. It is for engineers who want to try Magnetar, read the architecture, inspect the ADRs, compare behavior with existing Pulsar clients, and help shape the Rust-native Pulsar ecosystem.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>The high-level client API starts with the usual shape:</p>
<!-- /wp:paragraph -->

<!-- wp:html -->
<div
  style="
    max-width: 780px;
    margin: 1.5rem auto;
    padding: 16px 20px;
    background: #0f172a;
    color: #e5eefc;
    border: 1px solid rgba(255, 255, 255, 0.08);
    border-radius: 12px;
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.08);
    font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI',
      Roboto, 'Helvetica Neue', Arial, sans-serif;
    font-size: 15px;
    line-height: 1.7;
  "
>
  <pre
    style="
      margin: 0;
      overflow-x: auto;
      white-space: pre-wrap;
      font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas,
        'Liberation Mono', 'Courier New', monospace;
    "
  ><code>let client = PulsarClient::builder()
    .service_url("pulsar://localhost:6650")
    .build()
    .await?;

let producer = client
    .producer("persistent://public/default/orders")
    .create()
    .await?;</code></pre>
</div>
<!-- /wp:html -->

<!-- wp:paragraph -->
<p>That API is important because the client must be usable. But the release is also an invitation to inspect the lower layers. Read the <a href="https://github.com/CleverCloud/magnetar/blob/main/README.md">README</a> for the feature matrix. Read the <a href="https://github.com/CleverCloud/magnetar/blob/main/ARCHITECTURE.md">architecture document</a> for the sans-io design. Read the <a href="https://github.com/CleverCloud/magnetar/tree/main/specs/adr">ADRs</a> for the decisions behind no channels, swappable engines, clock injection, Java parity, Moonpool parity, TLS provider choices, and cross-runtime validation. Read the <a href="https://github.com/CleverCloud/magnetar/blob/main/docs/moonpool-engine.md">Moonpool engine documentation</a> if you are interested in how deterministic simulation can be applied to a real network client.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>The important point for this article is the direction: Magnetar is public so engineers can evaluate both the client surface and the engineering model behind it.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>The inaugural technical entry point is available via <a href="https://github.com/CleverCloud/magnetar/releases#release-v1.0.0">v1.0.0</a>, while the current state of the driver can be tracked in the <a href="https://github.com/CleverCloud/magnetar/releases#release-v1.2.0">v1.2.0</a> release.&nbsp;</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2 class="wp-block-heading">Why this matters beyond Magnetar</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Magnetar is an Apache Pulsar client. It is also a concrete example of how we want to build more Rust infrastructure software.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Distributed systems fail through state transitions. Some of those transitions are obvious and easy to test. Many are not. They happen when time advances in an unlucky place, when a retry overlaps with a close path, when a broker drops a connection after accepting part of the session, when a callback is registered just after a notification, or when a reconnect path rebuilds one handle but not another.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>You can try to chase those bugs after they happen. Sometimes that is unavoidable. But the architecture can make the chase easier or harder.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>A client with a pure protocol core, explicit events, injected time, replaceable I/O, deterministic seeds, and cross-runtime comparison gives engineers better tools. It lets them reduce a failure to a trace. It lets them replay that trace. It lets them ask whether a simulated failure corresponds to the production runtime. It lets them add an invariant where a silent state drift used to hide.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>That is the direction Magnetar takes. Make the protocol explicit. Make the runtime replaceable. Make failures reproducible. Make correctness something the code has to demonstrate continuously.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Thank you to Pierre Zemb for Moonpool and for pushing this deterministic-simulation direction in Rust, and to the contributors and maintainers in the Rust Pulsar ecosystem whose work made the next step possible.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Magnetar is open source. The code, architecture notes, ADRs, and documentation live at <a href="https://github.com/CleverCloud/magnetar">github.com/CleverCloud/magnetar</a>.</p>
<!-- /wp:paragraph -->

<!-- wp:spacer {"height":"25px"} -->
<div style="height:25px" aria-hidden="true" class="wp-block-spacer"></div>
<!-- /wp:spacer -->

<!-- wp:html -->
<hr style="border: none; height: 1px; background-color: #ccc; margin: 32px 0;">
<!-- /wp:html -->

<!-- wp:spacer {"height":"25px"} -->
<div style="height:25px" aria-hidden="true" class="wp-block-spacer"></div>
<!-- /wp:spacer -->

<!-- wp:heading -->
<h2 class="wp-block-heading">References</h2>
<!-- /wp:heading -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">Magnetar</h3>
<!-- /wp:heading -->

<!-- wp:list -->
<ul class="wp-block-list"><!-- wp:list-item -->
<li><strong>Magnetar repository</strong>. Public Rust Apache Pulsar client repository. <a href="https://github.com/CleverCloud/magnetar">https://github.com/CleverCloud/magnetar</a></li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><strong>Magnetar README</strong>. Public feature surface, Java client parity matrix, supported PIPs, engine coverage, and status. <a href="https://github.com/CleverCloud/magnetar/blob/main/README.md">https://github.com/CleverCloud/magnetar/blob/main/README.md</a></li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><strong>Magnetar architecture</strong>. Sans-io rationale, crate topology, driver loop, protocol state machine, and tests. <a href="https://github.com/CleverCloud/magnetar/blob/main/ARCHITECTURE.md">https://github.com/CleverCloud/magnetar/blob/main/ARCHITECTURE.md</a></li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><strong>Magnetar documentation index</strong>. Moonpool engine, testing, CLI, observability, logging, PIP features. <a href="https://github.com/CleverCloud/magnetar/blob/main/docs/README.md">https://github.com/CleverCloud/magnetar/blob/main/docs/README.md</a></li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><strong>Moonpool engine documentation</strong>. Deterministic-simulation engine, chaos pack, differential harness, provider model. <a href="https://github.com/CleverCloud/magnetar/blob/main/docs/moonpool-engine.md">https://github.com/CleverCloud/magnetar/blob/main/docs/moonpool-engine.md</a></li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><strong>Testing documentation</strong>. Test categories and validation commands. <a href="https://github.com/CleverCloud/magnetar/blob/main/docs/testing.md">https://github.com/CleverCloud/magnetar/blob/main/docs/testing.md</a></li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><strong>ADR-0004</strong>. Sans-io magnetar-proto and swappable I/O engines. <a href="https://github.com/CleverCloud/magnetar/blob/main/specs/adr/0004-sans-io-protocol-core.md">https://github.com/CleverCloud/magnetar/blob/main/specs/adr/0004-sans-io-protocol-core.md</a></li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><strong>ADR-0010</strong>. Full Java-client parity scope. <a href="https://github.com/CleverCloud/magnetar/blob/main/specs/adr/0010-v0-1-full-java-parity.md">https://github.com/CleverCloud/magnetar/blob/main/specs/adr/0010-v0-1-full-java-parity.md</a></li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><strong>ADR-0024</strong>. Cross-runtime test and coverage policy. <a href="https://github.com/CleverCloud/magnetar/blob/main/specs/adr/0024-cross-runtime-test-and-coverage-policy.md">https://github.com/CleverCloud/magnetar/blob/main/specs/adr/0024-cross-runtime-test-and-coverage-policy.md</a></li>
<!-- /wp:list-item --></ul>
<!-- /wp:list -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">Ecosystem</h3>
<!-- /wp:heading -->

<!-- wp:list -->
<ul class="wp-block-list"><!-- wp:list-item -->
<li><strong>pulsar-rs</strong>. Existing Rust Apache Pulsar client project. <a href="https://github.com/streamnative/pulsar-rs">https://github.com/streamnative/pulsar-rs</a></li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><strong>Apache Pulsar</strong>. Distributed messaging and streaming platform. <a href="https://pulsar.apache.org/">https://pulsar.apache.org/</a></li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><strong>Apache Pulsar Java client</strong>. Reference client surface for many Pulsar users. <a href="https://pulsar.apache.org/docs/">https://pulsar.apache.org/docs/</a></li>
<!-- /wp:list-item --></ul>
<!-- /wp:list -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">Deterministic simulation</h3>
<!-- /wp:heading -->

<!-- wp:list -->
<ul class="wp-block-list"><!-- wp:list-item -->
<li><strong>FoundationDB testing</strong>. Deterministic simulation and fault injection lineage. <a href="https://apple.github.io/foundationdb/testing.html">https://apple.github.io/foundationdb/testing.html</a></li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><strong>TigerBeetle TigerStyle</strong>. Assertion-first engineering style. <a href="https://github.com/tigerbeetle/tigerbeetle/blob/main/docs/TIGER_STYLE.md">https://github.com/tigerbeetle/tigerbeetle/blob/main/docs/TIGER_STYLE.md</a></li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><strong>TigerBeetle VOPR</strong>. Simulation testing approach. <a href="https://github.com/tigerbeetle/tigerbeetle/blob/main/docs/internals/vopr.md">https://github.com/tigerbeetle/tigerbeetle/blob/main/docs/internals/vopr.md</a></li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><strong>Moonpool repository</strong>. Deterministic simulation for Rust systems, developed by Pierre Zemb. <a href="https://github.com/PierreZ/moonpool">https://github.com/PierreZ/moonpool</a></li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><strong>moonpool-sim</strong>. Simulation engine crate for Moonpool. <a href="https://crates.io/crates/moonpool-sim">https://crates.io/crates/moonpool-sim</a></li>
<!-- /wp:list-item --></ul>
<!-- /wp:list -->]]></description>
										<content:encoded><![CDATA[<p><img width="2400" height="1065" src="https://cdn.clever-cloud.com/uploads/2026/07/2026-07-15-clever-cloud-banniere-blog-magnetar-en.png" class="attachment-post-thumbnail size-post-thumbnail wp-post-image" alt="2026.07.15 Clever Cloud Bannière Blog Magnetar EN" decoding="async" loading="lazy" srcset="https://cdn.clever-cloud.com/uploads/2026/07/2026-07-15-clever-cloud-banniere-blog-magnetar-en.png 2400w, https://cdn.clever-cloud.com/uploads/2026/07/2026-07-15-clever-cloud-banniere-blog-magnetar-en-300x133.png 300w, https://cdn.clever-cloud.com/uploads/2026/07/2026-07-15-clever-cloud-banniere-blog-magnetar-en-1024x454.png 1024w, https://cdn.clever-cloud.com/uploads/2026/07/2026-07-15-clever-cloud-banniere-blog-magnetar-en-768x341.png 768w, https://cdn.clever-cloud.com/uploads/2026/07/2026-07-15-clever-cloud-banniere-blog-magnetar-en-1536x682.png 1536w, https://cdn.clever-cloud.com/uploads/2026/07/2026-07-15-clever-cloud-banniere-blog-magnetar-en-2048x909.png 2048w, https://cdn.clever-cloud.com/uploads/2026/07/2026-07-15-clever-cloud-banniere-blog-magnetar-en-1368x607.png 1368w" sizes="auto, (max-width: 2400px) 100vw, 2400px" /></p><!-- wp:paragraph -->
<p><a href="https://apple.github.io/foundationdb/testing.html">FoundationDB</a> made this idea famous. Instead of relying only on unit tests and real-cluster end-to-end tests, it runs distributed workloads inside a simulated world where time, network faults, process failures, and scheduling decisions can be explored and reproduced from a seed. <a href="https://github.com/tigerbeetle/tigerbeetle/blob/main/docs/TIGER_STYLE.md">TigerBeetle</a> pushed a complementary discipline: make invariants part of the code, assert the shape of the state continuously, and turn silent corruption into loud local failures.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>At Clever Cloud, we have been applying that direction to Rust infrastructure software. <a href="https://github.com/PierreZ/moonpool">Moonpool</a>, developed by Pierre Zemb, gives Rust systems a deterministic simulation environment where time, networking, tasks, randomness, and storage can be virtualized behind provider traits. <a href="https://github.com/CleverCloud/magnetar">Magnetar</a> is where we apply that approach to a client for <a href="https://pulsar.apache.org/">Apache Pulsar</a>. This is also the approach that we are taking in <a href="https://www.clever.cloud/blog/company/2026/07/01/sozu-2-1-0-udp-load-balancer-programmable-edge/">Sōzu</a>.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Magnetar is a from-scratch Apache Pulsar client driver in Rust. It is built around a sans-io protocol core, a production Tokio engine, and a Moonpool engine for deterministic simulation. This first public release is meant for engineers who want to try Magnetar, evaluate the architecture, compare behavior with existing Pulsar clients, and help shape a stronger Rust-native Pulsar ecosystem.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>The goal is not only to expose a Rust API around Pulsar. The goal is to build a client whose difficult behavior can be inspected, replayed, and made to fail before production gets the chance.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2 class="wp-block-heading">A Pulsar client is part of the distributed system</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>It is tempting to think about a client library as the easy side of a distributed system. The broker is where replication, storage, ownership, and coordination live. The client only connects, sends messages, receives messages, and acknowledges them.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>That view does not survive contact with a real Apache Pulsar client.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>A serious Pulsar client has to manage producers, consumers, readers, partitioned topics, multi-topic consumers, pattern subscriptions, transactions, schemas, authentication, proxy routing, broker lookup, cluster failover, reconnect, backoff, batching, chunking, ack grouping, unacked-message tracking, negative acknowledgements, retry-letter and dead-letter flows, observability, and a long list of Pulsar Improvement Proposals.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Many of the hard bugs are not about one command being encoded incorrectly. They are about time and ordering. A broker drops while a publish is in flight. A reconnect happens while a consumer has pending acknowledgements. A token refresh races with a session reset. A proxy lookup points to a new broker while the old connection is still draining. A topic migrates and the client must rebuild enough state to continue without pretending the old session still exists.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>That means a Pulsar client is not just a convenience wrapper around a socket. It is part of the distributed system. It owns state that has to remain coherent while the world around it changes.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>If that state is hidden inside runtime tasks, channel queues, implicit clocks, and timing accidents, then the client becomes hardest to reason about exactly when precision matters most. Magnetar starts from the opposite assumption: make the protocol state explicit, drive it through narrow boundaries, and keep the I/O outside.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2 class="wp-block-heading">From the Rust Pulsar ecosystem to Magnetar</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Magnetar comes from experience with the Rust Pulsar ecosystem, including maintaining and using <a href="https://github.com/streamnative/pulsar-rs">pulsar-rs</a>. That work matters. It gave Rust users an Apache Pulsar client and created the practical context in which the next generation of driver work could be evaluated.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Magnetar is not an article-length criticism of what existed before it. It is a continuation of the same ecosystem from a different architectural starting point. After spending time with real Pulsar usage, the shape of the next step became clearer: a Rust Pulsar driver should make the protocol/runtime boundary sharper, make difficult behavior reproducible, track parity explicitly, and make testability a first-class design constraint.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>That is why Magnetar does not begin with the public builder API. It begins with the protocol.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>The user-facing API matters, and the first release already exposes a broad surface. But for a distributed client, the deeper question is what happens underneath that API when the broker moves, the connection drops, the clock advances, a timeout fires, a subscription is rebuilt, or the same trace is replayed under a different runtime.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2 class="wp-block-heading">The sans-io core</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>The heart of Magnetar is <a href="https://github.com/CleverCloud/magnetar/tree/main/crates/magnetar-proto">magnetar-proto</a>. It is a synchronous protocol state machine. It has no sockets. It does not depend on Tokio. It does not spawn tasks. It does not use async. It does not read the host clock on the protocol hot path.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Its shape follows the same broad idea that made <a href="https://github.com/quinn-rs/quinn/tree/main/quinn-proto">quinn-proto</a> influential in the Rust networking world: feed bytes in, poll bytes out, poll semantic events, and ask the state machine when its next timer expires.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Conceptually, the interface looks like this:</p>
<!-- /wp:paragraph -->

<!-- wp:html -->
<div
  style="
    max-width: 780px;
    margin: 1.5rem auto;
    padding: 16px 20px;
    background: #0f172a;
    color: #e5eefc;
    border: 1px solid rgba(255, 255, 255, 0.08);
    border-radius: 12px;
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.08);
    font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI',
      Roboto, 'Helvetica Neue', Arial, sans-serif;
    font-size: 15px;
    line-height: 1.7;
  "
>
  <pre
    style="
      margin: 0;
      overflow-x: auto;
      white-space: pre-wrap;
      font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas,
        'Liberation Mono', 'Courier New', monospace;
    "
  ><code>&gt; connection.handle_bytes(now, bytes);

connection.poll_transmit(&amp;mut out);
connection.poll_event();
connection.poll_timeout();</code></pre>
</div>
<!-- /wp:html -->

<!-- wp:paragraph -->
<p>That small shape is a large architectural choice.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>handle_bytes lets an engine feed wire bytes into the state machine. poll_transmit drains outbound frames. poll_event yields semantic events that the runtime must react to, such as authentication challenges, lookup outcomes, checksum mismatches, reconnect signals, or protocol-level transitions. poll_timeout lets the runtime ask when to wake the state machine again.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>The state machine does not decide where bytes come from. It does not know whether the network is a real TCP stream, a TLS stream, a byte pipe inside a simulator, or a scripted broker in a differential harness. It does not decide what "now" means. The engine passes time in.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>The public traits in magnetar-proto follow the same rule. They are not runtime services hidden behind async callbacks. They are small protocol contracts at the points where the state machine needs a decision or a transformation: <a href="https://github.com/CleverCloud/magnetar/blob/main/crates/magnetar-proto/src/auth.rs">AuthProvider</a> produces authentication bytes, <a href="https://github.com/CleverCloud/magnetar/blob/main/crates/magnetar-proto/src/schema/mod.rs">Schema</a> defines encoding, decoding, schema data, and broker-resolved schema hooks, <a href="https://github.com/CleverCloud/magnetar/blob/main/crates/magnetar-proto/src/crypto.rs">MessageEncryptor and MessageDecryptor</a> describe payload crypto over bytes and message metadata, <a href="https://github.com/CleverCloud/magnetar/blob/main/crates/magnetar-proto/src/service_url.rs">ServiceUrlProvider</a> exposes the current service URL for failover, and <a href="https://github.com/CleverCloud/magnetar/blob/main/crates/magnetar-proto/src/health_probe.rs">HealthProbe</a> uses a poll-style contract instead of binding the protocol crate to an async runtime. The pattern is deliberate: the protocol core can ask for facts, bytes, or readiness, while the I/O, caching, refresh logic, network probes, and scheduler stay outside.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>This separation is not just a clean layering exercise. It is what makes the protocol testable without a broker, without a socket, and without an async runtime. A protocol bug can be reduced to a fixture: feed these bytes at this instant, poll these outputs, assert this event stream, and replay the same sequence again.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>For an Apache Pulsar client, that matters because the wire protocol is not only a happy path. It includes producer creation, consumer subscription, acks, nacks, transactions, broker errors, redirects, authentication challenges, topic migration, replicated-subscription markers, schema metadata, batching, chunking, and close paths. Each of these has state. Each state transition is easier to reason about when it is not mixed with socket reads, task scheduling, and runtime-specific wakeups.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2 class="wp-block-heading">No channels as an architectural constraint</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Magnetar also makes an unusual Rust async choice: channel primitives are banned from the workspace.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>The straightforward architecture for a network client is often producer future to channel, channel to driver task, driver task to channel, channel to consumer future. That can work, but it spreads state across queues and tasks. Backpressure becomes implicit. Close semantics become library-specific. Dropped futures can leave messages stranded in places that are hard to inspect. The debugging question becomes "where did this message go?"</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Magnetar uses a different pattern. State lives inside the protocol state machine and the runtime-owned shared connection. User-facing futures register wakers in slabs keyed by operation identifiers. The driver owns the I/O loop, feeds bytes into the state machine, drains outbound frames, and wakes the matching futures as outcomes arrive.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>This is not an aesthetic ban on channels. It is a way to keep ownership of state explicit. When the driver rebuilds producers after a reconnect, when a consumer waits for a message, when an ack outcome is delivered, or when a pending operation fails because a session is gone, the relevant state is in the state machine and can be inspected there.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>That design has trade-offs. It puts more pressure on the correctness of the state machine. It requires careful lock ordering. It requires reviewers to understand waker registration and wakeup paths. But it also makes the behavior much easier to simulate, replay, and compare across runtimes.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2 class="wp-block-heading">Two engines, one state machine</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Magnetar ships two engines that drive the same protocol core.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>The default engine is <a href="https://github.com/CleverCloud/magnetar/tree/main/crates/magnetar-runtime-tokio">magnetar-runtime-tokio</a>. It is the production execution path: TCP, TLS through tokio-rustls, driver tasks, real time, real sockets, and the public PulsarClient surface most users will reach first.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>The second engine is <a href="https://github.com/CleverCloud/magnetar/tree/main/crates/magnetar-runtime-moonpool">magnetar-runtime-moonpool</a>. It drives the same magnetar-proto::Connection state machine through Moonpool providers. Instead of baking in the runtime, Moonpool exposes provider traits for networking, time, task spawning, randomness, and storage. Under a production-style provider bundle, the engine can run against real I/O. Under simulation providers, those same categories can be virtualized.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>This is where deterministic simulation becomes practical. The client can be driven in a world where time advances under control, network delivery can be reordered or interrupted, tasks run under a deterministic scheduler, randomness is seeded, and failures can be replayed from the same seed.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Moonpool is not a mock. A mock usually replaces a component with simplified behavior. That is useful for many unit tests, but it is not the same thing as exercising a real client through hard interleavings.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Moonpool is also not a normal end-to-end test. An e2e test runs the real system, which is essential, but it usually runs with real time, real networking, and failures that are difficult to reproduce once the timing has moved on.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Moonpool sits in a different space. It keeps the client code close to the real execution path while virtualizing the providers that make distributed behavior hard to reproduce. The point is not to avoid e2e tests. The point is to add a regime where failures are not anecdotes. They become seeds.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Magnetar's Moonpool engine uses the same protocol state machine as the Tokio engine. The TLS path is also driven in a way that preserves the simulation boundary: instead of relying on tokio-rustls, the Moonpool engine drives rustls::ClientConnection over the byte pipe directly. That keeps TLS handshakes under the same deterministic control as the rest of the simulated network.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2 class="wp-block-heading">Differential testing: making the engines agree</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Two engines are useful only if they do not silently become two different clients.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Magnetar therefore includes a differential harness. It runs a trace, such as connect, open producer, send, subscribe, receive, ack, seek, and close, against both the Tokio and Moonpool engines, then compares the user-visible event streams.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>This matters because the Moonpool engine is used to find bugs that are difficult to expose with real time and real sockets. For that to be meaningful, the simulated engine must remain observationally aligned with the production engine at the user boundary.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>If Tokio and Moonpool drift, the simulator becomes less trustworthy. If the differential harness keeps them aligned, then a seed failure in the simulated world is much more likely to point at a real property of the client, not a separate test-only implementation.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>This is also why Magnetar's validation policy is strict about cross-runtime coverage. Behavioral changes are expected to exercise the sans-io layer, the Tokio runtime, the Moonpool runtime, differential equivalence, and the e2e surface when applicable. That is more work than adding one unit test. It is also the cost of making deterministic simulation a real engineering tool rather than a side experiment.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2 class="wp-block-heading">Java parity as a credibility contract</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Simulation is not a substitute for feature breadth. It is what makes feature breadth less fragile.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Apache Pulsar has a mature <a href="https://pulsar.apache.org/docs/">Java client</a>, and for many users that client defines what "a Pulsar client" means. Basic produce and consume are not enough. A credible client must cover the behaviors applications rely on: batching, compression, transactions, schemas, partitioned topics, multi-topic and pattern consumers, retries, dead-letter flows, authentication providers, proxy support, failover, admin operations, and the PIPs that shape modern Pulsar usage.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Magnetar tracks Java-client parity as a public contract. The <a href="https://github.com/CleverCloud/magnetar/blob/main/README.md">README</a> carries the parity matrix and the engine-by-engine status. The article does not need to reproduce that matrix, but the matrix itself is important. It gives users a way to evaluate the project as a Pulsar client, not as a narrow experiment around one happy path.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>This is the reason Magnetar's first public release is broader than a minimal demo. It includes the protocol foundation, the public facade, runtime engines, admin support, authentication providers, message crypto, CLI work, observability hooks, and a growing list of PIP surfaces.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>The exact reason for tracking parity is simple: users do not choose a client library only because its internal architecture is elegant. They choose it because it can represent the system they actually run. Architecture makes that surface maintainable. Parity makes it useful.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2 class="wp-block-heading">Beyond produce and consume</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>The phrase "Pulsar client" can hide a lot of surface area. From the outside, the first examples usually look small: build a client, create a producer, send a payload, subscribe with a consumer, receive a message, acknowledge it. Those examples are useful because they show the entry point. They are not enough to evaluate the client.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Real Pulsar applications depend on behaviors that only appear after the first demo works. A producer may need batching, compression, chunking, access modes, sequence ids, send timeouts, per-message properties, transactions, interceptors, and latency statistics. A consumer may need batch receive, cumulative acknowledgements, batch-index acknowledgements, nack backoff, ack timeout handling, retry topics, dead-letter topics, seek, pause/resume, subscription modes, and per-partition behavior. Applications with strict schemas need Avro, JSON, Protobuf, Protobuf-native, KeyValue, primitive schemas, and broker-side schema lookup semantics. Deployments with security requirements need token auth, mTLS, OAuth2, SASL, Kerberos/GSSAPI, Athenz, TLS provider choices, and a way to reason about crypto behavior without making every build drag every provider.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Those features are not independent checkboxes. They interact. Batching interacts with compression and send timeouts. Chunking interacts with sequence ids and redelivery. Transactions interact with acknowledgements. Reconnect interacts with producers, consumers, lookups, proxy routing, and failover. Observability has to describe the behavior without leaking secrets or flooding operators under churn.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>That is why Magnetar's feature work and architecture work are tied together. The more complete the surface becomes, the more important it is that the protocol state is explicit and that the runtime boundary is narrow. A broad client built on accidental state becomes harder to maintain as it becomes more useful. A broad client built on replayable state gives maintainers a better chance to keep feature growth from turning into hidden behavior.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2 class="wp-block-heading">Validation as architecture</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Magnetar's test strategy is intentionally layered because each layer catches a different class of bug.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>The sans-io layer lets protocol behavior be tested without sockets or async tasks. The <a href="https://github.com/CleverCloud/magnetar/blob/main/docs/testing.md">project testing documentation</a> currently records more than 270 unit tests in magnetar-proto. Those tests exercise the state machine directly: bytes in, events out, transmit buffers out, state transitions checked.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Runtime integration tests exercise the glue that pure protocol tests cannot cover. The Tokio engine and Moonpool engine each have their own integration surfaces, and the project enforces runtime parity so one engine does not quietly fall behind the other.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>The deterministic chaos pack targets the failure schedules that motivated the architecture in the first place: reconnect, failover, virtual-clock timers, TLS handshake ordering, in-flight publishes, broker migration, and adversarial network behavior. The <a href="https://github.com/CleverCloud/magnetar/blob/main/docs/moonpool-engine.md">Moonpool engine documentation</a> describes a daily Moonpool seed sweep with 128 freshly rolled random seeds in parallel. The number is less important than what it represents: the client is being driven through schedules that a human would not write by hand.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Differential equivalence tests compare the two runtime worlds. They ask a direct question: if the same trace is run through Tokio and Moonpool, does the user see the same behavior?</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>End-to-end tests still matter. They keep Magnetar honest against a real Apache Pulsar broker. Simulation can make failures reproducible, but it does not replace compatibility with the system users actually deploy.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Taken together, these layers are not ceremony. They are part of the architecture. The point is not to collect large test numbers. The point is to put validation pressure exactly where distributed clients fail: protocol state, runtime boundaries, reconnect logic, timing, equivalence, and real broker behavior.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2 class="wp-block-heading">What reproducibility changes in practice</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>The practical value of deterministic simulation is not that it makes tests more sophisticated. It changes the debugging loop.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>When a traditional end-to-end test fails because of timing, the first question is often whether the failure is reproducible at all. If it is not, engineers start adding sleeps, logs, larger timeouts, or retry loops. Some of those changes are useful. Many of them only move the failure somewhere else. The failure remains a story: "we saw it once in CI".</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>With a deterministic simulation, the failure should become an artifact. The artifact is a seed, a trace, and a state transition that can be replayed. The question changes from "can we make it happen again?" to "what invariant did this schedule violate?"</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>That difference matters for a client library. Client bugs often sit at the boundary between user code and the broker. They are easy to misattribute. A publish can fail because the broker closed the connection, because the client lost an outcome, because the reconnect path rebuilt the producer too late, because an ack was delivered to the wrong waiter, because a timeout fired against stale session state, or because the runtime task died after the protocol had already transitioned.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>If all of that behavior is spread across tasks, channels, timers, and sockets, a failure report is hard to compress. If the protocol state machine is explicit, the runtime boundary is narrow, and the same sequence can be replayed under controlled providers, the report can become much smaller: this seed, this trace, this event order, this invariant.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>That is why Magnetar treats reproducibility as part of the client design. The point is not only to catch more bugs. The point is to make the bugs that do appear cheaper to understand and safer to fix.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>It also changes code review. A reviewer can ask whether a behavior is covered at the right layer. Is this a pure protocol transition? Then the sans-io test should feed bytes and assert events. Is it runtime glue? Then Tokio and Moonpool need equivalent coverage. Is it an observable behavior shared by both engines? Then the differential harness should compare the event streams. Is it broker compatibility? Then an e2e test should touch a real Pulsar broker.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Those questions are more precise than "did we add tests?" They connect the test to the failure model.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2 class="wp-block-heading">What to inspect first</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>For engineers reading Magnetar for the first time, the best entry point is not a single file. It is the relationship between the documents and the code.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>The <a href="https://github.com/CleverCloud/magnetar/blob/main/README.md">README</a> gives the public surface: what the client exposes, which features are implemented, how the Java-client parity matrix is tracked, which PIPs are supported, and how the two engines are positioned. That is the user-facing contract.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>The <a href="https://github.com/CleverCloud/magnetar/blob/main/ARCHITECTURE.md">architecture document</a> explains the shape underneath that contract. It shows the crate topology, the dependency direction, the sans-io boundary, the driver loop, the event model, the producer and consumer paths, the runtime engines, TLS sites, schemas, PIP coverage, and the validation strategy. That is the system map.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>The <a href="https://github.com/CleverCloud/magnetar/tree/main/specs/adr">ADR series</a> explains why the system has this shape. <a href="https://github.com/CleverCloud/magnetar/blob/main/specs/adr/0004-sans-io-protocol-core.md">ADR-0004</a> records the sans-io split. <a href="https://github.com/CleverCloud/magnetar/blob/main/specs/adr/0003-no-channels-rule.md">ADR-0003</a> records the no-channels rule. <a href="https://github.com/CleverCloud/magnetar/blob/main/specs/adr/0011-clock-injection-sans-io.md">ADR-0011</a> records clock injection. <a href="https://github.com/CleverCloud/magnetar/blob/main/specs/adr/0010-v0-1-full-java-parity.md">ADR-0010</a> records the Java parity decision. <a href="https://github.com/CleverCloud/magnetar/blob/main/specs/adr/0019-engine-scope-and-moonpool-parity.md">ADR-0019</a> records how the production Tokio engine and the Moonpool engine relate to the parity goal. <a href="https://github.com/CleverCloud/magnetar/blob/main/specs/adr/0024-cross-runtime-test-and-coverage-policy.md">ADR-0024</a> records the cross-runtime testing policy.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>This matters because Magnetar is intentionally not only a code drop. It is a set of engineering decisions with a public audit trail. If you disagree with the design, the ADRs give you the right surface to discuss. If you want to contribute a feature, the parity matrix and validation policy tell you what "done" means. If you want to evaluate the simulation work, the <a href="https://github.com/CleverCloud/magnetar/blob/main/docs/moonpool-engine.md">Moonpool engine documentation</a> and the differential harness show how the same protocol core is driven in different worlds.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>The first release should therefore be read in two ways. As a Pulsar user, look at the client surface and the parity matrix. As a Rust infrastructure engineer, look at the state-machine boundary and the simulation strategy. The interesting part of Magnetar is that both views are meant to reinforce each other.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2 class="wp-block-heading">What the first public release gives you</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>This first public release is a technical entry point. It is for engineers who want to try Magnetar, read the architecture, inspect the ADRs, compare behavior with existing Pulsar clients, and help shape the Rust-native Pulsar ecosystem.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>The high-level client API starts with the usual shape:</p>
<!-- /wp:paragraph -->

<!-- wp:html -->
<div
  style="
    max-width: 780px;
    margin: 1.5rem auto;
    padding: 16px 20px;
    background: #0f172a;
    color: #e5eefc;
    border: 1px solid rgba(255, 255, 255, 0.08);
    border-radius: 12px;
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.08);
    font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI',
      Roboto, 'Helvetica Neue', Arial, sans-serif;
    font-size: 15px;
    line-height: 1.7;
  "
>
  <pre
    style="
      margin: 0;
      overflow-x: auto;
      white-space: pre-wrap;
      font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas,
        'Liberation Mono', 'Courier New', monospace;
    "
  ><code>let client = PulsarClient::builder()
    .service_url("pulsar://localhost:6650")
    .build()
    .await?;

let producer = client
    .producer("persistent://public/default/orders")
    .create()
    .await?;</code></pre>
</div>
<!-- /wp:html -->

<!-- wp:paragraph -->
<p>That API is important because the client must be usable. But the release is also an invitation to inspect the lower layers. Read the <a href="https://github.com/CleverCloud/magnetar/blob/main/README.md">README</a> for the feature matrix. Read the <a href="https://github.com/CleverCloud/magnetar/blob/main/ARCHITECTURE.md">architecture document</a> for the sans-io design. Read the <a href="https://github.com/CleverCloud/magnetar/tree/main/specs/adr">ADRs</a> for the decisions behind no channels, swappable engines, clock injection, Java parity, Moonpool parity, TLS provider choices, and cross-runtime validation. Read the <a href="https://github.com/CleverCloud/magnetar/blob/main/docs/moonpool-engine.md">Moonpool engine documentation</a> if you are interested in how deterministic simulation can be applied to a real network client.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>The important point for this article is the direction: Magnetar is public so engineers can evaluate both the client surface and the engineering model behind it.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>The inaugural technical entry point is available via <a href="https://github.com/CleverCloud/magnetar/releases#release-v1.0.0">v1.0.0</a>, while the current state of the driver can be tracked in the <a href="https://github.com/CleverCloud/magnetar/releases#release-v1.2.0">v1.2.0</a> release.&nbsp;</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2 class="wp-block-heading">Why this matters beyond Magnetar</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Magnetar is an Apache Pulsar client. It is also a concrete example of how we want to build more Rust infrastructure software.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Distributed systems fail through state transitions. Some of those transitions are obvious and easy to test. Many are not. They happen when time advances in an unlucky place, when a retry overlaps with a close path, when a broker drops a connection after accepting part of the session, when a callback is registered just after a notification, or when a reconnect path rebuilds one handle but not another.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>You can try to chase those bugs after they happen. Sometimes that is unavoidable. But the architecture can make the chase easier or harder.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>A client with a pure protocol core, explicit events, injected time, replaceable I/O, deterministic seeds, and cross-runtime comparison gives engineers better tools. It lets them reduce a failure to a trace. It lets them replay that trace. It lets them ask whether a simulated failure corresponds to the production runtime. It lets them add an invariant where a silent state drift used to hide.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>That is the direction Magnetar takes. Make the protocol explicit. Make the runtime replaceable. Make failures reproducible. Make correctness something the code has to demonstrate continuously.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Thank you to Pierre Zemb for Moonpool and for pushing this deterministic-simulation direction in Rust, and to the contributors and maintainers in the Rust Pulsar ecosystem whose work made the next step possible.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Magnetar is open source. The code, architecture notes, ADRs, and documentation live at <a href="https://github.com/CleverCloud/magnetar">github.com/CleverCloud/magnetar</a>.</p>
<!-- /wp:paragraph -->

<!-- wp:spacer {"height":"25px"} -->
<div style="height:25px" aria-hidden="true" class="wp-block-spacer"></div>
<!-- /wp:spacer -->

<!-- wp:html -->
<hr style="border: none; height: 1px; background-color: #ccc; margin: 32px 0;">
<!-- /wp:html -->

<!-- wp:spacer {"height":"25px"} -->
<div style="height:25px" aria-hidden="true" class="wp-block-spacer"></div>
<!-- /wp:spacer -->

<!-- wp:heading -->
<h2 class="wp-block-heading">References</h2>
<!-- /wp:heading -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">Magnetar</h3>
<!-- /wp:heading -->

<!-- wp:list -->
<ul class="wp-block-list"><!-- wp:list-item -->
<li><strong>Magnetar repository</strong>. Public Rust Apache Pulsar client repository. <a href="https://github.com/CleverCloud/magnetar">https://github.com/CleverCloud/magnetar</a></li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><strong>Magnetar README</strong>. Public feature surface, Java client parity matrix, supported PIPs, engine coverage, and status. <a href="https://github.com/CleverCloud/magnetar/blob/main/README.md">https://github.com/CleverCloud/magnetar/blob/main/README.md</a></li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><strong>Magnetar architecture</strong>. Sans-io rationale, crate topology, driver loop, protocol state machine, and tests. <a href="https://github.com/CleverCloud/magnetar/blob/main/ARCHITECTURE.md">https://github.com/CleverCloud/magnetar/blob/main/ARCHITECTURE.md</a></li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><strong>Magnetar documentation index</strong>. Moonpool engine, testing, CLI, observability, logging, PIP features. <a href="https://github.com/CleverCloud/magnetar/blob/main/docs/README.md">https://github.com/CleverCloud/magnetar/blob/main/docs/README.md</a></li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><strong>Moonpool engine documentation</strong>. Deterministic-simulation engine, chaos pack, differential harness, provider model. <a href="https://github.com/CleverCloud/magnetar/blob/main/docs/moonpool-engine.md">https://github.com/CleverCloud/magnetar/blob/main/docs/moonpool-engine.md</a></li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><strong>Testing documentation</strong>. Test categories and validation commands. <a href="https://github.com/CleverCloud/magnetar/blob/main/docs/testing.md">https://github.com/CleverCloud/magnetar/blob/main/docs/testing.md</a></li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><strong>ADR-0004</strong>. Sans-io magnetar-proto and swappable I/O engines. <a href="https://github.com/CleverCloud/magnetar/blob/main/specs/adr/0004-sans-io-protocol-core.md">https://github.com/CleverCloud/magnetar/blob/main/specs/adr/0004-sans-io-protocol-core.md</a></li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><strong>ADR-0010</strong>. Full Java-client parity scope. <a href="https://github.com/CleverCloud/magnetar/blob/main/specs/adr/0010-v0-1-full-java-parity.md">https://github.com/CleverCloud/magnetar/blob/main/specs/adr/0010-v0-1-full-java-parity.md</a></li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><strong>ADR-0024</strong>. Cross-runtime test and coverage policy. <a href="https://github.com/CleverCloud/magnetar/blob/main/specs/adr/0024-cross-runtime-test-and-coverage-policy.md">https://github.com/CleverCloud/magnetar/blob/main/specs/adr/0024-cross-runtime-test-and-coverage-policy.md</a></li>
<!-- /wp:list-item --></ul>
<!-- /wp:list -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">Ecosystem</h3>
<!-- /wp:heading -->

<!-- wp:list -->
<ul class="wp-block-list"><!-- wp:list-item -->
<li><strong>pulsar-rs</strong>. Existing Rust Apache Pulsar client project. <a href="https://github.com/streamnative/pulsar-rs">https://github.com/streamnative/pulsar-rs</a></li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><strong>Apache Pulsar</strong>. Distributed messaging and streaming platform. <a href="https://pulsar.apache.org/">https://pulsar.apache.org/</a></li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><strong>Apache Pulsar Java client</strong>. Reference client surface for many Pulsar users. <a href="https://pulsar.apache.org/docs/">https://pulsar.apache.org/docs/</a></li>
<!-- /wp:list-item --></ul>
<!-- /wp:list -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">Deterministic simulation</h3>
<!-- /wp:heading -->

<!-- wp:list -->
<ul class="wp-block-list"><!-- wp:list-item -->
<li><strong>FoundationDB testing</strong>. Deterministic simulation and fault injection lineage. <a href="https://apple.github.io/foundationdb/testing.html">https://apple.github.io/foundationdb/testing.html</a></li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><strong>TigerBeetle TigerStyle</strong>. Assertion-first engineering style. <a href="https://github.com/tigerbeetle/tigerbeetle/blob/main/docs/TIGER_STYLE.md">https://github.com/tigerbeetle/tigerbeetle/blob/main/docs/TIGER_STYLE.md</a></li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><strong>TigerBeetle VOPR</strong>. Simulation testing approach. <a href="https://github.com/tigerbeetle/tigerbeetle/blob/main/docs/internals/vopr.md">https://github.com/tigerbeetle/tigerbeetle/blob/main/docs/internals/vopr.md</a></li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><strong>Moonpool repository</strong>. Deterministic simulation for Rust systems, developed by Pierre Zemb. <a href="https://github.com/PierreZ/moonpool">https://github.com/PierreZ/moonpool</a></li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><strong>moonpool-sim</strong>. Simulation engine crate for Moonpool. <a href="https://crates.io/crates/moonpool-sim">https://crates.io/crates/moonpool-sim</a></li>
<!-- /wp:list-item --></ul>
<!-- /wp:list -->]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Kubernetes orchestration: what is container orchestration for?</title>
		<link>https://www.clever.cloud/blog/engineering/2026/07/03/kubernetes-orchestration-containers-what-is-it-for/</link>
		
		<dc:creator><![CDATA[Leo Le Levé Dandé]]></dc:creator>
		<pubDate>Fri, 03 Jul 2026 09:40:46 +0000</pubDate>
				<category><![CDATA[Engineering]]></category>
		<category><![CDATA[Kubernetes]]></category>
		<guid isPermaLink="false">https://www.clever.cloud/?p=24866</guid>

					<description><![CDATA[<p><img width="2500" height="1109" src="https://cdn.clever-cloud.com/uploads/2026/07/2026-07-02-clever-cloud-banniere-blog-kubernetes-orchestration-en.png" class="attachment-post-thumbnail size-post-thumbnail wp-post-image" alt="2026.07.02 Clever Cloud Bannière Blog Kubernetes Orchestration EN" decoding="async" loading="lazy" srcset="https://cdn.clever-cloud.com/uploads/2026/07/2026-07-02-clever-cloud-banniere-blog-kubernetes-orchestration-en.png 2500w, https://cdn.clever-cloud.com/uploads/2026/07/2026-07-02-clever-cloud-banniere-blog-kubernetes-orchestration-en-300x133.png 300w, https://cdn.clever-cloud.com/uploads/2026/07/2026-07-02-clever-cloud-banniere-blog-kubernetes-orchestration-en-1024x454.png 1024w, https://cdn.clever-cloud.com/uploads/2026/07/2026-07-02-clever-cloud-banniere-blog-kubernetes-orchestration-en-768x341.png 768w, https://cdn.clever-cloud.com/uploads/2026/07/2026-07-02-clever-cloud-banniere-blog-kubernetes-orchestration-en-1536x681.png 1536w, https://cdn.clever-cloud.com/uploads/2026/07/2026-07-02-clever-cloud-banniere-blog-kubernetes-orchestration-en-2048x908.png 2048w, https://cdn.clever-cloud.com/uploads/2026/07/2026-07-02-clever-cloud-banniere-blog-kubernetes-orchestration-en-1368x607.png 1368w" sizes="auto, (max-width: 2500px) 100vw, 2500px" /></p><!-- wp:html -->
<style>
  .cc-table-wrap { overflow-x: auto; }
  .cc-table {
    width: 100%;
    border-collapse: collapse;
    table-layout: fixed;
    font-size: 17px;
    font-family: "Plus Jakarta Sans","PlusJakartaSans",-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Arial,sans-serif;
    color: #111827;
  }
  .cc-table th,
  .cc-table td {
    text-align: left;
    padding: 12px 16px;
    vertical-align: top;
    line-height: 1.6;
  }
  .cc-table tbody tr + tr td,
  .cc-table tbody tr:first-child td {
    border-top: 1px solid #deddee;
  }
  .cc-table th + th,
  .cc-table td + td {
    border-left: 1px solid #deddee;
  }
  .cc-table thead th {
    font-weight: 700;
    text-align: center;
  }
  .cc-table th:nth-child(1),
  .cc-table td:nth-child(1) { width: 28%; }
  .cc-table th:nth-child(2),
  .cc-table td:nth-child(2) { width: 36%; }
  .cc-table th:nth-child(3),
  .cc-table td:nth-child(3) { width: 36%; }
</style>
<!-- /wp:html -->

<!-- wp:paragraph -->
<p>It is a function distinct from containerization itself, which packages an application and its dependencies into a standard format. The <a href="https://www.clever.cloud/blog/features/2026/05/22/kubernetes-vs-docker-differences-and-when-to-use-them/">differences between Docker and Kubernetes</a> rest precisely on that distinction: Docker builds and runs containers, Kubernetes orchestrates them. Today Kubernetes is the reference orchestrator, but orchestration as a concept exists independently of the tool that implements it.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2 class="wp-block-heading">Why orchestration exists</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Running three containers on a single server does not call for orchestration. You start them, you watch them by eye, you restart one by hand if something crashes. The nature of the problem changes the moment an application becomes a distributed system: several services, several machines, variable traffic, frequent deployments. The operational questions that appear then are concrete. Which machine should this new container run on? What happens if a node goes down in the middle of the night? How do you move from version 1.4 to 1.5 with no visible interruption? How does one internal service find another when IP addresses change on every restart?</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Each of these questions has a possible manual answer, one you can even script. Orchestration is about automating them coherently, under a single model.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2 class="wp-block-heading">The five core functions of orchestration</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p><a href="https://www.clever.cloud/product/kubernetes/">Kubernetes</a> handles these questions through a <a href="https://www.clever.cloud/blog/engineering/2026/05/19/k8s-kubernetes-definition-standard/">declarative model built on reconciliation loops</a>: you describe the desired state of the system, and the orchestrator constantly compares that desired state to the actual state to bring them together. The five functions that follow are instances of this general mechanism.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">Scheduling: placing containers on the right machines</h3>
<!-- /wp:heading -->

<!-- wp:image {"id":25312,"sizeSlug":"large","linkDestination":"none","align":"wide"} -->
<figure class="wp-block-image alignwide size-large"><img src="https://cdn.clever-cloud.com/uploads/2026/07/kubernetes-orchestration-scheduling-diagram-1024x411.webp" alt="Kubernetes scheduling diagram: kube-scheduler filters and scores nodes, then binds pod A to the selected node through the API server." class="wp-image-25312"/><figcaption class="wp-element-caption">kubernetes orchestration scheduling diagram</figcaption></figure>
<!-- /wp:image -->

<!-- wp:paragraph -->
<p>Scheduling answers one question: when a new container needs to start, which machine in the cluster should run it? On a cluster of a few nodes with identical profiles, the decision is trivial. On a real cluster, it is not: some machines have GPUs and others do not, some are already loaded, some applications must be isolated while others must instead be co-located for latency reasons.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>The kube-scheduler component makes this choice in two steps: filtering, which rules out the nodes that cannot host the pod (insufficient capacity, affinity constraints, taints and tolerations), and scoring, which ranks the remaining nodes against several criteria. The pod is then assigned to the chosen node through a binding operation with the API server. The quality of the decision depends on the information given to the scheduler. It is the resource requests declared on the pods that drive placement: the scheduler looks for a node whose available capacity covers those requests. The limits, on the other hand, play no part in placement; they cap a container’s consumption once it is running.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">Scaling: matching capacity to real traffic</h3>
<!-- /wp:heading -->

<!-- wp:image {"id":25314,"sizeSlug":"large","linkDestination":"none","align":"wide"} -->
<figure class="wp-block-image alignwide size-large"><img src="https://cdn.clever-cloud.com/uploads/2026/07/kubernetes-orchestration-scaling-diagram-1024x385.webp" alt="Kubernetes scaling diagram: Horizontal Pod Autoscaler, Vertical Pod Autoscaler and Cluster Autoscaler adjusting pod count, pod size and nodes." class="wp-image-25314"/></figure>
<!-- /wp:image -->

<!-- wp:paragraph -->
<p>Scaling automates a decision that is simple to state: how many copies of a service should run at a given moment? Too many copies cost money. Too few cause incidents at the first spike.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Scaling is a function common to every orchestrator; the mechanisms vary by implementation. In Kubernetes, it rests on three distinct building blocks. The Horizontal Pod Autoscaler (HPA), part of core Kubernetes, adjusts the number of pods in a deployment based on a metric. To do so it relies on the Metrics Server, a component you install separately, because metric collection is not provided by default. The Vertical Pod Autoscaler (VPA), also shipped as a separate project, adjusts the resources allocated to each pod. The Cluster Autoscaler, finally, adds or removes whole nodes according to aggregate needs. These mechanisms assume reliable metrics: an HPA driven by CPU, when the service is actually constrained by disk I/O, will not produce the expected result.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">Self-healing: replacing what fails</h3>
<!-- /wp:heading -->

<!-- wp:image {"id":25315,"sizeSlug":"large","linkDestination":"none","align":"wide"} -->
<figure class="wp-block-image alignwide size-large"><img src="https://cdn.clever-cloud.com/uploads/2026/07/kubernetes-orchestration-self-healing-diagram-1024x371.webp" alt="Kubernetes self-healing diagram: the controller reconciliation loop replaces a failed pod to restore the desired state of three replicas." class="wp-image-25315"/></figure>
<!-- /wp:image -->

<!-- wp:paragraph -->
<p>Past a certain number of machines, failures stop being exceptional events and become background noise. A disk fails, a kernel panic happens, a container leaks memory and ends up OOM-killed. Without orchestration, every failure triggers human intervention, more or less urgent. With orchestration, these events are absorbed without intervention.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Within Kubernetes, the mechanism rests on two elements. First, probes (liveness, readiness, startup) that let it know whether a container is actually working, and not merely whether it has started. Second, the principle that any object managed by a controller (Deployment, StatefulSet, DaemonSet) is constantly compared against the desired state: if a pod disappears, the controller requests a new one. The accuracy of the probes determines the quality of self-healing: probes that are too strict cause needless restarts, probes that are too lax let broken containers through.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">Service discovery and internal load balancing</h3>
<!-- /wp:heading -->

<!-- wp:image {"id":25316,"sizeSlug":"large","linkDestination":"none","align":"wide"} -->
<figure class="wp-block-image alignwide size-large"><img src="https://cdn.clever-cloud.com/uploads/2026/07/kubernetes-orchestration-service-discovery-diagram-1024x303.webp" alt="Kubernetes service discovery diagram: CoreDNS resolves a Service name to a virtual IP and kube-proxy sends traffic to ready pods only." class="wp-image-25316"/></figure>
<!-- /wp:image -->

<!-- wp:paragraph -->
<p>In a moving fleet of containers, where each pod has an ephemeral IP address, two services that need to communicate cannot rely on static IP configurations. Service discovery solves this through a layer of indirection. In Kubernetes, a Service object groups a set of pods (selected by labels) under a stable DNS name and a virtual IP. CoreDNS, the cluster’s internal DNS server, resolves these names. Traffic sent to the Service IP is distributed across the ready pods via kube-proxy. This principle is not specific to Kubernetes: other orchestrators meet the same need differently. On Clever Cloud, for instance, services find each other through configuration injection between applications and through Network Groups, an encrypted private network with internal DNS resolution.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Several types of Services exist (ClusterIP for internal traffic, NodePort and LoadBalancer for external traffic), alongside the notion of Ingress for application-level HTTP routing. This network layer, simple in appearance, holds a substantial share of the operational complexity of Kubernetes: CNI plugin choice, network policies, east-west traffic observability.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">Rolling updates and rollbacks</h3>
<!-- /wp:heading -->

<!-- wp:image {"id":25317,"sizeSlug":"large","linkDestination":"none","align":"wide"} -->
<figure class="wp-block-image alignwide size-large"><img src="https://cdn.clever-cloud.com/uploads/2026/07/kubernetes-orchestration-rolling-update-diagram-1024x426.webp" alt="Kubernetes rolling update diagram: pods replaced one by one from v1.4 to v1.5 with no downtime; on failure the rollout stops and kubectl rollout undo reverts it." class="wp-image-25317"/></figure>
<!-- /wp:image -->

<!-- wp:paragraph -->
<p>Shipping a new version to production without interrupting the service is a risky operation when done by hand. Kubernetes treats it as a state transition: you change the Deployment manifest to point to the new image version, and the controller applies the configured rollout strategy.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>The RollingUpdate strategy (the default) progressively replaces old pods with new ones, guaranteeing that a minimum number stays available at all times. The Recreate strategy stops everything and then restarts, useful for incompatible schema migrations. In case of failure, the rollout does not revert on its own to the previous state: it stops, the new pods that fail their probes do not replace the old ones, and it is an operator who triggers the return to the previous version with kubectl rollout undo. For this to work, the versions must be compatible with each other during the transition, which implies discipline on API contracts and database migrations.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2 class="wp-block-heading">Beyond the five core functions</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Kubernetes orchestration does not stop at these five functions. In practice, a production Kubernetes cluster also manages application configuration (ConfigMaps), secrets (with or without encryption at rest), persistent storage through PersistentVolumeClaims, authorization (RBAC), network isolation (NetworkPolicies), observability (logs, metrics, traces), and certificate lifecycle management. Each of these is itself an operational responsibility that adds to the base.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2 class="wp-block-heading">Without an orchestrator vs with Kubernetes: a function-by-function comparison</h2>
<!-- /wp:heading -->

<!-- wp:spacer {"height":"25px"} -->
<div style="height:25px" aria-hidden="true" class="wp-block-spacer"></div>
<!-- /wp:spacer -->

<!-- wp:html -->
<div class="cc-table-wrap">
  <table class="cc-table">
    <thead>
      <tr>
        <th>Function</th>
        <th>Without an orchestrator</th>
        <th>With Kubernetes</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td>Scheduling</td>
        <td>Manual placement or custom allocation scripts</td>
        <td>kube-scheduler with declarative constraints</td>
      </tr>
      <tr>
        <td>Scaling</td>
        <td>Manual provisioning or external rules</td>
        <td>HPA, VPA, Cluster Autoscaler</td>
      </tr>
      <tr>
        <td>Self-healing</td>
        <td>External monitoring and restart scripts</td>
        <td>Built-in probes and controllers</td>
      </tr>
      <tr>
        <td>Service discovery</td>
        <td>Config files, Consul, standalone etcd</td>
        <td>Native Services and internal DNS</td>
      </tr>
      <tr>
        <td>Rolling updates</td>
        <td>Custom deployment scripts and manual load balancer switchover</td>
        <td>Deployment controller and declarative strategies</td>
      </tr>
    </tbody>
  </table>
</div>
<!-- /wp:html -->

<!-- wp:spacer {"height":"25px"} -->
<div style="height:25px" aria-hidden="true" class="wp-block-spacer"></div>
<!-- /wp:spacer -->

<!-- wp:paragraph -->
<p>The table does not rank the two columns. It shows that Kubernetes provides a unified model for these five functions, where an approach without an orchestrator handles them separately with different tools. For a system that does not need this unification, the left-hand column remains perfectly valid.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2 class="wp-block-heading">Common practices worth knowing</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p><strong>Choose the tool based on the need, not by default.</strong> Not every application needs scheduling, automatic scaling or service discovery at the level Kubernetes offers. A PaaS, a VM deployment, or a systemd binary meet many needs with a different operational model.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p><strong>Think about observability from the start.</strong> A Kubernetes cluster without centralized logs, aggregated metrics and traces quickly becomes hard to operate beyond a handful of services. Observability is an integral part of orchestration, not an optional add-on.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p><strong>Define requests and limits before enabling autoscaling.</strong> The HPA and the Cluster Autoscaler rely on the pods’ declared resources to decide on scaling. Without declarations, their decisions rest on partial information.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p><strong>Get probe configuration right.</strong> Liveness and readiness probes govern both self-healing and traffic routing. A rough configuration degrades both functions at once.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2 class="wp-block-heading">When Kubernetes orchestration becomes relevant</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>No single one of the five functions, taken in isolation, justifies bringing Kubernetes into a system. A deployment script, a properly configured load balancer, a monitoring tool with automatic restart can each cover one of them individually. What justifies adopting an orchestrator is the point where the five functions all become necessary at once, on an infrastructure distributed enough to make ad hoc solutions expensive to maintain.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Concretely, that corresponds to architectures with a dozen services or more, deployed across several machines, with frequent deployment cycles, significant load variations and resilience requirements that no longer tolerate manual intervention. For contexts more constrained in resources (edge, IoT, development machines, small clusters), a <a href="https://www.clever.cloud/blog/features/2026/05/28/k3s-vs-k8s-what-are-the-differences-and-which-one-should-you-choose-in-2026/">lightweight Kubernetes distribution such as K3s can be a good fit</a>. <a href="https://www.clever.cloud/blog/engineering/2025/03/05/what-is-a-paas/">A PaaS also meets these needs</a>, as it does many other application profiles (industrialized deployment, automatic scaling, resilience, updates), with an operational model distinct from Kubernetes.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>When Kubernetes does become relevant, the next question rarely concerns installation and more often day-to-day operations: control plane updates, etcd management, certificate rotation, observability, backups. That observation is what explains the growing adoption of managed Kubernetes services. At Clever Cloud, <a href="https://www.clever.cloud/clever-kubernetes-engine/">Clever Kubernetes Engine</a> addresses this need with Materia etcd, a serverless implementation of the etcd API built on FoundationDB that takes over from standard etcd, a known bottleneck at scale, on sovereign infrastructure spread across our three Paris datacenters.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2 class="wp-block-heading">Container orchestration in summary</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Container orchestration automates several categories of operational decisions, chief among them five main classes: where to place a container, when to start more of them, what to do when one of them fails, how they find one another, and how to move from one version to the next without interruption. Kubernetes brings these functions together under a unified model, which makes it the reference tool for distributed systems that need them all at once. The useful question, faced with a project, is not whether you should do orchestration, but which of these functions are actually needed, and at what level of automation.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2 class="wp-block-heading">FAQ - Kubernetes orchestration</h2>
<!-- /wp:heading -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading"><strong>What is the difference between containerization and orchestration?</strong></h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Containerization packages an application and its dependencies into a standardized format that runs identically on any compatible host. Orchestration automates the management of a fleet of containers in production: placement, scaling, self-healing, service discovery, updates. Docker is the reference tool for the former, Kubernetes for the latter.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">Do you necessarily need Kubernetes to orchestrate containers?</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>No. Kubernetes is the most widely adopted orchestrator, but others exist: HashiCorp’s Nomad, which orchestrates containers, VMs and binaries in a single cluster, or Docker Swarm, still maintained but with declining adoption. Apache Mesos, long cited as an alternative, was retired to the Apache Attic in October 2025 and is no longer in active development. Beyond that, a PaaS like Clever Cloud covers the full set of these orchestration functions (placement, automatic scaling, self-healing, rolling updates, service discovery) with its own control plane, independent of Kubernetes. It is that control plane that orchestrates both the applications running in VMs and the containers of the platform’s Docker runtime.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">Is container orchestration necessary for CI/CD?</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>No, but the two are often used together. Modern CI/CD pipelines produce container images as their final artifact, and the orchestrator (Kubernetes or another) takes over to deploy and operate those images. CI/CD and orchestration are two complementary stages of the application lifecycle.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">Does K3s allow orchestration in constrained environments?</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Yes. K3s is a CNCF-certified Kubernetes distribution designed for resource-limited environments (edge, IoT, development machines, small clusters). It keeps the standard Kubernetes APIs while reducing the resource footprint and deployment complexity.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">Does managed Kubernetes change the orchestration functions available?</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>No. Managed Kubernetes provides the same set of orchestration functions as a self-hosted cluster, since it is the same Kubernetes. The difference lies in how operational responsibilities are split: the provider takes on control plane management, updates, and the underlying monitoring. Users then focus on their application workloads.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">Which orchestration function is the hardest to master?</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Networking is frequently cited as the most complex. Service discovery, internal load balancing, NetworkPolicies, Ingress, CNI plugin, east-west traffic observability: the Kubernetes network layer concentrates a significant share of advanced operational topics and remains a frequent source of production incidents.</p>
<!-- /wp:paragraph -->]]></description>
										<content:encoded><![CDATA[<p><img width="2500" height="1109" src="https://cdn.clever-cloud.com/uploads/2026/07/2026-07-02-clever-cloud-banniere-blog-kubernetes-orchestration-en.png" class="attachment-post-thumbnail size-post-thumbnail wp-post-image" alt="2026.07.02 Clever Cloud Bannière Blog Kubernetes Orchestration EN" decoding="async" loading="lazy" srcset="https://cdn.clever-cloud.com/uploads/2026/07/2026-07-02-clever-cloud-banniere-blog-kubernetes-orchestration-en.png 2500w, https://cdn.clever-cloud.com/uploads/2026/07/2026-07-02-clever-cloud-banniere-blog-kubernetes-orchestration-en-300x133.png 300w, https://cdn.clever-cloud.com/uploads/2026/07/2026-07-02-clever-cloud-banniere-blog-kubernetes-orchestration-en-1024x454.png 1024w, https://cdn.clever-cloud.com/uploads/2026/07/2026-07-02-clever-cloud-banniere-blog-kubernetes-orchestration-en-768x341.png 768w, https://cdn.clever-cloud.com/uploads/2026/07/2026-07-02-clever-cloud-banniere-blog-kubernetes-orchestration-en-1536x681.png 1536w, https://cdn.clever-cloud.com/uploads/2026/07/2026-07-02-clever-cloud-banniere-blog-kubernetes-orchestration-en-2048x908.png 2048w, https://cdn.clever-cloud.com/uploads/2026/07/2026-07-02-clever-cloud-banniere-blog-kubernetes-orchestration-en-1368x607.png 1368w" sizes="auto, (max-width: 2500px) 100vw, 2500px" /></p><!-- wp:html -->
<style>
  .cc-table-wrap { overflow-x: auto; }
  .cc-table {
    width: 100%;
    border-collapse: collapse;
    table-layout: fixed;
    font-size: 17px;
    font-family: "Plus Jakarta Sans","PlusJakartaSans",-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Arial,sans-serif;
    color: #111827;
  }
  .cc-table th,
  .cc-table td {
    text-align: left;
    padding: 12px 16px;
    vertical-align: top;
    line-height: 1.6;
  }
  .cc-table tbody tr + tr td,
  .cc-table tbody tr:first-child td {
    border-top: 1px solid #deddee;
  }
  .cc-table th + th,
  .cc-table td + td {
    border-left: 1px solid #deddee;
  }
  .cc-table thead th {
    font-weight: 700;
    text-align: center;
  }
  .cc-table th:nth-child(1),
  .cc-table td:nth-child(1) { width: 28%; }
  .cc-table th:nth-child(2),
  .cc-table td:nth-child(2) { width: 36%; }
  .cc-table th:nth-child(3),
  .cc-table td:nth-child(3) { width: 36%; }
</style>
<!-- /wp:html -->

<!-- wp:paragraph -->
<p>It is a function distinct from containerization itself, which packages an application and its dependencies into a standard format. The <a href="https://www.clever.cloud/blog/features/2026/05/22/kubernetes-vs-docker-differences-and-when-to-use-them/">differences between Docker and Kubernetes</a> rest precisely on that distinction: Docker builds and runs containers, Kubernetes orchestrates them. Today Kubernetes is the reference orchestrator, but orchestration as a concept exists independently of the tool that implements it.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2 class="wp-block-heading">Why orchestration exists</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Running three containers on a single server does not call for orchestration. You start them, you watch them by eye, you restart one by hand if something crashes. The nature of the problem changes the moment an application becomes a distributed system: several services, several machines, variable traffic, frequent deployments. The operational questions that appear then are concrete. Which machine should this new container run on? What happens if a node goes down in the middle of the night? How do you move from version 1.4 to 1.5 with no visible interruption? How does one internal service find another when IP addresses change on every restart?</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Each of these questions has a possible manual answer, one you can even script. Orchestration is about automating them coherently, under a single model.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2 class="wp-block-heading">The five core functions of orchestration</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p><a href="https://www.clever.cloud/product/kubernetes/">Kubernetes</a> handles these questions through a <a href="https://www.clever.cloud/blog/engineering/2026/05/19/k8s-kubernetes-definition-standard/">declarative model built on reconciliation loops</a>: you describe the desired state of the system, and the orchestrator constantly compares that desired state to the actual state to bring them together. The five functions that follow are instances of this general mechanism.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">Scheduling: placing containers on the right machines</h3>
<!-- /wp:heading -->

<!-- wp:image {"id":25312,"sizeSlug":"large","linkDestination":"none","align":"wide"} -->
<figure class="wp-block-image alignwide size-large"><img src="https://cdn.clever-cloud.com/uploads/2026/07/kubernetes-orchestration-scheduling-diagram-1024x411.webp" alt="Kubernetes scheduling diagram: kube-scheduler filters and scores nodes, then binds pod A to the selected node through the API server." class="wp-image-25312"/><figcaption class="wp-element-caption">kubernetes orchestration scheduling diagram</figcaption></figure>
<!-- /wp:image -->

<!-- wp:paragraph -->
<p>Scheduling answers one question: when a new container needs to start, which machine in the cluster should run it? On a cluster of a few nodes with identical profiles, the decision is trivial. On a real cluster, it is not: some machines have GPUs and others do not, some are already loaded, some applications must be isolated while others must instead be co-located for latency reasons.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>The kube-scheduler component makes this choice in two steps: filtering, which rules out the nodes that cannot host the pod (insufficient capacity, affinity constraints, taints and tolerations), and scoring, which ranks the remaining nodes against several criteria. The pod is then assigned to the chosen node through a binding operation with the API server. The quality of the decision depends on the information given to the scheduler. It is the resource requests declared on the pods that drive placement: the scheduler looks for a node whose available capacity covers those requests. The limits, on the other hand, play no part in placement; they cap a container’s consumption once it is running.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">Scaling: matching capacity to real traffic</h3>
<!-- /wp:heading -->

<!-- wp:image {"id":25314,"sizeSlug":"large","linkDestination":"none","align":"wide"} -->
<figure class="wp-block-image alignwide size-large"><img src="https://cdn.clever-cloud.com/uploads/2026/07/kubernetes-orchestration-scaling-diagram-1024x385.webp" alt="Kubernetes scaling diagram: Horizontal Pod Autoscaler, Vertical Pod Autoscaler and Cluster Autoscaler adjusting pod count, pod size and nodes." class="wp-image-25314"/></figure>
<!-- /wp:image -->

<!-- wp:paragraph -->
<p>Scaling automates a decision that is simple to state: how many copies of a service should run at a given moment? Too many copies cost money. Too few cause incidents at the first spike.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Scaling is a function common to every orchestrator; the mechanisms vary by implementation. In Kubernetes, it rests on three distinct building blocks. The Horizontal Pod Autoscaler (HPA), part of core Kubernetes, adjusts the number of pods in a deployment based on a metric. To do so it relies on the Metrics Server, a component you install separately, because metric collection is not provided by default. The Vertical Pod Autoscaler (VPA), also shipped as a separate project, adjusts the resources allocated to each pod. The Cluster Autoscaler, finally, adds or removes whole nodes according to aggregate needs. These mechanisms assume reliable metrics: an HPA driven by CPU, when the service is actually constrained by disk I/O, will not produce the expected result.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">Self-healing: replacing what fails</h3>
<!-- /wp:heading -->

<!-- wp:image {"id":25315,"sizeSlug":"large","linkDestination":"none","align":"wide"} -->
<figure class="wp-block-image alignwide size-large"><img src="https://cdn.clever-cloud.com/uploads/2026/07/kubernetes-orchestration-self-healing-diagram-1024x371.webp" alt="Kubernetes self-healing diagram: the controller reconciliation loop replaces a failed pod to restore the desired state of three replicas." class="wp-image-25315"/></figure>
<!-- /wp:image -->

<!-- wp:paragraph -->
<p>Past a certain number of machines, failures stop being exceptional events and become background noise. A disk fails, a kernel panic happens, a container leaks memory and ends up OOM-killed. Without orchestration, every failure triggers human intervention, more or less urgent. With orchestration, these events are absorbed without intervention.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Within Kubernetes, the mechanism rests on two elements. First, probes (liveness, readiness, startup) that let it know whether a container is actually working, and not merely whether it has started. Second, the principle that any object managed by a controller (Deployment, StatefulSet, DaemonSet) is constantly compared against the desired state: if a pod disappears, the controller requests a new one. The accuracy of the probes determines the quality of self-healing: probes that are too strict cause needless restarts, probes that are too lax let broken containers through.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">Service discovery and internal load balancing</h3>
<!-- /wp:heading -->

<!-- wp:image {"id":25316,"sizeSlug":"large","linkDestination":"none","align":"wide"} -->
<figure class="wp-block-image alignwide size-large"><img src="https://cdn.clever-cloud.com/uploads/2026/07/kubernetes-orchestration-service-discovery-diagram-1024x303.webp" alt="Kubernetes service discovery diagram: CoreDNS resolves a Service name to a virtual IP and kube-proxy sends traffic to ready pods only." class="wp-image-25316"/></figure>
<!-- /wp:image -->

<!-- wp:paragraph -->
<p>In a moving fleet of containers, where each pod has an ephemeral IP address, two services that need to communicate cannot rely on static IP configurations. Service discovery solves this through a layer of indirection. In Kubernetes, a Service object groups a set of pods (selected by labels) under a stable DNS name and a virtual IP. CoreDNS, the cluster’s internal DNS server, resolves these names. Traffic sent to the Service IP is distributed across the ready pods via kube-proxy. This principle is not specific to Kubernetes: other orchestrators meet the same need differently. On Clever Cloud, for instance, services find each other through configuration injection between applications and through Network Groups, an encrypted private network with internal DNS resolution.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Several types of Services exist (ClusterIP for internal traffic, NodePort and LoadBalancer for external traffic), alongside the notion of Ingress for application-level HTTP routing. This network layer, simple in appearance, holds a substantial share of the operational complexity of Kubernetes: CNI plugin choice, network policies, east-west traffic observability.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">Rolling updates and rollbacks</h3>
<!-- /wp:heading -->

<!-- wp:image {"id":25317,"sizeSlug":"large","linkDestination":"none","align":"wide"} -->
<figure class="wp-block-image alignwide size-large"><img src="https://cdn.clever-cloud.com/uploads/2026/07/kubernetes-orchestration-rolling-update-diagram-1024x426.webp" alt="Kubernetes rolling update diagram: pods replaced one by one from v1.4 to v1.5 with no downtime; on failure the rollout stops and kubectl rollout undo reverts it." class="wp-image-25317"/></figure>
<!-- /wp:image -->

<!-- wp:paragraph -->
<p>Shipping a new version to production without interrupting the service is a risky operation when done by hand. Kubernetes treats it as a state transition: you change the Deployment manifest to point to the new image version, and the controller applies the configured rollout strategy.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>The RollingUpdate strategy (the default) progressively replaces old pods with new ones, guaranteeing that a minimum number stays available at all times. The Recreate strategy stops everything and then restarts, useful for incompatible schema migrations. In case of failure, the rollout does not revert on its own to the previous state: it stops, the new pods that fail their probes do not replace the old ones, and it is an operator who triggers the return to the previous version with kubectl rollout undo. For this to work, the versions must be compatible with each other during the transition, which implies discipline on API contracts and database migrations.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2 class="wp-block-heading">Beyond the five core functions</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Kubernetes orchestration does not stop at these five functions. In practice, a production Kubernetes cluster also manages application configuration (ConfigMaps), secrets (with or without encryption at rest), persistent storage through PersistentVolumeClaims, authorization (RBAC), network isolation (NetworkPolicies), observability (logs, metrics, traces), and certificate lifecycle management. Each of these is itself an operational responsibility that adds to the base.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2 class="wp-block-heading">Without an orchestrator vs with Kubernetes: a function-by-function comparison</h2>
<!-- /wp:heading -->

<!-- wp:spacer {"height":"25px"} -->
<div style="height:25px" aria-hidden="true" class="wp-block-spacer"></div>
<!-- /wp:spacer -->

<!-- wp:html -->
<div class="cc-table-wrap">
  <table class="cc-table">
    <thead>
      <tr>
        <th>Function</th>
        <th>Without an orchestrator</th>
        <th>With Kubernetes</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td>Scheduling</td>
        <td>Manual placement or custom allocation scripts</td>
        <td>kube-scheduler with declarative constraints</td>
      </tr>
      <tr>
        <td>Scaling</td>
        <td>Manual provisioning or external rules</td>
        <td>HPA, VPA, Cluster Autoscaler</td>
      </tr>
      <tr>
        <td>Self-healing</td>
        <td>External monitoring and restart scripts</td>
        <td>Built-in probes and controllers</td>
      </tr>
      <tr>
        <td>Service discovery</td>
        <td>Config files, Consul, standalone etcd</td>
        <td>Native Services and internal DNS</td>
      </tr>
      <tr>
        <td>Rolling updates</td>
        <td>Custom deployment scripts and manual load balancer switchover</td>
        <td>Deployment controller and declarative strategies</td>
      </tr>
    </tbody>
  </table>
</div>
<!-- /wp:html -->

<!-- wp:spacer {"height":"25px"} -->
<div style="height:25px" aria-hidden="true" class="wp-block-spacer"></div>
<!-- /wp:spacer -->

<!-- wp:paragraph -->
<p>The table does not rank the two columns. It shows that Kubernetes provides a unified model for these five functions, where an approach without an orchestrator handles them separately with different tools. For a system that does not need this unification, the left-hand column remains perfectly valid.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2 class="wp-block-heading">Common practices worth knowing</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p><strong>Choose the tool based on the need, not by default.</strong> Not every application needs scheduling, automatic scaling or service discovery at the level Kubernetes offers. A PaaS, a VM deployment, or a systemd binary meet many needs with a different operational model.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p><strong>Think about observability from the start.</strong> A Kubernetes cluster without centralized logs, aggregated metrics and traces quickly becomes hard to operate beyond a handful of services. Observability is an integral part of orchestration, not an optional add-on.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p><strong>Define requests and limits before enabling autoscaling.</strong> The HPA and the Cluster Autoscaler rely on the pods’ declared resources to decide on scaling. Without declarations, their decisions rest on partial information.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p><strong>Get probe configuration right.</strong> Liveness and readiness probes govern both self-healing and traffic routing. A rough configuration degrades both functions at once.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2 class="wp-block-heading">When Kubernetes orchestration becomes relevant</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>No single one of the five functions, taken in isolation, justifies bringing Kubernetes into a system. A deployment script, a properly configured load balancer, a monitoring tool with automatic restart can each cover one of them individually. What justifies adopting an orchestrator is the point where the five functions all become necessary at once, on an infrastructure distributed enough to make ad hoc solutions expensive to maintain.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Concretely, that corresponds to architectures with a dozen services or more, deployed across several machines, with frequent deployment cycles, significant load variations and resilience requirements that no longer tolerate manual intervention. For contexts more constrained in resources (edge, IoT, development machines, small clusters), a <a href="https://www.clever.cloud/blog/features/2026/05/28/k3s-vs-k8s-what-are-the-differences-and-which-one-should-you-choose-in-2026/">lightweight Kubernetes distribution such as K3s can be a good fit</a>. <a href="https://www.clever.cloud/blog/engineering/2025/03/05/what-is-a-paas/">A PaaS also meets these needs</a>, as it does many other application profiles (industrialized deployment, automatic scaling, resilience, updates), with an operational model distinct from Kubernetes.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>When Kubernetes does become relevant, the next question rarely concerns installation and more often day-to-day operations: control plane updates, etcd management, certificate rotation, observability, backups. That observation is what explains the growing adoption of managed Kubernetes services. At Clever Cloud, <a href="https://www.clever.cloud/clever-kubernetes-engine/">Clever Kubernetes Engine</a> addresses this need with Materia etcd, a serverless implementation of the etcd API built on FoundationDB that takes over from standard etcd, a known bottleneck at scale, on sovereign infrastructure spread across our three Paris datacenters.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2 class="wp-block-heading">Container orchestration in summary</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Container orchestration automates several categories of operational decisions, chief among them five main classes: where to place a container, when to start more of them, what to do when one of them fails, how they find one another, and how to move from one version to the next without interruption. Kubernetes brings these functions together under a unified model, which makes it the reference tool for distributed systems that need them all at once. The useful question, faced with a project, is not whether you should do orchestration, but which of these functions are actually needed, and at what level of automation.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2 class="wp-block-heading">FAQ - Kubernetes orchestration</h2>
<!-- /wp:heading -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading"><strong>What is the difference between containerization and orchestration?</strong></h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Containerization packages an application and its dependencies into a standardized format that runs identically on any compatible host. Orchestration automates the management of a fleet of containers in production: placement, scaling, self-healing, service discovery, updates. Docker is the reference tool for the former, Kubernetes for the latter.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">Do you necessarily need Kubernetes to orchestrate containers?</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>No. Kubernetes is the most widely adopted orchestrator, but others exist: HashiCorp’s Nomad, which orchestrates containers, VMs and binaries in a single cluster, or Docker Swarm, still maintained but with declining adoption. Apache Mesos, long cited as an alternative, was retired to the Apache Attic in October 2025 and is no longer in active development. Beyond that, a PaaS like Clever Cloud covers the full set of these orchestration functions (placement, automatic scaling, self-healing, rolling updates, service discovery) with its own control plane, independent of Kubernetes. It is that control plane that orchestrates both the applications running in VMs and the containers of the platform’s Docker runtime.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">Is container orchestration necessary for CI/CD?</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>No, but the two are often used together. Modern CI/CD pipelines produce container images as their final artifact, and the orchestrator (Kubernetes or another) takes over to deploy and operate those images. CI/CD and orchestration are two complementary stages of the application lifecycle.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">Does K3s allow orchestration in constrained environments?</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Yes. K3s is a CNCF-certified Kubernetes distribution designed for resource-limited environments (edge, IoT, development machines, small clusters). It keeps the standard Kubernetes APIs while reducing the resource footprint and deployment complexity.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">Does managed Kubernetes change the orchestration functions available?</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>No. Managed Kubernetes provides the same set of orchestration functions as a self-hosted cluster, since it is the same Kubernetes. The difference lies in how operational responsibilities are split: the provider takes on control plane management, updates, and the underlying monitoring. Users then focus on their application workloads.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">Which orchestration function is the hardest to master?</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Networking is frequently cited as the most complex. Service discovery, internal load balancing, NetworkPolicies, Ingress, CNI plugin, east-west traffic observability: the Kubernetes network layer concentrates a significant share of advanced operational topics and remains a frequent source of production incidents.</p>
<!-- /wp:paragraph -->]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Sōzu 2.0 — turning a reverse proxy into a programmable edge</title>
		<link>https://www.clever.cloud/blog/engineering/2026/05/29/sozu-2-0-reverse-proxy-programmable-edge/</link>
		
		<dc:creator><![CDATA[Florentin Dubois]]></dc:creator>
		<pubDate>Fri, 29 May 2026 15:16:11 +0000</pubDate>
				<category><![CDATA[Engineering]]></category>
		<category><![CDATA[Sozu]]></category>
		<guid isPermaLink="false">https://www.clever.cloud/?p=24440</guid>

					<description><![CDATA[<p><img width="2499" height="1109" src="https://cdn.clever-cloud.com/uploads/2026/05/2026-05-29-clever-cloud-banniere-blog-sozu-2-0-en.png" class="attachment-post-thumbnail size-post-thumbnail wp-post-image" alt="2026.05.29 Clever Cloud Bannière Blog Sōzu 2.0 EN" decoding="async" loading="lazy" srcset="https://cdn.clever-cloud.com/uploads/2026/05/2026-05-29-clever-cloud-banniere-blog-sozu-2-0-en.png 2499w, https://cdn.clever-cloud.com/uploads/2026/05/2026-05-29-clever-cloud-banniere-blog-sozu-2-0-en-300x133.png 300w, https://cdn.clever-cloud.com/uploads/2026/05/2026-05-29-clever-cloud-banniere-blog-sozu-2-0-en-1024x454.png 1024w, https://cdn.clever-cloud.com/uploads/2026/05/2026-05-29-clever-cloud-banniere-blog-sozu-2-0-en-768x341.png 768w, https://cdn.clever-cloud.com/uploads/2026/05/2026-05-29-clever-cloud-banniere-blog-sozu-2-0-en-1536x682.png 1536w, https://cdn.clever-cloud.com/uploads/2026/05/2026-05-29-clever-cloud-banniere-blog-sozu-2-0-en-2048x909.png 2048w, https://cdn.clever-cloud.com/uploads/2026/05/2026-05-29-clever-cloud-banniere-blog-sozu-2-0-en-1368x607.png 1368w" sizes="auto, (max-width: 2499px) 100vw, 2499px" /></p><!-- wp:paragraph -->
<p>This release is a milestone: the underlying machine is now ready for the product features we have been waiting to build on top of it. Rather than a list of patches, we've grouped the work into six themes; for each, we say two things — what shipped, and what it makes possible, for the people running their applications on the platform and for the operators who run Sōzu on their own infrastructure.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2 class="wp-block-heading">1. A from-scratch HTTP/2 multiplexer</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Sōzu's HTTP/1 stack had already been rewritten around <strong>kawa</strong>, our pivot format: a single internal representation of the HTTP message, independent of its protocol version — the same idea as HAProxy's HTX. The HTTP/2 multiplexer is its natural extension: it adds session management and stream multiplexing on top of kawa.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>It supports the full protocol matrix (H1↔H1, H1↔H2, H2↔H1, H2↔H2), with shared stream state, HPACK compression via loona-hpack, backend H2 connection pooling, <a href="https://datatracker.ietf.org/doc/html/rfc9218">RFC 9218</a> Extensible Priorities for stream prioritisation, and per-listener ALPN negotiation so each TLS connection lands on the right code path. Around 181 end-to-end tests and two cargo-fuzz targets keep the parser and the HPACK decoder honest — including regression guards that pin large-response integrity byte-for-byte across an H1-backend → H2-frontend path, the exact boundary where edge-triggered epoll readiness bugs hide.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>For Clever Cloud customers, the practical impact is simple: <strong>every application served by the platform now speaks HTTP/2 by default, on the frontend</strong> — no opt-in, no code change, no configuration. Enabling HTTP/2 all the way to the backend stays a per-cluster choice — a <em>cluster</em>, in Sōzu's model, is one of your applications; turned on end-to-end, it unlocks gRPC across the whole chain. Page loads finish in fewer TCP connections; browsers can coalesce requests across hostnames that share a certificate (we honour <a href="https://datatracker.ietf.org/doc/html/rfc7540">RFC 7540 §9.1.1</a> SAN coalescing, so when the certificate, authority and connection conditions line up, Firefox and Chrome can reuse a single connection across your cdn.example.com and assets.example.com instead of opening parallel ones). It is, in the best sense, a quiet platform upgrade.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>It is also the structural prerequisite for what comes after — HTTP/3 over QUIC and stronger streaming foundations at the edge. The mux rewrite is the part of the roadmap that had to land first.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2 class="wp-block-heading">2. Security as a baseline, not a toggle</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>The second half of the H2 rewrite is the part nobody asks for until it's missing: flood and DoS hardening. Sōzu 2.0 ships built-in mitigations for <a href="https://nvd.nist.gov/vuln/detail/CVE-2023-44487"><strong>CVE-2023-44487</strong></a><strong> (Rapid Reset)</strong>, <a href="https://nvd.nist.gov/vuln/detail/CVE-2024-27316"><strong>CVE-2024-27316</strong></a><strong> (CONTINUATION flood)</strong>, <a href="https://nvd.nist.gov/vuln/detail/CVE-2025-8671"><strong>CVE-2025-8671</strong></a><strong> (MadeYouReset)</strong>, and the PING / SETTINGS / empty-DATA flood family from <a href="https://nvd.nist.gov/vuln/detail/CVE-2019-9512">CVE-2019-9512</a>/<a href="https://nvd.nist.gov/vuln/detail/CVE-2019-9515">CVE-2019-9515</a>/<a href="https://nvd.nist.gov/vuln/detail/CVE-2019-9518">CVE-2019-9518</a>. Each mitigation surfaces a dedicated counter — twelve metrics under h2.flood.violation.* — so a SIEM can window the trip rate without parsing logs. Seventeen HPACK rejection reasons are surfaced the same way; that is the first operator-visible signal for request-smuggling probes against the H2 stack.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>The rest of the security work fans out across the proxy: a per-(cluster, source-IP) connection cap with 429 Too Many Requests; opt-in eviction of the oldest sessions when the accept queue saturates; hardening across the command channel, the HTTP/1 parser, the pattern-trie router (closing a routing-bypass through unanchored regex) and the wildcard matcher; audit-log sanitisation against <a href="https://nvd.nist.gov/vuln/detail/CVE-2021-42574">Trojan-Source</a> and SIEM column-smuggling; and a TLS certificate hot-rotation that <strong>never drops the working certificate on failure</strong>, even if the new one is malformed. Four dependency advisories cleared in the same window.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Every privileged mutation now lands in a structured audit log: each control-plane action is recorded as a Command(verb=…, actor_uid=…, actor_user=…, result=…) line — who did what, from where, and whether it succeeded. Two dedicated sinks ship it out: audit_logs_target for the human-readable stream, and audit_logs_json_target for one stable-schema JSON object per line, so the trail tails straight into a SIEM (Wazuh, Elastic, Loki, Splunk) without a bespoke parser — in a shape designed for PCI-DSS 10.5.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>The product framing is straightforward: <strong>our job is to operate the platform and shield your applications as soon as we can</strong>. When the next H/2 vulnerability in this class lands at 9pm on a Friday, it does not have to translate into a patch-and-redeploy weekend across thousands of applications — attacks of this class are largely absorbed or mitigated at the proxy, surfaced as a counter on a dashboard, while applications keep serving traffic. Trust-by-default is not a marketing claim; it is the cumulative effect of dozens of small, defensive fixes shipped at the layer where the security boundary actually lives.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2 class="wp-block-heading">3. Visibility on every layer</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>The largest single user-facing addition in 2.0 is <strong>sozu top</strong> — an operator TUI (behind the tui Cargo feature) that gives you a live btop/htop-style view across seven panes: Overview, Clusters, Backends, Listeners, H2, Certificates, Events. Colour-blind-safe palette, customisable themes — the essentials fit in a terminal, no external dashboard required.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Underneath the TUI, the metric surface itself was rewritten. The mux exposes per-frame-type counters and a breakdown by <a href="https://datatracker.ietf.org/doc/html/rfc9113">RFC 9113</a> error code, TLS handshake telemetry, per-status HTTP counters, and new worker lifecycle gauges. The access log gains TLS and forwarding fields (version, cipher, SNI, ALPN, XFF chain), x_request_id propagation end-to-end, and client and server RTT — enough to follow a request from one hop to the next.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>A new command, SetMetricDetail, lets an operator raise metric cardinality on demand via a time-bounded lease that expires: production stays low-cardinality by default, and deep inspection becomes a one-off decision rather than a config rewrite.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>For Clever Cloud, this is the foundation of the <strong>next chapter of customer-facing observability</strong> — per-application latency percentiles, per-cluster availability, TLS handshake breakdowns, request IDs you can follow across hops. The metrics now exist at the proxy. The next step is to surface them in the Clever Cloud console where they belong, alongside the build and deploy views — so you do not need an external APM to understand the traffic your application actually sees.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2 class="wp-block-heading">4. Traffic policies that you can finally toggle</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Sōzu 2.0 reshapes the entire frontend-policy surface (#1231): <strong>typed HSTS</strong> (<a href="https://datatracker.ietf.org/doc/html/rfc6797">RFC 6797</a>) configurable per listener and per frontend; <strong>URL rewrite</strong> (host, path, port) with regex capture propagation from the routing trie into rewrite templates; <strong>request- and response-header rewriting</strong> per frontend — add, set, or delete any header (an empty value deletes it, HAProxy del-header parity), with listener-scoped X-Real-IP injection and anti-spoof elision of client-supplied values on top; <strong>HTTP 301 / 302 / 308 redirects</strong> through a typed RedirectPolicy enum; and <strong>HTTP Basic authentication</strong> per frontend, with SHA-256-hashed credentials and a constant-time compare via the subtle crate (the credential boundary is hardened against timing side-channels — the audit caught it at review time).</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>This is the part of the release where the product opportunity is most visible. Today, doing a clean domain migration on a managed platform typically requires either a backend that knows how to redirect or a separately deployed redirect service; putting a staging URL behind a password typically requires an authentication add-on. <strong>In Sōzu 2.0, these become knobs at the proxy.</strong> The plumbing exists; what remains is to expose those knobs in the Clever Cloud console — as a checkbox on a domain, or a one-click toggle for preview environments. That is the no-code traffic-control surface we want to build next.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2 class="wp-block-heading">5. Operations as the customer benefit</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>A rewrite this deep only ships safely if the fleet keeps moving underneath it. Day-to-day operations got a lot of attention in 2.0.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>sozu listener {http,https,tcp} update is a new field-masked patch verb that tunes non-bind-only listener settings on a running proxy without cycling sockets — H/2 flood thresholds, SNI binding, ALPN preference, idle timeouts, HSTS, custom answers. <strong>CVE mitigations can now be tightened under attack without cycling listener sockets.</strong> Active backend health checks run inside the existing mio event loop (no async runtime, no extra threads) with HTTP/1.1 and HTTP/2 probes, jittered intervals, and a fail-open path that routes through Normal-status backends whose retry policy allows it. systemd integration (closes #228) now does the right thing: Type=notify units, READY=1 only after the initial workers spawn and the saved state replays, STOPPING=1 on graceful shutdown, MAINPID=&lt;new&gt; across hot upgrades.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Releases themselves changed shape. Pushing a tag now produces <strong>ten pre-built tarballs</strong> (three Linux targets crossed with up to four crypto providers), signed keyless via sigstore (cosign + GitHub OIDC), with SLSA build provenance and a SOURCE.txt corresponding-source pointer satisfying AGPL §6 / LGPL §4 — closing the gap noted in #1089. ACME fullchain.pem files now load cleanly even when the client emitted the leaf at the start (Certbot, lego, acme.sh); a six-year-old worker-auto-restart binary race (#515) is fixed by pinning the original inode through /proc/self/fd. The LoadState IPC verb stays forward-compatible with sozu-command-lib 1.1.1 clients, so the ecosystem of integrations does not break on the upgrade.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>At Clever Cloud's scale, the cost of an operational incident isn't a ticket — it is compounding latency for thousands of applications, and the engineers' time we owe to building the next thing. <strong>Sōzu 2.0 is the proxy that is quiet to operate, and that quietness is what customers experience as uptime.</strong> It's also what makes Sōzu credible as something you can run on your own infrastructure: signed binaries, hot reloads, ACME quirks ironed out, systemd integration done properly.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2 class="wp-block-heading">6. Crypto that's ready for tomorrow</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>The TLS stack got a quieter but equally important rework (#1191). Sōzu now supports <strong>four pluggable crypto providers</strong> for rustls — crypto-ring (the default), crypto-aws-lc-rs, crypto-openssl, and fips (which implies aws-lc-rs in FIPS mode). All four are exercised by CI, and the precedence chain fips &gt; ring &gt; aws-lc-rs &gt; openssl resolves the active provider deterministically when several features are enabled together.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>What we are most happy about, though, is the default groups_list: <strong>X25519MLKEM768</strong><strong> is now the first-preference key-exchange group</strong> where the provider supports it. That is the post-quantum hybrid being standardised through the IETF (<a href="https://datatracker.ietf.org/doc/html/draft-ietf-tls-ecdhe-mlkem">draft-ietf-tls-ecdhe-mlkem</a>) and already registered in the IANA TLS registry; what it means in practice is that an X25519-only client and a PQ-capable client both negotiate the most robust mutually supported exchange, with no operator action.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>When the post-quantum migration becomes a regulatory requirement — on a timeline the industry is still debating — <strong>the groundwork on Clever Cloud will already be in place</strong>: every TLS 1.3 client that offers the hybrid negotiates it today, with no operator action. We made the choice quietly, and we made it the default.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2 class="wp-block-heading">From reverse proxy to programmable edge</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Sōzu has always been an <strong>infrastructure load balancer</strong>: well beyond HTTP, it also balances raw TCP, with a zero-copy forwarding path via splice(2) on Linux for TCP listeners. With 2.0 it moves closer to an <strong>API gateway</strong> and becomes the substrate of a <strong>programmable edge</strong> — and "programmable" is the operative word. Each capability described above (HTTP/2 by default, anti-abuse controls, observability, traffic policies, crypto agility, operational quietness) is a knob. The next year of Clever Cloud's roadmap is about exposing those knobs as product features: through the console, through the API, through the workflows you already use to deploy your applications.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>This is what we mean when we say Sōzu 2.0 is a first step of something greater. Two-point-zero is not the destination — it is the platform we now build on top of. Managed HTTP/2 everywhere is the first building block. The next is a console where you toggle HSTS, password-protect a preview environment, or redirect a migrated domain. The destination — a fully programmable edge with policy primitives you can compose — is what we are building toward over the coming release cycle.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Two more pieces are already on the bench. First, a <strong>UDP load-balancing</strong> layer — in the spirit of IPVS, but with Sōzu's hot-reload model — paired with <strong>TCP health checks</strong> that probe the liveness of the UDP backends; this cements the infrastructure-load-balancer role further. Second, <strong>HTTPS-reachable backends</strong>, which firm up upstream connectivity and open the road to the API gateway.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Sōzu is open source under AGPL-3.0 (the command library is LGPL-3.0). The 2.0 release binaries are signed via sigstore and ship SLSA provenance; if you operate your own edge, this release is yours to use, audit, and extend. The code, the issue tracker, and the conversations live at <a href="https://github.com/sozu-proxy/sozu">github.com/sozu-proxy/sozu</a>.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Thank you to the contributors who made this release happen — and to everyone running Sōzu in production, whose feedback shapes where it goes next.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>References</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">Standards and specifications</h3>
<!-- /wp:heading -->

<!-- wp:list -->
<ul class="wp-block-list"><!-- wp:list-item -->
<li><strong>RFC 6797</strong> — HTTP Strict Transport Security (HSTS). <a href="https://datatracker.ietf.org/doc/html/rfc6797">https://datatracker.ietf.org/doc/html/rfc6797</a></li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><strong>RFC 7540</strong> — Hypertext Transfer Protocol Version 2 (HTTP/2). Now obsoleted by RFC 9113, but §9.1.1 on connection coalescing remains the citation reused by RFC 9113. <a href="https://datatracker.ietf.org/doc/html/rfc7540">https://datatracker.ietf.org/doc/html/rfc7540</a></li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><strong>RFC 9113</strong> — HTTP/2 (current). §5 streams, §6 frames, §6.8 GOAWAY, §7 error codes, §8.1 HTTP semantics. <a href="https://datatracker.ietf.org/doc/html/rfc9113">https://datatracker.ietf.org/doc/html/rfc9113</a></li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><strong>RFC 9218</strong> — Extensible Prioritization Scheme for HTTP. <a href="https://datatracker.ietf.org/doc/html/rfc9218">https://datatracker.ietf.org/doc/html/rfc9218</a></li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><strong>draft-ietf-tls-ecdhe-mlkem</strong> — Hybrid key exchange in TLS 1.3: X25519MLKEM768 (IETF Internet-Draft, IANA-registered; the post-quantum hybrid Sōzu prefers by default). <a href="https://datatracker.ietf.org/doc/html/draft-ietf-tls-ecdhe-mlkem">https://datatracker.ietf.org/doc/html/draft-ietf-tls-ecdhe-mlkem</a></li>
<!-- /wp:list-item --></ul>
<!-- /wp:list -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">CVEs</h3>
<!-- /wp:heading -->

<!-- wp:list -->
<ul class="wp-block-list"><!-- wp:list-item -->
<li><strong>CVE-2019-9512</strong> — HTTP/2 Ping Flood. <a href="https://nvd.nist.gov/vuln/detail/CVE-2019-9512">https://nvd.nist.gov/vuln/detail/CVE-2019-9512</a></li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><strong>CVE-2019-9515</strong> — HTTP/2 Settings Flood. <a href="https://nvd.nist.gov/vuln/detail/CVE-2019-9515">https://nvd.nist.gov/vuln/detail/CVE-2019-9515</a></li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><strong>CVE-2019-9518</strong> — HTTP/2 Empty Frames Flood. <a href="https://nvd.nist.gov/vuln/detail/CVE-2019-9518">https://nvd.nist.gov/vuln/detail/CVE-2019-9518</a></li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><strong>CVE-2021-42574</strong> — Trojan Source (bidirectional override). <a href="https://nvd.nist.gov/vuln/detail/CVE-2021-42574">https://nvd.nist.gov/vuln/detail/CVE-2021-42574</a></li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><strong>CVE-2023-44487</strong> — HTTP/2 Rapid Reset. <a href="https://nvd.nist.gov/vuln/detail/CVE-2023-44487">https://nvd.nist.gov/vuln/detail/CVE-2023-44487</a></li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><strong>CVE-2024-27316</strong> — HTTP/2 CONTINUATION Flood. <a href="https://nvd.nist.gov/vuln/detail/CVE-2024-27316">https://nvd.nist.gov/vuln/detail/CVE-2024-27316</a></li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><strong>CVE-2025-8671</strong> — MadeYouReset (HTTP/2). <a href="https://nvd.nist.gov/vuln/detail/CVE-2025-8671">https://nvd.nist.gov/vuln/detail/CVE-2025-8671</a></li>
<!-- /wp:list-item --></ul>
<!-- /wp:list -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">Further reading</h3>
<!-- /wp:heading -->

<!-- wp:list -->
<ul class="wp-block-list"><!-- wp:list-item -->
<li><strong>Cloudflare Learning Center</strong> — <em>What is HSTS?</em>. Accessible primer on HSTS, the max-age / includeSubDomains / preload semantics, and the HSTS preload list policy. <a href="https://www.cloudflare.com/learning/ssl/what-is-hsts/">https://www.cloudflare.com/learning/ssl/what-is-hsts/</a></li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><strong>Cloudflare</strong> — <em>HTTP/2 Rapid Reset: deconstructing the record-breaking attack</em>. The canonical write-up of the October 2023 coordinated disclosure, including attack mechanics and the 398 M rps peak captured live. <a href="https://blog.cloudflare.com/technical-breakdown-http2-rapid-reset-ddos-attack/">https://blog.cloudflare.com/technical-breakdown-http2-rapid-reset-ddos-attack/</a></li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><strong>HAProxy Technologies</strong> — <em>HAProxy is Not Affected by the HTTP/2 Rapid Reset Attack (CVE-2023-44487)</em>. HAProxy's structural argument for why their stream lifecycle naturally absorbs Rapid Reset; a useful contrast against Sōzu's flood-counter approach. <a href="https://www.haproxy.com/blog/haproxy-is-not-affected-by-the-http-2-rapid-reset-attack-cve-2023-44487">https://www.haproxy.com/blog/haproxy-is-not-affected-by-the-http-2-rapid-reset-attack-cve-2023-44487</a></li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><strong>Cloudflare blog — Post-quantum series</strong>. Multi-year coverage by Bas Westerbaan and colleagues on PQ key exchange and hybrid groups; lineage of the X25519MLKEM768 hybrid Sōzu now negotiates by default. <a href="https://blog.cloudflare.com/tag/post-quantum/">https://blog.cloudflare.com/tag/post-quantum/</a></li>
<!-- /wp:list-item --></ul>
<!-- /wp:list -->]]></description>
										<content:encoded><![CDATA[<p><img width="2499" height="1109" src="https://cdn.clever-cloud.com/uploads/2026/05/2026-05-29-clever-cloud-banniere-blog-sozu-2-0-en.png" class="attachment-post-thumbnail size-post-thumbnail wp-post-image" alt="2026.05.29 Clever Cloud Bannière Blog Sōzu 2.0 EN" decoding="async" loading="lazy" srcset="https://cdn.clever-cloud.com/uploads/2026/05/2026-05-29-clever-cloud-banniere-blog-sozu-2-0-en.png 2499w, https://cdn.clever-cloud.com/uploads/2026/05/2026-05-29-clever-cloud-banniere-blog-sozu-2-0-en-300x133.png 300w, https://cdn.clever-cloud.com/uploads/2026/05/2026-05-29-clever-cloud-banniere-blog-sozu-2-0-en-1024x454.png 1024w, https://cdn.clever-cloud.com/uploads/2026/05/2026-05-29-clever-cloud-banniere-blog-sozu-2-0-en-768x341.png 768w, https://cdn.clever-cloud.com/uploads/2026/05/2026-05-29-clever-cloud-banniere-blog-sozu-2-0-en-1536x682.png 1536w, https://cdn.clever-cloud.com/uploads/2026/05/2026-05-29-clever-cloud-banniere-blog-sozu-2-0-en-2048x909.png 2048w, https://cdn.clever-cloud.com/uploads/2026/05/2026-05-29-clever-cloud-banniere-blog-sozu-2-0-en-1368x607.png 1368w" sizes="auto, (max-width: 2499px) 100vw, 2499px" /></p><!-- wp:paragraph -->
<p>This release is a milestone: the underlying machine is now ready for the product features we have been waiting to build on top of it. Rather than a list of patches, we've grouped the work into six themes; for each, we say two things — what shipped, and what it makes possible, for the people running their applications on the platform and for the operators who run Sōzu on their own infrastructure.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2 class="wp-block-heading">1. A from-scratch HTTP/2 multiplexer</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Sōzu's HTTP/1 stack had already been rewritten around <strong>kawa</strong>, our pivot format: a single internal representation of the HTTP message, independent of its protocol version — the same idea as HAProxy's HTX. The HTTP/2 multiplexer is its natural extension: it adds session management and stream multiplexing on top of kawa.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>It supports the full protocol matrix (H1↔H1, H1↔H2, H2↔H1, H2↔H2), with shared stream state, HPACK compression via loona-hpack, backend H2 connection pooling, <a href="https://datatracker.ietf.org/doc/html/rfc9218">RFC 9218</a> Extensible Priorities for stream prioritisation, and per-listener ALPN negotiation so each TLS connection lands on the right code path. Around 181 end-to-end tests and two cargo-fuzz targets keep the parser and the HPACK decoder honest — including regression guards that pin large-response integrity byte-for-byte across an H1-backend → H2-frontend path, the exact boundary where edge-triggered epoll readiness bugs hide.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>For Clever Cloud customers, the practical impact is simple: <strong>every application served by the platform now speaks HTTP/2 by default, on the frontend</strong> — no opt-in, no code change, no configuration. Enabling HTTP/2 all the way to the backend stays a per-cluster choice — a <em>cluster</em>, in Sōzu's model, is one of your applications; turned on end-to-end, it unlocks gRPC across the whole chain. Page loads finish in fewer TCP connections; browsers can coalesce requests across hostnames that share a certificate (we honour <a href="https://datatracker.ietf.org/doc/html/rfc7540">RFC 7540 §9.1.1</a> SAN coalescing, so when the certificate, authority and connection conditions line up, Firefox and Chrome can reuse a single connection across your cdn.example.com and assets.example.com instead of opening parallel ones). It is, in the best sense, a quiet platform upgrade.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>It is also the structural prerequisite for what comes after — HTTP/3 over QUIC and stronger streaming foundations at the edge. The mux rewrite is the part of the roadmap that had to land first.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2 class="wp-block-heading">2. Security as a baseline, not a toggle</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>The second half of the H2 rewrite is the part nobody asks for until it's missing: flood and DoS hardening. Sōzu 2.0 ships built-in mitigations for <a href="https://nvd.nist.gov/vuln/detail/CVE-2023-44487"><strong>CVE-2023-44487</strong></a><strong> (Rapid Reset)</strong>, <a href="https://nvd.nist.gov/vuln/detail/CVE-2024-27316"><strong>CVE-2024-27316</strong></a><strong> (CONTINUATION flood)</strong>, <a href="https://nvd.nist.gov/vuln/detail/CVE-2025-8671"><strong>CVE-2025-8671</strong></a><strong> (MadeYouReset)</strong>, and the PING / SETTINGS / empty-DATA flood family from <a href="https://nvd.nist.gov/vuln/detail/CVE-2019-9512">CVE-2019-9512</a>/<a href="https://nvd.nist.gov/vuln/detail/CVE-2019-9515">CVE-2019-9515</a>/<a href="https://nvd.nist.gov/vuln/detail/CVE-2019-9518">CVE-2019-9518</a>. Each mitigation surfaces a dedicated counter — twelve metrics under h2.flood.violation.* — so a SIEM can window the trip rate without parsing logs. Seventeen HPACK rejection reasons are surfaced the same way; that is the first operator-visible signal for request-smuggling probes against the H2 stack.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>The rest of the security work fans out across the proxy: a per-(cluster, source-IP) connection cap with 429 Too Many Requests; opt-in eviction of the oldest sessions when the accept queue saturates; hardening across the command channel, the HTTP/1 parser, the pattern-trie router (closing a routing-bypass through unanchored regex) and the wildcard matcher; audit-log sanitisation against <a href="https://nvd.nist.gov/vuln/detail/CVE-2021-42574">Trojan-Source</a> and SIEM column-smuggling; and a TLS certificate hot-rotation that <strong>never drops the working certificate on failure</strong>, even if the new one is malformed. Four dependency advisories cleared in the same window.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Every privileged mutation now lands in a structured audit log: each control-plane action is recorded as a Command(verb=…, actor_uid=…, actor_user=…, result=…) line — who did what, from where, and whether it succeeded. Two dedicated sinks ship it out: audit_logs_target for the human-readable stream, and audit_logs_json_target for one stable-schema JSON object per line, so the trail tails straight into a SIEM (Wazuh, Elastic, Loki, Splunk) without a bespoke parser — in a shape designed for PCI-DSS 10.5.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>The product framing is straightforward: <strong>our job is to operate the platform and shield your applications as soon as we can</strong>. When the next H/2 vulnerability in this class lands at 9pm on a Friday, it does not have to translate into a patch-and-redeploy weekend across thousands of applications — attacks of this class are largely absorbed or mitigated at the proxy, surfaced as a counter on a dashboard, while applications keep serving traffic. Trust-by-default is not a marketing claim; it is the cumulative effect of dozens of small, defensive fixes shipped at the layer where the security boundary actually lives.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2 class="wp-block-heading">3. Visibility on every layer</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>The largest single user-facing addition in 2.0 is <strong>sozu top</strong> — an operator TUI (behind the tui Cargo feature) that gives you a live btop/htop-style view across seven panes: Overview, Clusters, Backends, Listeners, H2, Certificates, Events. Colour-blind-safe palette, customisable themes — the essentials fit in a terminal, no external dashboard required.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Underneath the TUI, the metric surface itself was rewritten. The mux exposes per-frame-type counters and a breakdown by <a href="https://datatracker.ietf.org/doc/html/rfc9113">RFC 9113</a> error code, TLS handshake telemetry, per-status HTTP counters, and new worker lifecycle gauges. The access log gains TLS and forwarding fields (version, cipher, SNI, ALPN, XFF chain), x_request_id propagation end-to-end, and client and server RTT — enough to follow a request from one hop to the next.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>A new command, SetMetricDetail, lets an operator raise metric cardinality on demand via a time-bounded lease that expires: production stays low-cardinality by default, and deep inspection becomes a one-off decision rather than a config rewrite.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>For Clever Cloud, this is the foundation of the <strong>next chapter of customer-facing observability</strong> — per-application latency percentiles, per-cluster availability, TLS handshake breakdowns, request IDs you can follow across hops. The metrics now exist at the proxy. The next step is to surface them in the Clever Cloud console where they belong, alongside the build and deploy views — so you do not need an external APM to understand the traffic your application actually sees.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2 class="wp-block-heading">4. Traffic policies that you can finally toggle</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Sōzu 2.0 reshapes the entire frontend-policy surface (#1231): <strong>typed HSTS</strong> (<a href="https://datatracker.ietf.org/doc/html/rfc6797">RFC 6797</a>) configurable per listener and per frontend; <strong>URL rewrite</strong> (host, path, port) with regex capture propagation from the routing trie into rewrite templates; <strong>request- and response-header rewriting</strong> per frontend — add, set, or delete any header (an empty value deletes it, HAProxy del-header parity), with listener-scoped X-Real-IP injection and anti-spoof elision of client-supplied values on top; <strong>HTTP 301 / 302 / 308 redirects</strong> through a typed RedirectPolicy enum; and <strong>HTTP Basic authentication</strong> per frontend, with SHA-256-hashed credentials and a constant-time compare via the subtle crate (the credential boundary is hardened against timing side-channels — the audit caught it at review time).</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>This is the part of the release where the product opportunity is most visible. Today, doing a clean domain migration on a managed platform typically requires either a backend that knows how to redirect or a separately deployed redirect service; putting a staging URL behind a password typically requires an authentication add-on. <strong>In Sōzu 2.0, these become knobs at the proxy.</strong> The plumbing exists; what remains is to expose those knobs in the Clever Cloud console — as a checkbox on a domain, or a one-click toggle for preview environments. That is the no-code traffic-control surface we want to build next.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2 class="wp-block-heading">5. Operations as the customer benefit</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>A rewrite this deep only ships safely if the fleet keeps moving underneath it. Day-to-day operations got a lot of attention in 2.0.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>sozu listener {http,https,tcp} update is a new field-masked patch verb that tunes non-bind-only listener settings on a running proxy without cycling sockets — H/2 flood thresholds, SNI binding, ALPN preference, idle timeouts, HSTS, custom answers. <strong>CVE mitigations can now be tightened under attack without cycling listener sockets.</strong> Active backend health checks run inside the existing mio event loop (no async runtime, no extra threads) with HTTP/1.1 and HTTP/2 probes, jittered intervals, and a fail-open path that routes through Normal-status backends whose retry policy allows it. systemd integration (closes #228) now does the right thing: Type=notify units, READY=1 only after the initial workers spawn and the saved state replays, STOPPING=1 on graceful shutdown, MAINPID=&lt;new&gt; across hot upgrades.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Releases themselves changed shape. Pushing a tag now produces <strong>ten pre-built tarballs</strong> (three Linux targets crossed with up to four crypto providers), signed keyless via sigstore (cosign + GitHub OIDC), with SLSA build provenance and a SOURCE.txt corresponding-source pointer satisfying AGPL §6 / LGPL §4 — closing the gap noted in #1089. ACME fullchain.pem files now load cleanly even when the client emitted the leaf at the start (Certbot, lego, acme.sh); a six-year-old worker-auto-restart binary race (#515) is fixed by pinning the original inode through /proc/self/fd. The LoadState IPC verb stays forward-compatible with sozu-command-lib 1.1.1 clients, so the ecosystem of integrations does not break on the upgrade.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>At Clever Cloud's scale, the cost of an operational incident isn't a ticket — it is compounding latency for thousands of applications, and the engineers' time we owe to building the next thing. <strong>Sōzu 2.0 is the proxy that is quiet to operate, and that quietness is what customers experience as uptime.</strong> It's also what makes Sōzu credible as something you can run on your own infrastructure: signed binaries, hot reloads, ACME quirks ironed out, systemd integration done properly.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2 class="wp-block-heading">6. Crypto that's ready for tomorrow</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>The TLS stack got a quieter but equally important rework (#1191). Sōzu now supports <strong>four pluggable crypto providers</strong> for rustls — crypto-ring (the default), crypto-aws-lc-rs, crypto-openssl, and fips (which implies aws-lc-rs in FIPS mode). All four are exercised by CI, and the precedence chain fips &gt; ring &gt; aws-lc-rs &gt; openssl resolves the active provider deterministically when several features are enabled together.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>What we are most happy about, though, is the default groups_list: <strong>X25519MLKEM768</strong><strong> is now the first-preference key-exchange group</strong> where the provider supports it. That is the post-quantum hybrid being standardised through the IETF (<a href="https://datatracker.ietf.org/doc/html/draft-ietf-tls-ecdhe-mlkem">draft-ietf-tls-ecdhe-mlkem</a>) and already registered in the IANA TLS registry; what it means in practice is that an X25519-only client and a PQ-capable client both negotiate the most robust mutually supported exchange, with no operator action.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>When the post-quantum migration becomes a regulatory requirement — on a timeline the industry is still debating — <strong>the groundwork on Clever Cloud will already be in place</strong>: every TLS 1.3 client that offers the hybrid negotiates it today, with no operator action. We made the choice quietly, and we made it the default.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2 class="wp-block-heading">From reverse proxy to programmable edge</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Sōzu has always been an <strong>infrastructure load balancer</strong>: well beyond HTTP, it also balances raw TCP, with a zero-copy forwarding path via splice(2) on Linux for TCP listeners. With 2.0 it moves closer to an <strong>API gateway</strong> and becomes the substrate of a <strong>programmable edge</strong> — and "programmable" is the operative word. Each capability described above (HTTP/2 by default, anti-abuse controls, observability, traffic policies, crypto agility, operational quietness) is a knob. The next year of Clever Cloud's roadmap is about exposing those knobs as product features: through the console, through the API, through the workflows you already use to deploy your applications.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>This is what we mean when we say Sōzu 2.0 is a first step of something greater. Two-point-zero is not the destination — it is the platform we now build on top of. Managed HTTP/2 everywhere is the first building block. The next is a console where you toggle HSTS, password-protect a preview environment, or redirect a migrated domain. The destination — a fully programmable edge with policy primitives you can compose — is what we are building toward over the coming release cycle.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Two more pieces are already on the bench. First, a <strong>UDP load-balancing</strong> layer — in the spirit of IPVS, but with Sōzu's hot-reload model — paired with <strong>TCP health checks</strong> that probe the liveness of the UDP backends; this cements the infrastructure-load-balancer role further. Second, <strong>HTTPS-reachable backends</strong>, which firm up upstream connectivity and open the road to the API gateway.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Sōzu is open source under AGPL-3.0 (the command library is LGPL-3.0). The 2.0 release binaries are signed via sigstore and ship SLSA provenance; if you operate your own edge, this release is yours to use, audit, and extend. The code, the issue tracker, and the conversations live at <a href="https://github.com/sozu-proxy/sozu">github.com/sozu-proxy/sozu</a>.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Thank you to the contributors who made this release happen — and to everyone running Sōzu in production, whose feedback shapes where it goes next.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>References</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">Standards and specifications</h3>
<!-- /wp:heading -->

<!-- wp:list -->
<ul class="wp-block-list"><!-- wp:list-item -->
<li><strong>RFC 6797</strong> — HTTP Strict Transport Security (HSTS). <a href="https://datatracker.ietf.org/doc/html/rfc6797">https://datatracker.ietf.org/doc/html/rfc6797</a></li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><strong>RFC 7540</strong> — Hypertext Transfer Protocol Version 2 (HTTP/2). Now obsoleted by RFC 9113, but §9.1.1 on connection coalescing remains the citation reused by RFC 9113. <a href="https://datatracker.ietf.org/doc/html/rfc7540">https://datatracker.ietf.org/doc/html/rfc7540</a></li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><strong>RFC 9113</strong> — HTTP/2 (current). §5 streams, §6 frames, §6.8 GOAWAY, §7 error codes, §8.1 HTTP semantics. <a href="https://datatracker.ietf.org/doc/html/rfc9113">https://datatracker.ietf.org/doc/html/rfc9113</a></li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><strong>RFC 9218</strong> — Extensible Prioritization Scheme for HTTP. <a href="https://datatracker.ietf.org/doc/html/rfc9218">https://datatracker.ietf.org/doc/html/rfc9218</a></li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><strong>draft-ietf-tls-ecdhe-mlkem</strong> — Hybrid key exchange in TLS 1.3: X25519MLKEM768 (IETF Internet-Draft, IANA-registered; the post-quantum hybrid Sōzu prefers by default). <a href="https://datatracker.ietf.org/doc/html/draft-ietf-tls-ecdhe-mlkem">https://datatracker.ietf.org/doc/html/draft-ietf-tls-ecdhe-mlkem</a></li>
<!-- /wp:list-item --></ul>
<!-- /wp:list -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">CVEs</h3>
<!-- /wp:heading -->

<!-- wp:list -->
<ul class="wp-block-list"><!-- wp:list-item -->
<li><strong>CVE-2019-9512</strong> — HTTP/2 Ping Flood. <a href="https://nvd.nist.gov/vuln/detail/CVE-2019-9512">https://nvd.nist.gov/vuln/detail/CVE-2019-9512</a></li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><strong>CVE-2019-9515</strong> — HTTP/2 Settings Flood. <a href="https://nvd.nist.gov/vuln/detail/CVE-2019-9515">https://nvd.nist.gov/vuln/detail/CVE-2019-9515</a></li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><strong>CVE-2019-9518</strong> — HTTP/2 Empty Frames Flood. <a href="https://nvd.nist.gov/vuln/detail/CVE-2019-9518">https://nvd.nist.gov/vuln/detail/CVE-2019-9518</a></li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><strong>CVE-2021-42574</strong> — Trojan Source (bidirectional override). <a href="https://nvd.nist.gov/vuln/detail/CVE-2021-42574">https://nvd.nist.gov/vuln/detail/CVE-2021-42574</a></li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><strong>CVE-2023-44487</strong> — HTTP/2 Rapid Reset. <a href="https://nvd.nist.gov/vuln/detail/CVE-2023-44487">https://nvd.nist.gov/vuln/detail/CVE-2023-44487</a></li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><strong>CVE-2024-27316</strong> — HTTP/2 CONTINUATION Flood. <a href="https://nvd.nist.gov/vuln/detail/CVE-2024-27316">https://nvd.nist.gov/vuln/detail/CVE-2024-27316</a></li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><strong>CVE-2025-8671</strong> — MadeYouReset (HTTP/2). <a href="https://nvd.nist.gov/vuln/detail/CVE-2025-8671">https://nvd.nist.gov/vuln/detail/CVE-2025-8671</a></li>
<!-- /wp:list-item --></ul>
<!-- /wp:list -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">Further reading</h3>
<!-- /wp:heading -->

<!-- wp:list -->
<ul class="wp-block-list"><!-- wp:list-item -->
<li><strong>Cloudflare Learning Center</strong> — <em>What is HSTS?</em>. Accessible primer on HSTS, the max-age / includeSubDomains / preload semantics, and the HSTS preload list policy. <a href="https://www.cloudflare.com/learning/ssl/what-is-hsts/">https://www.cloudflare.com/learning/ssl/what-is-hsts/</a></li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><strong>Cloudflare</strong> — <em>HTTP/2 Rapid Reset: deconstructing the record-breaking attack</em>. The canonical write-up of the October 2023 coordinated disclosure, including attack mechanics and the 398 M rps peak captured live. <a href="https://blog.cloudflare.com/technical-breakdown-http2-rapid-reset-ddos-attack/">https://blog.cloudflare.com/technical-breakdown-http2-rapid-reset-ddos-attack/</a></li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><strong>HAProxy Technologies</strong> — <em>HAProxy is Not Affected by the HTTP/2 Rapid Reset Attack (CVE-2023-44487)</em>. HAProxy's structural argument for why their stream lifecycle naturally absorbs Rapid Reset; a useful contrast against Sōzu's flood-counter approach. <a href="https://www.haproxy.com/blog/haproxy-is-not-affected-by-the-http-2-rapid-reset-attack-cve-2023-44487">https://www.haproxy.com/blog/haproxy-is-not-affected-by-the-http-2-rapid-reset-attack-cve-2023-44487</a></li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><strong>Cloudflare blog — Post-quantum series</strong>. Multi-year coverage by Bas Westerbaan and colleagues on PQ key exchange and hybrid groups; lineage of the X25519MLKEM768 hybrid Sōzu now negotiates by default. <a href="https://blog.cloudflare.com/tag/post-quantum/">https://blog.cloudflare.com/tag/post-quantum/</a></li>
<!-- /wp:list-item --></ul>
<!-- /wp:list -->]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>K3s vs K8s: What Are the Differences and Which One Should You Choose in 2026?</title>
		<link>https://www.clever.cloud/blog/features/2026/05/28/k3s-vs-k8s-what-are-the-differences-and-which-one-should-you-choose-in-2026/</link>
		
		<dc:creator><![CDATA[Marjorie Darrigade]]></dc:creator>
		<pubDate>Thu, 28 May 2026 07:19:05 +0000</pubDate>
				<category><![CDATA[Engineering]]></category>
		<category><![CDATA[Features]]></category>
		<category><![CDATA[K3s]]></category>
		<category><![CDATA[K8S]]></category>
		<category><![CDATA[Kubernetes]]></category>
		<guid isPermaLink="false">https://www.clever.cloud/?p=24419</guid>

					<description><![CDATA[<p><img width="800" height="355" src="https://cdn.clever-cloud.com/uploads/2026/05/2026-05-27-clever-cloud-banniere-blog-k3s-vs-k8s-en.png" class="attachment-post-thumbnail size-post-thumbnail wp-post-image" alt="K3s vs K8s EN" decoding="async" loading="lazy" srcset="https://cdn.clever-cloud.com/uploads/2026/05/2026-05-27-clever-cloud-banniere-blog-k3s-vs-k8s-en.png 800w, https://cdn.clever-cloud.com/uploads/2026/05/2026-05-27-clever-cloud-banniere-blog-k3s-vs-k8s-en-300x133.png 300w, https://cdn.clever-cloud.com/uploads/2026/05/2026-05-27-clever-cloud-banniere-blog-k3s-vs-k8s-en-768x341.png 768w" sizes="auto, (max-width: 800px) 100vw, 800px" /></p><!-- wp:paragraph -->
<p>In short: K3s is a CNCF-certified Kubernetes distribution optimized for constrained environments (edge, IoT, labs). K8s refers to the original Kubernetes project, designed for large-scale production clusters. The choice depends on your available resources, deployment context, and operational workload.</p>
<!-- /wp:paragraph -->

<!-- wp:spacer {"height":"15px"} -->
<div style="height:15px" aria-hidden="true" class="wp-block-spacer"></div>
<!-- /wp:spacer -->

<!-- wp:heading -->
<h2 class="wp-block-heading">K8s: Standard Kubernetes for Enterprise Environments</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>K8s is the abbreviation of Kubernetes, with the “8” representing the eight letters between the “K” and the “s”. It is the original open-source project maintained by the Cloud Native Computing Foundation (CNCF) and initially developed by Google.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Kubernetes is designed for <strong>large-scale production environments</strong>: multi-node clusters, high availability, integration with public clouds (AWS, GCP, Azure), or on-premises datacenters. Its control plane includes several separate components: API server, scheduler, controller manager, etcd, deployed independently, which provides maximum flexibility but requires significant operational expertise.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p><strong>Typical requirements for a production control plane node</strong>: at least 2 vCPUs and 2 GB of RAM for Kubernetes components alone, excluding etcd and application workloads.</p>
<!-- /wp:paragraph -->

<!-- wp:spacer {"height":"15px"} -->
<div style="height:15px" aria-hidden="true" class="wp-block-spacer"></div>
<!-- /wp:spacer -->

<!-- wp:heading -->
<h2 class="wp-block-heading">K3s: A CNCF-Certified Kubernetes Distribution, Not a Fork</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>K3s is a certified Kubernetes distribution, not an unofficial lightweight version or a fork. Created by Rancher Labs, it was <a href="https://thenewstack.io/ranchers-k3s-joins-cncf-sandbox-as-first-kubernetes-distribution/" target="_blank" rel="noreferrer noopener">donated to the CNCF in June 2020</a> and passes the same Sonobuoy conformance tests as all certified distributions. Any valid Kubernetes manifest works on K3s.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Its main goal is to <strong>drastically reduce the resources required </strong>to run Kubernetes in constrained environments (edge, IoT, CI/CD, labs) without giving up API compatibility.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">What K3s Changes Compared to K8s</h3>
<!-- /wp:heading -->

<!-- wp:list -->
<ul class="wp-block-list"><!-- wp:list-item -->
<li></li>
<!-- /wp:list-item --></ul>
<!-- /wp:list -->

<!-- wp:list -->
<ul class="wp-block-list"><!-- wp:list-item -->
<li><a href="https://k3s.io/" target="_blank" rel="noreferrer noopener">A single binary under 70 MB</a>  (supporting x86, ARM64, ARMv7, and S390X), including the containerd runtime, Flannel CNI, a Traefik ingress controller, and a Klipper load balancer.</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><strong>SQLite as the default datastore</strong> in single-node mode instead of etcd. In high-availability configurations (minimum three server nodes), K3s can use <strong>embedded etcd </strong>or an external datastore (MySQL, PostgreSQL, external etcd).</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><strong>Alpha and beta components removed </strong>to reduce the attack surface and memory footprint.</li>
<!-- /wp:list-item --></ul>
<!-- /wp:list -->

<!-- wp:paragraph -->
<p><strong>Important point</strong>: K3s does not remove etcd; it makes it optional. In single-node mode, SQLite is sufficient. In high availability, embedded or external etcd is supported - although the latter is not officially supported by the K3s team.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading"><strong>Resource Footprint</strong></h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>K3s can run with as little as <strong>512 MB of RAM</strong> on an agent node. According to <a href="https://docs.k3s.io/installation/requirements" target="_blank" rel="noreferrer noopener">the official documentation</a> (updated May 2026), a server node (control plane) requires 2 GB of RAM and 2 CPU cores, excluding application workloads. A load-tested profile is available in the <a href="https://docs.k3s.io/reference/resource-profiling" target="_blank" rel="noreferrer noopener">K3s resource profiling guide</a>. It is worth noting that tests on hardware with 1 GB of total RAM showed instability across K3s, k0s, and MicroK8s when deploying real application workloads (even a lightweight Kubernetes cluster still consumes non-negligible control-plane resources).</p>
<!-- /wp:paragraph -->

<!-- wp:spacer {"height":"15px"} -->
<div style="height:15px" aria-hidden="true" class="wp-block-spacer"></div>
<!-- /wp:spacer -->

<!-- wp:heading -->
<h2 class="wp-block-heading">Key Technical Differences</h2>
<!-- /wp:heading -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">Datastore</h3>
<!-- /wp:heading -->

<!-- wp:spacer {"height":"25px"} -->
<div style="height:25px" aria-hidden="true" class="wp-block-spacer"></div>
<!-- /wp:spacer -->

<!-- wp:html -->
<style>
  .cc-table-wrap { overflow-x: auto; }
  .cc-table {
    width: 100%;
    border-collapse: collapse;
    table-layout: fixed;
    font-size: 17px;
    font-family: "Plus Jakarta Sans","PlusJakartaSans",-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Arial,sans-serif;
    color: #111827;
  }
  .cc-table th,
  .cc-table td {
    text-align: left;
    padding: 12px 16px;
    vertical-align: top;
    line-height: 1.6;
  }
  .cc-table tbody tr + tr td,
  .cc-table tbody tr:first-child td {
    border-top: 1px solid #deddee;
  }
  .cc-table th + th,
  .cc-table td + td {
    border-left: 1px solid #deddee;
  }
  .cc-table thead th {
    font-weight: 700;
    text-align: center;
  }
  .cc-table th:nth-child(1),
  .cc-table td:nth-child(1) { width: 28%; }
  .cc-table th:nth-child(2),
  .cc-table td:nth-child(2) { width: 36%; }
  .cc-table th:nth-child(3),
  .cc-table td:nth-child(3) { width: 36%; }
</style>

<div class="cc-table-wrap">
  <table class="cc-table">
    <thead>
      <tr>
        <th>Scenario</th>
        <th>K8s</th>
        <th>K3s</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td>Single-node</td>
        <td>etcd required</td>
        <td>SQLite by default</td>
      </tr>
      <tr>
        <td>Multi-node High Availability</td>
        <td>etcd</td>
        <td>Embedded or external etcd (MySQL, PostgreSQL)</td>
      </tr>
    </tbody>
  </table>
</div>
<!-- /wp:html -->

<!-- wp:spacer {"height":"20px"} -->
<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>
<!-- /wp:spacer -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">Runtime and packaging</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>K8s no longer provides a default runtime since the removal of dockershim (v1.24, 2022). Starting with Kubernetes 1.24, you must install a CRI-compatible runtime (containerd or CRI-O). K3s embeds containerd directly into its binary.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading"><strong>Control Plane Architecture</strong></h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>In K8s, control plane components (API server, scheduler, controller manager) are separate processes. In K3s, they are merged into a single binary, which reduces overhead but limits some advanced isolation configurations.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading"><strong>Scalability</strong></h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>K3s is suitable for moderately sized clusters. In high-availability configurations (3 server nodes, 4 vCPU / 8 GB RAM), <a href="https://docs.k3s.io/installation/requirements" target="_blank" rel="noreferrer noopener">the official documentation</a> indicates a capacity of around 1,200 agents. For very large clusters (several thousand nodes), K8s remains the reference.</p>
<!-- /wp:paragraph -->

<!-- wp:spacer {"height":"15px"} -->
<div style="height:15px" aria-hidden="true" class="wp-block-spacer"></div>
<!-- /wp:spacer -->

<!-- wp:heading -->
<h2 class="wp-block-heading">K3s vs K8s Comparison Table</h2>
<!-- /wp:heading -->

<!-- wp:spacer {"height":"35px"} -->
<div style="height:35px" aria-hidden="true" class="wp-block-spacer"></div>
<!-- /wp:spacer -->

<!-- wp:html -->
<style>
  .cc-table-wrap { overflow-x: auto; }
  .cc-table {
    width: 100%;
    border-collapse: collapse;
    table-layout: fixed;
    font-size: 17px;
    font-family: "Plus Jakarta Sans","PlusJakartaSans",-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Arial,sans-serif;
    color: #111827;
  }
  .cc-table th,
  .cc-table td {
    text-align: left;
    padding: 12px 16px;
    vertical-align: top;
    line-height: 1.6;
  }
  .cc-table tbody tr + tr td,
  .cc-table tbody tr:first-child td {
    border-top: 1px solid #deddee;
  }
  .cc-table th + th,
  .cc-table td + td {
    border-left: 1px solid #deddee;
  }
  .cc-table thead th {
    font-weight: 700;
    text-align: center;
  }
  .cc-table tbody td:first-child {
    font-weight: 600;
  }
  .cc-table th:nth-child(1),
  .cc-table td:nth-child(1) { width: 28%; }
  .cc-table th:nth-child(2),
  .cc-table td:nth-child(2) { width: 36%; }
  .cc-table th:nth-child(3),
  .cc-table td:nth-child(3) { width: 36%; }
</style>

<div class="cc-table-wrap">
  <table class="cc-table">
    <thead>
      <tr>
        <th>Criterion</th>
        <th>K3s</th>
        <th>K8s</th>
      </tr>
    </thead>
    <tbody>
      <tr><td>CNCF certification</td><td>Yes (certified distribution)</td><td>Yes (original project)</td></tr>
      <tr><td>Binary size</td><td>&lt; 100 MB</td><td>Not applicable (separate components)</td></tr>
      <tr><td>Default datastore</td><td>SQLite (single-node) / etcd (high availability)</td><td>etcd</td></tr>
      <tr><td>Embedded runtime</td><td>containerd</td><td>No (to be installed separately)</td></tr>
      <tr><td>ARM support</td><td>Yes (ARM64, ARMv7)</td><td>Yes (depends on the distribution)</td></tr>
      <tr><td>Default ingress</td><td>Traefik (included)</td><td>No (to be deployed separately)</td></tr>
      <tr><td>API compatibility</td><td>Required APIs certified by the CNCF</td><td>Reference implementation (original project)</td></tr>
      <tr><td>Documented max scalability</td><td>~1200 agents (High Availability 3 servers)</td><td>Several thousand nodes</td></tr>
      <tr><td>Main use case</td><td>Edge, IoT, lab, CI/CD</td><td>Enterprise, cloud, datacenters</td></tr>
      <tr><td>Operational complexity</td><td>Low</td><td>High</td></tr>
      <tr><td>Alpha/beta components</td><td>Removed</td><td>Included</td></tr>
    </tbody>
  </table>
</div>
<!-- /wp:html -->

<!-- wp:spacer {"height":"20px"} -->
<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>
<!-- /wp:spacer -->

<!-- wp:heading -->
<h2 class="wp-block-heading">Use Cases: Which One Should You Choose?</h2>
<!-- /wp:heading -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">Choose K3s if:</h3>
<!-- /wp:heading -->

<!-- wp:list -->
<ul class="wp-block-list"><!-- wp:list-item -->
<li>You deploy on <strong>constrained hardware</strong> (Raspberry Pi, industrial appliances, edge servers with limited RAM).</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>You manage remote <strong>IoT or edge clusters</strong>, potentially in disconnected environments.</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>You need a <strong>development or CI cluster</strong> that starts quickly, including on modest hardware.</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>You want an operational cluster with <strong>minimal initial configuration</strong>.</li>
<!-- /wp:list-item --></ul>
<!-- /wp:list -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">Choose K8s (or an enterprise distribution) if:</h3>
<!-- /wp:heading -->

<!-- wp:list -->
<ul class="wp-block-list"><!-- wp:list-item -->
<li>You orchestrate <strong>hundreds or thousands of production nodes</strong>.</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>Your workloads require <strong>advanced cloud-native integrations</strong> (storage, load balancers, IAM) provided by hyperscalers.</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>You need <strong>alpha or beta API components</strong> unavailable in K3s.</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>Your organization has a <strong>dedicated SRE team</strong> operating clusters.</li>
<!-- /wp:list-item --></ul>
<!-- /wp:list -->

<!-- wp:spacer {"height":"20px"} -->
<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>
<!-- /wp:spacer -->

<!-- wp:heading -->
<h2 class="wp-block-heading">Hybrid Use Cases: K3s and K8s Together</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>K3s and K8s are not mutually exclusive. Several hybrid architectures are documented in production:</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">Fleet Management with Rancher</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Edge K3s clusters are managed from a central control plane running on K8s or RKE2. The Home Depot (large American retailer with more than 2,300 stores) <a href="https://www.datacenterknowledge.com/data-center-site-selection/home-depot-upgrades-2-300-retail-edge-locations-using-suse-rancher-k3s" target="_blank" rel="noreferrer noopener">manages its sites using K3s supervised through Rancher</a>.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">K3s for Dev and Staging, K8s for Production</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>API compatibility guarantees that manifests and Helm charts tested on K3s work in production on an enterprise cluster. This parity reduces surprises when promoting environments.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">CI/CD</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Test pipelines run on K3s (low cost, fast startup) while production environments use managed K8s clusters.</p>
<!-- /wp:paragraph -->

<!-- wp:spacer {"height":"20px"} -->
<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>
<!-- /wp:spacer -->

<!-- wp:heading -->
<h2 class="wp-block-heading">Managed Kubernetes: A Third Path</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Neither K3s nor K8s solves the question of <strong>daily operations</strong>: updates, certificates, control plane monitoring, or failure management. This is precisely what managed Kubernetes solutions cover.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Hyperscalers (EKS, GKE, AKS) provide this management within their own clouds. But managed solutions also exist outside these ecosystems, especially for organizations that want to retain control over their data and choose sovereign Kubernetes, or even French-operated Kubernetes.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p><a href="https://www.clever.cloud/clever-kubernetes-engine/">Clever Kubernetes Engine (CKE)</a> is Clever Cloud’s <a href="https://www.clever.cloud/product/kubernetes/">managed Kubernetes</a> service, designed for teams already using Kubernetes and wanting to delegate control plane management (updates, high availability, monitoring) without being constrained to a single hyperscaler. CKE explicitly targets teams that are not fully covered by the traditional  <a href="https://www.clever.cloud/clever-cloud-paas/">PaaS</a> model (multi-runtime use cases, non-twelve-factor workloads, or the need for granular resource control).</p>
<!-- /wp:paragraph -->

<!-- wp:spacer {"height":"150px"} -->
<div style="height:150px" aria-hidden="true" class="wp-block-spacer"></div>
<!-- /wp:spacer -->

<!-- wp:heading {"level":1,"style":{"typography":{"textAlign":"center"}}} -->
<h1 class="wp-block-heading has-text-align-center">FAQ</h1>
<!-- /wp:heading -->

<!-- wp:html -->
<div style="height: 1px; background-color: #DEDDEE; margin: 30px auto; width: 100%;"></div>
<!-- /wp:html -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">Is K3s a Kubernetes fork?</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>No. K3s is a CNCF-certified Kubernetes distribution. It passes Sonobuoy conformance tests and supports the same APIs as K8s. It is not maintained separately from Kubernetes: it follows upstream Kubernetes releases.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">Can K3s Be Used in Production?</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Yes, with some nuances. K3s is documented for production workloads in constrained environments (edge, IoT). For large-scale clusters or critical workloads with high SLA requirements, K8s (or an enterprise distribution such as RKE2) is more appropriate.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">Does K3s Support Helm?</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Yes. K3s includes an integrated Helm controller and is compatible with any valid Helm chart.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">What Is the Difference Between K3s and K3d?</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>K3d is a tool that runs K3s inside Docker containers. It further simplifies the creation of local K3s clusters for development, but it is not intended for production use.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">Does K3s Run on ARM?</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Yes. ARM64 and ARMv7 are natively supported, which explains its popularity on Raspberry Pi devices and industrial appliances.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">Managed Kubernetes vs Self-Hosted K3s: Which One Should You Choose?</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Self-hosted K3s gives you full control but makes you responsible for operations (updates, security, high availability). Managed Kubernetes delegates this responsibility to an operator, at the cost of dependency on that provider. The choice depends on your operational resources and control requirements.</p>
<!-- /wp:paragraph -->

<!-- wp:spacer {"height":"90px"} -->
<div style="height:90px" aria-hidden="true" class="wp-block-spacer"></div>
<!-- /wp:spacer -->]]></description>
										<content:encoded><![CDATA[<p><img width="800" height="355" src="https://cdn.clever-cloud.com/uploads/2026/05/2026-05-27-clever-cloud-banniere-blog-k3s-vs-k8s-en.png" class="attachment-post-thumbnail size-post-thumbnail wp-post-image" alt="K3s vs K8s EN" decoding="async" loading="lazy" srcset="https://cdn.clever-cloud.com/uploads/2026/05/2026-05-27-clever-cloud-banniere-blog-k3s-vs-k8s-en.png 800w, https://cdn.clever-cloud.com/uploads/2026/05/2026-05-27-clever-cloud-banniere-blog-k3s-vs-k8s-en-300x133.png 300w, https://cdn.clever-cloud.com/uploads/2026/05/2026-05-27-clever-cloud-banniere-blog-k3s-vs-k8s-en-768x341.png 768w" sizes="auto, (max-width: 800px) 100vw, 800px" /></p><!-- wp:paragraph -->
<p>In short: K3s is a CNCF-certified Kubernetes distribution optimized for constrained environments (edge, IoT, labs). K8s refers to the original Kubernetes project, designed for large-scale production clusters. The choice depends on your available resources, deployment context, and operational workload.</p>
<!-- /wp:paragraph -->

<!-- wp:spacer {"height":"15px"} -->
<div style="height:15px" aria-hidden="true" class="wp-block-spacer"></div>
<!-- /wp:spacer -->

<!-- wp:heading -->
<h2 class="wp-block-heading">K8s: Standard Kubernetes for Enterprise Environments</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>K8s is the abbreviation of Kubernetes, with the “8” representing the eight letters between the “K” and the “s”. It is the original open-source project maintained by the Cloud Native Computing Foundation (CNCF) and initially developed by Google.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Kubernetes is designed for <strong>large-scale production environments</strong>: multi-node clusters, high availability, integration with public clouds (AWS, GCP, Azure), or on-premises datacenters. Its control plane includes several separate components: API server, scheduler, controller manager, etcd, deployed independently, which provides maximum flexibility but requires significant operational expertise.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p><strong>Typical requirements for a production control plane node</strong>: at least 2 vCPUs and 2 GB of RAM for Kubernetes components alone, excluding etcd and application workloads.</p>
<!-- /wp:paragraph -->

<!-- wp:spacer {"height":"15px"} -->
<div style="height:15px" aria-hidden="true" class="wp-block-spacer"></div>
<!-- /wp:spacer -->

<!-- wp:heading -->
<h2 class="wp-block-heading">K3s: A CNCF-Certified Kubernetes Distribution, Not a Fork</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>K3s is a certified Kubernetes distribution, not an unofficial lightweight version or a fork. Created by Rancher Labs, it was <a href="https://thenewstack.io/ranchers-k3s-joins-cncf-sandbox-as-first-kubernetes-distribution/" target="_blank" rel="noreferrer noopener">donated to the CNCF in June 2020</a> and passes the same Sonobuoy conformance tests as all certified distributions. Any valid Kubernetes manifest works on K3s.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Its main goal is to <strong>drastically reduce the resources required </strong>to run Kubernetes in constrained environments (edge, IoT, CI/CD, labs) without giving up API compatibility.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">What K3s Changes Compared to K8s</h3>
<!-- /wp:heading -->

<!-- wp:list -->
<ul class="wp-block-list"><!-- wp:list-item -->
<li></li>
<!-- /wp:list-item --></ul>
<!-- /wp:list -->

<!-- wp:list -->
<ul class="wp-block-list"><!-- wp:list-item -->
<li><a href="https://k3s.io/" target="_blank" rel="noreferrer noopener">A single binary under 70 MB</a>  (supporting x86, ARM64, ARMv7, and S390X), including the containerd runtime, Flannel CNI, a Traefik ingress controller, and a Klipper load balancer.</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><strong>SQLite as the default datastore</strong> in single-node mode instead of etcd. In high-availability configurations (minimum three server nodes), K3s can use <strong>embedded etcd </strong>or an external datastore (MySQL, PostgreSQL, external etcd).</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><strong>Alpha and beta components removed </strong>to reduce the attack surface and memory footprint.</li>
<!-- /wp:list-item --></ul>
<!-- /wp:list -->

<!-- wp:paragraph -->
<p><strong>Important point</strong>: K3s does not remove etcd; it makes it optional. In single-node mode, SQLite is sufficient. In high availability, embedded or external etcd is supported - although the latter is not officially supported by the K3s team.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading"><strong>Resource Footprint</strong></h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>K3s can run with as little as <strong>512 MB of RAM</strong> on an agent node. According to <a href="https://docs.k3s.io/installation/requirements" target="_blank" rel="noreferrer noopener">the official documentation</a> (updated May 2026), a server node (control plane) requires 2 GB of RAM and 2 CPU cores, excluding application workloads. A load-tested profile is available in the <a href="https://docs.k3s.io/reference/resource-profiling" target="_blank" rel="noreferrer noopener">K3s resource profiling guide</a>. It is worth noting that tests on hardware with 1 GB of total RAM showed instability across K3s, k0s, and MicroK8s when deploying real application workloads (even a lightweight Kubernetes cluster still consumes non-negligible control-plane resources).</p>
<!-- /wp:paragraph -->

<!-- wp:spacer {"height":"15px"} -->
<div style="height:15px" aria-hidden="true" class="wp-block-spacer"></div>
<!-- /wp:spacer -->

<!-- wp:heading -->
<h2 class="wp-block-heading">Key Technical Differences</h2>
<!-- /wp:heading -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">Datastore</h3>
<!-- /wp:heading -->

<!-- wp:spacer {"height":"25px"} -->
<div style="height:25px" aria-hidden="true" class="wp-block-spacer"></div>
<!-- /wp:spacer -->

<!-- wp:html -->
<style>
  .cc-table-wrap { overflow-x: auto; }
  .cc-table {
    width: 100%;
    border-collapse: collapse;
    table-layout: fixed;
    font-size: 17px;
    font-family: "Plus Jakarta Sans","PlusJakartaSans",-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Arial,sans-serif;
    color: #111827;
  }
  .cc-table th,
  .cc-table td {
    text-align: left;
    padding: 12px 16px;
    vertical-align: top;
    line-height: 1.6;
  }
  .cc-table tbody tr + tr td,
  .cc-table tbody tr:first-child td {
    border-top: 1px solid #deddee;
  }
  .cc-table th + th,
  .cc-table td + td {
    border-left: 1px solid #deddee;
  }
  .cc-table thead th {
    font-weight: 700;
    text-align: center;
  }
  .cc-table th:nth-child(1),
  .cc-table td:nth-child(1) { width: 28%; }
  .cc-table th:nth-child(2),
  .cc-table td:nth-child(2) { width: 36%; }
  .cc-table th:nth-child(3),
  .cc-table td:nth-child(3) { width: 36%; }
</style>

<div class="cc-table-wrap">
  <table class="cc-table">
    <thead>
      <tr>
        <th>Scenario</th>
        <th>K8s</th>
        <th>K3s</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td>Single-node</td>
        <td>etcd required</td>
        <td>SQLite by default</td>
      </tr>
      <tr>
        <td>Multi-node High Availability</td>
        <td>etcd</td>
        <td>Embedded or external etcd (MySQL, PostgreSQL)</td>
      </tr>
    </tbody>
  </table>
</div>
<!-- /wp:html -->

<!-- wp:spacer {"height":"20px"} -->
<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>
<!-- /wp:spacer -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">Runtime and packaging</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>K8s no longer provides a default runtime since the removal of dockershim (v1.24, 2022). Starting with Kubernetes 1.24, you must install a CRI-compatible runtime (containerd or CRI-O). K3s embeds containerd directly into its binary.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading"><strong>Control Plane Architecture</strong></h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>In K8s, control plane components (API server, scheduler, controller manager) are separate processes. In K3s, they are merged into a single binary, which reduces overhead but limits some advanced isolation configurations.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading"><strong>Scalability</strong></h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>K3s is suitable for moderately sized clusters. In high-availability configurations (3 server nodes, 4 vCPU / 8 GB RAM), <a href="https://docs.k3s.io/installation/requirements" target="_blank" rel="noreferrer noopener">the official documentation</a> indicates a capacity of around 1,200 agents. For very large clusters (several thousand nodes), K8s remains the reference.</p>
<!-- /wp:paragraph -->

<!-- wp:spacer {"height":"15px"} -->
<div style="height:15px" aria-hidden="true" class="wp-block-spacer"></div>
<!-- /wp:spacer -->

<!-- wp:heading -->
<h2 class="wp-block-heading">K3s vs K8s Comparison Table</h2>
<!-- /wp:heading -->

<!-- wp:spacer {"height":"35px"} -->
<div style="height:35px" aria-hidden="true" class="wp-block-spacer"></div>
<!-- /wp:spacer -->

<!-- wp:html -->
<style>
  .cc-table-wrap { overflow-x: auto; }
  .cc-table {
    width: 100%;
    border-collapse: collapse;
    table-layout: fixed;
    font-size: 17px;
    font-family: "Plus Jakarta Sans","PlusJakartaSans",-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Arial,sans-serif;
    color: #111827;
  }
  .cc-table th,
  .cc-table td {
    text-align: left;
    padding: 12px 16px;
    vertical-align: top;
    line-height: 1.6;
  }
  .cc-table tbody tr + tr td,
  .cc-table tbody tr:first-child td {
    border-top: 1px solid #deddee;
  }
  .cc-table th + th,
  .cc-table td + td {
    border-left: 1px solid #deddee;
  }
  .cc-table thead th {
    font-weight: 700;
    text-align: center;
  }
  .cc-table tbody td:first-child {
    font-weight: 600;
  }
  .cc-table th:nth-child(1),
  .cc-table td:nth-child(1) { width: 28%; }
  .cc-table th:nth-child(2),
  .cc-table td:nth-child(2) { width: 36%; }
  .cc-table th:nth-child(3),
  .cc-table td:nth-child(3) { width: 36%; }
</style>

<div class="cc-table-wrap">
  <table class="cc-table">
    <thead>
      <tr>
        <th>Criterion</th>
        <th>K3s</th>
        <th>K8s</th>
      </tr>
    </thead>
    <tbody>
      <tr><td>CNCF certification</td><td>Yes (certified distribution)</td><td>Yes (original project)</td></tr>
      <tr><td>Binary size</td><td>&lt; 100 MB</td><td>Not applicable (separate components)</td></tr>
      <tr><td>Default datastore</td><td>SQLite (single-node) / etcd (high availability)</td><td>etcd</td></tr>
      <tr><td>Embedded runtime</td><td>containerd</td><td>No (to be installed separately)</td></tr>
      <tr><td>ARM support</td><td>Yes (ARM64, ARMv7)</td><td>Yes (depends on the distribution)</td></tr>
      <tr><td>Default ingress</td><td>Traefik (included)</td><td>No (to be deployed separately)</td></tr>
      <tr><td>API compatibility</td><td>Required APIs certified by the CNCF</td><td>Reference implementation (original project)</td></tr>
      <tr><td>Documented max scalability</td><td>~1200 agents (High Availability 3 servers)</td><td>Several thousand nodes</td></tr>
      <tr><td>Main use case</td><td>Edge, IoT, lab, CI/CD</td><td>Enterprise, cloud, datacenters</td></tr>
      <tr><td>Operational complexity</td><td>Low</td><td>High</td></tr>
      <tr><td>Alpha/beta components</td><td>Removed</td><td>Included</td></tr>
    </tbody>
  </table>
</div>
<!-- /wp:html -->

<!-- wp:spacer {"height":"20px"} -->
<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>
<!-- /wp:spacer -->

<!-- wp:heading -->
<h2 class="wp-block-heading">Use Cases: Which One Should You Choose?</h2>
<!-- /wp:heading -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">Choose K3s if:</h3>
<!-- /wp:heading -->

<!-- wp:list -->
<ul class="wp-block-list"><!-- wp:list-item -->
<li>You deploy on <strong>constrained hardware</strong> (Raspberry Pi, industrial appliances, edge servers with limited RAM).</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>You manage remote <strong>IoT or edge clusters</strong>, potentially in disconnected environments.</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>You need a <strong>development or CI cluster</strong> that starts quickly, including on modest hardware.</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>You want an operational cluster with <strong>minimal initial configuration</strong>.</li>
<!-- /wp:list-item --></ul>
<!-- /wp:list -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">Choose K8s (or an enterprise distribution) if:</h3>
<!-- /wp:heading -->

<!-- wp:list -->
<ul class="wp-block-list"><!-- wp:list-item -->
<li>You orchestrate <strong>hundreds or thousands of production nodes</strong>.</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>Your workloads require <strong>advanced cloud-native integrations</strong> (storage, load balancers, IAM) provided by hyperscalers.</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>You need <strong>alpha or beta API components</strong> unavailable in K3s.</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>Your organization has a <strong>dedicated SRE team</strong> operating clusters.</li>
<!-- /wp:list-item --></ul>
<!-- /wp:list -->

<!-- wp:spacer {"height":"20px"} -->
<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>
<!-- /wp:spacer -->

<!-- wp:heading -->
<h2 class="wp-block-heading">Hybrid Use Cases: K3s and K8s Together</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>K3s and K8s are not mutually exclusive. Several hybrid architectures are documented in production:</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">Fleet Management with Rancher</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Edge K3s clusters are managed from a central control plane running on K8s or RKE2. The Home Depot (large American retailer with more than 2,300 stores) <a href="https://www.datacenterknowledge.com/data-center-site-selection/home-depot-upgrades-2-300-retail-edge-locations-using-suse-rancher-k3s" target="_blank" rel="noreferrer noopener">manages its sites using K3s supervised through Rancher</a>.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">K3s for Dev and Staging, K8s for Production</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>API compatibility guarantees that manifests and Helm charts tested on K3s work in production on an enterprise cluster. This parity reduces surprises when promoting environments.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">CI/CD</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Test pipelines run on K3s (low cost, fast startup) while production environments use managed K8s clusters.</p>
<!-- /wp:paragraph -->

<!-- wp:spacer {"height":"20px"} -->
<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>
<!-- /wp:spacer -->

<!-- wp:heading -->
<h2 class="wp-block-heading">Managed Kubernetes: A Third Path</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Neither K3s nor K8s solves the question of <strong>daily operations</strong>: updates, certificates, control plane monitoring, or failure management. This is precisely what managed Kubernetes solutions cover.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Hyperscalers (EKS, GKE, AKS) provide this management within their own clouds. But managed solutions also exist outside these ecosystems, especially for organizations that want to retain control over their data and choose sovereign Kubernetes, or even French-operated Kubernetes.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p><a href="https://www.clever.cloud/clever-kubernetes-engine/">Clever Kubernetes Engine (CKE)</a> is Clever Cloud’s <a href="https://www.clever.cloud/product/kubernetes/">managed Kubernetes</a> service, designed for teams already using Kubernetes and wanting to delegate control plane management (updates, high availability, monitoring) without being constrained to a single hyperscaler. CKE explicitly targets teams that are not fully covered by the traditional  <a href="https://www.clever.cloud/clever-cloud-paas/">PaaS</a> model (multi-runtime use cases, non-twelve-factor workloads, or the need for granular resource control).</p>
<!-- /wp:paragraph -->

<!-- wp:spacer {"height":"150px"} -->
<div style="height:150px" aria-hidden="true" class="wp-block-spacer"></div>
<!-- /wp:spacer -->

<!-- wp:heading {"level":1,"style":{"typography":{"textAlign":"center"}}} -->
<h1 class="wp-block-heading has-text-align-center">FAQ</h1>
<!-- /wp:heading -->

<!-- wp:html -->
<div style="height: 1px; background-color: #DEDDEE; margin: 30px auto; width: 100%;"></div>
<!-- /wp:html -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">Is K3s a Kubernetes fork?</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>No. K3s is a CNCF-certified Kubernetes distribution. It passes Sonobuoy conformance tests and supports the same APIs as K8s. It is not maintained separately from Kubernetes: it follows upstream Kubernetes releases.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">Can K3s Be Used in Production?</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Yes, with some nuances. K3s is documented for production workloads in constrained environments (edge, IoT). For large-scale clusters or critical workloads with high SLA requirements, K8s (or an enterprise distribution such as RKE2) is more appropriate.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">Does K3s Support Helm?</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Yes. K3s includes an integrated Helm controller and is compatible with any valid Helm chart.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">What Is the Difference Between K3s and K3d?</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>K3d is a tool that runs K3s inside Docker containers. It further simplifies the creation of local K3s clusters for development, but it is not intended for production use.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">Does K3s Run on ARM?</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Yes. ARM64 and ARMv7 are natively supported, which explains its popularity on Raspberry Pi devices and industrial appliances.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">Managed Kubernetes vs Self-Hosted K3s: Which One Should You Choose?</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Self-hosted K3s gives you full control but makes you responsible for operations (updates, security, high availability). Managed Kubernetes delegates this responsibility to an operator, at the cost of dependency on that provider. The choice depends on your operational resources and control requirements.</p>
<!-- /wp:paragraph -->

<!-- wp:spacer {"height":"90px"} -->
<div style="height:90px" aria-hidden="true" class="wp-block-spacer"></div>
<!-- /wp:spacer -->]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>How Clever Cloud responds to kernel vulnerabilities</title>
		<link>https://www.clever.cloud/blog/engineering/2026/05/26/how-clever-cloud-responds-to-kernel-vulnerabilities/</link>
		
		<dc:creator><![CDATA[Leo Le Levé Dandé]]></dc:creator>
		<pubDate>Tue, 26 May 2026 13:57:15 +0000</pubDate>
				<category><![CDATA[Engineering]]></category>
		<category><![CDATA[CVE]]></category>
		<category><![CDATA[Kernel]]></category>
		<category><![CDATA[Security]]></category>
		<guid isPermaLink="false">https://www.clever.cloud/?p=24388</guid>

					<description><![CDATA[<p><img width="800" height="355" src="https://cdn.clever-cloud.com/uploads/2026/05/2026-05-seo-how-clever-cloud-responds-to-kernel-vulnerabilities-en.png" class="attachment-post-thumbnail size-post-thumbnail wp-post-image" alt="2026.05 SEO How Clever Cloud responds to kernel vulnerabilities EN" decoding="async" loading="lazy" srcset="https://cdn.clever-cloud.com/uploads/2026/05/2026-05-seo-how-clever-cloud-responds-to-kernel-vulnerabilities-en.png 800w, https://cdn.clever-cloud.com/uploads/2026/05/2026-05-seo-how-clever-cloud-responds-to-kernel-vulnerabilities-en-300x133.png 300w, https://cdn.clever-cloud.com/uploads/2026/05/2026-05-seo-how-clever-cloud-responds-to-kernel-vulnerabilities-en-768x341.png 768w" sizes="auto, (max-width: 800px) 100vw, 800px" /></p><!-- wp:paragraph -->
<p>Several recent Linux kernel vulnerabilities have required a swift response from infrastructure operators. </p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Among them, <a href="https://access.redhat.com/security/vulnerabilities/RHSB-2026-002">Copy Fail</a> and <a href="https://access.redhat.com/security/vulnerabilities/RHSB-2026-003">Dirty Frag</a> drew attention because they involve local privilege escalation scenarios. Copy Fail is tracked as <a href="https://nvd.nist.gov/vuln/detail/CVE-2026-31431">CVE-2026-31431</a>. </p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Dirty Frag covers two distinct vulnerabilities, <a href="https://nvd.nist.gov/vuln/detail/CVE-2026-43284">CVE-2026-43284</a> and <a href="https://nvd.nist.gov/vuln/detail/CVE-2026-43500">CVE-2026-43500</a>, tied to Linux kernel components.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>At Clever Cloud, we treated these vulnerabilities as critical infrastructure matters. Our goal was twofold: quickly shrink the exposure window, then sustainably improve our kernel selection and deployment process.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>This article reviews our approach, the decisions made, and the changes brought to our operations pipeline</p>
<!-- /wp:paragraph -->

<!-- wp:spacer {"height":"15px"} -->
<div style="height:15px" aria-hidden="true" class="wp-block-spacer"></div>
<!-- /wp:spacer -->

<!-- wp:heading -->
<h2 class="wp-block-heading">Why these vulnerabilities called for a fast response</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Copy Fail and Dirty Frag belong to the family of local privilege escalation vulnerabilities. In this type of scenario, an attacker must already be able to execute code locally, but can then attempt to gain higher privileges on the affected machine.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Dirty Frag rests on two Linux kernel flaws. </p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>They notably affect modules related to ESP, used by <a href="https://en.wikipedia.org/wiki/IPsec">IPsec</a>, and to <a href="https://docs.kernel.org/networking/rxrpc.html">RxRPC</a>. On a cloud platform, this type of vulnerability calls for a rapid analysis. The risk is not limited to a single isolated machine. </p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Scenarios tied to shared environments, containerized workloads, and isolation mechanisms must also be assessed.</p>
<!-- /wp:paragraph -->

<!-- wp:spacer {"height":"15px"} -->
<div style="height:15px" aria-hidden="true" class="wp-block-spacer"></div>
<!-- /wp:spacer -->

<!-- wp:heading -->
<h2 class="wp-block-heading">What we verified</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>We analyzed the potential impact of these vulnerabilities on our environments. This step is not just about reading security advisories. It also involves verifying whether a theoretical scenario can become relevant in our operating context.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>In the case of Copy Fail, the flaw came under embargo together with its patch. We published a new system image with the patch applied in the days that followed. </p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Our customers' applications were redeployed shortly after.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>In the case of Dirty Frag, our internal analyses confirmed that these vulnerabilities had to be taken seriously. ESP modules are enabled in our kernels to support some specific customer needs. Fortunately, RxRPC-related modules are not present in our environment, as they serve no purpose for our usage. </p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>We do not detail the technical steps of the exploitation here, since the purpose of this article is to inform our customers, not to publish a reproducible procedure.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>This validation confirmed the operational decision: handle the matter immediately, reduce the exposed surface, then force the necessary redeployments.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p></p>
<!-- /wp:paragraph -->

<!-- wp:html -->
<table style="border-collapse:collapse;width:100%;font-family:Arial,sans-serif;">
<thead>
<tr style="background:#f5f5f5;">
<th style="border:1px solid #ddd;padding:12px 16px;text-align:left;">Period</th>
<th style="border:1px solid #ddd;padding:12px 16px;text-align:left;">Action</th>
</tr>
</thead>
<tbody>
<tr>
<td style="border:1px solid #ddd;padding:12px 16px;">April 30, 2026</td>
<td style="border:1px solid #ddd;padding:12px 16px;">Fast rollout of initial kernel mitigations</td>
</tr>
<tr>
<td style="border:1px solid #ddd;padding:12px 16px;">May 7, 2026</td>
<td style="border:1px solid #ddd;padding:12px 16px;">Update of kernels affected by the new vulnerabilities</td>
</tr>
<tr>
<td style="border:1px solid #ddd;padding:12px 16px;">May 8, 2026</td>
<td style="border:1px solid #ddd;padding:12px 16px;">Progressive workload redeployment to apply the patches</td>
</tr>
<tr>
<td style="border:1px solid #ddd;padding:12px 16px;">May 11, 2026</td>
<td style="border:1px solid #ddd;padding:12px 16px;">Production release of kernel management integration into the orchestration pipeline</td>
</tr>
</tbody>
</table>
<!-- /wp:html -->

<!-- wp:spacer {"height":"15px"} -->
<div style="height:15px" aria-hidden="true" class="wp-block-spacer"></div>
<!-- /wp:spacer -->

<!-- wp:heading -->
<h2 class="wp-block-heading">Our operational response</h2>
<!-- /wp:heading -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading"><strong>Rolling out immediate measures</strong></h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>We first applied quick measures on the affected kernels. In the case of Dirty Frag, the publicly recommended measures focus in particular on the kernel components related to ESP and RxRPC.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>On Clever Cloud's side, the goal was clear: reduce the identified exposed surfaces and shrink the exposure window without waiting for a standard maintenance cycle.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading"><strong>Redeploying the affected workloads</strong></h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>A kernel update only matters if the affected systems actually restart on a patched environment. We therefore launched a progressive redeployment of applications, then handled the cases that blocked this redeployment.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>This phase matters. On a managed platform, the fix is not limited to producing an image or compiling a kernel. The execution chain must also actually use the expected version.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p></p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading"><strong>Improving the process along the way</strong></h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>We also took advantage of this sequence to replace a temporary mechanism with a cleaner integration into our orchestration pipeline.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Concretely, the kernel choice is now passed more explicitly through our internal pipeline, all the way to Supernova, our hypervisor agent. This evolution replaces the stiffer workaround put in place in the heat of the moment.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>That is the central point of this intervention: fix fast, then make the fix more reliable for future operations.</p>
<!-- /wp:paragraph -->

<!-- wp:spacer {"height":"15px"} -->
<div style="height:15px" aria-hidden="true" class="wp-block-spacer"></div>
<!-- /wp:spacer -->

<!-- wp:heading -->
<h2 class="wp-block-heading">What this changes for Clever Cloud customers</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>For customers, the expected effect is simple: reduce exposure without any manual action on their part whenever the platform can handle the redeployment.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Clever Cloud runs an architecture that relies in particular on isolation through virtualization. This approach is documented on <a href="https://www.clever-cloud.com/security/">our security pages</a> and in our technical content on running containers inside virtual machines. It does not eliminate every risk, but it limits certain lateral movement scenarios compared to models where multiple workloads share the same execution environment directly.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>We avoid, however, presenting this isolation as an absolute guarantee. A kernel vulnerability must always be taken seriously. </p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>That is why we combined mitigation, redeployment, and improvement of our operations pipeline.</p>
<!-- /wp:paragraph -->

<!-- wp:spacer {"height":"15px"} -->
<div style="height:15px" aria-hidden="true" class="wp-block-spacer"></div>
<!-- /wp:spacer -->

<!-- wp:heading -->
<h2 class="wp-block-heading">What we take away</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>This sequence confirms three principles.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>First, a kernel vulnerability must be analyzed in its actual operating context. A public alert is not enough. We need to understand whether the conditions required for exploitation can exist on the platform.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Second, reaction speed matters. The Copy Fail and Dirty Frag vulnerabilities were disclosed publicly within a few days of each other, with analyses published by several players in the Linux and cloud ecosystem.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Finally, a useful security response must not only fix the problem of the moment. It must also improve the system that will handle the next incident.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>That is what we did here: handled the vulnerabilities, shrank the exposure window, and strengthened our kernel management process.</p>
<!-- /wp:paragraph -->

<!-- wp:spacer {"height":"15px"} -->
<div style="height:15px" aria-hidden="true" class="wp-block-spacer"></div>
<!-- /wp:spacer -->

<!-- wp:spacer -->
<div style="height:100px" aria-hidden="true" class="wp-block-spacer"></div>
<!-- /wp:spacer -->

<!-- wp:heading {"textAlign":"center","level":1} -->
<h1 class="wp-block-heading has-text-align-center">Q&amp;A</h1>
<!-- /wp:heading -->

<!-- wp:html -->
<div style="height: 1px; background-color: #DEDDEE; margin: 30px auto; width: 100%;"></div>
<!-- /wp:html -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading"><strong><strong>What is a local kernel vulnerability?</strong></strong></h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>A local kernel vulnerability is a flaw that already requires execution capability on the affected machine. It can then allow gaining higher privileges, such as root, if the kernel is vulnerable.<br></p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading"><strong><strong>Why do these flaws concern cloud platforms?</strong></strong></h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Cloud platforms run many workloads with isolation mechanisms. A kernel flaw can become critical if it allows crossing certain boundaries between processes, containers, or execution environments.<br></p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading"><strong><strong>Are Dirty Frag and Copy Fail the same vulnerability?</strong></strong></h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>No. Copy Fail is tracked as CVE-2026-31431. Dirty Frag covers CVE-2026-43284 and CVE-2026-43500. These vulnerabilities are close in impact, but they are distinct.<br></p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading"><strong><strong>What action is required from Clever Cloud customers?</strong></strong></h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>No general action is required from customers for environments handled by the platform. The automation brought by Clever Cloud allowed everything to be updated without action needed. Specific cases are tracked individually.<br></p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p></p>
<!-- /wp:paragraph -->]]></description>
										<content:encoded><![CDATA[<p><img width="800" height="355" src="https://cdn.clever-cloud.com/uploads/2026/05/2026-05-seo-how-clever-cloud-responds-to-kernel-vulnerabilities-en.png" class="attachment-post-thumbnail size-post-thumbnail wp-post-image" alt="2026.05 SEO How Clever Cloud responds to kernel vulnerabilities EN" decoding="async" loading="lazy" srcset="https://cdn.clever-cloud.com/uploads/2026/05/2026-05-seo-how-clever-cloud-responds-to-kernel-vulnerabilities-en.png 800w, https://cdn.clever-cloud.com/uploads/2026/05/2026-05-seo-how-clever-cloud-responds-to-kernel-vulnerabilities-en-300x133.png 300w, https://cdn.clever-cloud.com/uploads/2026/05/2026-05-seo-how-clever-cloud-responds-to-kernel-vulnerabilities-en-768x341.png 768w" sizes="auto, (max-width: 800px) 100vw, 800px" /></p><!-- wp:paragraph -->
<p>Several recent Linux kernel vulnerabilities have required a swift response from infrastructure operators. </p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Among them, <a href="https://access.redhat.com/security/vulnerabilities/RHSB-2026-002">Copy Fail</a> and <a href="https://access.redhat.com/security/vulnerabilities/RHSB-2026-003">Dirty Frag</a> drew attention because they involve local privilege escalation scenarios. Copy Fail is tracked as <a href="https://nvd.nist.gov/vuln/detail/CVE-2026-31431">CVE-2026-31431</a>. </p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Dirty Frag covers two distinct vulnerabilities, <a href="https://nvd.nist.gov/vuln/detail/CVE-2026-43284">CVE-2026-43284</a> and <a href="https://nvd.nist.gov/vuln/detail/CVE-2026-43500">CVE-2026-43500</a>, tied to Linux kernel components.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>At Clever Cloud, we treated these vulnerabilities as critical infrastructure matters. Our goal was twofold: quickly shrink the exposure window, then sustainably improve our kernel selection and deployment process.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>This article reviews our approach, the decisions made, and the changes brought to our operations pipeline</p>
<!-- /wp:paragraph -->

<!-- wp:spacer {"height":"15px"} -->
<div style="height:15px" aria-hidden="true" class="wp-block-spacer"></div>
<!-- /wp:spacer -->

<!-- wp:heading -->
<h2 class="wp-block-heading">Why these vulnerabilities called for a fast response</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Copy Fail and Dirty Frag belong to the family of local privilege escalation vulnerabilities. In this type of scenario, an attacker must already be able to execute code locally, but can then attempt to gain higher privileges on the affected machine.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Dirty Frag rests on two Linux kernel flaws. </p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>They notably affect modules related to ESP, used by <a href="https://en.wikipedia.org/wiki/IPsec">IPsec</a>, and to <a href="https://docs.kernel.org/networking/rxrpc.html">RxRPC</a>. On a cloud platform, this type of vulnerability calls for a rapid analysis. The risk is not limited to a single isolated machine. </p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Scenarios tied to shared environments, containerized workloads, and isolation mechanisms must also be assessed.</p>
<!-- /wp:paragraph -->

<!-- wp:spacer {"height":"15px"} -->
<div style="height:15px" aria-hidden="true" class="wp-block-spacer"></div>
<!-- /wp:spacer -->

<!-- wp:heading -->
<h2 class="wp-block-heading">What we verified</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>We analyzed the potential impact of these vulnerabilities on our environments. This step is not just about reading security advisories. It also involves verifying whether a theoretical scenario can become relevant in our operating context.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>In the case of Copy Fail, the flaw came under embargo together with its patch. We published a new system image with the patch applied in the days that followed. </p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Our customers' applications were redeployed shortly after.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>In the case of Dirty Frag, our internal analyses confirmed that these vulnerabilities had to be taken seriously. ESP modules are enabled in our kernels to support some specific customer needs. Fortunately, RxRPC-related modules are not present in our environment, as they serve no purpose for our usage. </p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>We do not detail the technical steps of the exploitation here, since the purpose of this article is to inform our customers, not to publish a reproducible procedure.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>This validation confirmed the operational decision: handle the matter immediately, reduce the exposed surface, then force the necessary redeployments.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p></p>
<!-- /wp:paragraph -->

<!-- wp:html -->
<table style="border-collapse:collapse;width:100%;font-family:Arial,sans-serif;">
<thead>
<tr style="background:#f5f5f5;">
<th style="border:1px solid #ddd;padding:12px 16px;text-align:left;">Period</th>
<th style="border:1px solid #ddd;padding:12px 16px;text-align:left;">Action</th>
</tr>
</thead>
<tbody>
<tr>
<td style="border:1px solid #ddd;padding:12px 16px;">April 30, 2026</td>
<td style="border:1px solid #ddd;padding:12px 16px;">Fast rollout of initial kernel mitigations</td>
</tr>
<tr>
<td style="border:1px solid #ddd;padding:12px 16px;">May 7, 2026</td>
<td style="border:1px solid #ddd;padding:12px 16px;">Update of kernels affected by the new vulnerabilities</td>
</tr>
<tr>
<td style="border:1px solid #ddd;padding:12px 16px;">May 8, 2026</td>
<td style="border:1px solid #ddd;padding:12px 16px;">Progressive workload redeployment to apply the patches</td>
</tr>
<tr>
<td style="border:1px solid #ddd;padding:12px 16px;">May 11, 2026</td>
<td style="border:1px solid #ddd;padding:12px 16px;">Production release of kernel management integration into the orchestration pipeline</td>
</tr>
</tbody>
</table>
<!-- /wp:html -->

<!-- wp:spacer {"height":"15px"} -->
<div style="height:15px" aria-hidden="true" class="wp-block-spacer"></div>
<!-- /wp:spacer -->

<!-- wp:heading -->
<h2 class="wp-block-heading">Our operational response</h2>
<!-- /wp:heading -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading"><strong>Rolling out immediate measures</strong></h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>We first applied quick measures on the affected kernels. In the case of Dirty Frag, the publicly recommended measures focus in particular on the kernel components related to ESP and RxRPC.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>On Clever Cloud's side, the goal was clear: reduce the identified exposed surfaces and shrink the exposure window without waiting for a standard maintenance cycle.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading"><strong>Redeploying the affected workloads</strong></h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>A kernel update only matters if the affected systems actually restart on a patched environment. We therefore launched a progressive redeployment of applications, then handled the cases that blocked this redeployment.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>This phase matters. On a managed platform, the fix is not limited to producing an image or compiling a kernel. The execution chain must also actually use the expected version.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p></p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading"><strong>Improving the process along the way</strong></h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>We also took advantage of this sequence to replace a temporary mechanism with a cleaner integration into our orchestration pipeline.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Concretely, the kernel choice is now passed more explicitly through our internal pipeline, all the way to Supernova, our hypervisor agent. This evolution replaces the stiffer workaround put in place in the heat of the moment.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>That is the central point of this intervention: fix fast, then make the fix more reliable for future operations.</p>
<!-- /wp:paragraph -->

<!-- wp:spacer {"height":"15px"} -->
<div style="height:15px" aria-hidden="true" class="wp-block-spacer"></div>
<!-- /wp:spacer -->

<!-- wp:heading -->
<h2 class="wp-block-heading">What this changes for Clever Cloud customers</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>For customers, the expected effect is simple: reduce exposure without any manual action on their part whenever the platform can handle the redeployment.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Clever Cloud runs an architecture that relies in particular on isolation through virtualization. This approach is documented on <a href="https://www.clever-cloud.com/security/">our security pages</a> and in our technical content on running containers inside virtual machines. It does not eliminate every risk, but it limits certain lateral movement scenarios compared to models where multiple workloads share the same execution environment directly.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>We avoid, however, presenting this isolation as an absolute guarantee. A kernel vulnerability must always be taken seriously. </p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>That is why we combined mitigation, redeployment, and improvement of our operations pipeline.</p>
<!-- /wp:paragraph -->

<!-- wp:spacer {"height":"15px"} -->
<div style="height:15px" aria-hidden="true" class="wp-block-spacer"></div>
<!-- /wp:spacer -->

<!-- wp:heading -->
<h2 class="wp-block-heading">What we take away</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>This sequence confirms three principles.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>First, a kernel vulnerability must be analyzed in its actual operating context. A public alert is not enough. We need to understand whether the conditions required for exploitation can exist on the platform.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Second, reaction speed matters. The Copy Fail and Dirty Frag vulnerabilities were disclosed publicly within a few days of each other, with analyses published by several players in the Linux and cloud ecosystem.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Finally, a useful security response must not only fix the problem of the moment. It must also improve the system that will handle the next incident.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>That is what we did here: handled the vulnerabilities, shrank the exposure window, and strengthened our kernel management process.</p>
<!-- /wp:paragraph -->

<!-- wp:spacer {"height":"15px"} -->
<div style="height:15px" aria-hidden="true" class="wp-block-spacer"></div>
<!-- /wp:spacer -->

<!-- wp:spacer -->
<div style="height:100px" aria-hidden="true" class="wp-block-spacer"></div>
<!-- /wp:spacer -->

<!-- wp:heading {"textAlign":"center","level":1} -->
<h1 class="wp-block-heading has-text-align-center">Q&amp;A</h1>
<!-- /wp:heading -->

<!-- wp:html -->
<div style="height: 1px; background-color: #DEDDEE; margin: 30px auto; width: 100%;"></div>
<!-- /wp:html -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading"><strong><strong>What is a local kernel vulnerability?</strong></strong></h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>A local kernel vulnerability is a flaw that already requires execution capability on the affected machine. It can then allow gaining higher privileges, such as root, if the kernel is vulnerable.<br></p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading"><strong><strong>Why do these flaws concern cloud platforms?</strong></strong></h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Cloud platforms run many workloads with isolation mechanisms. A kernel flaw can become critical if it allows crossing certain boundaries between processes, containers, or execution environments.<br></p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading"><strong><strong>Are Dirty Frag and Copy Fail the same vulnerability?</strong></strong></h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>No. Copy Fail is tracked as CVE-2026-31431. Dirty Frag covers CVE-2026-43284 and CVE-2026-43500. These vulnerabilities are close in impact, but they are distinct.<br></p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading"><strong><strong>What action is required from Clever Cloud customers?</strong></strong></h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>No general action is required from customers for environments handled by the platform. The automation brought by Clever Cloud allowed everything to be updated without action needed. Specific cases are tracked individually.<br></p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p></p>
<!-- /wp:paragraph -->]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>K8S: What Is Kubernetes, How It Works, and Why It Became the Standard</title>
		<link>https://www.clever.cloud/blog/engineering/2026/05/19/k8s-kubernetes-definition-standard/</link>
		
		<dc:creator><![CDATA[Leo Le Levé Dandé]]></dc:creator>
		<pubDate>Tue, 19 May 2026 10:54:29 +0000</pubDate>
				<category><![CDATA[Engineering]]></category>
		<category><![CDATA[Kubernetes]]></category>
		<guid isPermaLink="false">https://www.clever.cloud/?p=24294</guid>

					<description><![CDATA[<p><img width="2499" height="1109" src="https://cdn.clever-cloud.com/uploads/2026/05/2026-05-19-clever-cloud-banniere-blog-k8s-en.png" class="attachment-post-thumbnail size-post-thumbnail wp-post-image" alt="2026.05.19 Clever Cloud Bannière Blog K8S EN" decoding="async" loading="lazy" srcset="https://cdn.clever-cloud.com/uploads/2026/05/2026-05-19-clever-cloud-banniere-blog-k8s-en.png 2499w, https://cdn.clever-cloud.com/uploads/2026/05/2026-05-19-clever-cloud-banniere-blog-k8s-en-300x133.png 300w, https://cdn.clever-cloud.com/uploads/2026/05/2026-05-19-clever-cloud-banniere-blog-k8s-en-1024x454.png 1024w, https://cdn.clever-cloud.com/uploads/2026/05/2026-05-19-clever-cloud-banniere-blog-k8s-en-768x341.png 768w, https://cdn.clever-cloud.com/uploads/2026/05/2026-05-19-clever-cloud-banniere-blog-k8s-en-1536x682.png 1536w, https://cdn.clever-cloud.com/uploads/2026/05/2026-05-19-clever-cloud-banniere-blog-k8s-en-2048x909.png 2048w, https://cdn.clever-cloud.com/uploads/2026/05/2026-05-19-clever-cloud-banniere-blog-k8s-en-1368x607.png 1368w" sizes="auto, (max-width: 2499px) 100vw, 2499px" /></p><!-- wp:heading -->
<h2 class="wp-block-heading">How Kubernetes Works: a Declarative Orchestrator</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Most descriptions of <a href="https://www.clever.cloud/product/kubernetes/">Kubernetes</a> list its components (pods, deployments, services) without explaining the central mechanism. The fundamental concept lies elsewhere: Kubernetes is first and foremost an <strong>orchestrator</strong>, and its core engine relies on a reconciliation loop.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>You don't tell Kubernetes <em>what to do</em>. You tell it <em>what you want your system to look like</em>. This distinction, declarative versus imperative, changes everything.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>In practice, you describe the desired state in manifest files, typically in YAML format: "I want 3 replicas of this image, exposed on port 80, with these environment variables." You submit this manifest to the Kubernetes API via kubectl. From that point on, Kubernetes continuously compares the actual state of the cluster (what is actually running) to the desired state (what you declared), and acts to bring them into alignment. If a node dies, its pods are rescheduled elsewhere. If you change from 3 to 10 replicas in the manifest, Kubernetes starts 7 more. If a container crashes, it gets restarted.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>This reconciliation loop is the heart of everything Kubernetes does: self-healing, scaling, rolling updates, and rollbacks. To dive deeper into this mechanism and the other capabilities it enables, learn more about container orchestration.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2 class="wp-block-heading">Architecture in Brief: Control Plane, Nodes, Pods</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>A Kubernetes cluster is divided into two parts. The <strong>control plane</strong> is the brain: it makes global decisions, accepts API requests, schedules workloads, and monitors the state of the cluster. It relies on a few key components, including the API server (kube-apiserver), the scheduler (kube-scheduler), and the controller manager (kube-controller-manager), along with a distributed data store that holds the entire cluster state, traditionally etcd.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p><strong>Nodes</strong> are the machines that actually run the workloads. On each node, an agent called kubelet receives instructions from the control plane and launches containers through a container runtime (containerd, CRI-O, etc.). The smallest deployable unit is not an individual container but a <strong>pod</strong>: one or more containers that share a network and storage. Higher-level objects (Deployment, Service, Ingress, ConfigMap, Secret) describe how pods should be managed, exposed, and configured.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>This architecture is also the source of a common confusion with Docker, whose role is actually complementary to Kubernetes rather than competitive.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2 class="wp-block-heading">Why K8S Became the Orchestration Standard</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>According to the<a href="https://www.cncf.io/reports/"> CNCF Annual Cloud Native Survey 2025</a>, published in January 2026, 98% of surveyed organizations have adopted <a href="https://www.clever.cloud/blog/company/2025/05/30/what-is-native-cloud/">cloud native</a> techniques, and 82% of container users deploy Kubernetes in production, up from 66% in 2023. The dominance is massive. But explaining it solely through technical qualities would be incomplete; it is also a story of ecosystem dynamics and aligned interests.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p><strong>On the technical side</strong>, three properties explain adoption. First, the declarative model described above: it makes deployments reproducible, versionable in Git, and resilient to failures. Second, portability: the same manifest works on a development machine (Minikube, kind, k3d), on an on-premise cluster, and on any cloud. Third, extensibility: the Kubernetes API accepts Custom Resource Definitions (CRDs) and custom controllers (Operators), turning it into a platform for building platforms. This triggered a massive ecosystem dynamic.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p><strong>On the strategic side</strong>, the story is less often told. By 2014, Google had more than a decade of experience managing containers at scale with its internal systems Borg and Omega, whose design principles were shared publicly through academic research papers (Omega in 2013, Borg in 2015). Rather than open-sourcing Borg itself, which remained tightly coupled to Google's proprietary infrastructure, the team created Kubernetes as a new project inspired by that experience, with a distinct implementation designed from the outset for external adoption. The project was released as open source in June 2014 and donated to the Cloud Native Computing Foundation in 2015. This neutrality, a project hosted by a Linux foundation rather than a cloud provider, proved decisive. No competitor could afford <em>not</em> to adopt it without being marginalized from the emerging cloud-native ecosystem. AWS, which initially pushed its own proprietary solution (ECS), announced EKS in late 2017 and launched it in general availability in June 2018. By then, the standard was sealed.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p><strong>On the ecosystem side</strong>, the network effect did the rest: Helm for packaging applications, Prometheus for monitoring, Istio and Linkerd for service mesh, ArgoCD and Flux for GitOps, Trivy and Falco for security. Each additional tool reinforces the value of the standard. On the talent side, Kubernetes skills have become massively in-demand across DevOps and SRE roles, creating a virtuous cycle: more trained engineers, more adopting companies, more engineers getting trained.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>In the CNCF 2025 report, the community now describes Kubernetes as "boring," using the term as the highest praise: a mature, predictable tool whose APIs no longer break with every release. That is exactly what you want from infrastructure that has become standard.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2 class="wp-block-heading">When Kubernetes Adds Value, and When Other Approaches Are a Better Fit</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>The fact that K8S is the standard doesn't mean it's the right answer to every problem. Choosing Kubernetes, a <a href="https://www.clever.cloud/clever-cloud-paas/">PaaS</a>, or a combination of both depends on the technical and organizational context; at Clever Cloud, many teams use both in parallel for different workloads.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Kubernetes delivers real value in several contexts:</p>
<!-- /wp:paragraph -->

<!-- wp:list -->
<ul class="wp-block-list"><!-- wp:list-item -->
<li>strong portability requirements: multi-cloud, hybrid, or on-premise combined with cloud, where the Kubernetes manifest becomes a common denominator;</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>distributed architectures that apply 12-factor app principles and the "cattle" approach (interchangeable, stateless instances) with sophisticated orchestration needs;</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>strategic alignment with the CNCF ecosystem (Helm, Operators, ArgoCD, Istio, etc.) or client/partner prerequisites that impose the standard;</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>need for a shared platform across large teams, with a dedicated platform engineering team or the willingness to outsource that responsibility to a managed service.</li>
<!-- /wp:list-item --></ul>
<!-- /wp:list -->

<!-- wp:paragraph -->
<p>Conversely, in other contexts, a PaaS like Clever Cloud delivers the same outcomes as Kubernetes (industrialized deployments, autoscaling, resilience) without the operational complexity of the orchestrator. This is particularly true for standard application architectures (web + backend + database) where the effort of configuring and operating Kubernetes doesn't translate into tangible added value.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>And for intermediate workloads (IoT, edge, development environments, small clusters), the differences between K3S and K8S are worth weighing before deciding: the lightweight distribution is often a better fit. The de facto standard is not a moral obligation. It is a powerful and costly tool to operate, and its use should be chosen based on the problems it solves, often as a complement to other approaches rather than a replacement.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2 class="wp-block-heading">The Limits of the Standard: Operational Debt</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Running Kubernetes in production is not trivial. That's one of the reasons why many companies that adopt K8S opt for a managed service rather than a self-managed installation.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>The sources of complexity are numerous: configuring access control correctly (RBAC), choosing and operating a network plugin (CNI), wiring up persistent storage (CSI), setting up observability, managing certificates, performing minor and major upgrades without downtime, hardening security, managing control plane backups. Each of these topics is a discipline in itself. The CNCF 2025 report shows that challenges have actually shifted from purely technical to organizational: 47% of organizations now cite "cultural changes with the development team" as their top obstacle, ahead of raw technical complexity.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>At the heart of this debt sits a less-discussed component: <strong>etcd</strong>. It is the distributed key-value database that stores the complete state of the cluster. etcd is solid for moderately sized clusters, but becomes a bottleneck at scale. It's no coincidence that Google announced in late 2024 the replacement of etcd with Spanner for its managed GKE offering, retaining only the API compatibility layer. AWS, for its part, has built a "new generation" etcd architecture to handle scale. K3S, designed for lightweight environments, has pushed the logic further by offering several alternatives to etcd, including SQLite as the default. When the central component needs to be re-engineered to handle production use at scale, it's a telling sign.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>This realization is what led us, at Clever Cloud, to rethink this component. Our <a href="https://www.clever.cloud/clever-kubernetes-engine/">Clever Kubernetes Engine</a> replaces standard etcd with Materia etcd, our reimplementation of the etcd protocol built on top of <a href="https://www.clever.cloud/materia/materia-kv/">Materia KV</a> and FoundationDB, replicated across three Paris datacenters. This approach is also part of <a href="https://www.clever.cloud/blog/company/2026/04/08/what-makes-clever-cloud-unique/">what makes Clever Cloud unique</a>: a multi-tenant control plane that scales horizontally without degrading performance, benefits from FoundationDB’s continuous failure simulation model, and frees teams from managing thousands of fragile etcd instances.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>But whether you choose CKE or another service, the principle remains the same: if you want Kubernetes in production without building a dedicated platform engineering team, <a href="https://www.clever.cloud/blog/company/2026/04/27/cke-in-public-beta-managed-sovereign-and-properly-integrated-kubernetes/">a managed Kubernetes</a> is almost always the right decision.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2 class="wp-block-heading">In Summary</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Kubernetes became the standard for good technical reasons, but also thanks to an alignment of interests that drove the industry to converge around a neutral project governed by the CNCF. The core mechanism, the reconciliation loop and the declarative model, explains its robustness. The ecosystem that has built up around it explains its staying power.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>That doesn't mean it should be adopted for everything. For many contexts, a PaaS or another approach is a better fit, and in practice, the two often coexist within the same architecture, each where it delivers the most value. For serious distributed architectures, it remains the tool of reference, provided you account for the operational debt it introduces and choose between running it yourself or relying on a managed service.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>This is precisely the promise that<a href="https://www.clever.cloud/clever-kubernetes-engine/"> Clever Kubernetes Engine</a>, our managed Kubernetes, seeks to deliver: standard Kubernetes, operated in France on sovereign infrastructure, with a control plane redesigned to eliminate the friction of etcd at scale. And for teams that don't need Kubernetes, our PaaS remains the most direct path to production.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2 class="wp-block-heading">FAQ</h2>
<!-- /wp:heading -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">Are K8S and Kubernetes the same thing?</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Yes. K8S is an abbreviation: the letter K, followed by 8 (representing the eight letters in "ubernete"), followed by S. Both refer to the same container orchestration system.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">What is the difference between Docker and Kubernetes?</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Docker is a containerization engine: it packages an application with its dependencies into an image that runs as a container. Kubernetes is an orchestrator: it deploys, monitors, and scales those containers across a fleet of servers. This is one of the most commonly misunderstood distinctions in the ecosystem, even though the two tools serve different and complementary purposes.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">Is Kubernetes free?</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>The software is open source and free under the Apache 2.0 license. But the infrastructure it runs on, the engineering time to maintain it, and the complementary tools (monitoring, backups, security) have a real cost. That's why many companies opt for a managed Kubernetes offering.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">Do you always need Kubernetes for production deployments?</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>No. Kubernetes provides sophisticated orchestration, particularly suited to distributed architectures requiring portability, CNCF ecosystem alignment, or advanced orchestration. For many other contexts, a PaaS delivers the same outcomes (industrialized deployment, autoscaling, resilience) without the operational complexity. And in practice, the two approaches often coexist within the same architecture.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">What is the difference between K3S and K8S?</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>K3S is a CNCF-certified Kubernetes distribution (not a fork), designed to be lightweight and suited for resource-constrained environments: edge, IoT, development machines, small clusters. It replaces some components with lighter alternatives and ships as a single binary. The differences between K3S and K8S come down to several specific architectural choices worth evaluating before making a decision.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">How do I get started with Kubernetes?</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>The fastest way is to spin up a local cluster with Minikube, kind, or k3d, then deploy a simple application via a YAML manifest. For production, the reasonable choice for most teams is a managed Kubernetes offering.</p>
<!-- /wp:paragraph -->]]></description>
										<content:encoded><![CDATA[<p><img width="2499" height="1109" src="https://cdn.clever-cloud.com/uploads/2026/05/2026-05-19-clever-cloud-banniere-blog-k8s-en.png" class="attachment-post-thumbnail size-post-thumbnail wp-post-image" alt="2026.05.19 Clever Cloud Bannière Blog K8S EN" decoding="async" loading="lazy" srcset="https://cdn.clever-cloud.com/uploads/2026/05/2026-05-19-clever-cloud-banniere-blog-k8s-en.png 2499w, https://cdn.clever-cloud.com/uploads/2026/05/2026-05-19-clever-cloud-banniere-blog-k8s-en-300x133.png 300w, https://cdn.clever-cloud.com/uploads/2026/05/2026-05-19-clever-cloud-banniere-blog-k8s-en-1024x454.png 1024w, https://cdn.clever-cloud.com/uploads/2026/05/2026-05-19-clever-cloud-banniere-blog-k8s-en-768x341.png 768w, https://cdn.clever-cloud.com/uploads/2026/05/2026-05-19-clever-cloud-banniere-blog-k8s-en-1536x682.png 1536w, https://cdn.clever-cloud.com/uploads/2026/05/2026-05-19-clever-cloud-banniere-blog-k8s-en-2048x909.png 2048w, https://cdn.clever-cloud.com/uploads/2026/05/2026-05-19-clever-cloud-banniere-blog-k8s-en-1368x607.png 1368w" sizes="auto, (max-width: 2499px) 100vw, 2499px" /></p><!-- wp:heading -->
<h2 class="wp-block-heading">How Kubernetes Works: a Declarative Orchestrator</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Most descriptions of <a href="https://www.clever.cloud/product/kubernetes/">Kubernetes</a> list its components (pods, deployments, services) without explaining the central mechanism. The fundamental concept lies elsewhere: Kubernetes is first and foremost an <strong>orchestrator</strong>, and its core engine relies on a reconciliation loop.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>You don't tell Kubernetes <em>what to do</em>. You tell it <em>what you want your system to look like</em>. This distinction, declarative versus imperative, changes everything.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>In practice, you describe the desired state in manifest files, typically in YAML format: "I want 3 replicas of this image, exposed on port 80, with these environment variables." You submit this manifest to the Kubernetes API via kubectl. From that point on, Kubernetes continuously compares the actual state of the cluster (what is actually running) to the desired state (what you declared), and acts to bring them into alignment. If a node dies, its pods are rescheduled elsewhere. If you change from 3 to 10 replicas in the manifest, Kubernetes starts 7 more. If a container crashes, it gets restarted.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>This reconciliation loop is the heart of everything Kubernetes does: self-healing, scaling, rolling updates, and rollbacks. To dive deeper into this mechanism and the other capabilities it enables, learn more about container orchestration.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2 class="wp-block-heading">Architecture in Brief: Control Plane, Nodes, Pods</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>A Kubernetes cluster is divided into two parts. The <strong>control plane</strong> is the brain: it makes global decisions, accepts API requests, schedules workloads, and monitors the state of the cluster. It relies on a few key components, including the API server (kube-apiserver), the scheduler (kube-scheduler), and the controller manager (kube-controller-manager), along with a distributed data store that holds the entire cluster state, traditionally etcd.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p><strong>Nodes</strong> are the machines that actually run the workloads. On each node, an agent called kubelet receives instructions from the control plane and launches containers through a container runtime (containerd, CRI-O, etc.). The smallest deployable unit is not an individual container but a <strong>pod</strong>: one or more containers that share a network and storage. Higher-level objects (Deployment, Service, Ingress, ConfigMap, Secret) describe how pods should be managed, exposed, and configured.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>This architecture is also the source of a common confusion with Docker, whose role is actually complementary to Kubernetes rather than competitive.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2 class="wp-block-heading">Why K8S Became the Orchestration Standard</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>According to the<a href="https://www.cncf.io/reports/"> CNCF Annual Cloud Native Survey 2025</a>, published in January 2026, 98% of surveyed organizations have adopted <a href="https://www.clever.cloud/blog/company/2025/05/30/what-is-native-cloud/">cloud native</a> techniques, and 82% of container users deploy Kubernetes in production, up from 66% in 2023. The dominance is massive. But explaining it solely through technical qualities would be incomplete; it is also a story of ecosystem dynamics and aligned interests.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p><strong>On the technical side</strong>, three properties explain adoption. First, the declarative model described above: it makes deployments reproducible, versionable in Git, and resilient to failures. Second, portability: the same manifest works on a development machine (Minikube, kind, k3d), on an on-premise cluster, and on any cloud. Third, extensibility: the Kubernetes API accepts Custom Resource Definitions (CRDs) and custom controllers (Operators), turning it into a platform for building platforms. This triggered a massive ecosystem dynamic.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p><strong>On the strategic side</strong>, the story is less often told. By 2014, Google had more than a decade of experience managing containers at scale with its internal systems Borg and Omega, whose design principles were shared publicly through academic research papers (Omega in 2013, Borg in 2015). Rather than open-sourcing Borg itself, which remained tightly coupled to Google's proprietary infrastructure, the team created Kubernetes as a new project inspired by that experience, with a distinct implementation designed from the outset for external adoption. The project was released as open source in June 2014 and donated to the Cloud Native Computing Foundation in 2015. This neutrality, a project hosted by a Linux foundation rather than a cloud provider, proved decisive. No competitor could afford <em>not</em> to adopt it without being marginalized from the emerging cloud-native ecosystem. AWS, which initially pushed its own proprietary solution (ECS), announced EKS in late 2017 and launched it in general availability in June 2018. By then, the standard was sealed.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p><strong>On the ecosystem side</strong>, the network effect did the rest: Helm for packaging applications, Prometheus for monitoring, Istio and Linkerd for service mesh, ArgoCD and Flux for GitOps, Trivy and Falco for security. Each additional tool reinforces the value of the standard. On the talent side, Kubernetes skills have become massively in-demand across DevOps and SRE roles, creating a virtuous cycle: more trained engineers, more adopting companies, more engineers getting trained.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>In the CNCF 2025 report, the community now describes Kubernetes as "boring," using the term as the highest praise: a mature, predictable tool whose APIs no longer break with every release. That is exactly what you want from infrastructure that has become standard.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2 class="wp-block-heading">When Kubernetes Adds Value, and When Other Approaches Are a Better Fit</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>The fact that K8S is the standard doesn't mean it's the right answer to every problem. Choosing Kubernetes, a <a href="https://www.clever.cloud/clever-cloud-paas/">PaaS</a>, or a combination of both depends on the technical and organizational context; at Clever Cloud, many teams use both in parallel for different workloads.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Kubernetes delivers real value in several contexts:</p>
<!-- /wp:paragraph -->

<!-- wp:list -->
<ul class="wp-block-list"><!-- wp:list-item -->
<li>strong portability requirements: multi-cloud, hybrid, or on-premise combined with cloud, where the Kubernetes manifest becomes a common denominator;</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>distributed architectures that apply 12-factor app principles and the "cattle" approach (interchangeable, stateless instances) with sophisticated orchestration needs;</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>strategic alignment with the CNCF ecosystem (Helm, Operators, ArgoCD, Istio, etc.) or client/partner prerequisites that impose the standard;</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>need for a shared platform across large teams, with a dedicated platform engineering team or the willingness to outsource that responsibility to a managed service.</li>
<!-- /wp:list-item --></ul>
<!-- /wp:list -->

<!-- wp:paragraph -->
<p>Conversely, in other contexts, a PaaS like Clever Cloud delivers the same outcomes as Kubernetes (industrialized deployments, autoscaling, resilience) without the operational complexity of the orchestrator. This is particularly true for standard application architectures (web + backend + database) where the effort of configuring and operating Kubernetes doesn't translate into tangible added value.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>And for intermediate workloads (IoT, edge, development environments, small clusters), the differences between K3S and K8S are worth weighing before deciding: the lightweight distribution is often a better fit. The de facto standard is not a moral obligation. It is a powerful and costly tool to operate, and its use should be chosen based on the problems it solves, often as a complement to other approaches rather than a replacement.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2 class="wp-block-heading">The Limits of the Standard: Operational Debt</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Running Kubernetes in production is not trivial. That's one of the reasons why many companies that adopt K8S opt for a managed service rather than a self-managed installation.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>The sources of complexity are numerous: configuring access control correctly (RBAC), choosing and operating a network plugin (CNI), wiring up persistent storage (CSI), setting up observability, managing certificates, performing minor and major upgrades without downtime, hardening security, managing control plane backups. Each of these topics is a discipline in itself. The CNCF 2025 report shows that challenges have actually shifted from purely technical to organizational: 47% of organizations now cite "cultural changes with the development team" as their top obstacle, ahead of raw technical complexity.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>At the heart of this debt sits a less-discussed component: <strong>etcd</strong>. It is the distributed key-value database that stores the complete state of the cluster. etcd is solid for moderately sized clusters, but becomes a bottleneck at scale. It's no coincidence that Google announced in late 2024 the replacement of etcd with Spanner for its managed GKE offering, retaining only the API compatibility layer. AWS, for its part, has built a "new generation" etcd architecture to handle scale. K3S, designed for lightweight environments, has pushed the logic further by offering several alternatives to etcd, including SQLite as the default. When the central component needs to be re-engineered to handle production use at scale, it's a telling sign.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>This realization is what led us, at Clever Cloud, to rethink this component. Our <a href="https://www.clever.cloud/clever-kubernetes-engine/">Clever Kubernetes Engine</a> replaces standard etcd with Materia etcd, our reimplementation of the etcd protocol built on top of <a href="https://www.clever.cloud/materia/materia-kv/">Materia KV</a> and FoundationDB, replicated across three Paris datacenters. This approach is also part of <a href="https://www.clever.cloud/blog/company/2026/04/08/what-makes-clever-cloud-unique/">what makes Clever Cloud unique</a>: a multi-tenant control plane that scales horizontally without degrading performance, benefits from FoundationDB’s continuous failure simulation model, and frees teams from managing thousands of fragile etcd instances.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>But whether you choose CKE or another service, the principle remains the same: if you want Kubernetes in production without building a dedicated platform engineering team, <a href="https://www.clever.cloud/blog/company/2026/04/27/cke-in-public-beta-managed-sovereign-and-properly-integrated-kubernetes/">a managed Kubernetes</a> is almost always the right decision.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2 class="wp-block-heading">In Summary</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Kubernetes became the standard for good technical reasons, but also thanks to an alignment of interests that drove the industry to converge around a neutral project governed by the CNCF. The core mechanism, the reconciliation loop and the declarative model, explains its robustness. The ecosystem that has built up around it explains its staying power.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>That doesn't mean it should be adopted for everything. For many contexts, a PaaS or another approach is a better fit, and in practice, the two often coexist within the same architecture, each where it delivers the most value. For serious distributed architectures, it remains the tool of reference, provided you account for the operational debt it introduces and choose between running it yourself or relying on a managed service.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>This is precisely the promise that<a href="https://www.clever.cloud/clever-kubernetes-engine/"> Clever Kubernetes Engine</a>, our managed Kubernetes, seeks to deliver: standard Kubernetes, operated in France on sovereign infrastructure, with a control plane redesigned to eliminate the friction of etcd at scale. And for teams that don't need Kubernetes, our PaaS remains the most direct path to production.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2 class="wp-block-heading">FAQ</h2>
<!-- /wp:heading -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">Are K8S and Kubernetes the same thing?</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Yes. K8S is an abbreviation: the letter K, followed by 8 (representing the eight letters in "ubernete"), followed by S. Both refer to the same container orchestration system.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">What is the difference between Docker and Kubernetes?</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Docker is a containerization engine: it packages an application with its dependencies into an image that runs as a container. Kubernetes is an orchestrator: it deploys, monitors, and scales those containers across a fleet of servers. This is one of the most commonly misunderstood distinctions in the ecosystem, even though the two tools serve different and complementary purposes.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">Is Kubernetes free?</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>The software is open source and free under the Apache 2.0 license. But the infrastructure it runs on, the engineering time to maintain it, and the complementary tools (monitoring, backups, security) have a real cost. That's why many companies opt for a managed Kubernetes offering.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">Do you always need Kubernetes for production deployments?</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>No. Kubernetes provides sophisticated orchestration, particularly suited to distributed architectures requiring portability, CNCF ecosystem alignment, or advanced orchestration. For many other contexts, a PaaS delivers the same outcomes (industrialized deployment, autoscaling, resilience) without the operational complexity. And in practice, the two approaches often coexist within the same architecture.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">What is the difference between K3S and K8S?</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>K3S is a CNCF-certified Kubernetes distribution (not a fork), designed to be lightweight and suited for resource-constrained environments: edge, IoT, development machines, small clusters. It replaces some components with lighter alternatives and ships as a single binary. The differences between K3S and K8S come down to several specific architectural choices worth evaluating before making a decision.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">How do I get started with Kubernetes?</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>The fastest way is to spin up a local cluster with Minikube, kind, or k3d, then deploy a simple application via a YAML manifest. For production, the reasonable choice for most teams is a managed Kubernetes offering.</p>
<!-- /wp:paragraph -->]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Clever Cloud Takes Control of Its IP Prefix Announcements</title>
		<link>https://www.clever.cloud/blog/engineering/2026/05/04/clever-cloud-takes-control-of-its-ip-prefix-announcements/</link>
		
		<dc:creator><![CDATA[Arnaud Lefebvre]]></dc:creator>
		<pubDate>Mon, 04 May 2026 15:00:35 +0000</pubDate>
				<category><![CDATA[Engineering]]></category>
		<guid isPermaLink="false">https://www.clever.cloud/?p=23853</guid>

					<description><![CDATA[<p><img width="2499" height="1109" src="https://cdn.clever-cloud.com/uploads/2026/03/2026-03-17-clever-cloud-banniere-blog-clever-cloud-controle-lannonce-de-ses-prefixes-ip-en.png" class="attachment-post-thumbnail size-post-thumbnail wp-post-image" alt="2026 03 17 clever cloud banniere blog clever cloud controle lannonce de ses prefixes ip en" decoding="async" loading="lazy" srcset="https://cdn.clever-cloud.com/uploads/2026/03/2026-03-17-clever-cloud-banniere-blog-clever-cloud-controle-lannonce-de-ses-prefixes-ip-en.png 2499w, https://cdn.clever-cloud.com/uploads/2026/03/2026-03-17-clever-cloud-banniere-blog-clever-cloud-controle-lannonce-de-ses-prefixes-ip-en-300x133.png 300w, https://cdn.clever-cloud.com/uploads/2026/03/2026-03-17-clever-cloud-banniere-blog-clever-cloud-controle-lannonce-de-ses-prefixes-ip-en-1024x454.png 1024w, https://cdn.clever-cloud.com/uploads/2026/03/2026-03-17-clever-cloud-banniere-blog-clever-cloud-controle-lannonce-de-ses-prefixes-ip-en-768x341.png 768w, https://cdn.clever-cloud.com/uploads/2026/03/2026-03-17-clever-cloud-banniere-blog-clever-cloud-controle-lannonce-de-ses-prefixes-ip-en-1536x682.png 1536w, https://cdn.clever-cloud.com/uploads/2026/03/2026-03-17-clever-cloud-banniere-blog-clever-cloud-controle-lannonce-de-ses-prefixes-ip-en-2048x909.png 2048w, https://cdn.clever-cloud.com/uploads/2026/03/2026-03-17-clever-cloud-banniere-blog-clever-cloud-controle-lannonce-de-ses-prefixes-ip-en-1368x607.png 1368w" sizes="auto, (max-width: 2499px) 100vw, 2499px" /></p><!-- wp:paragraph -->
<p>This represents a major milestone that culminates three years of preparation and is part of our broader strategy to maintain complete control over our Paris region's network infrastructure.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2 class="wp-block-heading">Why We Made This Change</h2>
<!-- /wp:heading -->

<!-- wp:html -->
<div style="max-width:780px;margin:1.5rem auto;background:#0f172a;color:#e5eefc;border-radius:12px;padding:16px 20px;font-family:system-ui,-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,'Helvetica Neue',Arial,sans-serif;font-size:15px;line-height:1.7;box-shadow:0 1px 2px rgba(0,0,0,0.08);border:1px solid rgba(255,255,255,0.08);">
  <strong style="color:#e5eefc;">Note:</strong> Clever Cloud operates multiple regions worldwide. Paris is our main region — the largest, where we control the full stack: our own hardware, our own network, and now our own IP announcements. Other regions (hosted on OVH, Scaleway, Cloud Temple, Ionos, Oracle) rely on the underlying provider's infrastructure, including their network. The changes described in this article specifically concern our Paris region.
</div>
<!-- /wp:html -->

<!-- wp:paragraph -->
<p>In Clever Cloud's early years, we delegated network responsibility to partners. This approach made sense: it allowed us to accelerate development, focus on cloud services, and avoid investing in expertise we hadn't yet mastered. But as our infrastructure grew, the limitations of this dependency became clear. We had no control over strategic decisions — how traffic was routed across the Internet, which paths our packets took, or how quickly we could respond to failures. Every modification, every incident required the involvement of a third party.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>We decided to take this responsibility back. In doing so, we gained several concrete advantages. We optimize costs through direct management of our transit and peering relationships. We define our own routing policy instead of following an intermediary's constraints. We resolve incidents ourselves, without waiting for external providers. And we achieve complete control of our network stack — the same way we progressively took control of our servers and datacenters over the past few years.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>But this transition isn't just about our operational independence. It brings immediate, tangible benefits for you. The most critical is resilience. Previously, all traffic was routed through a single provider. Any incident on their side impacted every service we offered. We now maintain four upstream providers across three datacenters in the Paris area. When one link fails — and it has happened over the past year — traffic automatically shifts to available alternatives without customer-impacting interruption. We can even withstand the simultaneous loss of multiple transit links.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Beyond redundancy, we gain control over routing itself. We now decide how your traffic reaches its destination. This allows us to optimize paths for lower latency and better performance, and to adjust those decisions based on your specific needs and our network topology. We respond to congestion, to changing conditions, and to your requirements in real time.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Finally, there is the question of operational responsibility. Network issues no longer require us to wait for an external provider to acknowledge and resolve them. Public network failures fall directly under our responsibility — we detect them, analyze them, and fix them ourselves. This directly reduces the time between problem and resolution, which means less downtime and better reliability for our customers.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2 class="wp-block-heading">Operating Your Own Network on the Internet</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>To operate as an independent network on the Internet, organizations must work with a Regional Internet Registry (RIR). RIRs are responsible for allocating and managing IP addresses and AS numbers within specific geographical regions.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>There are five RIRs worldwide:</p>
<!-- /wp:paragraph -->

<!-- wp:list -->
<ul class="wp-block-list"><!-- wp:list-item -->
<li><strong>RIPE NCC</strong> — Europe, Central Asia, and the Middle East</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><strong>ARIN</strong> — North America (United States, Canada, and the Caribbean)</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><strong>LACNIC</strong> — Latin America and the Caribbean</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><strong>APNIC</strong> — Asia-Pacific region</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><strong>AFRINIC</strong> — Africa</li>
<!-- /wp:list-item --></ul>
<!-- /wp:list -->

<!-- wp:paragraph -->
<p>For Clever Cloud, since our infrastructure is primarily in Europe, we work with RIPE NCC (Réseaux Internet Publics Européens).</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">Allocated Address Space</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>As a member of a RIR, organizations receive allocations of both IPv4 and IPv6 address space. For RIPE NCC members, this typically includes a /24 block of IPv4 addresses (<a href="https://www.ripe.net/manage-ips-and-asns/ipv4/ipv4-waiting-list/">depending on the availability</a> of such a block) and a /29 block of IPv6 addresses. These allocations are managed under your membership and can be used to operate your network globally.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">Creating Our Autonomous System</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>The groundwork for this transition began several years ago. In 2019, we created our RIPE NCC account to become a LIR (Local Internet Registry). This gave us access to a /24 IPv4 block (91.208.207.0/24) and a /29 IPv6 block (2a0f:d0c0::/29).</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Then, in 2022, we registered our Autonomous System Number (ASN) with the Regional Internet Registry for our region. Our AS number is<a href="https://apps.db.ripe.net/db-web-ui/lookup?source=ripe&amp;key=AS213394&amp;type=aut-num"> AS213394</a>. Here is the aut-num object:</p>
<!-- /wp:paragraph -->

<!-- wp:html -->
<div style="display:flex;justify-content:center;">
<pre style="background:#0f172a;color:#e5eefc;border-radius:12px;padding:16px 20px;overflow-x:auto;white-space:pre;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,'Liberation Mono','Courier New',monospace;font-size:14px;line-height:1.6;margin:1.5rem 0;box-shadow:0 1px 2px rgba(0,0,0,0.08);max-width:900px;width:100%;"><code style="background:transparent;color:inherit;padding:0;font-size:inherit;font-family:inherit;">&gt; whois AS213394

aut-num:        AS213394
as-name:        CleverCloud
org:            ORG-CCS42-RIPE
import:         from AS29075 accept ANY
import:         from AS3257 accept ANY
import:         from AS3356 accept ANY
import:         from AS43424 accept ANY
export:         to AS29075 announce AS213394:AS-CLVRCLD
export:         to AS3257 announce AS213394:AS-CLVRCLD
export:         to AS3356 announce AS213394:AS-CLVRCLD
export:         to AS43424 announce AS213394:AS-CLVRCLD
admin-c:        QA171-RIPE
tech-c:         QA171-RIPE
status:         ASSIGNED
mnt-by:         RIPE-NCC-END-MNT
mnt-by:         mnt-fr-clvrcldnet-1
created:        2022-11-28T08:24:23Z
last-modified:  2025-02-25T16:36:15Z
source:         RIPE</code></pre>
</div>
<!-- /wp:html -->

<!-- wp:paragraph -->
<p>An Autonomous System Number (ASN) is a unique identifier for networks on the Internet. It's required to announce routes via BGP — the protocol that makes inter-network routing possible. Creating an AS early on allowed us to plan for this eventual transition and prepare the necessary infrastructure in advance.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Now that we have an ASN, we can start announcing our prefixes to other networks on the Internet using the BGP protocol.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">The Role of the RIPE Database</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>The RIPE NCC maintains a public database of routing objects (like the aut-num object above). Among these objects are route objects, which specify which AS is authorized to announce a particular IP prefix. In practice, these entries are primarily used by network operators and transit providers to build routing policy and filters (IRR-based filtering) to accept or deny announcements from their peers. This is one way to try to prevent BGP hijacks. By applying those filters to the routes you receive from your peers, you can limit the propagation of a prefix that originates from the wrong ASN.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Let's say that Org A owns 192.0.2.0/24 and announces it to Transit X. Transit X applies a filter on routes learned from Org A to only accept the IP prefixes that Org A has in its RIR database. This way, if Org A starts announcing a prefix it doesn't own (let's say our public prefix, 91.208.207.0/24), then Transit X is supposed to reject that route. This helps prevent the bad route from being propagated and traffic from being forwarded to the wrong entity.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>However, not all networks implement IRR filtering. Better mechanisms like ROA (Route Origin Authorization) exist to address this gap.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">The BGP Protocol: How the Internet Routes Traffic</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>To understand how we announce our prefixes on the Internet, it's essential to understand BGP — the Border Gateway Protocol. BGP is the de facto standard routing protocol of the Internet. It allows networks (Autonomous Systems) to exchange information about which IP prefixes they own and how to reach them.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>BGP works in both directions. When we announce to our peers and transit providers "we own 91.208.207.0/24", this announcement travels through the Internet from network to network. Each network that forwards our announcement prepends its own AS number to the AS_PATH — a list showing the sequence of networks a packet traverses to reach us. For example, OVHcloud (AS16276) sees the path [AS29075, AS213394]: traffic goes through one of our transit providers (AS29075), then reaches us (AS213394). Each network that forwards the announcement updates it this way, building a complete path. Here's an example using the<a href="https://lg.ovh.net/prefix_detail/lil1/ipv4?q=91.208.207.0/24"> OVHcloud Looking Glass service</a>:</p>
<!-- /wp:paragraph -->

<!-- wp:html -->
<div style="display:flex;justify-content:center;">
<pre style="background:#0f172a;color:#e5eefc;border-radius:12px;padding:16px 20px;overflow-x:auto;white-space:pre;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,'Liberation Mono','Courier New',monospace;font-size:14px;line-height:1.6;margin:1.5rem 0;box-shadow:0 1px 2px rgba(0,0,0,0.08);max-width:900px;width:100%;"><code style="background:transparent;color:inherit;padding:0;font-size:inherit;font-family:inherit;">&gt; show route for 91.208.207.0/24 all

91.208.207.0/24    via 172.18.16.0 on eno1 [lil1_rbx1_bagg1_8k 2025-12-25] * (100/0) [AS213394i]
    Type: BGP unicast univ
    BGP.origin: IGP
    BGP.as_path: 29075 213394
    BGP.next_hop: 172.18.16.0
    BGP.med: 161
    BGP.local_pref: 40
    BGP.community: (0,0) (29075,18000) (65535,65281)
    BGP.23 [t]: 00 00 b8 6e
                   via 172.18.16.64 on eno1 [lil1_rbx8_bagg1_8k 2025-12-25] (100/0) [AS213394i]</code></pre>
</div>
<!-- /wp:html -->

<!-- wp:paragraph -->
<p>At the same time, we receive announcements from other networks about their prefixes and the paths to reach them. This builds the opposite view: when we need to send traffic outbound, we know which path to take to reach any given destination. Here's an example with one of OVHcloud prefixes:</p>
<!-- /wp:paragraph -->

<!-- wp:html -->
<div style="display:flex;justify-content:center;">
<pre style="background:#0f172a;color:#e5eefc;border-radius:12px;padding:16px 20px;overflow-x:auto;white-space:pre;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,'Liberation Mono','Courier New',monospace;font-size:14px;line-height:1.6;margin:1.5rem 0;box-shadow:0 1px 2px rgba(0,0,0,0.08);max-width:900px;width:100%;"><code style="background:transparent;color:inherit;padding:0;font-size:inherit;font-family:inherit;">&gt; /routing/route/print detail where dst-address=5.39.0.0/17 and active

Ab   afi=ip4 contribution=active dst-address=5.39.0.0/17 routing-table=main pref-src=185.133.116.2 gateway=213.242.111.201 immediate-gw=213.242.111.201%sfp28-6 distance=20 scope=40 target-scope=10 belongs-to="bgp-IP-213.242.111.201"

      bgp.as-path="3356,16276" bgp.communities=3356:2,3356:2066,3356:22,16276:40001,3356:100,65002:7018,3356:123,3356:901,65002:701,65000:64990,65000:64995,65000:64996,3356:502 .med=0 .atomic-aggregate=no .origin=igp</code></pre>
</div>
<!-- /wp:html -->

<!-- wp:paragraph -->
<p>Here the network path OVHcloud uses to reach us is different from the one we use to reach them.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2 class="wp-block-heading">The Migration Process</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Our IP prefixes were entirely managed by our historical provider. While we legally owned the addresses, we delegated the technical responsibility of announcing them to the Internet to this single provider. This meant:</p>
<!-- /wp:paragraph -->

<!-- wp:list -->
<ul class="wp-block-list"><!-- wp:list-item -->
<li>Our provider's AS (AS43424) was listed as the origin of our prefixes in the Internet routing tables</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>All traffic destined for our services or outgoing to the Internet had to flow through their infrastructure</li>
<!-- /wp:list-item --></ul>
<!-- /wp:list -->

<!-- wp:html -->
<div style="display:flex;justify-content:center;">
<pre style="background:#0f172a;color:#e5eefc;border-radius:12px;padding:16px 20px;overflow-x:auto;white-space:pre;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,'Liberation Mono','Courier New',monospace;font-size:14px;line-height:1.6;margin:1.5rem 0;box-shadow:0 1px 2px rgba(0,0,0,0.08);border-left:4px solid #3b82f6;max-width:900px;width:100%;">Clever Cloud Services
   |
   | all inbound/outbound traffic
   v
Historical Provider (AS43424)
   |
   | originates: 91.208.207.0/24 (origin AS43424)
   v
Internet</pre>
</div>
<!-- /wp:html -->

<!-- wp:paragraph -->
<p>We now want our ASN to be the origin of the announcements. To migrate safely, we planned a three-step migration. The requirements were simple: we could not accept any customer-impacting interruption.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">Migrating a prefix between ASNs</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>To migrate a prefix from one AS to another, we needed to modify its route object in the RIPE database. The procedure was straightforward but required careful timing.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>First, we created a second route object in the RIPE database for our 91.208.207.0/24 prefix. Now both ASNs were registered as authorized to announce the same prefix — both our historical provider's AS and our own AS (213394).</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>These routing objects are publicly queryable via the whois command or through the RIPE web interface. For example, running whois -h whois.ripe.net -T route 91.208.207.0/24 returns both registered objects:</p>
<!-- /wp:paragraph -->

<!-- wp:html -->
<div style="display:flex;justify-content:center;">
<pre style="background:#0f172a;color:#e5eefc;border-radius:12px;padding:16px 20px;overflow-x:auto;white-space:pre;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,'Liberation Mono','Courier New',monospace;font-size:14px;line-height:1.6;margin:1.5rem 0;box-shadow:0 1px 2px rgba(0,0,0,0.08);max-width:900px;width:100%;"><code style="background:transparent;color:inherit;padding:0;font-size:inherit;font-family:inherit;">❯ whois -h whois.ripe.net -T route 91.208.207.0/24
% Information related to '91.208.207.0/24AS213394'

route:          91.208.207.0/24
mnt-by:         mnt-fr-clvrcldnet-1
descr:          CleverCloud subnet
origin:         AS213394
created:        2025-01-15T10:29:14Z
last-modified:  2025-01-15T10:29:14Z
source:         RIPE

% Information related to '91.208.207.0/24AS43424'

route:          91.208.207.0/24
mnt-by:         mnt-fr-clvrcldnet-1
mnt-by:         MAGICRETAIL-MNT
descr:          CleverCloud subnet
origin:         AS43424
created:        2020-02-13T09:06:33Z
last-modified:  2020-02-13T09:06:48Z
source:         RIPE</code></pre>
</div>
<!-- /wp:html -->

<!-- wp:paragraph -->
<p>Once this second route object was registered and propagated across the Internet (i.e., network operators pulled an up-to-date version of the RIPE database to build their routing filters), our new transit providers could see that our ASN was authorized to announce this prefix. At that point, we could begin announcing the prefix through our own infrastructure.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>If we didn't create that route object, our route announcement might have been rejected and we could have been flagged as BGP hijackers.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">Announcing Through Our Historical Provider</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Once the second route object was propagated, we performed the first step during the night of January 16, 2025: we began announcing the prefix ourselves via BGP to our historical provider. This was still using the same transit path, but now with Clever Cloud AS213394 originating the announcements instead of our historical provider. Our historical provider continued to relay the prefix, but now received it from us rather than announcing it directly.</p>
<!-- /wp:paragraph -->

<!-- wp:html -->
<div style="display:flex;justify-content:center;">
<pre style="background:#0f172a;color:#e5eefc;border-radius:12px;padding:16px 20px;overflow-x:auto;white-space:pre;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,'Liberation Mono','Courier New',monospace;font-size:14px;line-height:1.6;margin:1.5rem 0;box-shadow:0 1px 2px rgba(0,0,0,0.08);border-left:4px solid #3b82f6;max-width:900px;width:100%;">Clever Cloud Services (AS213394)
   |
   | originates: 91.208.207.0/24 (origin AS213394)
   v
Historical Provider (AS43424)
   |
   | re-announces: 91.208.207.0/24 (origin AS213394)
   v
Internet</pre>
</div>
<!-- /wp:html -->

<!-- wp:paragraph -->
<p>This first phase served as validation — if any issues arose, we could quickly revert without impacting other transit paths.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">Announcing Through Our Own Transits</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>A few days later, during the night of January 21, 2025, we took the final step: we began announcing the prefix through our own dedicated transit connections.</p>
<!-- /wp:paragraph -->

<!-- wp:html -->
<div style="display:flex;justify-content:center;">
<pre style="background:#0f172a;color:#e5eefc;border-radius:12px;padding:16px 20px;overflow-x:auto;white-space:pre;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,'Liberation Mono','Courier New',monospace;font-size:14px;line-height:1.6;margin:1.5rem 0;box-shadow:0 1px 2px rgba(0,0,0,0.08);border-left:4px solid #3b82f6;max-width:900px;width:100%;">Clever Cloud Services (AS213394)
   |
   | originates: 91.208.207.0/24 (origin AS213394)
   |
   +---+---+---+
   |   |   |   |
   v   v   v   v
  T1  T2  T3  HP
(Transit providers + historical provider)
   |   |   |   |
   +---+---+---+
   |
   v
Internet</pre>
</div>
<!-- /wp:html -->

<!-- wp:paragraph -->
<p>We now announce our prefixes directly to four upstream providers (three transit providers, T1/T2/T3, plus our historical provider HP). Traffic flows across all paths, and we have full control over routing decisions and redundancy.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Throughout both phases, we observed no customer-impacting interruption. The BGP protocol's built-in redundancy and the gradual nature of the transition ensured that traffic flowed smoothly regardless of which path was preferred at any given moment.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">Complete Internet Routing Visibility</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>As part of Phase 2, our three primary transit providers began sending us a "full view" of the Internet's routing table. This is the complete set of all publicly announced IPv4 and IPv6 prefixes — roughly ~1 million IPv4 routes and ~220,000 IPv6 routes.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>A full view gives us unprecedented visibility into how the Internet is structured and allows us to make sophisticated routing decisions. Rather than relying on a single provider's perspective, we now see all available paths to reach any destination on the Internet.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>With this information, we are able to:</p>
<!-- /wp:paragraph -->

<!-- wp:list -->
<ul class="wp-block-list"><!-- wp:list-item -->
<li><strong>Choose optimal paths</strong> for our outbound traffic based on our network topology and preferences</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><strong>Implement traffic engineering</strong> to direct flows through specific transit providers</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><strong>Respond dynamically</strong> to network conditions and congestion</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><strong>Balance load</strong> across our four transit connections based on real-time routing data</li>
<!-- /wp:list-item --></ul>
<!-- /wp:list -->

<!-- wp:paragraph -->
<p>This fine-grained control over our routing policy is a direct result of operating our own AS and managing our own announcements — exactly the kind of operational independence we sought when we began this transition.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2 class="wp-block-heading">One Year Later</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Nearly a year into operating our own network announcements, the transition has proven successful. We have experienced no major incidents, and our infrastructure has proven resilient. When minor issues have occurred — such as packet loss through a specific transit provider or the temporary loss of a transit link — traffic has automatically rebalanced across our remaining connections. We have been able to detect and respond to these issues directly, without waiting for a third-party provider to take action. Our customers experienced no customer-impacting interruption. This ability to own our problems and resolve them quickly is perhaps the greatest benefit we've gained.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">What's Next</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>This transition is far from finished. We have several roadmap items ahead of us:</p>
<!-- /wp:paragraph -->

<!-- wp:list -->
<ul class="wp-block-list"><!-- wp:list-item -->
<li><strong>Increased network capacity</strong> to handle growing traffic demands</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><strong>BGP peering</strong> with other networks to optimize traffic locally without paying for transit</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><strong>ROA (Route Origin Authorization)</strong> deployment to cryptographically sign our route announcements and prevent unauthorized parties from hijacking our prefixes</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><strong>RPKI (Resource Public Key Infrastructure) validation</strong> to ensure the legitimacy of announcements we receive from other networks and protect against prefix hijacking attacks</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><strong>IPv6 expansion</strong>, both inbound (accepting IPv6 traffic) and outbound (sending IPv6 traffic) — a transition we will roll out in phases</li>
<!-- /wp:list-item --></ul>
<!-- /wp:list -->

<!-- wp:heading -->
<h2 class="wp-block-heading">Conclusion</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>In early 2025, Clever Cloud completed its transition to fully independent network operations. We now announce our own IP prefixes through four upstream providers, giving us full authority over how traffic flows in and out of our infrastructure.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>For our customers, this translates to better reliability and faster problem resolution in our Paris region. When network issues occur, we handle them directly — and our multi-provider redundancy ensures traffic keeps flowing even when incidents occur.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>This milestone is just the beginning. We're already working on BGP peering to optimize local traffic, ROA signing and RPKI validation to strengthen routing security, and IPv6 expansion to fully embrace dual-stack connectivity. We're building a network as robust and self-sufficient as the rest of our infrastructure — and we're excited about what comes next.</p>
<!-- /wp:paragraph -->]]></description>
										<content:encoded><![CDATA[<p><img width="2499" height="1109" src="https://cdn.clever-cloud.com/uploads/2026/03/2026-03-17-clever-cloud-banniere-blog-clever-cloud-controle-lannonce-de-ses-prefixes-ip-en.png" class="attachment-post-thumbnail size-post-thumbnail wp-post-image" alt="2026 03 17 clever cloud banniere blog clever cloud controle lannonce de ses prefixes ip en" decoding="async" loading="lazy" srcset="https://cdn.clever-cloud.com/uploads/2026/03/2026-03-17-clever-cloud-banniere-blog-clever-cloud-controle-lannonce-de-ses-prefixes-ip-en.png 2499w, https://cdn.clever-cloud.com/uploads/2026/03/2026-03-17-clever-cloud-banniere-blog-clever-cloud-controle-lannonce-de-ses-prefixes-ip-en-300x133.png 300w, https://cdn.clever-cloud.com/uploads/2026/03/2026-03-17-clever-cloud-banniere-blog-clever-cloud-controle-lannonce-de-ses-prefixes-ip-en-1024x454.png 1024w, https://cdn.clever-cloud.com/uploads/2026/03/2026-03-17-clever-cloud-banniere-blog-clever-cloud-controle-lannonce-de-ses-prefixes-ip-en-768x341.png 768w, https://cdn.clever-cloud.com/uploads/2026/03/2026-03-17-clever-cloud-banniere-blog-clever-cloud-controle-lannonce-de-ses-prefixes-ip-en-1536x682.png 1536w, https://cdn.clever-cloud.com/uploads/2026/03/2026-03-17-clever-cloud-banniere-blog-clever-cloud-controle-lannonce-de-ses-prefixes-ip-en-2048x909.png 2048w, https://cdn.clever-cloud.com/uploads/2026/03/2026-03-17-clever-cloud-banniere-blog-clever-cloud-controle-lannonce-de-ses-prefixes-ip-en-1368x607.png 1368w" sizes="auto, (max-width: 2499px) 100vw, 2499px" /></p><!-- wp:paragraph -->
<p>This represents a major milestone that culminates three years of preparation and is part of our broader strategy to maintain complete control over our Paris region's network infrastructure.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2 class="wp-block-heading">Why We Made This Change</h2>
<!-- /wp:heading -->

<!-- wp:html -->
<div style="max-width:780px;margin:1.5rem auto;background:#0f172a;color:#e5eefc;border-radius:12px;padding:16px 20px;font-family:system-ui,-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,'Helvetica Neue',Arial,sans-serif;font-size:15px;line-height:1.7;box-shadow:0 1px 2px rgba(0,0,0,0.08);border:1px solid rgba(255,255,255,0.08);">
  <strong style="color:#e5eefc;">Note:</strong> Clever Cloud operates multiple regions worldwide. Paris is our main region — the largest, where we control the full stack: our own hardware, our own network, and now our own IP announcements. Other regions (hosted on OVH, Scaleway, Cloud Temple, Ionos, Oracle) rely on the underlying provider's infrastructure, including their network. The changes described in this article specifically concern our Paris region.
</div>
<!-- /wp:html -->

<!-- wp:paragraph -->
<p>In Clever Cloud's early years, we delegated network responsibility to partners. This approach made sense: it allowed us to accelerate development, focus on cloud services, and avoid investing in expertise we hadn't yet mastered. But as our infrastructure grew, the limitations of this dependency became clear. We had no control over strategic decisions — how traffic was routed across the Internet, which paths our packets took, or how quickly we could respond to failures. Every modification, every incident required the involvement of a third party.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>We decided to take this responsibility back. In doing so, we gained several concrete advantages. We optimize costs through direct management of our transit and peering relationships. We define our own routing policy instead of following an intermediary's constraints. We resolve incidents ourselves, without waiting for external providers. And we achieve complete control of our network stack — the same way we progressively took control of our servers and datacenters over the past few years.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>But this transition isn't just about our operational independence. It brings immediate, tangible benefits for you. The most critical is resilience. Previously, all traffic was routed through a single provider. Any incident on their side impacted every service we offered. We now maintain four upstream providers across three datacenters in the Paris area. When one link fails — and it has happened over the past year — traffic automatically shifts to available alternatives without customer-impacting interruption. We can even withstand the simultaneous loss of multiple transit links.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Beyond redundancy, we gain control over routing itself. We now decide how your traffic reaches its destination. This allows us to optimize paths for lower latency and better performance, and to adjust those decisions based on your specific needs and our network topology. We respond to congestion, to changing conditions, and to your requirements in real time.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Finally, there is the question of operational responsibility. Network issues no longer require us to wait for an external provider to acknowledge and resolve them. Public network failures fall directly under our responsibility — we detect them, analyze them, and fix them ourselves. This directly reduces the time between problem and resolution, which means less downtime and better reliability for our customers.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2 class="wp-block-heading">Operating Your Own Network on the Internet</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>To operate as an independent network on the Internet, organizations must work with a Regional Internet Registry (RIR). RIRs are responsible for allocating and managing IP addresses and AS numbers within specific geographical regions.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>There are five RIRs worldwide:</p>
<!-- /wp:paragraph -->

<!-- wp:list -->
<ul class="wp-block-list"><!-- wp:list-item -->
<li><strong>RIPE NCC</strong> — Europe, Central Asia, and the Middle East</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><strong>ARIN</strong> — North America (United States, Canada, and the Caribbean)</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><strong>LACNIC</strong> — Latin America and the Caribbean</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><strong>APNIC</strong> — Asia-Pacific region</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><strong>AFRINIC</strong> — Africa</li>
<!-- /wp:list-item --></ul>
<!-- /wp:list -->

<!-- wp:paragraph -->
<p>For Clever Cloud, since our infrastructure is primarily in Europe, we work with RIPE NCC (Réseaux Internet Publics Européens).</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">Allocated Address Space</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>As a member of a RIR, organizations receive allocations of both IPv4 and IPv6 address space. For RIPE NCC members, this typically includes a /24 block of IPv4 addresses (<a href="https://www.ripe.net/manage-ips-and-asns/ipv4/ipv4-waiting-list/">depending on the availability</a> of such a block) and a /29 block of IPv6 addresses. These allocations are managed under your membership and can be used to operate your network globally.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">Creating Our Autonomous System</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>The groundwork for this transition began several years ago. In 2019, we created our RIPE NCC account to become a LIR (Local Internet Registry). This gave us access to a /24 IPv4 block (91.208.207.0/24) and a /29 IPv6 block (2a0f:d0c0::/29).</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Then, in 2022, we registered our Autonomous System Number (ASN) with the Regional Internet Registry for our region. Our AS number is<a href="https://apps.db.ripe.net/db-web-ui/lookup?source=ripe&amp;key=AS213394&amp;type=aut-num"> AS213394</a>. Here is the aut-num object:</p>
<!-- /wp:paragraph -->

<!-- wp:html -->
<div style="display:flex;justify-content:center;">
<pre style="background:#0f172a;color:#e5eefc;border-radius:12px;padding:16px 20px;overflow-x:auto;white-space:pre;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,'Liberation Mono','Courier New',monospace;font-size:14px;line-height:1.6;margin:1.5rem 0;box-shadow:0 1px 2px rgba(0,0,0,0.08);max-width:900px;width:100%;"><code style="background:transparent;color:inherit;padding:0;font-size:inherit;font-family:inherit;">&gt; whois AS213394

aut-num:        AS213394
as-name:        CleverCloud
org:            ORG-CCS42-RIPE
import:         from AS29075 accept ANY
import:         from AS3257 accept ANY
import:         from AS3356 accept ANY
import:         from AS43424 accept ANY
export:         to AS29075 announce AS213394:AS-CLVRCLD
export:         to AS3257 announce AS213394:AS-CLVRCLD
export:         to AS3356 announce AS213394:AS-CLVRCLD
export:         to AS43424 announce AS213394:AS-CLVRCLD
admin-c:        QA171-RIPE
tech-c:         QA171-RIPE
status:         ASSIGNED
mnt-by:         RIPE-NCC-END-MNT
mnt-by:         mnt-fr-clvrcldnet-1
created:        2022-11-28T08:24:23Z
last-modified:  2025-02-25T16:36:15Z
source:         RIPE</code></pre>
</div>
<!-- /wp:html -->

<!-- wp:paragraph -->
<p>An Autonomous System Number (ASN) is a unique identifier for networks on the Internet. It's required to announce routes via BGP — the protocol that makes inter-network routing possible. Creating an AS early on allowed us to plan for this eventual transition and prepare the necessary infrastructure in advance.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Now that we have an ASN, we can start announcing our prefixes to other networks on the Internet using the BGP protocol.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">The Role of the RIPE Database</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>The RIPE NCC maintains a public database of routing objects (like the aut-num object above). Among these objects are route objects, which specify which AS is authorized to announce a particular IP prefix. In practice, these entries are primarily used by network operators and transit providers to build routing policy and filters (IRR-based filtering) to accept or deny announcements from their peers. This is one way to try to prevent BGP hijacks. By applying those filters to the routes you receive from your peers, you can limit the propagation of a prefix that originates from the wrong ASN.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Let's say that Org A owns 192.0.2.0/24 and announces it to Transit X. Transit X applies a filter on routes learned from Org A to only accept the IP prefixes that Org A has in its RIR database. This way, if Org A starts announcing a prefix it doesn't own (let's say our public prefix, 91.208.207.0/24), then Transit X is supposed to reject that route. This helps prevent the bad route from being propagated and traffic from being forwarded to the wrong entity.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>However, not all networks implement IRR filtering. Better mechanisms like ROA (Route Origin Authorization) exist to address this gap.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">The BGP Protocol: How the Internet Routes Traffic</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>To understand how we announce our prefixes on the Internet, it's essential to understand BGP — the Border Gateway Protocol. BGP is the de facto standard routing protocol of the Internet. It allows networks (Autonomous Systems) to exchange information about which IP prefixes they own and how to reach them.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>BGP works in both directions. When we announce to our peers and transit providers "we own 91.208.207.0/24", this announcement travels through the Internet from network to network. Each network that forwards our announcement prepends its own AS number to the AS_PATH — a list showing the sequence of networks a packet traverses to reach us. For example, OVHcloud (AS16276) sees the path [AS29075, AS213394]: traffic goes through one of our transit providers (AS29075), then reaches us (AS213394). Each network that forwards the announcement updates it this way, building a complete path. Here's an example using the<a href="https://lg.ovh.net/prefix_detail/lil1/ipv4?q=91.208.207.0/24"> OVHcloud Looking Glass service</a>:</p>
<!-- /wp:paragraph -->

<!-- wp:html -->
<div style="display:flex;justify-content:center;">
<pre style="background:#0f172a;color:#e5eefc;border-radius:12px;padding:16px 20px;overflow-x:auto;white-space:pre;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,'Liberation Mono','Courier New',monospace;font-size:14px;line-height:1.6;margin:1.5rem 0;box-shadow:0 1px 2px rgba(0,0,0,0.08);max-width:900px;width:100%;"><code style="background:transparent;color:inherit;padding:0;font-size:inherit;font-family:inherit;">&gt; show route for 91.208.207.0/24 all

91.208.207.0/24    via 172.18.16.0 on eno1 [lil1_rbx1_bagg1_8k 2025-12-25] * (100/0) [AS213394i]
    Type: BGP unicast univ
    BGP.origin: IGP
    BGP.as_path: 29075 213394
    BGP.next_hop: 172.18.16.0
    BGP.med: 161
    BGP.local_pref: 40
    BGP.community: (0,0) (29075,18000) (65535,65281)
    BGP.23 [t]: 00 00 b8 6e
                   via 172.18.16.64 on eno1 [lil1_rbx8_bagg1_8k 2025-12-25] (100/0) [AS213394i]</code></pre>
</div>
<!-- /wp:html -->

<!-- wp:paragraph -->
<p>At the same time, we receive announcements from other networks about their prefixes and the paths to reach them. This builds the opposite view: when we need to send traffic outbound, we know which path to take to reach any given destination. Here's an example with one of OVHcloud prefixes:</p>
<!-- /wp:paragraph -->

<!-- wp:html -->
<div style="display:flex;justify-content:center;">
<pre style="background:#0f172a;color:#e5eefc;border-radius:12px;padding:16px 20px;overflow-x:auto;white-space:pre;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,'Liberation Mono','Courier New',monospace;font-size:14px;line-height:1.6;margin:1.5rem 0;box-shadow:0 1px 2px rgba(0,0,0,0.08);max-width:900px;width:100%;"><code style="background:transparent;color:inherit;padding:0;font-size:inherit;font-family:inherit;">&gt; /routing/route/print detail where dst-address=5.39.0.0/17 and active

Ab   afi=ip4 contribution=active dst-address=5.39.0.0/17 routing-table=main pref-src=185.133.116.2 gateway=213.242.111.201 immediate-gw=213.242.111.201%sfp28-6 distance=20 scope=40 target-scope=10 belongs-to="bgp-IP-213.242.111.201"

      bgp.as-path="3356,16276" bgp.communities=3356:2,3356:2066,3356:22,16276:40001,3356:100,65002:7018,3356:123,3356:901,65002:701,65000:64990,65000:64995,65000:64996,3356:502 .med=0 .atomic-aggregate=no .origin=igp</code></pre>
</div>
<!-- /wp:html -->

<!-- wp:paragraph -->
<p>Here the network path OVHcloud uses to reach us is different from the one we use to reach them.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2 class="wp-block-heading">The Migration Process</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Our IP prefixes were entirely managed by our historical provider. While we legally owned the addresses, we delegated the technical responsibility of announcing them to the Internet to this single provider. This meant:</p>
<!-- /wp:paragraph -->

<!-- wp:list -->
<ul class="wp-block-list"><!-- wp:list-item -->
<li>Our provider's AS (AS43424) was listed as the origin of our prefixes in the Internet routing tables</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>All traffic destined for our services or outgoing to the Internet had to flow through their infrastructure</li>
<!-- /wp:list-item --></ul>
<!-- /wp:list -->

<!-- wp:html -->
<div style="display:flex;justify-content:center;">
<pre style="background:#0f172a;color:#e5eefc;border-radius:12px;padding:16px 20px;overflow-x:auto;white-space:pre;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,'Liberation Mono','Courier New',monospace;font-size:14px;line-height:1.6;margin:1.5rem 0;box-shadow:0 1px 2px rgba(0,0,0,0.08);border-left:4px solid #3b82f6;max-width:900px;width:100%;">Clever Cloud Services
   |
   | all inbound/outbound traffic
   v
Historical Provider (AS43424)
   |
   | originates: 91.208.207.0/24 (origin AS43424)
   v
Internet</pre>
</div>
<!-- /wp:html -->

<!-- wp:paragraph -->
<p>We now want our ASN to be the origin of the announcements. To migrate safely, we planned a three-step migration. The requirements were simple: we could not accept any customer-impacting interruption.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">Migrating a prefix between ASNs</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>To migrate a prefix from one AS to another, we needed to modify its route object in the RIPE database. The procedure was straightforward but required careful timing.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>First, we created a second route object in the RIPE database for our 91.208.207.0/24 prefix. Now both ASNs were registered as authorized to announce the same prefix — both our historical provider's AS and our own AS (213394).</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>These routing objects are publicly queryable via the whois command or through the RIPE web interface. For example, running whois -h whois.ripe.net -T route 91.208.207.0/24 returns both registered objects:</p>
<!-- /wp:paragraph -->

<!-- wp:html -->
<div style="display:flex;justify-content:center;">
<pre style="background:#0f172a;color:#e5eefc;border-radius:12px;padding:16px 20px;overflow-x:auto;white-space:pre;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,'Liberation Mono','Courier New',monospace;font-size:14px;line-height:1.6;margin:1.5rem 0;box-shadow:0 1px 2px rgba(0,0,0,0.08);max-width:900px;width:100%;"><code style="background:transparent;color:inherit;padding:0;font-size:inherit;font-family:inherit;">❯ whois -h whois.ripe.net -T route 91.208.207.0/24
% Information related to '91.208.207.0/24AS213394'

route:          91.208.207.0/24
mnt-by:         mnt-fr-clvrcldnet-1
descr:          CleverCloud subnet
origin:         AS213394
created:        2025-01-15T10:29:14Z
last-modified:  2025-01-15T10:29:14Z
source:         RIPE

% Information related to '91.208.207.0/24AS43424'

route:          91.208.207.0/24
mnt-by:         mnt-fr-clvrcldnet-1
mnt-by:         MAGICRETAIL-MNT
descr:          CleverCloud subnet
origin:         AS43424
created:        2020-02-13T09:06:33Z
last-modified:  2020-02-13T09:06:48Z
source:         RIPE</code></pre>
</div>
<!-- /wp:html -->

<!-- wp:paragraph -->
<p>Once this second route object was registered and propagated across the Internet (i.e., network operators pulled an up-to-date version of the RIPE database to build their routing filters), our new transit providers could see that our ASN was authorized to announce this prefix. At that point, we could begin announcing the prefix through our own infrastructure.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>If we didn't create that route object, our route announcement might have been rejected and we could have been flagged as BGP hijackers.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">Announcing Through Our Historical Provider</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Once the second route object was propagated, we performed the first step during the night of January 16, 2025: we began announcing the prefix ourselves via BGP to our historical provider. This was still using the same transit path, but now with Clever Cloud AS213394 originating the announcements instead of our historical provider. Our historical provider continued to relay the prefix, but now received it from us rather than announcing it directly.</p>
<!-- /wp:paragraph -->

<!-- wp:html -->
<div style="display:flex;justify-content:center;">
<pre style="background:#0f172a;color:#e5eefc;border-radius:12px;padding:16px 20px;overflow-x:auto;white-space:pre;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,'Liberation Mono','Courier New',monospace;font-size:14px;line-height:1.6;margin:1.5rem 0;box-shadow:0 1px 2px rgba(0,0,0,0.08);border-left:4px solid #3b82f6;max-width:900px;width:100%;">Clever Cloud Services (AS213394)
   |
   | originates: 91.208.207.0/24 (origin AS213394)
   v
Historical Provider (AS43424)
   |
   | re-announces: 91.208.207.0/24 (origin AS213394)
   v
Internet</pre>
</div>
<!-- /wp:html -->

<!-- wp:paragraph -->
<p>This first phase served as validation — if any issues arose, we could quickly revert without impacting other transit paths.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">Announcing Through Our Own Transits</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>A few days later, during the night of January 21, 2025, we took the final step: we began announcing the prefix through our own dedicated transit connections.</p>
<!-- /wp:paragraph -->

<!-- wp:html -->
<div style="display:flex;justify-content:center;">
<pre style="background:#0f172a;color:#e5eefc;border-radius:12px;padding:16px 20px;overflow-x:auto;white-space:pre;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,'Liberation Mono','Courier New',monospace;font-size:14px;line-height:1.6;margin:1.5rem 0;box-shadow:0 1px 2px rgba(0,0,0,0.08);border-left:4px solid #3b82f6;max-width:900px;width:100%;">Clever Cloud Services (AS213394)
   |
   | originates: 91.208.207.0/24 (origin AS213394)
   |
   +---+---+---+
   |   |   |   |
   v   v   v   v
  T1  T2  T3  HP
(Transit providers + historical provider)
   |   |   |   |
   +---+---+---+
   |
   v
Internet</pre>
</div>
<!-- /wp:html -->

<!-- wp:paragraph -->
<p>We now announce our prefixes directly to four upstream providers (three transit providers, T1/T2/T3, plus our historical provider HP). Traffic flows across all paths, and we have full control over routing decisions and redundancy.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Throughout both phases, we observed no customer-impacting interruption. The BGP protocol's built-in redundancy and the gradual nature of the transition ensured that traffic flowed smoothly regardless of which path was preferred at any given moment.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">Complete Internet Routing Visibility</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>As part of Phase 2, our three primary transit providers began sending us a "full view" of the Internet's routing table. This is the complete set of all publicly announced IPv4 and IPv6 prefixes — roughly ~1 million IPv4 routes and ~220,000 IPv6 routes.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>A full view gives us unprecedented visibility into how the Internet is structured and allows us to make sophisticated routing decisions. Rather than relying on a single provider's perspective, we now see all available paths to reach any destination on the Internet.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>With this information, we are able to:</p>
<!-- /wp:paragraph -->

<!-- wp:list -->
<ul class="wp-block-list"><!-- wp:list-item -->
<li><strong>Choose optimal paths</strong> for our outbound traffic based on our network topology and preferences</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><strong>Implement traffic engineering</strong> to direct flows through specific transit providers</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><strong>Respond dynamically</strong> to network conditions and congestion</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><strong>Balance load</strong> across our four transit connections based on real-time routing data</li>
<!-- /wp:list-item --></ul>
<!-- /wp:list -->

<!-- wp:paragraph -->
<p>This fine-grained control over our routing policy is a direct result of operating our own AS and managing our own announcements — exactly the kind of operational independence we sought when we began this transition.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2 class="wp-block-heading">One Year Later</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Nearly a year into operating our own network announcements, the transition has proven successful. We have experienced no major incidents, and our infrastructure has proven resilient. When minor issues have occurred — such as packet loss through a specific transit provider or the temporary loss of a transit link — traffic has automatically rebalanced across our remaining connections. We have been able to detect and respond to these issues directly, without waiting for a third-party provider to take action. Our customers experienced no customer-impacting interruption. This ability to own our problems and resolve them quickly is perhaps the greatest benefit we've gained.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">What's Next</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>This transition is far from finished. We have several roadmap items ahead of us:</p>
<!-- /wp:paragraph -->

<!-- wp:list -->
<ul class="wp-block-list"><!-- wp:list-item -->
<li><strong>Increased network capacity</strong> to handle growing traffic demands</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><strong>BGP peering</strong> with other networks to optimize traffic locally without paying for transit</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><strong>ROA (Route Origin Authorization)</strong> deployment to cryptographically sign our route announcements and prevent unauthorized parties from hijacking our prefixes</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><strong>RPKI (Resource Public Key Infrastructure) validation</strong> to ensure the legitimacy of announcements we receive from other networks and protect against prefix hijacking attacks</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><strong>IPv6 expansion</strong>, both inbound (accepting IPv6 traffic) and outbound (sending IPv6 traffic) — a transition we will roll out in phases</li>
<!-- /wp:list-item --></ul>
<!-- /wp:list -->

<!-- wp:heading -->
<h2 class="wp-block-heading">Conclusion</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>In early 2025, Clever Cloud completed its transition to fully independent network operations. We now announce our own IP prefixes through four upstream providers, giving us full authority over how traffic flows in and out of our infrastructure.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>For our customers, this translates to better reliability and faster problem resolution in our Paris region. When network issues occur, we handle them directly — and our multi-provider redundancy ensures traffic keeps flowing even when incidents occur.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>This milestone is just the beginning. We're already working on BGP peering to optimize local traffic, ROA signing and RPKI validation to strengthen routing security, and IPv6 expansion to fully embrace dual-stack connectivity. We're building a network as robust and self-sufficient as the rest of our infrastructure — and we're excited about what comes next.</p>
<!-- /wp:paragraph -->]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
