如何在Google Cloud上的Kubernetes中备份Postgres数据库?

Mat*_*tMS 9 postgresql google-cloud-storage kubernetes google-kubernetes-engine

备份在Google Cloud Container Engine上运行的Postgres数据库的最佳做法是什么?

我的想法是将备份存储在Google云端存储中,但我不确定如何将磁盘/ Pod连接到存储桶.

我使用以下配置在Kubernetes集群中运行Postgres:

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: postgres-deployment
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: postgres
    spec:
      containers:
        - image: postgres:9.6.2-alpine
          imagePullPolicy: IfNotPresent
          env:
            - name: PGDATA
              value: /var/lib/postgresql/data
            - name: POSTGRES_DB
              value: my-database-name
            - name: POSTGRES_PASSWORD
              value: my-password
            - name: POSTGRES_USER
              value: my-database-user
          name: postgres-container
          ports:
            - containerPort: 5432
          volumeMounts:
            - mountPath: /var/lib/postgresql
              name: my-postgres-volume
      volumes:
        - gcePersistentDisk:
            fsType: ext4
            pdName: my-postgres-disk
          name: my-postgres-volume
Run Code Online (Sandbox Code Playgroud)

我试图创建一个Job来运行备份:

apiVersion: batch/v1
kind: Job
metadata:
  name: postgres-dump-job
spec:
  template:
    metadata:
      labels:
        app: postgres-dump
    spec:
      containers:
        - command:
            - pg_dump
            - my-database-name
          # `env` value matches `env` from previous configuration.
          image: postgres:9.6.2-alpine
          imagePullPolicy: IfNotPresent
          name: my-postgres-dump-container
          volumeMounts:
            - mountPath: /var/lib/postgresql
              name: my-postgres-volume
              readOnly: true
      restartPolicy: Never
      volumes:
        - gcePersistentDisk:
            fsType: ext4
            pdName: my-postgres-disk
          name: my-postgres-volume
Run Code Online (Sandbox Code Playgroud)

(据我所知)这应该运行pg_dump命令并将备份数据输出到stdout(应该出现在kubectl logs)中.

顺便说一句,当我检查Pods(with kubectl get pods)时,它显示Pod永远不会退出"Pending"状态,我收集的状态是由于没有足够的资源来启动Job.

将此过程作为作业运行是否正确?如何将作业连接到Google云端存储?或者我应该做一些完全不同的事情?

我猜测由于性能损失而pg_dump在数据库Container(with kubectl exec)中运行是不明智的,但是在dev/staging服务器中这可能是正常的吗?

gan*_*gam 5

正如@Marco Lamina 所说,您可以在 postgres pod 上运行 pg_dump,例如

DUMP
// pod-name         name of the postgres pod
// postgres-user    database user that is able to access the database
// database-name    name of the database
kubectl exec [pod-name] -- bash -c "pg_dump -U [postgres-user] [database-name]" > database.sql


RESTORE
// pod-name         name of the postgres pod
// postgres-user    database user that is able to access the database
// database-name    name of the database
cat database.sql | kubectl exec -i [pod-name] -- psql -U [postgres-user] -d [database-name]
Run Code Online (Sandbox Code Playgroud)

您可以拥有一个运行此命令并将其导出到文件存储系统(例如 AWS s3)的作业 Pod。


Ale*_*ock 2

Jobs POD 保持状态的原因Pending是它永远尝试附加/挂载 GCE 永久磁盘,但未能成功,因为它已经附加/挂载到另一个 POD。

仅当所有 POD 以只读模式附加/装载卷时,才支持将永久磁盘附加到多个 POD。这对您来说当然不是可行的解决方案。

我从未使用过 GCE,但应该可以轻松地从 GCE 内的 PD 创建快照。这不会提供非常干净的备份,更像是处于“中间崩溃,但可恢复”状态的备份,但这对您来说可能是可以接受的。

pg_dump在数据库 POD 中运行是一个可行的解决方案,但也有一些您已经注意到的缺点,尤其是性能。之后您还必须从 POD 中移出生成的备份,例如使用kubectl cp和 另一个exec来清理 POD 中的备份。