实现过程
postgres-operator支持在postgresqls cr中定义additionalVolumes,用于为pod中指定容器的指定路径做独立挂载,详细使用如下:
apiVersion: acid.zalan.do/v1
kind: postgresql
metadata:
name: pg1
namespace: po
spec:
...
volume:
size: 1Gi
storageClass: local-path
additionalVolumes:
- name: log
mountPath: /home/postgres/pgdata/pgroot/pg_log #容器内挂载路径
targetContainers:
- postgres
volumeSource:
PersistentVolumeClaim:
claimName: pg-log
readyOnly: false
其中volumnSource就是通用的hostpath、emptydir、网络存储、配置文件、pvc等,不包括指定storageclass;
以上使用pvc方式实现分目录挂载前提就是预先创建pvc;
operator内部实现additionalVolumes的处理在generateStatefulSet->generatePodTemplate,具体细节如下:
如果postgres CR中additionalVolumes不为空,那么operator对additionalVolumes中每一层进行以下解析:
如果mountpath是/home/postgres/pgdata,那么略过该挂载;(pgdata默认用postgresqls cr中spec.volume下的配置)
如果targetContainers是空,那么默认选择postgres容器;
如果targetContainers是all,表示挂载适用于所有容器(包括postgres sidecar exporter等);
此外targetContainers还可以配置多个容器,但该方式与配置为all互斥;
将additionalVolumes中name及volumnsource配置生成到podTemplate/spec/volumns下;
将additionalVolumes中name及mountPath组成VolumeMounts结构,生成到指定container的volumeMounts中;
实际创建集群后, 反映在sts中如下:
kind: StatefulSet
apiVersion: apps/v1
metadata:
name: pg1
namespace: po
spec:
......
spec:
volumes:
- name: dshm
emptyDir:
medium: Memory
- name: log
persistentVolumeClaim:
claimName: pg-log
containers:
- name: postgres
image: spilo-14:2.1-p4
......
volumeMounts:
- name: pgdata
mountPath: /home/postgres/pgdata
- name: dshm
mountPath: /dev/shm
- name: log
mountPath: /home/postgres/pgdata/pgroot/pg_log
terminationMessagePath: /dev/termination-log
......
volumeClaimTemplates:
- kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: pgdata
creationTimestamp: null
annotations:
volume.beta.kubernetes.io/storage-class: local-path
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
storageClassName: local-path
volumeMode: Filesystem
status:
phase: Pending
......
使用效果
通过additionalVolumes的配置可以实现容器内指定路径使用指定pvc,从而实现分盘挂载,如下所示
PS C:\WINDOWS\system32> kubectl get pvc -n po
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
pg-log Bound pvc-df13c2e3-6b17-466d-b780-98cd1b0a8272 322122547200m RWX standard 54m
pgdata-pg1-0 Bound pvc-bfaedb3a-04b9-4218-a397-1308d7d5caa5 1Gi RWO local-path 54m
比如以上将数据主目录使用localpath方式挂载到主机/opt/local-path-provisioner:
# ls /tmp/hostpath-provisioner/po/pg-log/
postgresql-0.csv postgresql-2.csv postgresql-3.csv postgresql-5.csv postgresql-7.csv
postgresql-1.csv postgresql-2.log postgresql-4.csv postgresql-6.csv
注意点:
数据主目录由于默认挂载的容器内/home/postgres/pgdata,而pg_log是主目录的一个子目录,所以主目录在主机的挂载路径中,也是有pg_log这个目录的,只是该目录为空,实际pg_log内容在其单独挂载pv中。