<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Csi on Backend Engineering Strategy Tools</title><link>https://backend-engineering-strategy-tools.github.io/site/tags/csi/</link><description>Recent content in Csi on Backend Engineering Strategy Tools</description><generator>Hugo -- gohugo.io</generator><language>en-us</language><lastBuildDate>Thu, 14 May 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://backend-engineering-strategy-tools.github.io/site/tags/csi/index.xml" rel="self" type="application/rss+xml"/><item><title>Rook</title><link>https://backend-engineering-strategy-tools.github.io/site/public-notes/kubernetes/rook/</link><pubDate>Thu, 14 May 2026 00:00:00 +0000</pubDate><guid>https://backend-engineering-strategy-tools.github.io/site/public-notes/kubernetes/rook/</guid><description>&lt;p&gt;Rook is a Kubernetes operator that deploys and manages storage systems — primarily &lt;a class="link" href="https://backend-engineering-strategy-tools.github.io/site/public-notes/cloud-infrastructure/ceph/" &gt;Ceph&lt;/a&gt; — as native Kubernetes resources. The distinction: Ceph is the storage system; Rook is the Kubernetes wiring around it.&lt;/p&gt;
&lt;p&gt;Without Rook you would run Ceph manually (or via &lt;code&gt;cephadm&lt;/code&gt;) and then configure the Kubernetes CSI driver separately. Rook collapses that into CRDs and handles the full lifecycle: deployment, configuration, expansion, upgrades, and failure recovery.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="how-it-works"&gt;How it works
&lt;/h2&gt;&lt;p&gt;Rook introduces several CRDs:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;CephCluster&lt;/strong&gt; — declares the cluster: which nodes, which disks to use as OSDs, replication settings.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;CephBlockPool&lt;/strong&gt; — defines a Ceph pool (replication factor, failure domain). Maps to an RBD pool.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;StorageClass&lt;/strong&gt; — references a CephBlockPool and enables dynamic PVC provisioning. Kubernetes workloads request storage; Rook/Ceph fulfils it.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;CephFilesystem&lt;/strong&gt; — deploys CephFS + MDS for POSIX shared filesystem access.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;CephObjectStore&lt;/strong&gt; — deploys the Ceph RGW S3-compatible object storage gateway.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="typical-install-sequence"&gt;Typical install sequence
&lt;/h2&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;kubectl apply -f https://raw.githubusercontent.com/rook/rook/refs/tags/v1.17.9/deploy/examples/crds.yaml
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;kubectl apply -f https://raw.githubusercontent.com/rook/rook/refs/tags/v1.17.9/deploy/examples/common.yaml
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;kubectl apply -f https://raw.githubusercontent.com/rook/rook/refs/tags/v1.17.9/deploy/examples/operator.yaml
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Then apply a &lt;code&gt;CephCluster&lt;/code&gt; manifest declaring your storage topology, followed by &lt;code&gt;CephBlockPool&lt;/code&gt; and &lt;code&gt;StorageClass&lt;/code&gt; for PVC support.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="single-node-considerations"&gt;Single-node considerations
&lt;/h2&gt;&lt;p&gt;A single-node setup requires &lt;code&gt;allowMultiplePerNode: true&lt;/code&gt; in the &lt;code&gt;CephCluster&lt;/code&gt; spec (MONs, MGR, and OSDs all land on the same node). Replication &lt;code&gt;size&lt;/code&gt; must be set to &lt;code&gt;1&lt;/code&gt; — there is nowhere else to replicate. This works for experimentation; it is not a production configuration. See &lt;a class="link" href="https://backend-engineering-strategy-tools.github.io/site/public-notes/cloud-infrastructure/ceph/" &gt;Ceph&lt;/a&gt; for details on the replication model.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="related"&gt;Related
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://rook.io/docs/rook/latest/" target="_blank" rel="noopener"
 &gt;Rook documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://backend-engineering-strategy-tools.github.io/site/public-notes/cloud-infrastructure/ceph/" &gt;Ceph&lt;/a&gt; — the underlying storage system&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://backend-engineering-strategy-tools.github.io/site/homelab/rook-ceph/" &gt;Rook + Ceph in the homelab&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Managing Secrets in Kubernetes</title><link>https://backend-engineering-strategy-tools.github.io/site/public-notes/kubernetes/k8s-secrets/</link><pubDate>Mon, 01 Jan 2024 00:00:00 +0000</pubDate><guid>https://backend-engineering-strategy-tools.github.io/site/public-notes/kubernetes/k8s-secrets/</guid><description>&lt;p&gt;Kubernetes has a built-in &lt;code&gt;Secret&lt;/code&gt; resource, but it is not a secrets management solution — it is base64-encoded storage with no encryption at rest by default and no access audit trail. How you actually manage secrets in a Kubernetes cluster depends on how far you need to go beyond the default.&lt;/p&gt;
