<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>Postgresql on ege.dev</title>
    <link>https://ege.dev/tags/postgresql/</link>
    <description>Hello. I&#39;m Ege.</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>en</language>
    <copyright>&#169; 2026 ege.dev</copyright>
    <lastBuildDate>Tue, 19 May 2026 18:15:35 +0000</lastBuildDate>
    <atom:link href="https://ege.dev/tags/postgresql/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>watching it shatter</title>
      <link>https://ege.dev/entries/2026/03/watching-it-shatter/</link>
      <pubDate>Fri, 06 Mar 2026 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">https://ege.dev/entries/2026/03/watching-it-shatter/</guid>
      <description>&lt;p&gt;This week, just like the previous, was filled with PostgreSQL (PG). I’m still working on v2.9.0 release of the PG operator.&lt;/p&gt;
&lt;p&gt;Last week I merged the implementation of pg_tde to bring data-at-rest encryption to Kubernetes. Then we started doing QA: oh boy, did it ever surface problems!&lt;/p&gt;
&lt;p&gt;One of the goals of v2.9.0 is declaring major version upgrades production-ready. So we decided to test the upgrade with TDE enabled. Boom, &lt;a href=&#34;https://perconadev.atlassian.net/browse/PG-2240&#34;&gt;data corruption&lt;/a&gt;. &lt;a href=&#34;https://perconadev.atlassian.net/browse/PG-2239&#34;&gt;Point-in-time recovery&lt;/a&gt; is problematic, &lt;a href=&#34;https://perconadev.atlassian.net/browse/PG-2234&#34;&gt;pg_rewind&lt;/a&gt; too…&lt;/p&gt;
&lt;p&gt;This is one of my favorite things about Kubernetes. You put something fragile on it and watch it shatter. Of course I need to give credit to our QA engineers: they don’t stop until they watch the software crumbling in pain.&lt;/p&gt;
&lt;p&gt;Outside of PG stuff, I opened &lt;a href=&#34;https://github.com/bergerx/kubectl-status/pull/590&#34;&gt;a small PR&lt;/a&gt; for adding volume mount information to kubectl-status plugin. I needed to quickly check mounts for a few containers while testing PG major upgrades and did a quick implementation with Claude. Before opening the PR, I was unsure whether I should mention that the code was written by Claude. I still feel embarrassed about using AI code generation. In the end I decided to openly admit it because it’s the right thing to do. I also want our contributors to be open about their usage of AI (I know they use AI).&lt;/p&gt;
&lt;p&gt;Speaking of AI code generation, I feel that the vibe has shifted significantly. I see the pessimists have accepted defeat and I am one of them: AI can write code and the code is not crap. It’s not 2023 anymore and it looks like it’s time to update my priors. I am trying to integrate Claude Code into my workflows and I had a bunch of positive interactions with it the last few weeks. I am also coding a big feature using Claude just for the sake of the experience.​​​​​​​​​​​​​​​​&lt;/p&gt;
</description>
      <category>postgresql</category>
      <category>kubernetes</category>
    </item>
    <item>
      <title>Encrypt PostgreSQL Data at Rest on Kubernetes</title>
      <link>https://ege.dev/entries/2025/02/encrypt-postgresql-data-at-rest-on-kubernetes/</link>
      <pubDate>Fri, 07 Feb 2025 15:10:57 +0300</pubDate>
      <guid isPermaLink="false">https://ege.dev/entries/2025/02/encrypt-postgresql-data-at-rest-on-kubernetes/</guid>
      <description>&lt;p&gt;The upcoming Percona Operator for PostgreSQL v2.6.0 release introduces support
for PostgreSQL 17, which opens exciting possibilities for data security. Since
&lt;a href=&#34;https://github.com/percona/pg_tde&#34;&gt;pg_tde&lt;/a&gt; comes pre-installed in Percona’s
official PostgreSQL 17 images, this release presents an excellent opportunity
to implement Transparent Data Encryption in your Kubernetes-deployed databases.
Let’s look at how to configure and use pg_tde with the Percona PostgreSQL
Operator.&lt;/p&gt;
&lt;h3 id=&#34;understanding-pg_tde&#34;&gt;Understanding pg_tde&lt;/h3&gt;
&lt;p&gt;Transparent Data Encryption (TDE) offers encryption at the table level and
solves the problem of protecting data at rest. The Percona Distribution for
PostgreSQL currently offers the only open source implementation of TDE for
PostgreSQL. The encryption is transparent for users, allowing them to access
and manipulate the data without requiring application modifications.&lt;/p&gt;
&lt;p&gt;While pg_tde has a build available for PostgreSQL Community Server, the
extension leverages extended APIs introduced in Percona Server for PostgreSQL
to provide more complete and performant encryption. You can read more about the
pg_tde extension in the &lt;a href=&#34;https://www.percona.com/blog/open-source-postgresql-pg-tde-beta/&#34;&gt;TDE beta announcement blog
post&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The new Percona Operator release will include pg_tde pre-installed with
PostgreSQL 17, simplifying the implementation of encryption at rest. Note:
Currently, pg_tde is in the beta phase. Please try it out on non-production
setups and &lt;a href=&#34;https://github.com/percona/pg_tde/discussions/151&#34;&gt;share your feedback&lt;/a&gt;!&lt;/p&gt;
&lt;h3 id=&#34;initial-configuration&#34;&gt;Initial configuration&lt;/h3&gt;
&lt;p&gt;To begin, we need to configure PostgreSQL to load pg_tde during startup. This
configuration is managed through the deploy/cr.yaml file:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;patroni:
  dynamicConfiguration:
    postgresql:
      parameters:
        shared_preload_libraries: pg_tde
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;After updating the configuration, apply it and restart your PostgreSQL pods:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;kubectl apply -f deploy/cr.yaml

