|
| 1 | +--- |
| 2 | +title: "CNPG Recipe 22 - Leveraging the New Supply Chain and Image Catalogs" |
| 3 | +date: 2025-10-06T12:23:56+02:00 |
| 4 | +description: "Leverage a new, fully-controlled software supply chain and streamlined Image Catalogs for safer, simpler, and more declarative management of PostgreSQL on Kubernetes" |
| 5 | +tags: |
| 6 | + - postgresql |
| 7 | + - postgres |
| 8 | + - kubernetes |
| 9 | + - k8s |
| 10 | + - data on kubernetes |
| 11 | + - dok |
| 12 | + - cloudnativepg |
| 13 | + - cnpg |
| 14 | + - supply chain |
| 15 | + - container images |
| 16 | + - image catalogs |
| 17 | + - sbom |
| 18 | + - security |
| 19 | + - devsecops |
| 20 | + - upgrades |
| 21 | + - extensions |
| 22 | + - snyk |
| 23 | + - cosign |
| 24 | + - sigstore |
| 25 | + - tutorial |
| 26 | + - guide |
| 27 | +cover: cover.jpg |
| 28 | +thumb: thumb.jpg |
| 29 | +draft: false |
| 30 | +--- |
| 31 | + |
| 32 | +_This CNPG Recipe explores the latest enhancements to CloudNativePG's software |
| 33 | +supply chain and image management. Learn how our new, fully controlled build |
| 34 | +process—complete with Snyk scanning, image signing, and SBOMs—delivers smaller, |
| 35 | +more secure PostgreSQL images. We also detail how to leverage the newly |
| 36 | +streamlined image catalogs for simplified, declarative cluster management and |
| 37 | +safer fleet-wide upgrades in Kubernetes._ |
| 38 | + |
| 39 | +<!--more--> |
| 40 | + |
| 41 | +--- |
| 42 | + |
| 43 | +The container image is the most fundamental building block of a database in |
| 44 | +Kubernetes. As the [Data on Kubernetes (DoK) community](https://dok.community/) |
| 45 | +continues to grow and mature, managing the source, version, and security of |
| 46 | +this supply chain is critical for any production-grade data service. |
| 47 | + |
| 48 | +That's why I'm thrilled to announce a foundational improvement in how we build |
| 49 | +and source the official [PostgreSQL operand images](https://github.com/cloudnative-pg/postgres-containers) |
| 50 | +for CloudNativePG. |
| 51 | + |
| 52 | +This evolution significantly enhances security and reliability, improves the |
| 53 | +user experience around image management, and paves a more modular future for |
| 54 | +PostgreSQL on Kubernetes. |
| 55 | + |
| 56 | +In line with this, we have also converted our [PostGIS container images](https://github.com/cloudnative-pg/postgis-containers) |
| 57 | +to follow the same high standards as the main PostgreSQL images. |
| 58 | + |
| 59 | +## Taking Full Control of Our PostgreSQL Images |
| 60 | + |
| 61 | +First, we at CloudNativePG are making a landmark change to the operand images. |
| 62 | +We have definitively moved away from using the official `postgres` image from |
| 63 | +Docker Hub, which has accompanied the project since it was open-sourced. |
| 64 | + |
| 65 | +Instead, we have transitioned to a **new software supply chain, built from the |
| 66 | +ground up with `docker bake`, that is entirely under the control of the |
| 67 | +CloudNativePG project**. While the images continue to be hosted at the standard |
| 68 | +registry, their origin and build process are now fundamentally more secure and |
| 69 | +robust. |
| 70 | + |
| 71 | +This new, transparent, and secure supply chain provides several key guarantees: |
| 72 | + |
| 73 | +- **Vulnerability Scanning:** Every image is continuously scanned for |
| 74 | + vulnerabilities with **Snyk**, allowing us to react faster to newly |
| 75 | + discovered CVEs. |
| 76 | +- **Image Signing:** All images are cryptographically signed using |
| 77 | + **sigstore/cosign**. This provides a guarantee that the images you use were |
| 78 | + built by our pipeline and have not been tampered with. |
| 79 | +- **Software Bill of Materials (SBOM):** We generate and distribute an SBOM for |
| 80 | + each image, providing a complete inventory of every software component and |
| 81 | + dependency for full transparency. |
| 82 | +- **Optimised Multi-Arch Builds:** Our new `docker bake` pipeline is designed |
| 83 | + from the start to efficiently produce multi-architecture images (**amd64** |
| 84 | + and **arm64**), ensuring first-class support for diverse Kubernetes |
| 85 | + environments. |
| 86 | + |
| 87 | +## Image Catalogs, Perfected: A Reliable New Distribution Pipeline |
| 88 | + |
| 89 | +[**Image Catalogs**](https://cloudnative-pg.io/documentation/current/image_catalog/) |
| 90 | +have been a powerful feature in CloudNativePG for over two years, allowing you |
| 91 | +to decouple your cluster configuration from specific image tags. However, the |
| 92 | +responsibility of creating and maintaining the catalog manifests often fell |
| 93 | +to you, the user. |
| 94 | + |
| 95 | +Today, we are removing that friction completely. Our new, trusted distribution |
| 96 | +pipeline now provides a reliable, central source for these catalogs. Now, |
| 97 | +instead of managing these files yourself, you can install the complete, |
| 98 | +[officially maintained catalog](https://www.google.com/search?q=https://github.com/cloudnative-pg/artifacts/tree/main/image-catalogs) |
| 99 | +with a single command: |
| 100 | + |
| 101 | +```sh |
| 102 | +# Deploy all supported PostgreSQL version catalogs to your cluster |
| 103 | +kubectl apply -k \ |
| 104 | + https://github.com/cloudnative-pg/artifacts/image-catalogs?ref=main |
| 105 | +``` |
| 106 | + |
| 107 | +Once applied, you can verify that the catalogs have been successfully created |
| 108 | +in your cluster with the following command: |
| 109 | + |
| 110 | +```sh |
| 111 | +kubectl get clusterimagecatalogs.postgresql.cnpg.io |
| 112 | +``` |
| 113 | + |
| 114 | +You should see an output similar to this, listing all the available catalogue |
| 115 | +options with format `postgresql-<type>-<debian_version>`: |
| 116 | + |
| 117 | +```console |
| 118 | +NAME AGE |
| 119 | +postgresql-minimal-bookworm 19s |
| 120 | +postgresql-minimal-bullseye 19s |
| 121 | +postgresql-minimal-trixie 19s |
| 122 | +postgresql-standard-bookworm 19s |
| 123 | +postgresql-standard-bullseye 19s |
| 124 | +postgresql-standard-trixie 19s |
| 125 | +postgresql-system-bookworm 19s |
| 126 | +postgresql-system-bullseye 19s |
| 127 | +postgresql-system-trixie 19s |
| 128 | +``` |
| 129 | + |
| 130 | +To inspect a specific catalog and see the exact image versions it contains, you |
| 131 | +can use `kubectl describe`: |
| 132 | + |
| 133 | +```sh |
| 134 | +kubectl describe clusterimagecatalogs.postgresql.cnpg.io \ |
| 135 | + postgresql-minimal-trixie |
| 136 | +``` |
| 137 | + |
| 138 | +This reveals the mapping between each major PostgreSQL version and the precise, |
| 139 | +immutable container image digest that will be used: |
| 140 | + |
| 141 | +``` |
| 142 | +Name: postgresql-minimal-trixie |
| 143 | +... |
| 144 | +Spec: |
| 145 | + Images: |
| 146 | + Image: ghcr.io/cloudnative-pg/postgresql:16.10-202509290807-minimal-trixie@sha256:f69b49dc63c2988a358c58f8a1311ac98719846f91d8e97186eaf65c7085cf28 |
| 147 | + Major: 16 |
| 148 | + Image: ghcr.io/cloudnative-pg/postgresql:17.6-202509290807-minimal-trixie@sha256:f3e24407db6eb8c3c9a7cb433cfe81cbff006ba1f97ae9844a58c7d3cd8048d7 |
| 149 | + Major: 17 |
| 150 | + Image: ghcr.io/cloudnative-pg/postgresql:18.0-202509290807-minimal-trixie@sha256:dd7c678167cc6d06c2caf4e6ea7bc7a89e39754bc7e0111a81f5d75ac3068f70 |
| 151 | + Major: 18 |
| 152 | +... |
| 153 | +``` |
| 154 | + |
| 155 | +## Putting it to Work: Referencing the Catalog in a Cluster |
| 156 | + |
| 157 | +Once the catalogs are installed, using them in your `Cluster` manifest is |
| 158 | +simple and powerful. Instead of a hardcoded `imageName`, you can use |
| 159 | +`imageCatalogRef` to select both a catalog and a specific major version from |
| 160 | +it. |
| 161 | + |
| 162 | +```yaml |
| 163 | +{{< include "yaml/angus.yaml" >}} |
| 164 | +``` |
| 165 | + |
| 166 | +This elegant abstraction allows your manifest to declare its *intent*. In this |
| 167 | +case, you're requesting a cluster using the `postgresql-minimal-trixie` |
| 168 | +catalog, and pinning it specifically to **major version 18**. |
| 169 | + |
| 170 | +After the cluster is up and running, you can `describe` it to see how the |
| 171 | +operator has resolved your request into a specific image digest in the `Status` |
| 172 | +section: |
| 173 | + |
| 174 | +```sh |
| 175 | +kubectl describe cluster angus |
| 176 | +``` |
| 177 | + |
| 178 | +Notice how the `imageCatalogRef` from the `Spec` is translated into a concrete |
| 179 | +`Image` in the `Status`: |
| 180 | + |
| 181 | +``` |
| 182 | +... |
| 183 | +Spec: |
| 184 | + Image Catalog Ref: |
| 185 | + API Group: postgresql.cnpg.io |
| 186 | + Kind: ClusterImageCatalog |
| 187 | + Major: 18 |
| 188 | + Name: postgresql-minimal-trixie |
| 189 | +... |
| 190 | +Status: |
| 191 | +... |
| 192 | + Image: ghcr.io/cloudnative-pg/postgresql:18.0-202509290807-minimal-trixie@sha256:dd7c678167cc6d06c2caf4e6ea7bc7a89e39754bc7e0111a81f5d75ac3068f70 |
| 193 | +... |
| 194 | +``` |
| 195 | + |
| 196 | +## The Grand Finale: Safe, Automated Fleet Upgrades |
| 197 | + |
| 198 | +This improved system truly shines when managing a database fleet at scale. When |
| 199 | +you update the Image Catalog in your cluster, all related clusters will be |
| 200 | +scheduled for a rolling update. To prevent a "thundering herd" that could |
| 201 | +overwhelm your system, you can control the rollout globally. |
| 202 | + |
| 203 | +This feature, called **spread upgrades**, is configured in the operator's main |
| 204 | +`ConfigMap`. By setting the `CLUSTERS_ROLLOUT_DELAY` variable, you instruct the |
| 205 | +operator to wait a specific number of seconds before starting the update on the |
| 206 | +next cluster. |
| 207 | + |
| 208 | +For example, to set a 2-minute delay between each cluster update: |
| 209 | + |
| 210 | +```yaml |
| 211 | +{{< include "yaml/operator-config.yaml" >}} |
| 212 | +``` |
| 213 | + |
| 214 | +This is a powerful and simple way to ensure a safe, controlled, and completely |
| 215 | +automated rollout of updates across your entire database fleet. |
| 216 | + |
| 217 | +## A More Declarative and Modular Future |
| 218 | + |
| 219 | +These improvements—a fully controlled supply chain and a reliable distribution |
| 220 | +pipeline for catalogs—are more than just operational conveniences. |
| 221 | +They are foundational steps towards a more secure and modular architecture for |
| 222 | +running PostgreSQL on Kubernetes. Our ultimate goal is to ship "minimal" |
| 223 | +PostgreSQL images containing only the core database engine. |
| 224 | + |
| 225 | +This vision is realised through another powerful feature called "extension |
| 226 | +image volumes". Instead of bundling every possible extension into a single, |
| 227 | +monolithic image, each extension is packaged in its own separate image. |
| 228 | + |
| 229 | +A newborn project, [PostgreSQL Extension Containers](https://github.com/cloudnative-pg/postgres-extensions-containers), |
| 230 | +will contain these images. |
| 231 | + |
| 232 | +When needed, CloudNativePG dynamically loads it into your PostgreSQL pod. |
| 233 | + |
| 234 | +This combined approach is the future: |
| 235 | + |
| 236 | +- **Enhanced Security:** Your core database has a **smaller surface attack**. |
| 237 | +- **Modularity and Flexibility:** Manage, version, and update extensions |
| 238 | + independently of the PostgreSQL engine. |
| 239 | + |
| 240 | +The image catalogs are the control plane that makes this modular ecosystem |
| 241 | +possible, providing the robust, declarative mechanism to manage the entire |
| 242 | +suite of components that power your applications. |
| 243 | + |
| 244 | +## Get Started Today |
| 245 | + |
| 246 | +First, I want to thank the entire CloudNativePG team for completing this epic |
| 247 | +enhancement, which we started at the beginning of the year. I am really proud |
| 248 | +of the result we have achieved from every aspect: operations, security, and |
| 249 | +extensibility. |
| 250 | + |
| 251 | +The fact that the [PostgreSQL 18 minimal image is now ~230MB]({{< relref "../20250926-postgresql-18/index.md" >}}) |
| 252 | +—45% smaller than the equivalent for PostgreSQL 17—is a major step forward. The |
| 253 | +image catalogue artifacts are also an important achievement for |
| 254 | +standardisation, simplifying integration into any deployment. |
| 255 | + |
| 256 | +I encourage you to adopt this new, simplified workflow for image catalogs |
| 257 | +today. You can get started by applying them from our |
| 258 | +[`artifacts` repository](https://github.com/cloudnative-pg/artifacts/tree/main/image-catalogs). |
| 259 | + |
| 260 | +For a deeper dive, check out the official documentation on [image catalogs](https://cloudnative-pg.io/documentation/current/image_catalog/) |
| 261 | +and [spread upgrades](https://cloudnative-pg.io/documentation/current/installation_upgrade/#spread-upgrades). |
| 262 | + |
| 263 | +To see where this is headed, I invite you to read my previous article on |
| 264 | +["The Immutable Future of PostgreSQL Extensions"]({{< relref "../20250303-volume-source-extension-control-path/index.md" >}}) |
| 265 | +and the official docs on [extension image volumes](https://cloudnative-pg.io/documentation/current/imagevolume_extensions/). |
| 266 | + |
| 267 | +--- |
| 268 | + |
| 269 | +Stay tuned for the upcoming recipes! For the latest updates, consider |
| 270 | +subscribing to my [LinkedIn](https://www.linkedin.com/in/gbartolini/) and |
| 271 | +[Twitter](https://twitter.com/_GBartolini_) channels. |
| 272 | + |
| 273 | +If you found this article informative, feel free to share it within your |
| 274 | +network on social media using the provided links below. Your support is |
| 275 | +immensely appreciated! |
0 commit comments