查看原文
其他

Kubernetes上PostgreSQL的存储策略



预计阅读时间

10分钟

导 读


在Kubernetes上部署PostgreSQL并不是新鲜事,可以通过各种Operators(包括Percona)轻松实现。在Percona Operator for PostgreSQL中,你可以选择多种存储配置方式。在这篇博客中,我们将回顾各种存储策略——从基础到更复杂的用例。

Percona Operator for PostgreSQL:

https://docs.percona.com/percona-operator-for-postgresql/2.0/index.html


01


基础知识


1.1 设置StorageClass


Kubernetes中的

StorageClass

资源允许用户设置底层存储的各种参数。例如,你可以选择公共云存储类型(如gp3、io2等)或设置文件系统。


StorageClass:

https://kubernetes.io/docs/concepts/storage/storage-classes/


你可以通过运行以下命令来检查现有的存储类:

$ kubectl get sc
NAME                      PROVISIONER             RECLAIMPOLICY   VOLUMEBINDINGMODE      ALLOWVOLUMEEXPANSION   AGE
premium-rwo               pd.csi.storage.gke.io   Delete          WaitForFirstConsumer   true                   54m
regionalpd-storageclass   pd.csi.storage.gke.io   Delete          WaitForFirstConsumer   false                  51m
standard                  kubernetes.io/gce-pd    Delete          Immediate              true                   54m
standard-rwo (default)    pd.csi.storage.gke.io   Delete          WaitForFirstConsumer   true                   54m


你会看到standard-rwo是默认的StorageClass,这意味着如果你如果不指定Operator将默认使用它。


要指示Percona Operator for PostgreSQL使用哪个存储类,请在spec.instances.[].dataVolumeClaimSpec部分设置它:

dataVolumeClaimSpec:
  accessModes:
    - ReadWriteOnce
  storageClassName: STORAGE_CLASS_NAME
  resources:
    requests:
      storage: 1Gi


1.2 为预写日志(WAL)分配单独的卷


预写日志(WAL)记录了PostgreSQL部署中的每个事务。它们对于时间点恢复和最小化恢复点目标(Recovery Point Objective,RPO)很有用。


在Percona Operator中,可以为WAL设置单独的卷,以最小化对性能和存储容量的影响。


要设置它,请使用spec.instances.[].walVolumeClaimSpec部分:

walVolumeClaimSpec:
  accessModes:
    - ReadWriteOnce
  storageClassName: STORAGE_CLASS_NAME
  resources:
    requests:
      storage: 1Gi


如果启用walVolumeClaimSpec,运营商将为每个副本Pod创建两个卷——一个用于数据,一个用于WAL。

cluster1-instance1-8b2m-pgdata   Bound    pvc-2f919a49-d672-49cb-89bd-f86469241381   1Gi        RWO            standard-rwo   36s
cluster1-instance1-8b2m-pgwal    Bound    pvc-bf2c26d8-cf42-44cd-a053-ccb6abadd096   1Gi        RWO            standard-rwo   36s
cluster1-instance1-ncfq-pgdata   Bound    pvc-7ab7e59f-017a-4655-b617-ff17907ace3f   1Gi        RWO            standard-rwo   36s
cluster1-instance1-ncfq-pgwal    Bound    pvc-51baffcf-0edc-472f-9c95-7a0cea3e6507   1Gi        RWO            standard-rwo   36s
cluster1-instance1-w4d8-pgdata   Bound    pvc-c60282ed-3599-4033-afc7-e967871efa1b   1Gi        RWO            standard-rwo   36s
cluster1-instance1-w4d8-pgwal    Bound    pvc-ef530cb4-82fb-4661-ac76-ee7fda1f89ce   1Gi        RWO            standard-rwo   36s


1.3 更改存储大小


如果你的StorageClass和存储接口(CSI)支持

VolumeExpansion

,你可以直接在自定义资源清单中更改存储大小。运营商将完成剩下的工作并自动扩展存储。这是一个零停机操作,仅受底层存储能力的限制。


VolumeExpansion:

https://kubernetes.io/blog/2018/08/02/dynamically-expand-volume-with-csi-and-kubernetes/


1.4 更改存储


也可以更改存储能力,例如文件系统、IOPs和类型。目前,可以通过创建新的存储类并将其应用于新的实例组来实现:

spec:
  instances:
    - name: newGroup
      dataVolumeClaimSpec:
        accessModes:
          - ReadWriteOnce
        storageClassName: NEW_STORAGE_CLASS
        resources:
          requests:
            storage: 2Gi


创建新的实例组会将数据复制到新的副本节点。这是无停机完成的,但复制可能会在主节点和网络上引入额外负载。


Kubernetes Enhancement Proposal (KEP)

#3780