for sts in $(kubectl get statefulset -o name | grep cluster1-instance1); do
    kubectl rollout restart $sts
done
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;Note: Attempting to enable pg_tde without properly configuring
shared_preload_libraries will result in an error indicating that pg_tde can
only be loaded at server startup.&lt;/strong&gt;&lt;/p&gt;
&lt;h3 id=&#34;secure-key-management-with-hashicorp-vault&#34;&gt;Secure key management with HashiCorp Vault&lt;/h3&gt;
&lt;p&gt;While pg_tde supports file-based key storage, it is recommended that production
environments use a Key Management Service such as HashiCorp Vault or OpenBao to
ensure secure key management.&lt;/p&gt;
&lt;p&gt;Deploy Vault in your Kubernetes cluster:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;helm repo add hashicorp https://helm.releases.hashicorp.com
helm install vault hashicorp/vault 
  --disable-openapi-validation 
  --version 0.16.1 
  --namespace vault 
  --set dataStorage.enabled=false 
  --set global.logLevel=trace 
  --set global.platform=kubernetes
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;After deploying Vault, we need to initialize it and obtain the root token. This
process involves creating an initial set of encryption keys and unsealing the
Vault instance:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;kubectl exec -it vault-0 -- vault operator init 
  -tls-skip-verify 
  -key-shares=1 
  -key-threshold=1 
  -format=json &amp;gt;vault.json

unsealKey=$(jq -r &amp;#34;.unseal_keys_b64[]&amp;#34; &amp;lt;vault.json)
token=$(jq -r &amp;#34;.root_token&amp;#34; &amp;lt;vault.json)

kubectl exec -it vault-0 -- vault operator unseal -tls-skip-verify &amp;#34;$unsealKey&amp;#34;

kubectl exec -it vault-0 -- sh -c 
  &amp;#34;export VAULT_TOKEN=$token &amp;amp;&amp;amp; 
   export VAULT_LOG_LEVEL=trace &amp;amp;&amp;amp; 
   vault secrets enable --version=1 -tls-skip-verify -path=secret kv&amp;#34;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now, we can configure pg_tde to use Vault as the key provider:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;SELECT pg_tde_add_key_provider_vault_v2(
  &amp;#39;vault-provider&amp;#39;,
  &amp;#39;&amp;lt;rootToken&amp;gt;&amp;#39;,
  &amp;#39;http://vault.vault.svc.cluster.local:8200&amp;#39;,
  &amp;#39;secret&amp;#39;,
  NULL
);

SELECT pg_tde_set_principal_key(&amp;#39;tde-principal-key&amp;#39;,&amp;#39;vault-provider&amp;#39;);
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;creating-encrypted-tables&#34;&gt;Creating encrypted tables&lt;/h3&gt;
&lt;p&gt;Percona Server for PostgreSQL offers two encryption methods:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;tde_heap&lt;/strong&gt;: Available exclusively in Percona Server for PostgreSQL 17,
this method provides comprehensive encryption of tuples, Write Ahead Log
(WAL), and indexes with optimized performance.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;tde_heap_basic&lt;/strong&gt;: Compatible with Community PostgreSQL 16 and 17, this
method encrypts tuples and WAL. Unfortunately this method does not encrypt
indexes, which is an important limitation to the production use cases.
Considering the performance limitations of this method encrypting/decrypting
data whenever it enters/exits shared buffers it is not recommended to use this
method in production use cases.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;When using Percona Server for PostgreSQL images, we can utilize the more comprehensive tde_heap method:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;CREATE TABLE encrypted_data (
  id INTEGER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
  t text not null
) USING tde_heap;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Verify the encryption status of your table:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;SELECT pg_tde_is_encrypted(&amp;#39;encrypted_data&amp;#39;);
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;For more detailed information about pg_tde capabilities and configurations,
please refer to the &lt;a href=&#34;https://percona.github.io/pg_tde/main/index.html&#34;&gt;official Percona documentation&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;current-implementation-status-and-future-plans&#34;&gt;Current implementation status and future plans&lt;/h3&gt;
&lt;p&gt;In the current release of Percona Operator for PostgreSQL, implementing pg_tde
requires manual configuration steps as outlined above. Users need to explicitly
configure shared libraries, set up key providers, and manage the encryption
infrastructure themselves. This approach, while functional, requires careful
attention to detail and a thorough understanding of both pg_tde and Kubernetes
operations.&lt;/p&gt;
&lt;p&gt;However, future releases of the Percona Operator will introduce seamless
integration with pg_tde, significantly simplifying the encryption
implementation process. The operator will handle the underlying configuration
automatically, allowing users to focus primarily on their database design. In
these upcoming versions, enabling encryption will be as straightforward as
creating tables with the tde_heap access method while the operator manages all
the necessary infrastructure and configuration behind the scenes.&lt;/p&gt;
</description>
      <category>postgresql</category>
      <category>kubernetes</category>
    </item>
  </channel>
</rss>
