For example, use a storage service (like Rook/openEBS/portworx/etc) that uses node-attached disks to create a data layer. Then you can assign volumes to your individual workloads created and managed by the storage service.
This provides reliable and portable storage for your other services without having to tying them to lower-level details.
Having Postgres replicate the data across AZs or run Ceph on top of EBS to do it at the storage level are options. The complexity of setup is made simpler by running their respective operators.
There used to be bugs with this years ago but all storage providers now get this right.
I’ve not had issues with EBS/AWS, and affinity configs meant it was really easy to spread nodes throughout AZ’s.
On Azure though, volume mounts/unmounts were an absolute dumpster fire.
I've faced so many issues with the CSI driver which doesn't attach/deattach properly when you modify anything on the Statetfulset.
Additionally, you need to pin your DBs ("statefulset workloads") to certain Nodes based on the AZs since a block storage like an EBS cannot really be attached from Zone 1 to Zone 2 automatically.
Based on these limitations, I dont really see any utility/usefulness in running a DB on K8s. I get all of the other niceties that K8s offers, but here it makes the Ops work more complex than desired.