&lt;h2 id="native-kubernetes-secrets"&gt;Native Kubernetes Secrets
&lt;/h2&gt;&lt;p&gt;The baseline. A &lt;code&gt;Secret&lt;/code&gt; is a key-value store mounted into pods as environment variables or files:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;apiVersion&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;v1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;kind&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;Secret&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;metadata&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;name&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;db-credentials&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;type&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;Opaque&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;data&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;username&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;YWRtaW4= &lt;/span&gt; &lt;span style="color:#75715e"&gt;# base64(&amp;#34;admin&amp;#34;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;password&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;cGFzc3dvcmQ=&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The problems: base64 is encoding, not encryption. Secrets are stored in etcd — enabling etcd encryption at rest is a cluster configuration step that is easy to skip. Secrets are visible to anyone with &lt;code&gt;kubectl get secret&lt;/code&gt; in that namespace. For anything beyond a local dev cluster or a low-sensitivity workload, you need something more.&lt;/p&gt;
&lt;h2 id="sealed-secrets"&gt;Sealed Secrets
&lt;/h2&gt;&lt;p&gt;A Kubernetes controller from Bitnami. &lt;code&gt;SealedSecret&lt;/code&gt; resources contain secrets encrypted with the cluster&amp;rsquo;s public key — only the controller running in that cluster can decrypt them. The encrypted form is safe to commit to Git, which makes GitOps workflows possible without a separate secrets store. Simple to operate, no external dependency. The tradeoff: secrets are tied to a specific cluster&amp;rsquo;s key, cross-cluster sharing requires re-encryption, and there is no centralised audit trail.&lt;/p&gt;
&lt;h2 id="external-secrets-operator"&gt;External Secrets Operator
&lt;/h2&gt;&lt;p&gt;ESO reads secrets from an external store (AWS Secrets Manager, HashiCorp Vault, GCP Secret Manager, Azure Key Vault, 1Password) and syncs them into native Kubernetes Secrets. Your source of truth stays in the external system; the K8s Secret is a read-only projection of it, refreshed on a configurable interval:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;apiVersion&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;external-secrets.io/v1beta1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;kind&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;ExternalSecret&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;metadata&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;name&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;db-credentials&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;spec&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;refreshInterval&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;1h&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;secretStoreRef&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;name&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;aws-secrets-manager&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;kind&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;ClusterSecretStore&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;target&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;name&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;db-credentials&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;data&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#f92672"&gt;secretKey&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;password&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;remoteRef&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;key&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;prod/db/password&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;ESO is the right choice when you already have a secrets store and want Kubernetes workloads to consume from it without changing how secrets are managed elsewhere.&lt;/p&gt;
&lt;h2 id="secrets-store-csi-driver"&gt;Secrets Store CSI Driver
&lt;/h2&gt;&lt;p&gt;An alternative to ESO for the same problem: mount secrets from an external store directly as files in a pod, without creating a Kubernetes Secret at all. The secret materialises only in the pod&amp;rsquo;s filesystem, is not stored in etcd, and disappears when the pod terminates. Supported by AWS, Azure, GCP, and Vault providers. Used in combination with a &lt;code&gt;SecretProviderClass&lt;/code&gt; to define what to fetch and where to mount it.&lt;/p&gt;
&lt;h2 id="hashicorp-vault"&gt;HashiCorp Vault
&lt;/h2&gt;&lt;p&gt;A dedicated secrets management platform. Vault stores arbitrary secrets, issues dynamic credentials (database passwords that expire, AWS IAM credentials valid for an hour), manages PKI, and provides a full audit log of every read and write. Kubernetes workloads authenticate to Vault via the Kubernetes auth method (using the pod&amp;rsquo;s service account token) and receive a Vault token scoped to the secrets their service account is allowed to read. More to operate than the other options, but the right answer for organisations that need dynamic credentials, fine-grained access control, and audit logs.&lt;/p&gt;
&lt;h2 id="summary"&gt;Summary
&lt;/h2&gt;&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;Approach&lt;/th&gt;
 &lt;th&gt;Good for&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;Native Secrets&lt;/td&gt;
 &lt;td&gt;Local dev, low-sensitivity workloads&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Sealed Secrets&lt;/td&gt;
 &lt;td&gt;GitOps, single-cluster, no external dependency&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;External Secrets Operator&lt;/td&gt;
 &lt;td&gt;Syncing from existing external stores&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Secrets Store CSI&lt;/td&gt;
 &lt;td&gt;Avoiding etcd entirely, file-based secret injection&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;HashiCorp Vault&lt;/td&gt;
 &lt;td&gt;Dynamic credentials, audit logs, enterprise requirements&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="resources"&gt;Resources
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://github.com/bitnami-labs/sealed-secrets" target="_blank" rel="noopener"
 &gt;Sealed Secrets&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://external-secrets.io/" target="_blank" rel="noopener"
 &gt;External Secrets Operator&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://secrets-store-csi-driver.sigs.k8s.io/" target="_blank" rel="noopener"
 &gt;Secrets Store CSI Driver&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://developer.hashicorp.com/vault/docs/platform/k8s" target="_blank" rel="noopener"
 &gt;HashiCorp Vault on Kubernetes&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item></channel></rss>