正在进行中。它将允许用户通过存储类以外的方式动态更改各种卷属性。


#3780:

https://github.com/kubernetes/enhancements/pull/3780



02


数据持久化


2.1 Finalizers


默认情况下,如果删除集群,Operator会保留存储和“秘密”资源。我们这样做是为了保护用户免受人为错误和其他情况的影响。


这样,用户可以快速启动集群,重用现有的存储和“秘密”。


可以通过在自定义资源中启用终结器来更改此默认行为:

apiVersion: pgv2.percona.com/v2
kind: PerconaPGCluster
metadata:
  name: cluster1
finalizers:
  - percona.com/delete-pvc
  - percona.com/delete-ssl


这对于不需要保留数据的非生产集群很有用。


2.2 StorageClass数据保护


在极端情况下,人为错误是不可避免的。例如,有人可能会删除整个Kubernetes集群或命名空间。


好在StorageClass资源带有reclaimPolicy选项,它可以指示容器存储接口保留底层卷。这个选项不受Operator控制,你应该单独为StorageClass设置它。

apiVersion: storage.k8s.io/v1
kind: StorageClass
...
provisioner: pd.csi.storage.gke.io
- reclaimPolicy: Delete
+ reclaimPolicy: Retain


在这种情况下,即使删除了Kubernetes资源,物理存储仍然存在。


2.3 区域磁盘


区域磁盘在Azure和Google Cloud上可用,但在AWS上尚未可用。简而言之,它是跨两个可用区(AZ)复制的磁盘。


图1


要使用区域磁盘,你需要一个指定了它将在哪些AZ中可用并复制到的存储类:

kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
  name: regionalpd-storageclass
provisioner: pd.csi.storage.gke.io
parameters:
  type: pd-balanced
  replication-type: regional-pd
  volumeBindingMode: WaitForFirstConsumer
  allowedTopologies:
    - matchLabelExpressions:
      - key: topology.gke.io/zone
        values:
          - us-central1-a
          - us-central1-b



有一些情况下,区域磁盘可以帮助降低成本。让我们回顾三种PostgreSQL拓扑:


1.单节点,普通磁盘

2.单节点,区域

3.PostgreSQL高可用集群,普通磁盘


图2


如果我们将可用区故障应用于这些拓扑,我们将得到以下结果:


1.单节点,普通磁盘是最便宜的,但在AZ故障的情况下,恢复可能需要几小时甚至几天——取决于数据。

2.单节点和区域磁盘,你不会在副本的计算上花费一分钱,但同时你将在几分钟内恢复。

3.PostgreSQL集群提供最佳可用性,但也伴随着高昂的计算成本。



PostgreSQL单节点,普通磁盘

PostgreSQL单节点,普通磁盘

PostgreSQL单节点, 区域磁盘

计算费用


$

$

$$

存储费用

$

$$

$$

网络费用

$0

$0

$

恢复时间级别

小时级

分钟级

秒级


图3


03


本地存储


在Kubernetes上降低有状态工作负载的总拥有成本(TCO)并提高性能的一种方法是使用本地存储,而不是网络磁盘。公共云提供了可以在k8s中使用像

OpenEBS

Portworx

等工具的NVMe SSD实例。它是通过常规存储类消费的,值得单独写一篇博客。


OpenEBS:

https://openebs.io/

Portworx:

https://portworx.com/


04


结论


在这篇博客文章中,我们讨论了存储配置的基础知识,并看到了如何微调各种存储参数。在Kubernetes上运行PostgreSQL有不同的拓扑、需求和相应的策略,根据你的成本、性能和可用性需求,你可以通过Percona Operator选择多种选项。


加入Percona Kubernetes Squad——一个由数据库专业人士组成的团队,他们在各自的组织和更广泛的领域中引领在Kubernetes上创新数据库操作。该小组致力于为其成员提供坚定的支持,共同探索云原生的发展趋势。

图4

* 本文由IvorySQL社区翻译

原文链接:https://www.percona.com/blog/storage-strategies-for-postgresql-on-kubernetes/



推荐阅读


📙IvorySQL3.0:基于PG16.0最新内核,实现兼容Oracle数据库再升级
📙IvorySQL新增命令及有关配置参数介绍




IvorySQL


  一款开源的兼容Oracle的PostgreSQL

官方网址:
https://www.ivorysql.org
社区仓库:
https://github.com/IvorySQL/IvorySQL
IvorySQL社区欢迎并赞赏所有类型的贡献,期待您的加入!
记得在GitHub给我们一个 ⭐奥~


点击文末的 “阅读原文”,开启您的IvorySQL3.0 Release Notes探索之旅,深入了解更多独家特性。

继续滑动看下一个
IvorySQL开源数据库社区
向上滑动看下一个

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存