Kubernetes 使用相同的PVC';s作为状态集中的另一个Pod

Kubernetes 使用相同的PVC';s作为状态集中的另一个Pod,kubernetes,kubernetes-statefulset,kubernetes-cronjob,Kubernetes,Kubernetes Statefulset,Kubernetes Cronjob,在Kubernetes集群中,我希望能够安排一个作业(使用CronJob),该作业将装载与给定状态集的1个Pod相同的卷。哪个Pod是运行时决策,取决于调度作业时在Pod上设置的标签 我想很多人都会想知道为什么,因此,请描述一下我们正在做和试图做的事情: 当前设置 我们有一个为PostgreSQL数据库服务的StatefulSet。(一个主副本,多个副本) 我们希望能够从StatefulSet的一个pod创建备份 对于PostgreSQL,我们已经可以使用pg_basebackup通过网络进行备

在Kubernetes集群中,我希望能够安排一个作业(使用CronJob),该作业将装载与给定状态集的1个Pod相同的卷。哪个Pod是运行时决策,取决于调度作业时在Pod上设置的标签

我想很多人都会想知道为什么,因此,请描述一下我们正在做和试图做的事情:

当前设置 我们有一个为PostgreSQL数据库服务的StatefulSet。(一个主副本,多个副本) 我们希望能够从StatefulSet的一个pod创建备份

对于PostgreSQL,我们已经可以使用
pg_basebackup
通过网络进行备份,但是我们正在运行多TB的PostgreSQL数据库,这意味着完全流式备份(使用
pg_basebackup
)是不可行的

我们目前使用
pgbackback
来备份数据库,这允许增量备份

由于
pgbackback
的增量备份需要访问数据卷和WAL卷,因此我们需要在与PostgreSQL实例相同的Kubernetes节点上运行备份容器,目前我们甚至在单独容器中的同一个Pod内运行它

在容器内部,一个小型api包裹在
pgbackback
周围,可以通过向api发送
POST
请求来触发,该触发当前使用CronJobs完成

缺点
  • 每个PostgreSQL实例在Pod中都有多个容器,1个用于服务Postgres,1个用于服务
    pgbackback
  • 作业日志仅显示成功的备份触发器,实际备份日志是备份容器的一部分
  • 运行备份的Pod可能运行在相对较旧的配置上,更改备份配置需要重新安排Pod,这可能意味着PostgreSQL主服务器的故障转移
拟议设置 有一个CronJob计划一个与StatefulSet的一个Pod具有相同卷的Pod。这将允许备份使用这些卷

但是,它需要哪些卷是一个运行时决策:我们可能希望在连接到主卷的卷上运行备份,或者我们可能希望使用副本的卷进行备份。主/副本可能随时更改,因为PostgreSQL主服务器的自动故障切换是解决方案的一部分

目前,这是不可能的,因为我在CronJob规范中找不到任何方法来使用k8sapi中的信息

什么有用,但不是很好:

  • 使用安排作业的CronJob
  • 此作业查询k8s api并安排另一个作业
例如,我们可以使用以下运行时信息让一个作业创建另一个作业:

apiVersion: batch/v1beta1
kind: CronJob
metadata:
  name: schedule-backup
spec:
  schedule: "13 03 * * *"
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: backup-trigger
            image: bitnami/kubectl
            command:
            - sh
            - -c
            - |
              PRIMARYPOD=$(kubectl get pods -l cluster-name=<NAME>,role=master -o custom-columns=":metadata.name" --no-headers)
              kubectl apply -f - <<__JOB__
                apiVersion: batch/v1
                kind: Job
                metadata:
                  name: test
                spec:
                  volumes:
                    name: storage-volume
                    persistentVolumeClaim:
                      claimName:
                        data-volume-${PRIMARYPOD}
                  [...]
              __JOB__
apiVersion:batch/v1beta1
种类:克朗乔
元数据:
名称:计划备份
规格:
附表:“13 03***”
作业模板:
规格:
模板:
规格:
容器:
-名称:备份触发器
图片:bitnami/kubectl
命令:
-嘘
--c
- |
PRIMARYPOD=$(kubectl get pods-l cluster name=,role=master-o custom columns=“:metadata.name”--无标题)

kubectl apply-f-好吧,简单而简短的回答是:你通常不能

但让我们暂时发挥创意:)

数量非常有限的存储后端支持RWX(读写多)访问,在大多数情况下,这些都是在用于数据库时希望避免的较慢的访问。这意味着,除非您将备份包装器作为一个侧车运行(您现在这样做),否则无法在不同的POD中访问PVs

我可能会坚持您最初的方法,并进行一些调整(比如确保您永远不会因为备份/配置更改而关闭主服务器)

在最新的K8S群集和受支持的基础结构提供程序上,您可能需要查找基于快照的备份,并可能使用快照作为源来启动增量备份作业。听起来有点复杂


您还可以使用有限的资源(无实时流量)运行一个备份专用的postgres副本播客,并仅在该播客中嵌入备份逻辑。

谢谢,我希望VolumeSnapshots在未来将变得非常有用。你关于只为备份设置一个单独的pod的建议似乎也很有价值!