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

Percona Operator for PostgreSQL:https://docs.percona.com/percona-operator-for-postgresql/2.0/...

01基础知识

1.1 设置StorageClass

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

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

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

$ kubectl get scNAME                      PROVISIONER             RECLAIMPOLICY   VOLUMEBINDINGMODE      ALLOWVOLUMEEXPANSION   AGEpremium-rwo               pd.csi.storage.gke.io   Delete          WaitForFirstConsumer   true                   54mregionalpd-storageclass   pd.csi.storage.gke.io   Delete          WaitForFirstConsumer   false                  51mstandard                  kubernetes.io/gce-pd    Delete          Immediate              true                   54mstandard-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   36scluster1-instance1-8b2m-pgwal    Bound    pvc-bf2c26d8-cf42-44cd-a053-ccb6abadd096   1Gi        RWO            standard-rwo   36scluster1-instance1-ncfq-pgdata   Bound    pvc-7ab7e59f-017a-4655-b617-ff17907ace3f   1Gi        RWO            standard-rwo   36scluster1-instance1-ncfq-pgwal    Bound    pvc-51baffcf-0edc-472f-9c95-7a0cea3e6507   1Gi        RWO            standard-rwo   36scluster1-instance1-w4d8-pgdata   Bound    pvc-c60282ed-3599-4033-afc7-e967871efa1b   1Gi        RWO            standard-rwo   36scluster1-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-volu...

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/v2kind: PerconaPGClustermetadata:  name: cluster1finalizers:  - percona.com/delete-pvc  - percona.com/delete-ssl

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

2.2 StorageClass数据保护

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

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

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

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

2.3 区域磁盘

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

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

kind: StorageClassapiVersion: storage.k8s.io/v1metadata:  name: regionalpd-storageclassprovisioner: pd.csi.storage.gke.ioparameters:  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集群提供最佳可用性,但也伴随着高昂的计算成本。
image.png

图片
图3

03本地存储

在Kubernetes上降低有状态工作负载的总拥有成本(TCO)并提高性能的一种方法是使用本地存储,而不是网络磁盘。公共云提供了可以在k8s中使用像OpenEBS、Portworx等工具的NVMe SSD实例。它是通过常规存储类消费的,值得单独写一篇博客。

OpenEBS:https://openebs.io/Portworxhttps://portworx.com/

04结论

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

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

图片
图4


IvorySQL
1 声望0 粉丝

IvorySQL 是瀚高公司主导研发的一款兼容 Oracle 的开源 PostgreSQL 数据库。