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

时间:2017-02-21 07:11:35

标签: postgresql google-cloud-storage kubernetes google-kubernetes-engine

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

我的想法是将备份存储在Google Cloud Storage中,但我不确定如何将磁盘/ 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

我尝试创建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

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

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

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

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

3 个答案:

答案 0 :(得分:2)

我认为将pg_dump作为工作运行是个好主意,但是直接连接到数据库的永久磁盘却不是。尝试让pg_dump通过网络连接到您的数据库!然后,您可以拥有第二个磁盘,pg_dump命令会将备份转储到该磁盘上。为了安全起见,您可以创建第二个磁盘的常规快照。

答案 1 :(得分:1)

作业POD保持Pending状态的原因是它永远尝试附加/挂载GCE永久磁盘而未能这样做,因为它已经附加/挂载到另一个POD。

仅当所有这些POD都以ReadOnly模式附加/装入卷时,才支持将永久磁盘附加到多个POD。这当然不适合你。

我从未与GCE合作,但应该可以从GCE内轻松地从PD创建快照。这不会给出一个非常干净的备份,更像是在中间崩溃的状态,但是可以恢复",但这对你来说可能是可接受的。

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

答案 2 :(得分:1)

您可以使用Minio Client

首先使用简单的dockerfile使docker映像包含postgres以及minio client(将该映像命名为 postgres_backup ):

FROM postgres

RUN apt-get update && apt-get install -y wget

RUN wget https://dl.min.io/client/mc/release/linux-amd64/mc

RUN chmod +x mc

RUN ./mc alias set gcs  https://storage.googleapis.com BKIKJAA5BMMU2RHO6IBB V8f1CwQqAcwo80UEIJEjc5gVQUSSx5ohQ9GSrr12

现在,您可以在CronJob中使用 postgres_backup 图片(我假设您在Google存储空间中创建了 backups 存储桶)

apiVersion: batch/v1beta1
kind: CronJob
metadata:
  name: backup-job
spec:
  # Backup the database every day at 2AM
  schedule: "0 2 * * *"
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: postgres-backup
            image: postgres_backup
            env:
            - name: POSTGRES_HOST_AUTH_METHOD
              value: trust
            command: ["/bin/sh"]
            args: ["-c", 'pg_dump -Fc -U [Your Postgres Username] -W [Your Postgres Password] -h [Your Postgres Host] [Your Postgres Database] | ./mc pipe gcs/backups/$(date -Iseconds).dump']
          restartPolicy: Never